summaryrefslogtreecommitdiff
path: root/usr.sbin/netgroup_mkdb
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /usr.sbin/netgroup_mkdb
initial import of NetBSD tree
Diffstat (limited to 'usr.sbin/netgroup_mkdb')
-rw-r--r--usr.sbin/netgroup_mkdb/Makefile8
-rw-r--r--usr.sbin/netgroup_mkdb/netgroup_mkdb.888
-rw-r--r--usr.sbin/netgroup_mkdb/netgroup_mkdb.c715
-rw-r--r--usr.sbin/netgroup_mkdb/str.c119
-rw-r--r--usr.sbin/netgroup_mkdb/str.h47
-rw-r--r--usr.sbin/netgroup_mkdb/util.c104
-rw-r--r--usr.sbin/netgroup_mkdb/util.h40
7 files changed, 1121 insertions, 0 deletions
diff --git a/usr.sbin/netgroup_mkdb/Makefile b/usr.sbin/netgroup_mkdb/Makefile
new file mode 100644
index 00000000000..1424a3d839b
--- /dev/null
+++ b/usr.sbin/netgroup_mkdb/Makefile
@@ -0,0 +1,8 @@
+# from: @(#)Makefile 5.1 (Berkeley) 3/8/91
+# $Id: Makefile,v 1.1 1995/10/18 08:47:57 deraadt Exp $
+
+PROG= netgroup_mkdb
+SRCS= netgroup_mkdb.c util.c str.c
+MAN= netgroup_mkdb.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/netgroup_mkdb/netgroup_mkdb.8 b/usr.sbin/netgroup_mkdb/netgroup_mkdb.8
new file mode 100644
index 00000000000..751d4804f09
--- /dev/null
+++ b/usr.sbin/netgroup_mkdb/netgroup_mkdb.8
@@ -0,0 +1,88 @@
+.\"
+.\" Copyright (c) 1994 Christos Zoulas
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Christos Zoulas.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $Id: netgroup_mkdb.8,v 1.1 1995/10/18 08:47:57 deraadt Exp $
+.\"
+.Dd February 3, 1994
+.Dt NETGROUP_MKDB 8
+.Os
+.Sh NAME
+.Nm netgroup_mkdb
+.Nd generate the netgroup databases
+.Sh SYNOPSIS
+.Nm netgroup_mkdb
+.Op Fl o Ar database
+.Op file
+.Sh DESCRIPTION
+.Nm Netgroup_mkdb
+creates
+.Xr db 3
+style databases for the specified file. If no file is specified, then
+.Pa /etc/netgroup
+is used.
+These databases are then installed into
+.Pa /etc/netgroup.db.
+The file must be in the correct format (see
+.Xr netgroup 5 ).
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl o Ar database
+Put the output databases in the named file.
+.El
+.Pp
+The databases are used by the C library netgroup routines (see
+.Xr getnetgrent 3 ).
+.Pp
+.Nm Netgroup_mkdb
+exits zero on success, non-zero on failure.
+.Sh FILES
+.Bl -tag -width 24n -compact
+.It Pa /etc/netgroup.db
+The current netgroup database
+.It Pa /etc/netgroup.db.tmp
+A temporary file
+.It Pa /etc/netgroup
+The current netgroup file
+.El
+.Sh BUGS
+Because
+.Nm netgroup_mkdb
+guarantees not to install a partial destination file it must
+build a temporary file in the same file system and if successful use
+.Xr rename 2
+to install over the destination file.
+.Pp
+If
+.Nm netgroup_mkdb
+fails it will leave the previous version of the destination file intact.
+.Sh SEE ALSO
+.Xr db 3 ,
+.Xr getnetgrent 3 ,
+.Xr netgroup 5
diff --git a/usr.sbin/netgroup_mkdb/netgroup_mkdb.c b/usr.sbin/netgroup_mkdb/netgroup_mkdb.c
new file mode 100644
index 00000000000..ebc0a0e5c4d
--- /dev/null
+++ b/usr.sbin/netgroup_mkdb/netgroup_mkdb.c
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef lint
+static char *rcsid = "$Id: netgroup_mkdb.c,v 1.1 1995/10/18 08:47:57 deraadt Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <db.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <netgroup.h>
+#include <assert.h>
+
+#include "str.h"
+#include "util.h"
+
+#define NEW(a) (a *) emalloc(sizeof(a))
+
+struct nentry {
+ int n_type;
+ size_t n_size; /* Buffer size required for printing */
+ union {
+ char *_name;
+ struct netgroup *_group;
+ } _n;
+#define n_name _n._name
+#define n_group _n._group
+ struct nentry *n_next;
+};
+
+
+struct stringlist;
+
+extern struct stringlist
+ *_ng_sl_init __P((void));
+extern void _ng_sl_add __P((struct stringlist *, char *));
+extern void _ng_sl_free __P((struct stringlist *, int));
+extern char *_ng_sl_find __P((struct stringlist *, char *));
+
+extern char *_ng_makekey __P((const char *, const char *, size_t));
+extern int _ng_parse __P((char **, char **, struct netgroup **));
+
+static DB *ng_insert __P((DB *, const char *));
+static void ng_reventry __P((DB *, DB *, struct nentry *, char *,
+ size_t, struct stringlist *));
+
+static void ng_print __P((struct nentry *, struct string *));
+static void ng_rprint __P((DB *, struct string *));
+static DB *ng_reverse __P((DB *, size_t));
+static DB *ng_load __P((const char *));
+static void ng_write __P((DB *, DB *, int));
+static void ng_rwrite __P((DB *, DB *, int));
+static void usage __P((void));
+static void cleanup __P((void));
+
+#ifdef DEBUG_NG
+static void ng_dump __P((DB *));
+static void ng_rdump __P((DB *));
+#endif /* DEBUG_NG */
+
+static const char ng_empty[] = "";
+#define NG_EMPTY(a) ((a) ? (a) : ng_empty)
+
+static char *dbname = _PATH_NETGROUP_DB;
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ DB *db, *ndb, *hdb, *udb;
+ int ch;
+ char buf[MAXPATHLEN];
+ char *fname = _PATH_NETGROUP;
+
+
+ while ((ch = getopt(argc, argv, "o:")) != EOF)
+ switch (ch) {
+ case 'o':
+ dbname = optarg;
+ break;
+
+ case '?':
+ default:
+ usage();
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 1)
+ fname = *argv;
+ else if (argc > 1)
+ usage();
+
+ if (atexit(cleanup))
+ err(1, "Cannot install exit handler");
+
+ /* Read and parse the netgroup file */
+ ndb = ng_load(fname);
+#ifdef DEBUG_NG
+ (void) fprintf(stderr, "#### Database\n");
+ ng_dump(ndb);
+#endif
+
+ /* Reverse the database by host */
+ hdb = ng_reverse(ndb, offsetof(struct netgroup, ng_host));
+#ifdef DEBUG_NG
+ (void) fprintf(stderr, "#### Reverse by host\n");
+ ng_rdump(hdb);
+#endif
+
+ /* Reverse the database by user */
+ udb = ng_reverse(ndb, offsetof(struct netgroup, ng_user));
+#ifdef DEBUG_NG
+ (void) fprintf(stderr, "#### Reverse by user\n");
+ ng_rdump(udb);
+#endif
+
+ (void) snprintf(buf, sizeof(buf), "%s.tmp", dbname);
+
+ db = dbopen(buf, O_RDWR | O_CREAT | O_EXCL,
+ (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, NULL);
+ if (!db)
+ err(1, buf);
+
+ ng_write(db, ndb, _NG_KEYBYNAME);
+ ng_rwrite(db, udb, _NG_KEYBYUSER);
+ ng_rwrite(db, hdb, _NG_KEYBYHOST);
+
+ if ((db->close)(db))
+ err(1, "Error closing database");
+
+ if (rename(buf, dbname) == -1)
+ err(1, "Cannot rename `%s' to `%s'", buf, dbname);
+
+ return 0;
+}
+
+
+/*
+ * cleanup(): Remove temporary files upon exit
+ */
+static void
+cleanup()
+{
+ char buf[MAXPATHLEN];
+ (void) snprintf(buf, sizeof(buf), "%s.tmp", dbname);
+ (void) unlink(buf);
+}
+
+
+
+/*
+ * ng_load(): Load the netgroup database from a file
+ */
+static DB *
+ng_load(fname)
+ const char *fname;
+{
+ FILE *fp;
+ DB *db;
+ char *buf;
+ size_t size;
+ struct nentry *tail, *head, *e;
+ char *p, *name;
+ struct netgroup *ng;
+ DBT data, key;
+
+ /* Open the netgroup file */
+ if ((fp = fopen(fname, "r")) == NULL)
+ err(1, fname);
+
+ db = dbopen(NULL, O_RDWR | O_CREAT | O_EXCL, 0, DB_HASH, NULL);
+
+ if (db == NULL)
+ err(1, "dbopen");
+
+ while ((buf = getline(fp, &size)) != NULL) {
+ tail = head = NULL;
+ p = buf;
+
+ while (p != NULL) {
+ switch (_ng_parse(&p, &name, &ng)) {
+ case _NG_NONE:
+ /* done with this one */
+ p = NULL;
+ free(buf);
+ if (head == NULL)
+ break;
+
+ key.data = (u_char *) head->n_name;
+ key.size = strlen(head->n_name) + 1;
+ data.data = (u_char *) & head;
+ data.size = sizeof(head);
+ switch ((db->put)(db, &key, &data,
+ R_NOOVERWRITE)) {
+ case 0:
+ break;
+
+ case 1:
+ warnx("Duplicate entry netgroup `%s'\n",
+ head->n_name);
+ break;
+
+ case -1:
+ err(1, "put");
+ break;
+
+ default:
+ abort();
+ break;
+ }
+ break;
+
+ case _NG_NAME:
+ e = NEW(struct nentry);
+ e->n_type = _NG_NAME;
+ e->n_name = name;
+ e->n_next = NULL;
+ e->n_size = size;
+ if (tail == NULL)
+ head = tail = e;
+ else {
+ tail->n_next = e;
+ tail = e;
+ }
+ break;
+
+ case _NG_GROUP:
+ if (tail == NULL)
+ errx(1, "no netgroup key");
+ else {
+ e = NEW(struct nentry);
+ e->n_type = _NG_GROUP;
+ e->n_group = ng;
+ e->n_next = NULL;
+ e->n_size = size;
+ tail->n_next = e;
+ tail = e;
+ }
+ break;
+
+ default:
+ abort();
+ break;
+ }
+ }
+ }
+ (void) fclose(fp);
+ return db;
+}
+
+
+/*
+ * ng_insert(): Insert named key into the database, and return its associated
+ * string database
+ */
+static DB *
+ng_insert(db, name)
+ DB *db;
+ const char *name;
+{
+ DB *xdb = NULL;
+ DBT key, data;
+
+ key.data = (u_char *) name;
+ key.size = strlen(name) + 1;
+
+ switch ((db->get)(db, &key, &data, 0)) {
+ case 0:
+ memcpy(&xdb, data.data, sizeof(xdb));
+ break;
+
+ case 1:
+ xdb = dbopen(NULL, O_RDWR | O_CREAT | O_EXCL, 0, DB_HASH, NULL);
+ if (xdb == NULL)
+ err(1, "dbopen");
+
+ data.data = (u_char *) & xdb;
+ data.size = sizeof(xdb);
+ switch ((db->put)(db, &key, &data, R_NOOVERWRITE)) {
+ case 0:
+ break;
+
+ case -1:
+ err(1, "db put `%s'", name);
+ break;
+
+ case 1:
+ default:
+ abort();
+ }
+ break;
+
+ case -1:
+ err(1, "db get `%s'", name);
+ break;
+
+ default:
+ abort();
+ break;
+ }
+
+ return xdb;
+}
+
+
+/*
+ * ng_reventry(): Recursively add all the netgroups to the group entry.
+ */
+static void
+ng_reventry(db, udb, fe, name, s, ss)
+ DB *db, *udb;
+ struct nentry *fe;
+ char *name;
+ size_t s;
+ struct stringlist *ss;
+{
+ DBT key, data;
+ struct nentry *e;
+ struct netgroup *ng;
+ char *p;
+ DB *xdb;
+
+ if (_ng_sl_find(ss, name) != NULL) {
+ warnx("Cycle in netgroup `%s'", name);
+ return;
+ }
+ _ng_sl_add(ss, name);
+
+ for (e = fe->n_next; e != NULL; e = e->n_next)
+ switch (e->n_type) {
+ case _NG_GROUP:
+ ng = e->n_group;
+ p = _ng_makekey(*((char **)(((char *) ng) + s)),
+ ng->ng_domain, e->n_size);
+ xdb = ng_insert(udb, p);
+ key.data = (u_char *) name;
+ key.size = strlen(name) + 1;
+ data.data = NULL;
+ data.size = 0;
+ switch ((xdb->put)(xdb, &key, &data, R_NOOVERWRITE)) {
+ case 0:
+ case 1:
+ break;
+
+ case -1:
+ err(1, "db put `%s'", name);
+ return;
+
+ default:
+ abort();
+ break;
+ }
+ free(p);
+ break;
+
+ case _NG_NAME:
+ key.data = (u_char *) e->n_name;
+ key.size = strlen(e->n_name) + 1;
+ switch ((db->get)(db, &key, &data, 0)) {
+ case 0:
+ memcpy(&fe, data.data, sizeof(fe));
+ ng_reventry(db, udb, fe, e->n_name, s, ss);
+ break;
+
+ case 1:
+ break;
+
+ case -1:
+ err(1, "db get `%s'", e->n_name);
+ return;
+
+ default:
+ abort();
+ return;
+ }
+ break;
+
+ default:
+ abort();
+ break;
+ }
+}
+
+
+/*
+ * ng_reverse(): Reverse the database
+ */
+static DB *
+ng_reverse(db, s)
+ DB *db;
+ size_t s;
+{
+ int pos;
+ struct stringlist *sl;
+ DBT key, data;
+ struct nentry *fe;
+ DB *udb = dbopen(NULL, O_RDWR | O_CREAT | O_EXCL, 0,
+ DB_HASH, NULL);
+
+ if (udb == NULL)
+ err(1, "dbopen");
+
+ for (pos = R_FIRST;; pos = R_NEXT)
+ switch ((db->seq)(db, &key, &data, pos)) {
+ case 0:
+ sl = _ng_sl_init();
+ memcpy(&fe, data.data, sizeof(fe));
+ ng_reventry(db, udb, fe, (char *) key.data, s, sl);
+ _ng_sl_free(sl, 0);
+ break;
+
+ case 1:
+ return udb;
+
+ case -1:
+ err(1, "seq");
+ return udb;
+ }
+
+ return udb;
+}
+
+
+/*
+ * ng_print(): Pretty print a netgroup entry
+ */
+static void
+ng_print(e, str)
+ struct nentry *e;
+ struct string *str;
+{
+ char *ptr = emalloc(e->n_size);
+
+ for (e = e->n_next; e != NULL; e = e->n_next) {
+ switch (e->n_type) {
+ case _NG_NAME:
+ (void) snprintf(ptr, e->n_size, "%s", e->n_name);
+ break;
+
+ case _NG_GROUP:
+ (void) snprintf(ptr, e->n_size, "(%s,%s,%s)",
+ NG_EMPTY(e->n_group->ng_host),
+ NG_EMPTY(e->n_group->ng_user),
+ NG_EMPTY(e->n_group->ng_domain));
+ break;
+
+ default:
+ errx(1, "Internal error: Bad netgroup type\n");
+ break;
+ }
+ str_append(str, ptr, ' ');
+ }
+ free(ptr);
+}
+
+
+/*
+ * ng_rprint(): Pretty print all reverse netgroup mappings in the given entry
+ */
+static void
+ng_rprint(db, str)
+ DB *db;
+ struct string *str;
+{
+ int pos;
+ DBT key, data;
+
+ for (pos = R_FIRST;; pos = R_NEXT)
+ switch ((db->seq)(db, &key, &data, pos)) {
+ case 0:
+ str_append(str, (char *) key.data, ',');
+ break;
+
+ case 1:
+ return;
+
+ default:
+ err(1, "seq");
+ break;
+ }
+}
+
+
+#ifdef DEBUG_NG
+/*
+ * ng_dump(): Pretty print all netgroups in the given database
+ */
+static void
+ng_dump(db)
+ DB *db;
+{
+ int pos;
+ DBT key, data;
+ struct nentry *e;
+ struct string buf;
+
+ for (pos = R_FIRST;; pos = R_NEXT)
+ switch ((db->seq)(db, &key, &data, pos)) {
+ case 0:
+ memcpy(&e, data.data, sizeof(e));
+ str_init(&buf);
+ assert(e->n_type == _NG_NAME);
+
+ ng_print(e, &buf);
+ (void) fprintf(stderr, "%s\t%s\n", e->n_name,
+ buf.s_str ? buf.s_str : "");
+ str_free(&buf);
+ break;
+
+ case 1:
+ return;
+
+ default:
+ err(1, "seq");
+ return;
+ }
+}
+
+
+/*
+ * ng_rdump(): Pretty print all reverse mappings in the given database
+ */
+static void
+ng_rdump(db)
+ DB *db;
+{
+ int pos;
+ DBT key, data;
+ DB *xdb;
+ struct string buf;
+
+ for (pos = R_FIRST;; pos = R_NEXT)
+ switch ((db->seq)(db, &key, &data, pos)) {
+ case 0:
+ memcpy(&xdb, data.data, sizeof(xdb));
+ str_init(&buf);
+ ng_rprint(xdb, &buf);
+ (void) fprintf(stderr, "%s\t%s\n",
+ (char *) key.data,
+ buf.s_str ? buf.s_str : "");
+ str_free(&buf);
+ break;
+
+ case 1:
+ return;
+
+ default:
+ err(1, "seq");
+ return;
+ }
+}
+#endif /* DEBUG_NG */
+
+
+/*
+ * ng_write(): Dump the database into a file.
+ */
+static void
+ng_write(odb, idb, k)
+ DB *odb, *idb;
+ int k;
+{
+ int pos;
+ DBT key, data;
+ struct nentry *e;
+ struct string skey, sdata;
+
+ for (pos = R_FIRST;; pos = R_NEXT)
+ switch ((idb->seq)(idb, &key, &data, pos)) {
+ case 0:
+ memcpy(&e, data.data, sizeof(e));
+ str_init(&skey);
+ str_init(&sdata);
+ assert(e->n_type == _NG_NAME);
+
+ str_prepend(&skey, e->n_name, k);
+ ng_print(e, &sdata);
+ key.data = (u_char *) skey.s_str;
+ key.size = skey.s_len + 1;
+ data.data = (u_char *) sdata.s_str;
+ data.size = sdata.s_len + 1;
+
+ switch ((odb->put)(odb, &key, &data, R_NOOVERWRITE)) {
+ case 0:
+ break;
+
+ case -1:
+ err(1, "put");
+ break;
+
+ case 1:
+ default:
+ abort();
+ break;
+ }
+
+ str_free(&skey);
+ str_free(&sdata);
+ break;
+
+ case 1:
+ return;
+
+ default:
+ err(1, "seq");
+ return;
+ }
+}
+
+
+/*
+ * ng_rwrite(): Write the database
+ */
+static void
+ng_rwrite(odb, idb, k)
+ DB *odb;
+ DB *idb;
+ int k;
+{
+ int pos;
+ DBT key, data;
+ DB *xdb;
+ struct string skey, sdata;
+
+ for (pos = R_FIRST;; pos = R_NEXT)
+ switch ((idb->seq)(idb, &key, &data, pos)) {
+ case 0:
+ memcpy(&xdb, data.data, sizeof(xdb));
+ str_init(&skey);
+ str_init(&sdata);
+
+ str_prepend(&skey, (char *) key.data, k);
+ ng_rprint(xdb, &sdata);
+ key.data = (u_char *) skey.s_str;
+ key.size = skey.s_len + 1;
+ data.data = (u_char *) sdata.s_str;
+ data.size = sdata.s_len + 1;
+
+ switch ((odb->put)(odb, &key, &data, R_NOOVERWRITE)) {
+ case 0:
+ break;
+
+ case -1:
+ err(1, "put");
+ break;
+
+ case 1:
+ default:
+ abort();
+ break;
+ }
+
+ str_free(&skey);
+ str_free(&sdata);
+ break;
+
+ case 1:
+ return;
+
+ default:
+ err(1, "seq");
+ return;
+ }
+}
+
+
+/*
+ * usage(): Print usage message and exit
+ */
+static void
+usage()
+{
+ extern const char *__progname;
+ fprintf(stderr, "usage: %s [-o db] file\n", __progname);
+ exit(1);
+}
diff --git a/usr.sbin/netgroup_mkdb/str.c b/usr.sbin/netgroup_mkdb/str.c
new file mode 100644
index 00000000000..dafa49180cb
--- /dev/null
+++ b/usr.sbin/netgroup_mkdb/str.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char *rcsid = "$Id: str.c,v 1.1 1995/10/18 08:47:57 deraadt Exp $";
+#endif
+
+/*
+ * Counted strings
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+#include "str.h"
+
+/*
+ * str_init(): Initialize string
+ */
+void
+str_init(s)
+ struct string *s;
+{
+ s->s_str = NULL;
+ s->s_len = 0;
+}
+
+
+/*
+ * str_append(): Append string allocating buffer as necessary
+ */
+void
+str_append(buf, str, del)
+ struct string *buf;
+ const char *str;
+ int del;
+{
+ size_t len = strlen(str) + 1;
+
+ if (buf->s_str == NULL)
+ buf->s_str = emalloc(len);
+ else {
+ buf->s_str = erealloc(buf->s_str, buf->s_len + len +
+ (del ? 2 : 1));
+ if (del)
+ buf->s_str[buf->s_len++] = del;
+ }
+
+ memcpy(&buf->s_str[buf->s_len], str, len);
+ buf->s_len += len - 1;
+}
+
+/*
+ * str_prepend(): Prepend string allocating buffer as necessary
+ */
+void
+str_prepend(buf, str, del)
+ struct string *buf;
+ const char *str;
+ int del;
+{
+ char *ptr, *sptr;
+ size_t len = strlen(str) + 1;
+
+ sptr = ptr = emalloc(buf->s_len + len + (del ? 2 : 1));
+
+ if (del)
+ *ptr++ = del;
+
+ memcpy(ptr, str, len);
+
+ if (buf->s_str) {
+ memcpy(&ptr[len - 1], buf->s_str, buf->s_len + 1);
+ free(buf->s_str);
+ }
+
+ buf->s_str = sptr;
+ buf->s_len += del ? len : len - 1;
+}
+
+/*
+ * str_free(): Free a string
+ */
+void
+str_free(s)
+ struct string *s;
+{
+ free(s->s_str);
+ s->s_str = NULL;
+ s->s_len = 0;
+}
diff --git a/usr.sbin/netgroup_mkdb/str.h b/usr.sbin/netgroup_mkdb/str.h
new file mode 100644
index 00000000000..da5fd9a6713
--- /dev/null
+++ b/usr.sbin/netgroup_mkdb/str.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: str.h,v 1.1 1995/10/18 08:47:57 deraadt Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+struct string {
+ char *s_str;
+ size_t s_len;
+};
+
+__BEGIN_DECLS
+void str_init __P((struct string *));
+void str_append __P((struct string *, const char *, int));
+void str_prepend __P((struct string *, const char *, int));
+void str_free __P((struct string *));
+__END_DECLS
diff --git a/usr.sbin/netgroup_mkdb/util.c b/usr.sbin/netgroup_mkdb/util.c
new file mode 100644
index 00000000000..6a82557e561
--- /dev/null
+++ b/usr.sbin/netgroup_mkdb/util.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char *rcsid = "$Id: util.c,v 1.1 1995/10/18 08:47:57 deraadt Exp $";
+#endif
+
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+/* emalloc():
+ * Error checked malloc
+ */
+void *
+emalloc(s)
+ size_t s;
+{
+ void *ptr = malloc(s);
+ if (ptr == NULL)
+ /* Crappy gcc warning! */
+ err(1, "%s", "");
+ return ptr;
+}
+
+
+/* erealloc():
+ * Error checked realloc
+ */
+void *
+erealloc(p, s)
+ void *p;
+ size_t s;
+{
+ void *ptr = realloc(p, s);
+ if (ptr == NULL)
+ /* Crappy gcc warning! */
+ err(1, "%s", "");
+ return ptr;
+}
+
+
+/* getline():
+ * Read a line from a file parsing continuations ending in \
+ * and eliminating trailing newlines.
+ */
+char *
+getline(fp, size)
+ FILE *fp;
+ size_t *size;
+{
+ size_t s, len = 0;
+ char *buf = NULL;
+ char *ptr;
+ int cnt = 1;
+
+ while (cnt) {
+ if ((ptr = fgetln(fp, &s)) == NULL) {
+ *size = len;
+ return buf;
+ }
+ if (ptr[s - 1] == '\n') /* the newline may be missing at EOF */
+ s--; /* forget newline */
+ if ((cnt = (ptr[s - 1] == '\\'))) /* check for \\ */
+ s--; /* forget \\ */
+
+ buf = erealloc(buf, len + s + 1);
+ memcpy(buf + len, ptr, s);
+ len += s;
+ buf[len] = '\0';
+ }
+ *size = len;
+ return buf;
+}
diff --git a/usr.sbin/netgroup_mkdb/util.h b/usr.sbin/netgroup_mkdb/util.h
new file mode 100644
index 00000000000..a9773fa2cb5
--- /dev/null
+++ b/usr.sbin/netgroup_mkdb/util.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void *emalloc __P((size_t));
+void *erealloc __P((void *, size_t));
+char *getline __P((FILE *, size_t *));
+__END_DECLS