xref: /titanic_44/usr/src/cmd/ypcmd/mknetid/mknetid.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1990-2000, Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SMI4.1 1.5 */
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * Network name to unix credential database generator.
32*7c478bd9Sstevel@tonic-gate  * Uses /etc/passwd, /etc/group, /etc/hosts and /etc/netid to
33*7c478bd9Sstevel@tonic-gate  * create the database.
34*7c478bd9Sstevel@tonic-gate  *
35*7c478bd9Sstevel@tonic-gate  * If some user appears in passwd, they get an entry like:
36*7c478bd9Sstevel@tonic-gate  *	sun.<uid>@<domainname>	<uid>:<gid1>,<gid2>,...
37*7c478bd9Sstevel@tonic-gate  * If some host appears in hosts, it gets an entry like:
38*7c478bd9Sstevel@tonic-gate  *	sun.<hostname>@<domainname>	0:<hostname>
39*7c478bd9Sstevel@tonic-gate  *
40*7c478bd9Sstevel@tonic-gate  * The file /etc/netid is used to add other domains (possibly non-unix)
41*7c478bd9Sstevel@tonic-gate  * to the database.
42*7c478bd9Sstevel@tonic-gate  */
43*7c478bd9Sstevel@tonic-gate #include <stdio.h>
44*7c478bd9Sstevel@tonic-gate #include <pwd.h>
45*7c478bd9Sstevel@tonic-gate #include <limits.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
47*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
48*7c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h>
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #define	MAXNAMELEN	256
52*7c478bd9Sstevel@tonic-gate #define	MAXLINELEN	1024
53*7c478bd9Sstevel@tonic-gate #define	MAXDOMAINLEN	32
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate #define	GRPTABSIZE	256		/* size of group table */
56*7c478bd9Sstevel@tonic-gate #define	PRNTABSIZE	4096		/* size of printed item table */
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate #define	NUMGIDS	(NGROUPS_MAX + 1)	/* group-access-list + gid */
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate extern char **getline();
61*7c478bd9Sstevel@tonic-gate extern char *malloc();
62*7c478bd9Sstevel@tonic-gate extern char *strcpy();
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate /*
65*7c478bd9Sstevel@tonic-gate  * The group list
66*7c478bd9Sstevel@tonic-gate  * Store username and groups to which he/she belongs
67*7c478bd9Sstevel@tonic-gate  */
68*7c478bd9Sstevel@tonic-gate struct group_list {
69*7c478bd9Sstevel@tonic-gate 	char *user;
70*7c478bd9Sstevel@tonic-gate 	int group_len;
71*7c478bd9Sstevel@tonic-gate 	int groups[NUMGIDS];
72*7c478bd9Sstevel@tonic-gate 	struct group_list *next;
73*7c478bd9Sstevel@tonic-gate };
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate /*
76*7c478bd9Sstevel@tonic-gate  * General purpose list of strings
77*7c478bd9Sstevel@tonic-gate  */
78*7c478bd9Sstevel@tonic-gate struct string_list {
79*7c478bd9Sstevel@tonic-gate 	char *str;
80*7c478bd9Sstevel@tonic-gate 	struct string_list *next;
81*7c478bd9Sstevel@tonic-gate };
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate static FILE *openfile();
84*7c478bd9Sstevel@tonic-gate static char *scanargs();
85*7c478bd9Sstevel@tonic-gate static int atoi();
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate static char *cmdname;	/* name of this program */
88*7c478bd9Sstevel@tonic-gate static int quietmode;	/* quiet mode: don't print error messages */
89*7c478bd9Sstevel@tonic-gate static char *curfile;	/* name of file we are parsing */
90*7c478bd9Sstevel@tonic-gate static int curline;		/* current line parsed in this file */
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate static struct group_list *groups[GRPTABSIZE];	/* group table */
93*7c478bd9Sstevel@tonic-gate static struct string_list *printed[PRNTABSIZE];	/* printed item table */
94*7c478bd9Sstevel@tonic-gate static char domain[MAXDOMAINLEN];	/* name of our domain */
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate static char PASSWD[] = "/etc/passwd";	/* default passwd database */
97*7c478bd9Sstevel@tonic-gate static char IDMAP[] = "/etc/idmap";	/* default net-id map database */
98*7c478bd9Sstevel@tonic-gate static char GROUP[] = "/etc/group";	/* default group database */
99*7c478bd9Sstevel@tonic-gate static char HOSTS[] = "/etc/hosts";	/* default hosts database */
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate static char *pwdfile = PASSWD;	/* password file to parse */
102*7c478bd9Sstevel@tonic-gate static char *grpfile = GROUP;	/* group file */
103*7c478bd9Sstevel@tonic-gate static char *hostfile = HOSTS;	/* hosts file */
104*7c478bd9Sstevel@tonic-gate static char *mapfile = IDMAP;	/* network id file */
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate /*
107*7c478bd9Sstevel@tonic-gate  * Various separaters
108*7c478bd9Sstevel@tonic-gate  */
109*7c478bd9Sstevel@tonic-gate static char WHITE[] = "\t ";
110*7c478bd9Sstevel@tonic-gate static char COLON[] = ":";
111*7c478bd9Sstevel@tonic-gate static char COMMA[] = ",";
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate main(argc, argv)
114*7c478bd9Sstevel@tonic-gate 	int argc;
115*7c478bd9Sstevel@tonic-gate 	char *argv[];
116*7c478bd9Sstevel@tonic-gate {
117*7c478bd9Sstevel@tonic-gate 	FILE *pf, *mf, *gf, *hf;
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate 	cmdname = argv[0];
120*7c478bd9Sstevel@tonic-gate 	if (!parseargs(argc, argv)) {
121*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
122*7c478bd9Sstevel@tonic-gate 			"usage: %s [-q] [-pghm filename]\n", cmdname);
123*7c478bd9Sstevel@tonic-gate 		exit(1);
124*7c478bd9Sstevel@tonic-gate 	}
125*7c478bd9Sstevel@tonic-gate 	(void) getdomainname(domain, sizeof (domain));
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	pf = openfile(pwdfile);
128*7c478bd9Sstevel@tonic-gate 	gf = openfile(grpfile);
129*7c478bd9Sstevel@tonic-gate 	hf = openfile(hostfile);
130*7c478bd9Sstevel@tonic-gate 	mf = fopen(mapfile, "r");
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate 	if (mf != NULL) {
134*7c478bd9Sstevel@tonic-gate 		domapfile(mapfile, mf);
135*7c478bd9Sstevel@tonic-gate 	}
136*7c478bd9Sstevel@tonic-gate 	dogrpfile(grpfile, gf);
137*7c478bd9Sstevel@tonic-gate 	dopwdfile(pwdfile, pf);
138*7c478bd9Sstevel@tonic-gate 	dohostfile(hostfile, hf);
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 	exit(0);
141*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
142*7c478bd9Sstevel@tonic-gate }
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate /*
145*7c478bd9Sstevel@tonic-gate  * Parse the network id mapping file
146*7c478bd9Sstevel@tonic-gate  */
147*7c478bd9Sstevel@tonic-gate domapfile(mapfile, mf)
148*7c478bd9Sstevel@tonic-gate 	char *mapfile;
149*7c478bd9Sstevel@tonic-gate 	FILE *mf;
150*7c478bd9Sstevel@tonic-gate {
151*7c478bd9Sstevel@tonic-gate 	char **lp;
152*7c478bd9Sstevel@tonic-gate 	char line[MAXLINELEN];
153*7c478bd9Sstevel@tonic-gate 	char name[MAXNAMELEN];
154*7c478bd9Sstevel@tonic-gate 	int uid, gid;
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	curfile = mapfile;
157*7c478bd9Sstevel@tonic-gate 	curline = 0;
158*7c478bd9Sstevel@tonic-gate 	while (lp = getline(line, sizeof (line), mf, &curline, "#")) {
159*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, WHITE, "#");
160*7c478bd9Sstevel@tonic-gate 		if (wasprinted(name)) {
161*7c478bd9Sstevel@tonic-gate 			multdef(name);
162*7c478bd9Sstevel@tonic-gate 			continue;
163*7c478bd9Sstevel@tonic-gate 		}
164*7c478bd9Sstevel@tonic-gate 		put_s(name);
165*7c478bd9Sstevel@tonic-gate 		(void) putchar(' ');
166*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, COLON, "#");
167*7c478bd9Sstevel@tonic-gate 		uid = Atoi(name);
168*7c478bd9Sstevel@tonic-gate 		put_d(uid);
169*7c478bd9Sstevel@tonic-gate 		(void) putchar(':');
170*7c478bd9Sstevel@tonic-gate 		if (uid == 0) {
171*7c478bd9Sstevel@tonic-gate 			check_getname(lp, name, WHITE, "\t\n ", "#");
172*7c478bd9Sstevel@tonic-gate 			put_s(name);
173*7c478bd9Sstevel@tonic-gate 			(void) putchar(' ');
174*7c478bd9Sstevel@tonic-gate 		} else {
175*7c478bd9Sstevel@tonic-gate 			check_getname(lp, name, WHITE, ",\n", "#");
176*7c478bd9Sstevel@tonic-gate 			gid = Atoi(name);
177*7c478bd9Sstevel@tonic-gate 			put_d(gid);
178*7c478bd9Sstevel@tonic-gate 			while (getname(name, sizeof (name), WHITE, ",\n", lp,
179*7c478bd9Sstevel@tonic-gate 					"#") >= 0) {
180*7c478bd9Sstevel@tonic-gate 				gid = Atoi(name);
181*7c478bd9Sstevel@tonic-gate 				(void) putchar(',');
182*7c478bd9Sstevel@tonic-gate 				put_d(gid);
183*7c478bd9Sstevel@tonic-gate 			}
184*7c478bd9Sstevel@tonic-gate 		}
185*7c478bd9Sstevel@tonic-gate 		(void) putchar('\n');
186*7c478bd9Sstevel@tonic-gate 	}
187*7c478bd9Sstevel@tonic-gate }
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate /*
191*7c478bd9Sstevel@tonic-gate  * Parse the groups file
192*7c478bd9Sstevel@tonic-gate  */
193*7c478bd9Sstevel@tonic-gate dogrpfile(grpfile, gf)
194*7c478bd9Sstevel@tonic-gate 	char *grpfile;
195*7c478bd9Sstevel@tonic-gate 	FILE *gf;
196*7c478bd9Sstevel@tonic-gate {
197*7c478bd9Sstevel@tonic-gate 	char **lp;
198*7c478bd9Sstevel@tonic-gate 	char line[MAXLINELEN];
199*7c478bd9Sstevel@tonic-gate 	char name[MAXNAMELEN];
200*7c478bd9Sstevel@tonic-gate 	int gid;
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 	curfile = grpfile;
203*7c478bd9Sstevel@tonic-gate 	curline = 0;
204*7c478bd9Sstevel@tonic-gate 	while (lp = getline(line, sizeof (line), gf, &curline, "")) {
205*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, COLON, "");
206*7c478bd9Sstevel@tonic-gate 		if (name[0] == '+') {
207*7c478bd9Sstevel@tonic-gate 			continue;
208*7c478bd9Sstevel@tonic-gate 		}
209*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, COLON, ""); /* ignore passwd */
210*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, COLON, "");
211*7c478bd9Sstevel@tonic-gate 		gid = Atoi(name);
212*7c478bd9Sstevel@tonic-gate 		while (getname(name, sizeof (name), WHITE, COMMA, lp,
213*7c478bd9Sstevel@tonic-gate 				"") >= 0) {
214*7c478bd9Sstevel@tonic-gate 			storegid(gid, name);
215*7c478bd9Sstevel@tonic-gate 		}
216*7c478bd9Sstevel@tonic-gate 	}
217*7c478bd9Sstevel@tonic-gate }
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate /*
221*7c478bd9Sstevel@tonic-gate  * Parse the password file
222*7c478bd9Sstevel@tonic-gate  */
223*7c478bd9Sstevel@tonic-gate dopwdfile(pwdfile, pf)
224*7c478bd9Sstevel@tonic-gate 	char *pwdfile;
225*7c478bd9Sstevel@tonic-gate 	FILE *pf;
226*7c478bd9Sstevel@tonic-gate {
227*7c478bd9Sstevel@tonic-gate 	char **lp;
228*7c478bd9Sstevel@tonic-gate 	char line[MAXLINELEN];
229*7c478bd9Sstevel@tonic-gate 	char name[MAXNAMELEN];
230*7c478bd9Sstevel@tonic-gate 	char user[MAXNAMELEN];
231*7c478bd9Sstevel@tonic-gate 	int uid, gid;
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 	curfile = pwdfile;
234*7c478bd9Sstevel@tonic-gate 	curline = 0;
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 	while (lp = getline(line, sizeof (line), pf, &curline, "")) {
237*7c478bd9Sstevel@tonic-gate 		check_getname(lp, user, WHITE, COLON, ""); 	/* username */
238*7c478bd9Sstevel@tonic-gate 		if (user[0] == '-' || user[0] == '+') {
239*7c478bd9Sstevel@tonic-gate 			continue;	/* NIS entry */
240*7c478bd9Sstevel@tonic-gate 		}
241*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, COLON, ""); /* ignore passwd */
242*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, COLON, ""); /* but get uid */
243*7c478bd9Sstevel@tonic-gate 		uid = Atoi(name);
244*7c478bd9Sstevel@tonic-gate 		user2netname(name, uid, domain);
245*7c478bd9Sstevel@tonic-gate 		if (wasprinted(name)) {
246*7c478bd9Sstevel@tonic-gate 			multdef(name);
247*7c478bd9Sstevel@tonic-gate 			continue;
248*7c478bd9Sstevel@tonic-gate 		}
249*7c478bd9Sstevel@tonic-gate 		put_s(name);
250*7c478bd9Sstevel@tonic-gate 		(void) putchar(' ');
251*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, COLON, "");
252*7c478bd9Sstevel@tonic-gate 		gid = Atoi(name);
253*7c478bd9Sstevel@tonic-gate 		put_d(uid);
254*7c478bd9Sstevel@tonic-gate 		(void) putchar(':');
255*7c478bd9Sstevel@tonic-gate 		printgroups(user, gid);
256*7c478bd9Sstevel@tonic-gate 	}
257*7c478bd9Sstevel@tonic-gate }
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate /*
261*7c478bd9Sstevel@tonic-gate  * Parse the hosts file
262*7c478bd9Sstevel@tonic-gate  */
263*7c478bd9Sstevel@tonic-gate dohostfile(hostfile, hf)
264*7c478bd9Sstevel@tonic-gate 	char *hostfile;
265*7c478bd9Sstevel@tonic-gate 	FILE *hf;
266*7c478bd9Sstevel@tonic-gate {
267*7c478bd9Sstevel@tonic-gate 	char **lp;
268*7c478bd9Sstevel@tonic-gate 	char line[MAXLINELEN];
269*7c478bd9Sstevel@tonic-gate 	char name[MAXNAMELEN];
270*7c478bd9Sstevel@tonic-gate 	char netname[MAXNETNAMELEN];
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 	curfile = hostfile;
273*7c478bd9Sstevel@tonic-gate 	curline = 0;
274*7c478bd9Sstevel@tonic-gate 	while (lp = getline(line, sizeof (line), hf, &curline, "#")) {
275*7c478bd9Sstevel@tonic-gate 		check_getname(lp, name, WHITE, WHITE, "#");
276*7c478bd9Sstevel@tonic-gate 		if (getname(name, MAXNAMELEN, WHITE, WHITE, lp, "#") != 1) {
277*7c478bd9Sstevel@tonic-gate 			continue;
278*7c478bd9Sstevel@tonic-gate 		}
279*7c478bd9Sstevel@tonic-gate 		host2netname(netname, name, domain);
280*7c478bd9Sstevel@tonic-gate 		if (wasprinted(netname)) {
281*7c478bd9Sstevel@tonic-gate 			multdef(netname);
282*7c478bd9Sstevel@tonic-gate 			continue;
283*7c478bd9Sstevel@tonic-gate 		}
284*7c478bd9Sstevel@tonic-gate 		(void) printf("%s 0:%.*s\n", netname, sizeof (name), name);
285*7c478bd9Sstevel@tonic-gate 	}
286*7c478bd9Sstevel@tonic-gate }
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate /*
289*7c478bd9Sstevel@tonic-gate  * Open a file, exit on failure
290*7c478bd9Sstevel@tonic-gate  */
291*7c478bd9Sstevel@tonic-gate static FILE *
292*7c478bd9Sstevel@tonic-gate openfile(fname)
293*7c478bd9Sstevel@tonic-gate 	char *fname;
294*7c478bd9Sstevel@tonic-gate {
295*7c478bd9Sstevel@tonic-gate 	FILE *f;
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate 	f = fopen(fname, "r");
298*7c478bd9Sstevel@tonic-gate 	if (f == NULL) {
299*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: can't open %s\n", cmdname, fname);
300*7c478bd9Sstevel@tonic-gate 		exit(1);
301*7c478bd9Sstevel@tonic-gate 	}
302*7c478bd9Sstevel@tonic-gate 	return (f);
303*7c478bd9Sstevel@tonic-gate }
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate /*
306*7c478bd9Sstevel@tonic-gate  * Print syntax error message, then exit
307*7c478bd9Sstevel@tonic-gate  */
308*7c478bd9Sstevel@tonic-gate syntaxerror()
309*7c478bd9Sstevel@tonic-gate {
310*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: syntax error in file \"%s\", line %d\n",
311*7c478bd9Sstevel@tonic-gate 	    cmdname, curfile, curline);
312*7c478bd9Sstevel@tonic-gate 	exit(1);
313*7c478bd9Sstevel@tonic-gate }
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate /*
317*7c478bd9Sstevel@tonic-gate  * an atoi() that prints a message and exits upong failure
318*7c478bd9Sstevel@tonic-gate  */
319*7c478bd9Sstevel@tonic-gate static int
320*7c478bd9Sstevel@tonic-gate Atoi(str)
321*7c478bd9Sstevel@tonic-gate 	char *str;
322*7c478bd9Sstevel@tonic-gate {
323*7c478bd9Sstevel@tonic-gate 	int res;
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	if (!sscanf(str, "%d", &res)) {
326*7c478bd9Sstevel@tonic-gate 		syntaxerror();
327*7c478bd9Sstevel@tonic-gate 	}
328*7c478bd9Sstevel@tonic-gate 	return (res);
329*7c478bd9Sstevel@tonic-gate }
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate /*
333*7c478bd9Sstevel@tonic-gate  * Attempt to get a token from a file, print a message and exit upon failure
334*7c478bd9Sstevel@tonic-gate  */
335*7c478bd9Sstevel@tonic-gate check_getname(lp, name, skip, term, com)
336*7c478bd9Sstevel@tonic-gate 	char **lp;
337*7c478bd9Sstevel@tonic-gate 	char *name;
338*7c478bd9Sstevel@tonic-gate 	char *skip;
339*7c478bd9Sstevel@tonic-gate 	char *term;
340*7c478bd9Sstevel@tonic-gate 	char *com;
341*7c478bd9Sstevel@tonic-gate {
342*7c478bd9Sstevel@tonic-gate 	if (getname(name, MAXNAMELEN, skip, term, lp, com) != 1) {
343*7c478bd9Sstevel@tonic-gate 		syntaxerror();
344*7c478bd9Sstevel@tonic-gate 	}
345*7c478bd9Sstevel@tonic-gate }
346*7c478bd9Sstevel@tonic-gate 
347*7c478bd9Sstevel@tonic-gate /*
348*7c478bd9Sstevel@tonic-gate  * Something was defined more than once
349*7c478bd9Sstevel@tonic-gate  */
350*7c478bd9Sstevel@tonic-gate multdef(name)
351*7c478bd9Sstevel@tonic-gate 	char *name;
352*7c478bd9Sstevel@tonic-gate {
353*7c478bd9Sstevel@tonic-gate 	if (!quietmode) {
354*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
355*7c478bd9Sstevel@tonic-gate 			"%s: %s multiply defined, other definitions ignored\n",
356*7c478bd9Sstevel@tonic-gate 			cmdname, name);
357*7c478bd9Sstevel@tonic-gate 	}
358*7c478bd9Sstevel@tonic-gate }
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate static
361*7c478bd9Sstevel@tonic-gate hash(str, size)
362*7c478bd9Sstevel@tonic-gate 	unsigned char *str;
363*7c478bd9Sstevel@tonic-gate 	int size;
364*7c478bd9Sstevel@tonic-gate {
365*7c478bd9Sstevel@tonic-gate 	unsigned val;
366*7c478bd9Sstevel@tonic-gate 	int flip;
367*7c478bd9Sstevel@tonic-gate 
368*7c478bd9Sstevel@tonic-gate 	val = 0;
369*7c478bd9Sstevel@tonic-gate 	flip = 0;
370*7c478bd9Sstevel@tonic-gate 	while (*str) {
371*7c478bd9Sstevel@tonic-gate 		if (flip) {
372*7c478bd9Sstevel@tonic-gate 			val ^= (*str++ << 6);
373*7c478bd9Sstevel@tonic-gate 		} else {
374*7c478bd9Sstevel@tonic-gate 			val ^= *str++;
375*7c478bd9Sstevel@tonic-gate 		}
376*7c478bd9Sstevel@tonic-gate 		flip = !flip;
377*7c478bd9Sstevel@tonic-gate 	}
378*7c478bd9Sstevel@tonic-gate 	return (val % size);
379*7c478bd9Sstevel@tonic-gate }
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate /*
383*7c478bd9Sstevel@tonic-gate  * Check if an item has been printed
384*7c478bd9Sstevel@tonic-gate  * If not, store the item into the printed item table
385*7c478bd9Sstevel@tonic-gate  */
386*7c478bd9Sstevel@tonic-gate static
387*7c478bd9Sstevel@tonic-gate wasprinted(name)
388*7c478bd9Sstevel@tonic-gate 	char *name;
389*7c478bd9Sstevel@tonic-gate {
390*7c478bd9Sstevel@tonic-gate 	struct string_list *s;
391*7c478bd9Sstevel@tonic-gate 	int val;
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate 	val = hash((unsigned char *) name, PRNTABSIZE);
394*7c478bd9Sstevel@tonic-gate 	for (s = printed[val]; s != NULL && strcmp(s->str, name); s = s->next)
395*7c478bd9Sstevel@tonic-gate 		;
396*7c478bd9Sstevel@tonic-gate 	if (s != NULL) {
397*7c478bd9Sstevel@tonic-gate 		return (1);
398*7c478bd9Sstevel@tonic-gate 	}
399*7c478bd9Sstevel@tonic-gate 	s = (struct string_list *)malloc(sizeof (struct string_list));
400*7c478bd9Sstevel@tonic-gate 	s->str = malloc((unsigned)strlen(name) + 1);
401*7c478bd9Sstevel@tonic-gate 	(void) strcpy(s->str, name);
402*7c478bd9Sstevel@tonic-gate 	s->next = printed[val];
403*7c478bd9Sstevel@tonic-gate 	printed[val] = s;
404*7c478bd9Sstevel@tonic-gate 	return (0);
405*7c478bd9Sstevel@tonic-gate }
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate /*
408*7c478bd9Sstevel@tonic-gate  * Add gid to the list of a user's groups
409*7c478bd9Sstevel@tonic-gate  */
410*7c478bd9Sstevel@tonic-gate storegid(gid, user)
411*7c478bd9Sstevel@tonic-gate 	int gid;
412*7c478bd9Sstevel@tonic-gate 	char *user;
413*7c478bd9Sstevel@tonic-gate {
414*7c478bd9Sstevel@tonic-gate 	struct group_list *g;
415*7c478bd9Sstevel@tonic-gate 	int i;
416*7c478bd9Sstevel@tonic-gate 	int val;
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate 	val = hash((unsigned char *) user, GRPTABSIZE);
419*7c478bd9Sstevel@tonic-gate 	for (g = groups[val]; g != NULL && strcmp(g->user, user); g = g->next)
420*7c478bd9Sstevel@tonic-gate 		;
421*7c478bd9Sstevel@tonic-gate 	if (g == NULL) {
422*7c478bd9Sstevel@tonic-gate 		g = (struct group_list *)malloc(sizeof (struct group_list));
423*7c478bd9Sstevel@tonic-gate 		g->user = malloc((unsigned)strlen(user) + 1);
424*7c478bd9Sstevel@tonic-gate 		(void) strcpy(g->user, user);
425*7c478bd9Sstevel@tonic-gate 		g->group_len = 1;
426*7c478bd9Sstevel@tonic-gate 		g->groups[0] = gid;
427*7c478bd9Sstevel@tonic-gate 		g->next = groups[val];
428*7c478bd9Sstevel@tonic-gate 		groups[val] = g;
429*7c478bd9Sstevel@tonic-gate 	} else {
430*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < g->group_len; i++) {
431*7c478bd9Sstevel@tonic-gate 			if (g->groups[i] == gid) {
432*7c478bd9Sstevel@tonic-gate 				return;
433*7c478bd9Sstevel@tonic-gate 			}
434*7c478bd9Sstevel@tonic-gate 		}
435*7c478bd9Sstevel@tonic-gate 		if (g->group_len >= NUMGIDS) {
436*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: %s's groups exceed %d\n",
437*7c478bd9Sstevel@tonic-gate 				cmdname, user, NGROUPS_MAX);
438*7c478bd9Sstevel@tonic-gate 			return;
439*7c478bd9Sstevel@tonic-gate 		}
440*7c478bd9Sstevel@tonic-gate 		g->groups[g->group_len++] = gid;
441*7c478bd9Sstevel@tonic-gate 	}
442*7c478bd9Sstevel@tonic-gate }
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate /*
445*7c478bd9Sstevel@tonic-gate  * print out a user's groups
446*7c478bd9Sstevel@tonic-gate  */
447*7c478bd9Sstevel@tonic-gate printgroups(user, gid)
448*7c478bd9Sstevel@tonic-gate 	char *user;
449*7c478bd9Sstevel@tonic-gate 	int gid;
450*7c478bd9Sstevel@tonic-gate {
451*7c478bd9Sstevel@tonic-gate 	struct group_list *g;
452*7c478bd9Sstevel@tonic-gate 	int i;
453*7c478bd9Sstevel@tonic-gate 	int val;
454*7c478bd9Sstevel@tonic-gate 
455*7c478bd9Sstevel@tonic-gate 	val = hash((unsigned char *) user, GRPTABSIZE);
456*7c478bd9Sstevel@tonic-gate 	for (g = groups[val]; g != NULL && strcmp(g->user, user); g = g->next)
457*7c478bd9Sstevel@tonic-gate 		;
458*7c478bd9Sstevel@tonic-gate 	put_d(gid);
459*7c478bd9Sstevel@tonic-gate 	if (g != NULL) {
460*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < g->group_len; i++) {
461*7c478bd9Sstevel@tonic-gate 			if (gid != g->groups[i]) {
462*7c478bd9Sstevel@tonic-gate 				(void) putchar(',');
463*7c478bd9Sstevel@tonic-gate 				put_d(g->groups[i]);
464*7c478bd9Sstevel@tonic-gate 			}
465*7c478bd9Sstevel@tonic-gate 		}
466*7c478bd9Sstevel@tonic-gate 	}
467*7c478bd9Sstevel@tonic-gate 	(void) putchar('\n');
468*7c478bd9Sstevel@tonic-gate }
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate /*
472*7c478bd9Sstevel@tonic-gate  * Parse command line arguments
473*7c478bd9Sstevel@tonic-gate  */
474*7c478bd9Sstevel@tonic-gate parseargs(argc, argv)
475*7c478bd9Sstevel@tonic-gate 	int argc;
476*7c478bd9Sstevel@tonic-gate 	char *argv[];
477*7c478bd9Sstevel@tonic-gate {
478*7c478bd9Sstevel@tonic-gate 	int i;
479*7c478bd9Sstevel@tonic-gate 	int j;
480*7c478bd9Sstevel@tonic-gate 	static struct {
481*7c478bd9Sstevel@tonic-gate 		char letter;
482*7c478bd9Sstevel@tonic-gate 		char *standard;
483*7c478bd9Sstevel@tonic-gate 		char **filename;
484*7c478bd9Sstevel@tonic-gate 	} whattodo[] = {
485*7c478bd9Sstevel@tonic-gate 		{ 'p', PASSWD, &pwdfile },
486*7c478bd9Sstevel@tonic-gate 		{ 'g', GROUP, &grpfile },
487*7c478bd9Sstevel@tonic-gate 		{ 'm', IDMAP, &mapfile },
488*7c478bd9Sstevel@tonic-gate 		{ 'h', HOSTS, &hostfile }
489*7c478bd9Sstevel@tonic-gate 	};
490*7c478bd9Sstevel@tonic-gate 
491*7c478bd9Sstevel@tonic-gate #define	TABSIZE  sizeof (whattodo)/sizeof (whattodo[0])
492*7c478bd9Sstevel@tonic-gate 
493*7c478bd9Sstevel@tonic-gate 	for (i = 1; i < argc; i++) {
494*7c478bd9Sstevel@tonic-gate 		if (argv[i][0] == '-') {
495*7c478bd9Sstevel@tonic-gate 			if (argv[i][2] != 0) {
496*7c478bd9Sstevel@tonic-gate 				return (0);
497*7c478bd9Sstevel@tonic-gate 			}
498*7c478bd9Sstevel@tonic-gate 			if (argv[i][1] == 'q') {
499*7c478bd9Sstevel@tonic-gate 				quietmode = 1;
500*7c478bd9Sstevel@tonic-gate 				continue;
501*7c478bd9Sstevel@tonic-gate 			}
502*7c478bd9Sstevel@tonic-gate 			for (j = 0; j < TABSIZE; j++) {
503*7c478bd9Sstevel@tonic-gate 				if (whattodo[j].letter == argv[i][1]) {
504*7c478bd9Sstevel@tonic-gate 					if (*whattodo[j].filename !=
505*7c478bd9Sstevel@tonic-gate 							whattodo[j].standard) {
506*7c478bd9Sstevel@tonic-gate 						return (0);
507*7c478bd9Sstevel@tonic-gate 					}
508*7c478bd9Sstevel@tonic-gate 					if (++i == argc) {
509*7c478bd9Sstevel@tonic-gate 						return (0);
510*7c478bd9Sstevel@tonic-gate 					}
511*7c478bd9Sstevel@tonic-gate 					*whattodo[j].filename = argv[i];
512*7c478bd9Sstevel@tonic-gate 					break;
513*7c478bd9Sstevel@tonic-gate 				}
514*7c478bd9Sstevel@tonic-gate 			}
515*7c478bd9Sstevel@tonic-gate 			if (j == TABSIZE) {
516*7c478bd9Sstevel@tonic-gate 				return (0);
517*7c478bd9Sstevel@tonic-gate 			}
518*7c478bd9Sstevel@tonic-gate 		}
519*7c478bd9Sstevel@tonic-gate 	}
520*7c478bd9Sstevel@tonic-gate 	return (1);
521*7c478bd9Sstevel@tonic-gate }
522*7c478bd9Sstevel@tonic-gate 
523*7c478bd9Sstevel@tonic-gate /*
524*7c478bd9Sstevel@tonic-gate  * Print a string, quickly
525*7c478bd9Sstevel@tonic-gate  */
526*7c478bd9Sstevel@tonic-gate put_s(s)
527*7c478bd9Sstevel@tonic-gate 	char *s;
528*7c478bd9Sstevel@tonic-gate {
529*7c478bd9Sstevel@tonic-gate 	(void) fwrite(s, strlen(s), 1, stdout);
530*7c478bd9Sstevel@tonic-gate }
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate /*
533*7c478bd9Sstevel@tonic-gate  * Print an integer, quickly
534*7c478bd9Sstevel@tonic-gate  */
535*7c478bd9Sstevel@tonic-gate put_d(d)
536*7c478bd9Sstevel@tonic-gate 	int d;
537*7c478bd9Sstevel@tonic-gate {
538*7c478bd9Sstevel@tonic-gate 	char buf[20];
539*7c478bd9Sstevel@tonic-gate 	char *p;
540*7c478bd9Sstevel@tonic-gate 
541*7c478bd9Sstevel@tonic-gate 	if (d == 0) {
542*7c478bd9Sstevel@tonic-gate 		(void) putchar('0');
543*7c478bd9Sstevel@tonic-gate 		return;
544*7c478bd9Sstevel@tonic-gate 	}
545*7c478bd9Sstevel@tonic-gate 	if (d < 0) {
546*7c478bd9Sstevel@tonic-gate 		(void) putchar('-');
547*7c478bd9Sstevel@tonic-gate 		d = -d;
548*7c478bd9Sstevel@tonic-gate 	}
549*7c478bd9Sstevel@tonic-gate 	p = buf + sizeof (buf);
550*7c478bd9Sstevel@tonic-gate 	*--p = 0;
551*7c478bd9Sstevel@tonic-gate 	while (d > 0) {
552*7c478bd9Sstevel@tonic-gate 		*--p = (d % 10) + '0';
553*7c478bd9Sstevel@tonic-gate 		d /= 10;
554*7c478bd9Sstevel@tonic-gate 	}
555*7c478bd9Sstevel@tonic-gate 	put_s(p);
556*7c478bd9Sstevel@tonic-gate }
557