diff options
Diffstat (limited to 'usr/src/lib/libdhcpsvc/private/confopt.c')
| -rw-r--r-- | usr/src/lib/libdhcpsvc/private/confopt.c | 415 |
1 files changed, 0 insertions, 415 deletions
diff --git a/usr/src/lib/libdhcpsvc/private/confopt.c b/usr/src/lib/libdhcpsvc/private/confopt.c deleted file mode 100644 index 05fb4fe758..0000000000 --- a/usr/src/lib/libdhcpsvc/private/confopt.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This module contains the functions implementing the interface to the - * /etc/inet/dhcpsvc.conf DHCP service configuration file. - */ - -#include <thread.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <alloca.h> -#include <string.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <dhcp_svc_confkey.h> -#include <dhcp_svc_confopt.h> -#include <dhcp_svc_private.h> - -/* - * Finds the parameter called key, and returns a reference to it. Returns - * NULL if not found or an error occurred. - */ -static dhcp_confopt_t * -find_dhcp_confopt(dhcp_confopt_t *ddp, const char *key) -{ - unsigned int i; - - if (ddp == NULL || key == NULL) - return (NULL); - - for (i = 0; ddp[i].co_type != DHCP_END; i++) { - if (ddp[i].co_type == DHCP_KEY && - strcasecmp(ddp[i].co_key, key) == 0) - return (&ddp[i]); - } - return (NULL); -} - -/* - * Adds a dhcp_confopt_t to the ddpp table. If the table is NULL, one is - * created. The table is terminated by a NULL entry. The key and value - * arguments are copied, not referenced directly. No check is done to see - * if the parameter already exists. Returns 0 for success, nonzero - * otherwise. - */ -int -add_dsvc_conf(dhcp_confopt_t **ddpp, const char *key, const char *value) -{ - dhcp_confopt_t *ndp, tdp; - unsigned int i; - - if (ddpp == NULL || key == NULL || value == NULL) { - errno = EINVAL; - return (-1); - } - - tdp.co_key = strdup(key); - tdp.co_type = DHCP_KEY; - tdp.co_value = strdup(value); - if (tdp.co_key == NULL || tdp.co_value == NULL) { - free(tdp.co_key); - free(tdp.co_value); - errno = ENOMEM; - return (-1); - } - - for (i = 0; *ddpp && (*ddpp)[i].co_key != NULL; i++) - ; - - ndp = realloc(*ddpp, (i + 2) * sizeof (dhcp_confopt_t)); - if (ndp == NULL) { - free(tdp.co_key); - free(tdp.co_value); - errno = ENOMEM; - return (-1); - } - - ndp[i] = tdp; - (void) memset(&ndp[i + 1], 0, sizeof (dhcp_confopt_t)); - *ddpp = ndp; - - return (0); -} - -/* - * Reads the contents of the configuration file into a dynamically - * allocated array of dhcp_confopt_t records. A zeroed element marks the - * end of the array. Blank lines are ignored. Caller is responsible for - * freeing ddp. - */ -int -read_dsvc_conf(dhcp_confopt_t **ddpp) -{ - struct stat sb; - int dd; - int error; - unsigned int entry; - char *cp, *dp, *eol, *value; - dhcp_confopt_t confopt, *tdp, *ddp = NULL; - char conf[MAXPATHLEN]; - - if (ddpp == NULL) { - errno = EINVAL; - return (-1); - } - - (void) snprintf(conf, sizeof (conf), "%s" DHCP_CONFOPT_FILE, - DHCP_CONFOPT_ROOT); - - if ((dd = open(conf, O_RDONLY)) == -1) - return (-1); - if (fstat(dd, &sb) == -1) { - error = errno; - (void) close(dd); - errno = error; - return (-1); - } - - dp = alloca(sb.st_size); - if (read(dd, dp, sb.st_size) != sb.st_size) { - error = errno; - (void) close(dd); - errno = error; - return (-1); - } - (void) close(dd); - - for (entry = 0, cp = dp; cp < &dp[sb.st_size]; cp = eol + 1) { - eol = strchr(cp, '\n'); - if (eol == NULL) /* done parsing file */ - break; - if (eol == cp) /* blank line -- skip */ - continue; - *eol = '\0'; - - if (*cp == '#') { - confopt.co_type = DHCP_COMMENT; - confopt.co_comment = strdup(cp + 1); - if (confopt.co_comment == NULL) - goto nomem; - } else { - value = strchr(cp, '='); - if (value == NULL) - continue; - *value = '\0'; - - confopt.co_type = DHCP_KEY; - confopt.co_key = strdup(cp); - if (confopt.co_key == NULL) - goto nomem; - - confopt.co_value = strdup(value + 1); - if (confopt.co_value == NULL) { - free(confopt.co_key); - goto nomem; - } - } - - /* always allocate a spare slot for the zeroed entry */ - tdp = realloc(ddp, (entry + 2) * sizeof (dhcp_confopt_t)); - if (tdp == NULL) - goto nomem; - - tdp[entry] = confopt; - (void) memset(&tdp[entry + 1], 0, sizeof (dhcp_confopt_t)); - ddp = tdp; - entry++; - } - - if (ddp == NULL) - return (-1); - - *ddpp = ddp; - return (0); - -nomem: - if (ddp != NULL) - free_dsvc_conf(ddp); - - errno = ENOMEM; - return (-1); -} - -/* - * If the requested parameter exists, replace its value with the new - * value. If it doesn't exist, then add the parameter with the new value. - * Returns 0 for success, -1 otherwise (errno is set). - */ -int -replace_dsvc_conf(dhcp_confopt_t **ddpp, const char *key, const char *value) -{ - dhcp_confopt_t *tdp; - int err; - - if (ddpp == NULL || key == NULL || value == NULL) { - errno = EINVAL; - return (-1); - } - if ((tdp = find_dhcp_confopt(*ddpp, key)) != NULL) { - char *valp; - - if ((valp = strdup(value)) == NULL) - return (-1); /* NOMEM */ - - if (tdp->co_value != NULL) - free(tdp->co_value); - - tdp->co_value = valp; - - errno = 0; - err = 0; - } else - err = (add_dsvc_conf(ddpp, key, value) == 0) ? 0 : -1; - - return (err); -} - -/* - * Writes ddp array to the configuration file. If the configuration file - * already exists, its contents are replaced with the contents of the ddp - * array. If the configuration file does not exist, it is created using - * the identity of the caller (euid/egid) with the permission bits - * specified by the mode argument (and modified by the umask). Caller is - * responsible for freeing the array. - */ -int -write_dsvc_conf(dhcp_confopt_t *ddp, mode_t mode) -{ - int tdd; - ssize_t bytes; - size_t i, size; - char *tmpbuf; - char tmpconf[MAXPATHLEN], conf[MAXPATHLEN]; - - if (ddp == NULL) { - errno = EINVAL; - return (-1); - } - - /* guess at final file size */ - for (i = 0, size = 0; ddp[i].co_type != DHCP_END; i++) { - if (ddp[i].co_type == DHCP_KEY) { - size += strlen(ddp[i].co_key) + 1; /* include = */ - size += strlen(ddp[i].co_value) + 1; /* include \n */ - } else - size += strlen(ddp[i].co_comment) + 2; /* inc # + \n */ - } - - if (size == 0) { - errno = EINVAL; - return (-1); - } - - (void) snprintf(conf, sizeof (conf), "%s" DHCP_CONFOPT_FILE, - DHCP_CONFOPT_ROOT); - (void) snprintf(tmpconf, sizeof (tmpconf), - "%s" DHCP_CONFOPT_FILE ".%ld.%u", DHCP_CONFOPT_ROOT, getpid(), - thr_self()); - - if ((tdd = open(tmpconf, O_CREAT | O_EXCL | O_WRONLY, mode)) < 0) - return (-1); - - tmpbuf = alloca(size); - for (i = 0; ddp[i].co_type != DHCP_END; i++) { - if (ddp[i].co_type == DHCP_KEY) - (void) snprintf(tmpbuf, size, "%s=%s\n", ddp[i].co_key, - ddp[i].co_value); - else - (void) snprintf(tmpbuf, size, "#%s\n", - ddp[i].co_comment); - - bytes = write(tdd, tmpbuf, strlen(tmpbuf)); - - /* Nuke the file if we can't successfully update it */ - if (bytes != strlen(tmpbuf)) { - (void) close(tdd); - (void) unlink(tmpconf); - return (-1); - } - } - (void) close(tdd); - - /* Move new file into place */ - if (rename(tmpconf, conf) < 0) { - (void) unlink(tmpconf); - return (-1); - } - - return (0); -} - -/* - * Frees the memory associated with the ddp array. - */ -void -free_dsvc_conf(dhcp_confopt_t *ddp) -{ - unsigned int i; - - if (ddp == NULL) - return; - - for (i = 0; ddp[i].co_type != DHCP_END; i++) { - if (ddp[i].co_type == DHCP_KEY) { - free(ddp[i].co_key); - free(ddp[i].co_value); - } else - free(ddp[i].co_comment); - } - free(ddp); -} - -/* - * Deletes the configuration file. - */ -int -delete_dsvc_conf(void) -{ - char confpath[MAXPATHLEN]; - - (void) snprintf(confpath, sizeof (confpath), "%s" DHCP_CONFOPT_FILE, - DHCP_CONFOPT_ROOT); - return (unlink(confpath)); -} - -/* - * Return a copy of the value portion of the named key. Caller is - * responsible for freeing value when they're finished using it. Returns 0 - * for success, -1 otherwise (errno is set). - */ -int -query_dsvc_conf(dhcp_confopt_t *ddp, const char *key, char **value) -{ - dhcp_confopt_t *tdp; - - if (key == NULL || value == NULL) { - errno = EINVAL; - return (-1); - } - if ((tdp = find_dhcp_confopt(ddp, key)) != NULL) { - *value = strdup(tdp->co_value); - if (*value == NULL) { - errno = ENOMEM; - return (-1); - } - errno = 0; - return (0); - } - errno = ENOENT; - *value = NULL; - return (-1); -} - -/* - * Given a dhcp_confopt_t structure, fill in a dsvc_datastore_t. - * Data is copied from dhcp_confopt_t structure. - */ -int -confopt_to_datastore(dhcp_confopt_t *ddp, dsvc_datastore_t *dsp) -{ - dhcp_confopt_t *tdp; - - if (ddp == NULL || dsp == NULL) - return (DSVC_INVAL); - - tdp = find_dhcp_confopt(ddp, DSVC_CK_CONVER); - if (tdp == NULL || tdp->co_value == NULL) - return (DSVC_BAD_CONVER); - dsp->d_conver = atoi(tdp->co_value); - - if (query_dsvc_conf(ddp, DSVC_CK_RESOURCE, &dsp->d_resource) == -1) - return (DSVC_BAD_RESOURCE); - - if (query_dsvc_conf(ddp, DSVC_CK_PATH, &dsp->d_location) == -1) { - free(dsp->d_resource); - return (DSVC_BAD_PATH); - } - - /* - * RESOURCE_CONFIG is optional - underlying service will complain - * if it isn't right. - */ - (void) query_dsvc_conf(ddp, DSVC_CK_RESOURCE_CONFIG, &dsp->d_config); - - return (DSVC_SUCCESS); -} |
