summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ypcmd/revnetgroup
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/ypcmd/revnetgroup
downloadillumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/ypcmd/revnetgroup')
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/Makefile59
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/getgroup.c249
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/getgroup.h50
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/revnetgroup.c299
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/table.c100
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/table.h58
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/util.c112
-rw-r--r--usr/src/cmd/ypcmd/revnetgroup/util.h67
8 files changed, 994 insertions, 0 deletions
diff --git a/usr/src/cmd/ypcmd/revnetgroup/Makefile b/usr/src/cmd/ypcmd/revnetgroup/Makefile
new file mode 100644
index 0000000000..174fd0bee0
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/Makefile
@@ -0,0 +1,59 @@
+#
+# 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 1996, 2002 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = revnetgroup
+
+include ../../Makefile.cmd
+
+OBJS = revnetgroup.o getgroup.o table.o util.o
+SRCS = $(OBJS:.o=.c)
+HDRS = getgroup.h table.h util.h
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+ $(RM) $(OBJS)
+
+lint:
+ ${LINT.c} ${SRCS}
+
+cstyle:
+ ${CSTYLE} ${SRCS}
+
+clobber: clean
+ $(RM) $(PROG)
+
+FRC:
diff --git a/usr/src/cmd/ypcmd/revnetgroup/getgroup.c b/usr/src/cmd/ypcmd/revnetgroup/getgroup.c
new file mode 100644
index 0000000000..7a48de096a
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/getgroup.c
@@ -0,0 +1,249 @@
+/*
+ * 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 (c) 1996, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ident "%Z%%M% %I% %E% SMI" /* SMI4.1 1.5 */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "table.h"
+#include "util.h"
+#include "getgroup.h"
+
+#define MAXGROUPLEN 1024
+
+/*
+ * Stolen mostly, from getnetgrent.c
+ *
+ * my_getgroup() performs the same function as _getgroup(), but operates
+ * on /etc/netgroup directly, rather than doing yp lookups.
+ *
+ * /etc/netgroup must first loaded into a hash table so the matching
+ * function can look up lines quickly.
+ */
+
+
+/* To check for cycles in netgroups */
+struct list {
+ char *name;
+ struct list *nxt;
+};
+
+
+extern stringtable ngtable; /* stored info from /etc/netgroup */
+
+static struct grouplist *grouplist; /* stores a list of users in a group */
+
+static char *any();
+static char *match();
+static char *fill();
+static void freegrouplist();
+static void doit();
+
+
+
+static void
+freegrouplist()
+{
+ struct grouplist *gl;
+
+ for (gl = grouplist; gl != NULL; gl = gl->gl_nxt) {
+ FREE(gl->gl_name);
+ FREE(gl->gl_domain);
+ FREE(gl->gl_machine);
+ FREE(gl);
+ }
+ grouplist = NULL;
+}
+
+
+
+
+struct grouplist *
+my_getgroup(group)
+ char *group;
+{
+ freegrouplist();
+ doit(group, (struct list *) NULL);
+ return (grouplist);
+}
+
+
+
+
+
+/*
+ * recursive function to find the members of netgroup "group". "list" is
+ * the path followed through the netgroups so far, to check for cycles.
+ */
+static void
+doit(group, list)
+ char *group;
+ struct list *list;
+{
+ register char *p, *q;
+ register struct list *ls;
+ struct list tmplist;
+ char *val;
+ struct grouplist *gpls;
+
+
+ /*
+ * check for non-existing groups
+ */
+ if ((val = match(group)) == NULL) {
+ return;
+ }
+
+
+ /*
+ * check for cycles
+ */
+ for (ls = list; ls != NULL; ls = ls->nxt) {
+ if (strcmp(ls->name, group) == 0) {
+ (void) fprintf(stderr,
+ "Cycle detected in /etc/netgroup: %s.\n",
+ group);
+ return;
+ }
+ }
+
+
+ ls = &tmplist;
+ ls->name = group;
+ ls->nxt = list;
+ list = ls;
+
+ p = val;
+ while (p != NULL) {
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == EOS || *p == '#')
+ break;
+ if (*p == '(') {
+ gpls = MALLOC(struct grouplist);
+ p++;
+
+ if (!(p = fill(p, &gpls->gl_machine, ','))) {
+ goto syntax_error;
+ }
+ if (!(p = fill(p, &gpls->gl_name, ','))) {
+ goto syntax_error;
+ }
+ if (!(p = fill(p, &gpls->gl_domain, ')'))) {
+ goto syntax_error;
+ }
+ gpls->gl_nxt = grouplist;
+ grouplist = gpls;
+ } else {
+ q = any(p, " \t\n#");
+ if (q && *q == '#')
+ break;
+ *q = EOS;
+ doit(p, list);
+ *q = ' ';
+ }
+ p = any(p, " \t");
+ }
+ return;
+
+syntax_error:
+ (void) fprintf(stderr, "syntax error in /etc/netgroup\n");
+ (void) fprintf(stderr, "--- %s %s\n", group, val);
+}
+
+
+
+
+/*
+ * Fill a buffer "target" selectively from buffer "start".
+ * "termchar" terminates the information in start, and preceding
+ * or trailing white space is ignored. If the buffer "start" is
+ * empty, "target" is filled with "*". The location just after the
+ * terminating character is returned.
+ */
+static char *
+fill(start, target, termchar)
+ char *start;
+ char **target;
+ char termchar;
+{
+ register char *p;
+ register char *q;
+ register char *r;
+ int size;
+
+ for (p = start; *p == ' ' || *p == '\t'; p++)
+ ;
+ r = strchr(p, termchar);
+ if (r == (char *)NULL) {
+ return ((char *)NULL);
+ }
+ if (p == r) {
+ *target = NULL;
+ } else {
+ for (q = r-1; *q == ' ' || *q == '\t'; q--)
+ ;
+ size = q-p+1;
+ STRNCPY(*target, p, size);
+ }
+ return (r+1);
+}
+
+
+/*
+ * scans cp, looking for a match with any character
+ * in match. Returns pointer to place in cp that matched
+ * (or NULL if no match)
+ */
+static char *
+any(cp, match)
+ register char *cp;
+ char *match;
+{
+ register char *mp, c;
+
+ while (c = *cp) {
+ for (mp = match; *mp; mp++)
+ if (*mp == c)
+ return (cp);
+ cp++;
+ }
+ return (NULL);
+}
+
+
+
+/*
+ * The equivalent of yp_match. Returns the match, or NULL if there is none.
+ */
+static char *
+match(group)
+ char *group;
+{
+ return (lookup(ngtable, group));
+}
diff --git a/usr/src/cmd/ypcmd/revnetgroup/getgroup.h b/usr/src/cmd/ypcmd/revnetgroup/getgroup.h
new file mode 100644
index 0000000000..6c1ab0ed2d
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/getgroup.h
@@ -0,0 +1,50 @@
+/*
+ * 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 1995 Sun Microsystems Inc.
+ * All rights reserved.
+ */
+
+
+#ifndef __GETGROUP_H
+#define __GETGROUP_H
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* SMI4.1 1.4 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct grouplist {
+ char *gl_machine;
+ char *gl_name;
+ char *gl_domain;
+ struct grouplist *gl_nxt;
+};
+
+struct grouplist *my_getgroup();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GETGROUP_H */
diff --git a/usr/src/cmd/ypcmd/revnetgroup/revnetgroup.c b/usr/src/cmd/ypcmd/revnetgroup/revnetgroup.c
new file mode 100644
index 0000000000..41f161e913
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/revnetgroup.c
@@ -0,0 +1,299 @@
+/*
+ * 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 (c) 1994, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+/*
+ * For SUNWnskit - version 1.1
+ *
+ * Based on:
+ * #pragma ident "%Z%%M% %I% %E% SMI" (SMI4.1 1.6)
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <rpcsvc/ypclnt.h>
+#include "util.h"
+#include "table.h"
+#include "getgroup.h"
+
+#define MAXDOMAINLEN 256
+#define MAXGROUPLEN 1024
+
+/*
+ * Reverse the netgroup file. A flag of "-u" means reverse by username,
+ * one of "-h" means reverse by hostname. Each line in the output file
+ * will begin with a key formed by concatenating the host or user name
+ * with the domain name. The key will be followed by a tab, then the
+ * comma-separated, newline-terminated list of groups to which the
+ * user or host belongs.
+ *
+ * Exception: Groups to which everyone belongs (universal groups) will
+ * not be included in the list. The universal groups will be listed under
+ * the special name "*".
+ *
+ * Thus to find out all the groups that user "foo" of domain "bar" is in,
+ * lookup the groups under foo.bar, foo.*, *.bar and *.*.
+ *
+ */
+
+
+
+/* Stores a list of strings */
+typedef struct stringnode *stringlist;
+struct stringnode {
+ char *str;
+ stringlist next;
+};
+typedef struct stringnode stringnode;
+
+
+
+/* Stores a list of (name,list-of-groups) */
+typedef struct groupentrynode *groupentrylist;
+struct groupentrynode {
+ char *name;
+ stringlist groups;
+ groupentrylist next;
+};
+typedef struct groupentrynode groupentrynode;
+
+stringtable ngtable;
+
+static groupentrylist grouptable[TABLESIZE];
+
+static char *nextgroup(void);
+static void storegroup(char *group, struct grouplist *glist, int byuser);
+static void enter(char *name, char *group);
+static void appendgroup(groupentrylist grlist, char *group);
+static groupentrylist newentry(char *name, char *group);
+static void loadtable(FILE *nf);
+static void dumptable(void);
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *group;
+ struct grouplist *glist;
+ int byuser;
+
+ loadtable(stdin);
+ if (argc == 2 && argv[1][0] == '-' &&
+ (argv[1][1] == 'u' || argv[1][1] == 'h')) {
+ byuser = (argv[1][1] == 'u');
+ } else {
+ (void) fprintf(stderr,
+ "usage: %s -h (by host), %s -u (by user)\n",
+ argv[0], argv[0]);
+ exit(1);
+ }
+
+ while (group = nextgroup()) {
+ glist = my_getgroup(group);
+ storegroup(group, glist, byuser);
+ }
+ dumptable();
+
+ return (0);
+}
+
+/*
+ * Get the next netgroup from /etc/netgroup
+ */
+static char *
+nextgroup(void)
+{
+ static int index = -1;
+ static tablelist cur = NULL;
+ char *group;
+
+ while (cur == NULL) {
+ if (++index == TABLESIZE) {
+ return (NULL);
+ }
+ cur = ngtable[index];
+ }
+ group = cur->key;
+ cur = cur->next;
+ return (group);
+}
+
+
+
+/*
+ * Dump out all of the stored info into a file
+ */
+static void
+dumptable(void)
+{
+ int i;
+ groupentrylist entry;
+ stringlist groups;
+
+ for (i = 0; i < TABLESIZE; i++) {
+ if (entry = grouptable[i]) {
+ while (entry) {
+ fputs(entry->name, stdout);
+ putc('\t', stdout);
+ for (groups = entry->groups; groups;
+ groups = groups->next) {
+ fputs(groups->str, stdout);
+ if (groups->next) {
+ putc(',', stdout);
+ }
+ }
+ putc('\n', stdout);
+ entry = entry->next;
+ }
+ }
+ }
+}
+
+
+
+
+/*
+ * Add a netgroup to a user's list of netgroups
+ */
+static void
+storegroup(char *group, struct grouplist *glist, int byuser)
+{
+ char *name; /* username or hostname */
+ char *domain;
+ char *key;
+ static char *universal = "*";
+
+ for (; glist; glist = glist->gl_nxt) {
+ name = byuser ? glist->gl_name : glist->gl_machine;
+ if (!name) {
+ name = universal;
+ } else if (!isalnum(*name) && *name != '_') {
+ continue;
+ }
+ domain = glist->gl_domain;
+ if (!domain) {
+ domain = universal;
+ }
+ key = malloc((unsigned) (strlen(name)+strlen(domain)+2));
+ (void) sprintf(key, "%s.%s", name, domain);
+ enter(key, group);
+ }
+}
+
+
+
+static groupentrylist
+newentry(char *name, char *group)
+{
+ groupentrylist new;
+
+ new = MALLOC(groupentrynode);
+
+ STRCPY(new->name, name);
+
+ new->groups = MALLOC(stringnode);
+ new->groups->str = group;
+ new->groups->next = NULL;
+
+ new->next = NULL;
+ return (new);
+}
+
+static void
+appendgroup(groupentrylist grlist, char *group)
+{
+ stringlist cur, prev;
+
+ for (cur = grlist->groups; cur; prev = cur, cur = cur->next) {
+ if (strcmp(group, cur->str) == 0) {
+ return;
+ }
+ }
+ prev->next = MALLOC(stringnode);
+ cur = prev->next;
+ cur->str = group;
+ cur->next = NULL;
+}
+
+static void
+enter(char *name, char *group)
+{
+ int key;
+ groupentrylist gel;
+ groupentrylist gelprev;
+
+ key = tablekey(name);
+ if (grouptable[key] == NULL) {
+ grouptable[key] = newentry(name, group);
+ } else {
+ gel = grouptable[key];
+ while (gel && strcmp(gel->name, name)) {
+ gelprev = gel;
+ gel = gel->next;
+ }
+ if (gel) {
+ appendgroup(gel, group);
+ } else {
+ gelprev->next = newentry(name, group);
+ }
+ }
+}
+
+/*
+ * Load up a hash table with the info in /etc/netgroup
+ */
+static void
+loadtable(FILE *nf)
+{
+ char buf[MAXGROUPLEN];
+ char *p;
+ char *group;
+ char *line;
+
+ while (getline(buf, MAXGROUPLEN, nf)) {
+ for (p = buf; *p && isspace((int)*p); p++)
+ ; /* skip leading blanks */
+ for (; *p && *p != '#' && *p != ' ' && *p != '\t'; p++)
+ ;
+ if (*p == EOS || *p == '#')
+ continue;
+ *p++ = EOS;
+
+ while (*p == ' ' || *p == '\t') {
+ p++;
+ }
+ if (*p == EOS || *p == '#')
+ continue;
+
+ STRCPY(group, buf);
+ STRCPY(line, p);
+ store(ngtable, group, line);
+ }
+}
diff --git a/usr/src/cmd/ypcmd/revnetgroup/table.c b/usr/src/cmd/ypcmd/revnetgroup/table.c
new file mode 100644
index 0000000000..140b213e38
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/table.c
@@ -0,0 +1,100 @@
+/*
+ * 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 (c) 1994, by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ident "%Z%%M% %I% %E% SMI" /* SMI4.1 1.4 */
+
+#include <ctype.h>
+#include "util.h"
+#include "table.h"
+
+
+
+/*
+ * Hash table manager. Store/lookup strings, keyed by string
+ */
+
+/*
+ * Generate the key into the table using the first two letters
+ * of "str". The table is alphabetized, with no distinction between
+ * upper and lower case. Non-letters are given least significance.
+ */
+int
+tablekey(str)
+ register char *str;
+{
+#define TOLOWER(c) (islower(c) ? c : \
+ (isupper(c) ? tolower(c) : ('a'+NUMLETTERS-1)))
+
+ register int c1, c2;
+
+ c1 = *str++;
+ c2 = *str;
+ if (c1 == EOS) {
+ c2 = EOS; /* just in case */
+ }
+ c1 = TOLOWER(c1) - 'a';
+ c2 = TOLOWER(c2) - 'a';
+ return (c1*NUMLETTERS + c2);
+}
+
+
+void
+store(table, key, datum)
+ stringtable table;
+ char *key;
+ char *datum;
+{
+ int index;
+ tablelist cur, new;
+
+ index = tablekey(key);
+ cur = table[index];
+
+ new = MALLOC(tablenode);
+ new->key = key;
+ new->datum = datum;
+ new->next = cur;
+ table[index] = new;
+}
+
+
+char *
+lookup(table, key)
+ stringtable table;
+ char *key;
+{
+ tablelist cur;
+
+ cur = table[tablekey(key)];
+ while (cur && strcmp(cur->key, key)) {
+ cur = cur->next;
+ }
+ if (cur) {
+ return (cur->datum);
+ } else {
+ return (NULL);
+ }
+}
diff --git a/usr/src/cmd/ypcmd/revnetgroup/table.h b/usr/src/cmd/ypcmd/revnetgroup/table.h
new file mode 100644
index 0000000000..8c304a0dda
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/table.h
@@ -0,0 +1,58 @@
+/*
+ * 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 1995 Sun Microsystems Inc.
+ * All rights reserved.
+ */
+
+
+#ifndef __TABLE_H
+#define __TABLE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* SMI4.1 1.4 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NUMLETTERS 27 /* 26 letters + 1 for anything else */
+#define TABLESIZE (NUMLETTERS*NUMLETTERS)
+
+typedef struct tablenode *tablelist;
+struct tablenode {
+ char *key;
+ char *datum;
+ tablelist next;
+};
+typedef struct tablenode tablenode;
+
+typedef tablelist stringtable[TABLESIZE];
+
+int tablekey();
+char *lookup();
+void store();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TABLE_H */
diff --git a/usr/src/cmd/ypcmd/revnetgroup/util.c b/usr/src/cmd/ypcmd/revnetgroup/util.c
new file mode 100644
index 0000000000..511bf34b5b
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/util.c
@@ -0,0 +1,112 @@
+/*
+ * 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 (c) 1996-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* SMI4.1 1.4 */
+
+#include <stdio.h>
+#include <string.h>
+#include "util.h"
+
+
+
+
+/*
+ * This is just like fgets, but recognizes that "\\n" signals a continuation
+ * of a line
+ */
+char *
+getline(line, maxlen, fp)
+ char *line;
+ int maxlen;
+ FILE *fp;
+{
+ register char *p;
+ register char *start;
+ int c;
+
+ start = line;
+
+nextline:
+ if (fgets(start, maxlen, fp) == NULL) {
+ return (NULL);
+ }
+ for (p = start; *p; p++) {
+ if (*p == '\n') {
+ if (p > start && *(p-1) == '\\') {
+ start = p - 1;
+ maxlen++;
+ goto nextline;
+ } else {
+ return (line);
+ }
+ }
+ maxlen--;
+ }
+
+ /*
+ * Input line is too long. Rest of the line needs to be discarded.
+ * Reinsert the last char into the stream. This is done so that
+ * in case the last char read is '\' and it is followed by a '\n'
+ * then the next line too can be discarded.
+ */
+ if (p > start)
+ (void) ungetc(*(p-1), fp);
+
+ /*
+ * Discard the rest of the line
+ */
+ while ((c = getc(fp)) != EOF) {
+ if (c == '\n')
+ break;
+ else if (c == '\\') {
+ /*
+ * Ignore the next character except EOF
+ */
+ if (getc(fp) == EOF)
+ break;
+ }
+ }
+
+ maxlen = strlen(line) + 1;
+
+ /*
+ * Certain functions expects a newline in the buffer.
+ */
+ if (maxlen >= 2)
+ line[maxlen - 2] = '\n';
+ (void) fprintf(stderr, "Following line too long - remaining chars "
+ "ignored\n--- %s", line);
+ return (line);
+}
+
+
+void
+fatal(message)
+ char *message;
+{
+ (void) fprintf(stderr, "fatal error: %s\n", message);
+ exit(1);
+}
diff --git a/usr/src/cmd/ypcmd/revnetgroup/util.h b/usr/src/cmd/ypcmd/revnetgroup/util.h
new file mode 100644
index 0000000000..e83ba1ed0f
--- /dev/null
+++ b/usr/src/cmd/ypcmd/revnetgroup/util.h
@@ -0,0 +1,67 @@
+/*
+ * 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 1995 Sun Microsystems Inc.
+ * All rights reserved.
+ */
+
+
+#ifndef __UTIL_H
+#define __UTIL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* SMI4.1 1.5 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EOS '\0'
+
+#ifndef NULL
+# define NULL ((char *) 0)
+#endif
+
+
+#define MALLOC(object_type) ((object_type *) malloc(sizeof(object_type)))
+
+#define FREE(ptr) free((char *) ptr)
+
+#define STRCPY(dst,src) \
+ (dst = malloc((unsigned)strlen(src)+1), (void) strcpy(dst,src))
+
+#define STRNCPY(dst,src,num) \
+ (dst = (char *) malloc((unsigned)(num) + 1),\
+ (void)strncpy(dst,src,num),(dst)[num] = EOS)
+
+/*
+extern char *malloc();
+*/
+extern char *alloca();
+
+char *getline();
+void fatal();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UTIL_H */