--- old/usr/src/lib/libdhcpsvc/modules/files/dhcptab.c	Tue Nov  4 14:40:12 2014
+++ /dev/null	Tue Nov  4 14:31:37 2014
@@ -1,577 +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 file contains public API functions for managing the dhcptab
- * container.  For the semantics of these functions, please see the
- * Enterprise DHCP Architecture Document.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <alloca.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <dhcp_svc_public.h>
-
-#include "dhcptab.h"
-#include "util.h"
-
-static void dt2path(char *, size_t, const char *, const char *);
-static int write_rec(int, dt_rec_t *, off_t);
-
-int
-open_dt(void **handlep, const char *location, uint_t flags)
-{
-	dt_handle_t	*dhp;
-	unsigned int	conver;
-	int		nelems;
-	int		retval;
-	char		nl;
-	int		fd;
-	char		dtpath[MAXPATHLEN];
-	FILE		*fp;
-
-	dhp = malloc(sizeof (dt_handle_t));
-	if (dhp == NULL)
-		return (DSVC_NO_MEMORY);
-
-	dhp->dh_oflags = flags;
-	(void) strlcpy(dhp->dh_location, location, MAXPATHLEN);
-
-	dt2path(dtpath, MAXPATHLEN, location, "");
-	retval = open_file(dtpath, flags, &fd);
-	if (retval != DSVC_SUCCESS) {
-		free(dhp);
-		return (retval);
-	}
-
-	fp = fdopen(fd, flags & DSVC_WRITE ? "r+" : "r");
-	if (fp == NULL) {
-		(void) close(fd);
-		free(dhp);
-		return (DSVC_INTERNAL);
-	}
-
-	if (flags & DSVC_CREATE) {
-		/*
-		 * We just created the per-network container; put the
-		 * header on for future use...
-		 */
-		retval = fprintf(fp, "# SUNWfiles%u_dhcptab\n", DSVC_CONVER);
-		if (retval < 0 || fflush(fp) == EOF) {
-			(void) fclose(fp);
-			(void) free(dhp);
-			return (DSVC_INTERNAL);
-		}
-
-		(void) fprintf(fp, "#\n# Do NOT edit this file by hand -- use");
-		(void) fprintf(fp, " dhtadm(1M) or dhcpmgr(1M) instead\n#\n");
-	} else {
-		/*
-		 * Container already exists; sanity check against the
-		 * header that's on-disk.
-		 */
-		nelems = fscanf(fp, "#%*1[ ]SUNWfiles%u_dhcptab%c", &conver,
-		    &nl);
-		if (nelems != 2 || conver != DSVC_CONVER || nl != '\n') {
-			(void) fclose(fp);
-			free(dhp);
-			return (DSVC_INTERNAL);
-		}
-	}
-
-	(void) fclose(fp);
-	*handlep = dhp;
-	return (DSVC_SUCCESS);
-}
-
-int
-close_dt(void **handlep)
-{
-	free(*handlep);
-	return (DSVC_SUCCESS);
-}
-
-int
-remove_dt(const char *location)
-{
-	char dtpath[MAXPATHLEN];
-
-	dt2path(dtpath, MAXPATHLEN, location, "");
-	if (unlink(dtpath) == -1)
-		return (syserr_to_dsvcerr(errno));
-
-	return (DSVC_SUCCESS);
-}
-
-/*
- * Internal version of lookup_dt() used by both lookup_dt() and
- * update_dt(); same semantics as lookup_dt() except that the `partial'
- * argument has been generalized into a `flags' field and the handle has
- * been turned into a FILE pointer.
- */
-static int
-find_dt(FILE *fp, uint_t flags, uint_t query, int count,
-    const dt_rec_t *targetp, dt_rec_list_t **recordsp, uint_t *nrecordsp)
-{
-	int		retval = DSVC_SUCCESS;
-	char 		*buf = NULL, *fields[DTF_FIELDS];
-	uint_t		nrecords;
-	dt_rec_t	dt, *recordp;
-	dt_rec_list_t	*records, *new_records;
-	off_t		recoff;
-	unsigned int	nfields;
-
-	if (fseek(fp, 0, SEEK_SET) == -1)
-		return (DSVC_INTERNAL);
-
-	records = NULL;
-	for (nrecords = 0; count < 0 || nrecords < count; ) {
-		free(buf);
-
-		if (flags & FIND_POSITION)
-			recoff = ftello(fp);
-
-		buf = read_entry(fp);
-		if (buf == NULL) {
-			if (!feof(fp))
-				retval = DSVC_NO_MEMORY;
-			break;
-		}
-
-		/*
-		 * Skip pure comment lines; for now this just skips the
-		 * header information at the top of the container.
-		 */
-		if (buf[0] == DTF_COMMENT_CHAR)
-			continue;
-
-		/*
-		 * Split the buffer up into DTF_FIELDS fields.
-		 */
-		nfields = field_split(buf, DTF_FIELDS, fields, "|");
-		if (nfields < DTF_FIELDS)
-			continue;
-
-		/*
-		 * See if we've got a match.  If so, allocate the new
-		 * record, fill it in, and continue.
-		 */
-		dt.dt_type = fields[DTF_TYPE][0];
-		if (DSVC_QISEQ(query, DT_QTYPE) &&
-		    targetp->dt_type != dt.dt_type)
-			continue;
-		else if (DSVC_QISNEQ(query, DT_QTYPE) &&
-		    targetp->dt_type == dt.dt_type)
-			continue;
-
-		unescape('|', fields[DTF_KEY], dt.dt_key, sizeof (dt.dt_key));
-		if (DSVC_QISEQ(query, DT_QKEY) &&
-		    strcmp(targetp->dt_key, dt.dt_key) != 0)
-			continue;
-		else if (DSVC_QISNEQ(query, DT_QKEY) &&
-		    strcmp(targetp->dt_key, dt.dt_key) == 0)
-			continue;
-
-		/*
-		 * Caller just wants a count of the number of matching
-		 * records, not the records themselves; continue.
-		 */
-		if (recordsp == NULL) {
-			nrecords++;
-			continue;
-		}
-
-		dt.dt_sig = atoll(fields[DTF_SIG]);
-		dt.dt_value = strdup(fields[DTF_VALUE]);
-		if (dt.dt_value == NULL) {
-			if ((flags & FIND_PARTIAL) == 0)
-				retval = DSVC_NO_MEMORY;
-			break;
-		}
-
-		/*
-		 * Allocate record; if FIND_POSITION flag is set, then
-		 * we need to allocate an extended (dt_recpos_t) record.
-		 */
-		if (flags & FIND_POSITION)
-			recordp = malloc(sizeof (dt_recpos_t));
-		else
-			recordp = malloc(sizeof (dt_rec_t));
-
-		if (recordp == NULL) {
-			free(dt.dt_value);
-			if ((flags & FIND_PARTIAL) == 0)
-				retval = DSVC_NO_MEMORY;
-			break;
-		}
-
-		/*
-		 * Fill in record; do a structure copy from our automatic
-		 * dt.  If FIND_POSITION flag is on, pass back additional
-		 * location information.
-		 */
-		*recordp = dt;
-		if (flags & FIND_POSITION) {
-			((dt_recpos_t *)recordp)->dtp_off = recoff;
-			((dt_recpos_t *)recordp)->dtp_size = ftello(fp) -
-			    recoff;
-		}
-
-		/*
-		 * Chuck the record on the list; up the counter.
-		 */
-		new_records = add_dtrec_to_list(recordp, records);
-		if (new_records == NULL) {
-			free_dtrec(recordp);
-			if ((flags & FIND_PARTIAL) == 0)
-				retval = DSVC_NO_MEMORY;
-			break;
-		}
-		records = new_records;
-		nrecords++;
-	}
-
-	free(buf);
-
-	if (retval == DSVC_SUCCESS) {
-		*nrecordsp = nrecords;
-		if (recordsp != NULL)
-			*recordsp = records;
-		return (DSVC_SUCCESS);
-	}
-
-	if (records != NULL)
-		free_dtrec_list(records);
-
-	return (retval);
-}
-
-int
-lookup_dt(void *handle, boolean_t partial, uint_t query, int count,
-    const dt_rec_t *targetp, dt_rec_list_t **recordsp, uint_t *nrecordsp)
-{
-	int		retval;
-	char		dtpath[MAXPATHLEN];
-	FILE		*fp;
-	dt_handle_t	*dhp = (dt_handle_t *)handle;
-
-	if ((dhp->dh_oflags & DSVC_READ) == 0)
-		return (DSVC_ACCESS);
-
-	dt2path(dtpath, MAXPATHLEN, dhp->dh_location, "");
-	fp = fopen(dtpath, "r");
-	if (fp == NULL)
-		return (syserr_to_dsvcerr(errno));
-
-	retval = find_dt(fp, partial ? FIND_PARTIAL : 0, query, count, targetp,
-	    recordsp, nrecordsp);
-
-	(void) fclose(fp);
-	return (retval);
-}
-
-/*
- * Internal dhcptab record update routine, used to factor out the
- * common code between add_dt(), delete_dt(), and modify_dt().  If
- * `origp' is NULL, then act like add_dt(); if `newp' is NULL, then
- * act like delete_dt(); otherwise act like modify_dt().
- */
-static int
-update_dt(const dt_handle_t *dhp, const dt_rec_t *origp, dt_rec_t *newp)
-{
-	char		dtpath[MAXPATHLEN], newpath[MAXPATHLEN];
-	int		retval = DSVC_SUCCESS;
-	off_t		recoff, recnext;
-	dt_rec_list_t	*reclist;
-	FILE		*fp;
-	int		newfd;
-	uint_t		found;
-	int		query;
-	struct stat	st;
-
-	if ((dhp->dh_oflags & DSVC_WRITE) == 0)
-		return (DSVC_ACCESS);
-
-	/*
-	 * Open the container to update and a new container file which we
-	 * will store the updated version of the container in.  When the
-	 * update is done, rename the new file to be the real container.
-	 */
-	dt2path(dtpath, MAXPATHLEN, dhp->dh_location, "");
-	fp = fopen(dtpath, "r");
-	if (fp == NULL)
-		return (syserr_to_dsvcerr(errno));
-
-	dt2path(newpath, MAXPATHLEN, dhp->dh_location, ".new");
-	(void) unlink(newpath);
-	newfd = open(newpath, O_CREAT|O_EXCL|O_WRONLY, 0644);
-	if (newfd == -1) {
-		(void) fclose(fp);
-		return (syserr_to_dsvcerr(errno));
-	}
-
-	DSVC_QINIT(query);
-	DSVC_QEQ(query, DT_QKEY|DT_QTYPE);
-
-	/*
-	 * If we're changing the key for this record, make sure the key
-	 * we're changing to doesn't already exist.
-	 */
-	if (origp != NULL && newp != NULL) {
-		if ((origp->dt_type != newp->dt_type ||
-		    strcmp(origp->dt_key, newp->dt_key) != 0)) {
-			retval = find_dt(fp, 0, query, 1, newp, NULL, &found);
-			if (retval != DSVC_SUCCESS)
-				goto out;
-			if (found != 0) {
-				retval = DSVC_EXISTS;
-				goto out;
-			}
-		}
-	}
-
-	/*
-	 * If we're adding a new record, make sure the record doesn't
-	 * already exist.
-	 */
-	if (newp != NULL && origp == NULL) {
-		retval = find_dt(fp, 0, query, 1, newp, NULL, &found);
-		if (retval != DSVC_SUCCESS)
-			goto out;
-		if (found != 0) {
-			retval = DSVC_EXISTS;
-			goto out;
-		}
-	}
-
-	/*
-	 * If we're deleting or modifying record, make sure the record
-	 * still exists and that our copy isn't stale.  Note that we don't
-	 * check signatures if we're deleting the record and origp->dt_sig
-	 * is zero, so that records can be deleted that weren't looked up
-	 * first.
-	 */
-	if (origp != NULL) {
-		retval = find_dt(fp, FIND_POSITION, query, 1, origp, &reclist,
-		    &found);
-		if (retval != DSVC_SUCCESS)
-			goto out;
-		if (found == 0) {
-			retval = DSVC_NOENT;
-			goto out;
-		}
-
-		if (reclist->dtl_rec->dt_sig != origp->dt_sig) {
-			if (newp != NULL || origp->dt_sig != 0) {
-				free_dtrec_list(reclist);
-				retval = DSVC_COLLISION;
-				goto out;
-			}
-		}
-
-		/*
-		 * Note the offset of the record we're modifying or deleting
-		 * for use down below.
-		 */
-		recoff  = ((dt_recpos_t *)reclist->dtl_rec)->dtp_off;
-		recnext = recoff + ((dt_recpos_t *)reclist->dtl_rec)->dtp_size;
-
-		free_dtrec_list(reclist);
-	} else {
-		/*
-		 * No record to modify or delete, so set `recoff' and
-		 * `recnext' appropriately.
-		 */
-		recoff = 0;
-		recnext = 0;
-	}
-
-	/*
-	 * Make a new copy of the container.  If we're deleting or
-	 * modifying a record, don't copy that record to the new container.
-	 */
-	if (fstat(fileno(fp), &st) == -1) {
-		retval = DSVC_INTERNAL;
-		goto out;
-	}
-
-	retval = copy_range(fileno(fp), 0, newfd, 0, recoff);
-	if (retval != DSVC_SUCCESS)
-		goto out;
-
-	retval = copy_range(fileno(fp), recnext, newfd, recoff,
-	    st.st_size - recnext);
-	if (retval != DSVC_SUCCESS)
-		goto out;
-
-	/*
-	 * If there's a new record, append it to the new container.
-	 */
-	if (newp != NULL) {
-		if (origp == NULL)
-			newp->dt_sig = gensig();
-		else
-			newp->dt_sig = origp->dt_sig + 1;
-
-		if (fstat(newfd, &st) == -1) {
-			retval = DSVC_INTERNAL;
-			goto out;
-		}
-
-		retval = write_rec(newfd, newp, st.st_size);
-		if (retval != DSVC_SUCCESS)
-			goto out;
-	}
-
-	/*
-	 * Note: we close these descriptors before the rename(2) (rather
-	 * than just having the `out:' label clean them up) to save NFS
-	 * some work (otherwise, NFS has to save `dnpath' to an alternate
-	 * name since its vnode would still be active).
-	 */
-	(void) fclose(fp);
-	(void) close(newfd);
-
-	if (rename(newpath, dtpath) == -1)
-		retval = syserr_to_dsvcerr(errno);
-
-	return (retval);
-out:
-	(void) fclose(fp);
-	(void) close(newfd);
-	(void) unlink(newpath);
-	return (retval);
-}
-
-int
-delete_dt(void *handle, const dt_rec_t *delp)
-{
-	return (update_dt((dt_handle_t *)handle, delp, NULL));
-}
-
-int
-add_dt(void *handle, dt_rec_t *addp)
-{
-	return (update_dt((dt_handle_t *)handle, NULL, addp));
-}
-
-int
-modify_dt(void *handle, const dt_rec_t *origp, dt_rec_t *newp)
-{
-	return (update_dt((dt_handle_t *)handle, origp, newp));
-}
-
-int
-list_dt(const char *location, char ***listppp, uint_t *countp)
-{
-	char	dtpath[MAXPATHLEN];
-	char	**listpp;
-
-	if (access(location, F_OK|R_OK) == -1) {
-		switch (errno) {
-		case EACCES:
-		case EPERM:
-			return (DSVC_ACCESS);
-		case ENOENT:
-			return (DSVC_NO_LOCATION);
-		default:
-			break;
-		}
-		return (DSVC_INTERNAL);
-	}
-
-	dt2path(dtpath, MAXPATHLEN, location, "");
-	if (access(dtpath, F_OK|R_OK) == -1) {
-		*countp = 0;
-		*listppp = NULL;
-		return (DSVC_SUCCESS);
-	}
-
-	listpp = malloc(sizeof (char **));
-	if (listpp == NULL)
-		return (DSVC_NO_MEMORY);
-	listpp[0] = strdup(DT_DHCPTAB);
-	if (listpp[0] == NULL) {
-		free(listpp);
-		return (DSVC_NO_MEMORY);
-	}
-
-	*listppp = listpp;
-	*countp = 1;
-	return (DSVC_SUCCESS);
-}
-
-/*
- * Given a buffer `path' of `pathlen' bytes, fill it in with a path to the
- * dhcptab in directory `dir' with a suffix of `suffix'.
- */
-static void
-dt2path(char *path, size_t pathlen, const char *dir, const char *suffix)
-{
-	(void) snprintf(path, pathlen, "%s/SUNWfiles%u_%s%s", dir,
-	    DSVC_CONVER, DT_DHCPTAB, suffix);
-}
-
-/*
- * Write the dt_rec_t pointed to by `recp' into the open container `fd' at
- * offset `recoff'.  Returns DSVC_* error code.
- */
-static int
-write_rec(int fd, dt_rec_t *recp, off_t recoff)
-{
-	char	escaped_key[DSVC_MAX_MACSYM_LEN * 2 + 1];
-	char	entbuf[1024], *ent = entbuf;
-	size_t	entsize = sizeof (entbuf);
-	int	entlen;
-
-	escape('|', recp->dt_key, escaped_key, sizeof (escaped_key));
-again:
-	entlen = snprintf(ent, entsize, "%s|%c|%llu|%s\n", escaped_key,
-	    recp->dt_type, recp->dt_sig, recp->dt_value);
-	if (entlen == -1)
-		return (syserr_to_dsvcerr(errno));
-
-	if (entlen > entsize) {
-		entsize = entlen;
-		ent = alloca(entlen);
-		goto again;
-	}
-
-	if (pnwrite(fd, ent, entlen, recoff) == -1)
-		return (syserr_to_dsvcerr(errno));
-
-	return (DSVC_SUCCESS);
-}
