xref: /titanic_41/usr/src/cmd/ypcmd/makedbm.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  * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
23*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved   */
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
31*7c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of
32*7c478bd9Sstevel@tonic-gate  * California.
33*7c478bd9Sstevel@tonic-gate  */
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate #undef NULL
38*7c478bd9Sstevel@tonic-gate #include <stdio.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/file.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
43*7c478bd9Sstevel@tonic-gate #include <ctype.h>
44*7c478bd9Sstevel@tonic-gate #include <limits.h>
45*7c478bd9Sstevel@tonic-gate #include <string.h>
46*7c478bd9Sstevel@tonic-gate #include <unistd.h>
47*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
49*7c478bd9Sstevel@tonic-gate #include <dlfcn.h>
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #include "ypdefs.h"
52*7c478bd9Sstevel@tonic-gate #include "ypsym.h"
53*7c478bd9Sstevel@tonic-gate USE_YP_MASTER_NAME
54*7c478bd9Sstevel@tonic-gate USE_YP_LAST_MODIFIED
55*7c478bd9Sstevel@tonic-gate USE_YP_INPUT_FILE
56*7c478bd9Sstevel@tonic-gate USE_YP_OUTPUT_NAME
57*7c478bd9Sstevel@tonic-gate USE_YP_DOMAIN_NAME
58*7c478bd9Sstevel@tonic-gate USE_YP_SECURE
59*7c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN
60*7c478bd9Sstevel@tonic-gate USE_DBM
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate #ifdef SYSVCONFIG
63*7c478bd9Sstevel@tonic-gate extern void sysvconfig();
64*7c478bd9Sstevel@tonic-gate #endif
65*7c478bd9Sstevel@tonic-gate extern int yp_getalias();
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate #define	MAXLINE 4096		/* max length of input line */
68*7c478bd9Sstevel@tonic-gate #define	DEFAULT_SEP	" "
69*7c478bd9Sstevel@tonic-gate static char *get_date();
70*7c478bd9Sstevel@tonic-gate static char *any();
71*7c478bd9Sstevel@tonic-gate static void addpair();
72*7c478bd9Sstevel@tonic-gate static void unmake();
73*7c478bd9Sstevel@tonic-gate static void usage();
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate int   inode_dev_valid = 0;
76*7c478bd9Sstevel@tonic-gate ino_t inode;
77*7c478bd9Sstevel@tonic-gate dev_t dev;
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate /*
80*7c478bd9Sstevel@tonic-gate  * Interpose _close(2) to enable us to keep one of the output
81*7c478bd9Sstevel@tonic-gate  * files open until process exit.
82*7c478bd9Sstevel@tonic-gate  */
83*7c478bd9Sstevel@tonic-gate int
84*7c478bd9Sstevel@tonic-gate _close(int filedes) {
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate 	struct stat	sb;
87*7c478bd9Sstevel@tonic-gate 	static int	(*fptr)() = 0;
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	if (fptr == 0) {
90*7c478bd9Sstevel@tonic-gate 		fptr = (int (*)())dlsym(RTLD_NEXT, "_close");
91*7c478bd9Sstevel@tonic-gate 		if (fptr == 0) {
92*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: dlopen(_close): %s\n",
93*7c478bd9Sstevel@tonic-gate 				dlerror());
94*7c478bd9Sstevel@tonic-gate 			errno = ELIBACC;
95*7c478bd9Sstevel@tonic-gate 			return (-1);
96*7c478bd9Sstevel@tonic-gate 		}
97*7c478bd9Sstevel@tonic-gate 	}
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate 	if (inode_dev_valid != 0 && fstat(filedes, &sb) == 0) {
100*7c478bd9Sstevel@tonic-gate 		if (sb.st_ino == inode && sb.st_dev == dev) {
101*7c478bd9Sstevel@tonic-gate 			/* Keep open; pretend successful */
102*7c478bd9Sstevel@tonic-gate 			return (0);
103*7c478bd9Sstevel@tonic-gate 		}
104*7c478bd9Sstevel@tonic-gate 	}
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate 	return ((*fptr)(filedes));
107*7c478bd9Sstevel@tonic-gate }
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate main(argc, argv)
110*7c478bd9Sstevel@tonic-gate 	int argc;
111*7c478bd9Sstevel@tonic-gate 	char **argv;
112*7c478bd9Sstevel@tonic-gate {
113*7c478bd9Sstevel@tonic-gate 	FILE *infp, *outfp;
114*7c478bd9Sstevel@tonic-gate 	datum key, content, tmp;
115*7c478bd9Sstevel@tonic-gate 	char buf[MAXLINE];
116*7c478bd9Sstevel@tonic-gate 	char pagbuf[MAXPATHLEN];
117*7c478bd9Sstevel@tonic-gate 	char tmppagbuf[MAXPATHLEN];
118*7c478bd9Sstevel@tonic-gate 	char dirbuf[MAXPATHLEN];
119*7c478bd9Sstevel@tonic-gate 	char tmpdirbuf[MAXPATHLEN];
120*7c478bd9Sstevel@tonic-gate 	char *p, ic;
121*7c478bd9Sstevel@tonic-gate 	char *infile, *outfile;
122*7c478bd9Sstevel@tonic-gate 	char outalias[MAXPATHLEN];
123*7c478bd9Sstevel@tonic-gate 	char outaliasmap[MAXNAMLEN];
124*7c478bd9Sstevel@tonic-gate 	char outaliasdomain[MAXNAMLEN];
125*7c478bd9Sstevel@tonic-gate 	char *last_slash, *next_to_last_slash;
126*7c478bd9Sstevel@tonic-gate 	char *infilename, *outfilename, *mastername, *domainname,
127*7c478bd9Sstevel@tonic-gate 	    *interdomain_bind, *security, *lower_case_keys;
128*7c478bd9Sstevel@tonic-gate 	char *key_sep = DEFAULT_SEP;
129*7c478bd9Sstevel@tonic-gate 	char local_host[MAX_MASTER_NAME];
130*7c478bd9Sstevel@tonic-gate 	int cnt, i;
131*7c478bd9Sstevel@tonic-gate 	DBM *fdb;
132*7c478bd9Sstevel@tonic-gate 	struct stat statbuf;
133*7c478bd9Sstevel@tonic-gate 	int num_del_to_match = 0;
134*7c478bd9Sstevel@tonic-gate 	/* flag to indicate if matching char can be escaped */
135*7c478bd9Sstevel@tonic-gate 	int count_esp = 0;
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	/* Ignore existing umask, always force 077 (owner rw only) */
138*7c478bd9Sstevel@tonic-gate 	umask(077);
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 	infile = outfile = NULL; /* where to get files */
141*7c478bd9Sstevel@tonic-gate 	/* name to imbed in database */
142*7c478bd9Sstevel@tonic-gate 	infilename = outfilename = mastername = domainname = interdomain_bind =
143*7c478bd9Sstevel@tonic-gate 	    security = lower_case_keys = NULL;
144*7c478bd9Sstevel@tonic-gate 	argv++;
145*7c478bd9Sstevel@tonic-gate 	argc--;
146*7c478bd9Sstevel@tonic-gate 	while (argc > 0) {
147*7c478bd9Sstevel@tonic-gate 		if (argv[0][0] == '-' && argv[0][1]) {
148*7c478bd9Sstevel@tonic-gate 			switch (argv[0][1]) {
149*7c478bd9Sstevel@tonic-gate 				case 'i':
150*7c478bd9Sstevel@tonic-gate 					infilename = argv[1];
151*7c478bd9Sstevel@tonic-gate 					argv++;
152*7c478bd9Sstevel@tonic-gate 					argc--;
153*7c478bd9Sstevel@tonic-gate 					break;
154*7c478bd9Sstevel@tonic-gate 				case 'o':
155*7c478bd9Sstevel@tonic-gate 					outfilename = argv[1];
156*7c478bd9Sstevel@tonic-gate 					argv++;
157*7c478bd9Sstevel@tonic-gate 					argc--;
158*7c478bd9Sstevel@tonic-gate 					break;
159*7c478bd9Sstevel@tonic-gate 				case 'm':
160*7c478bd9Sstevel@tonic-gate 					mastername = argv[1];
161*7c478bd9Sstevel@tonic-gate 					argv++;
162*7c478bd9Sstevel@tonic-gate 					argc--;
163*7c478bd9Sstevel@tonic-gate 					break;
164*7c478bd9Sstevel@tonic-gate 				case 'b':
165*7c478bd9Sstevel@tonic-gate 					interdomain_bind = argv[0];
166*7c478bd9Sstevel@tonic-gate 					break;
167*7c478bd9Sstevel@tonic-gate 				case 'd':
168*7c478bd9Sstevel@tonic-gate 					domainname = argv[1];
169*7c478bd9Sstevel@tonic-gate 					argv++;
170*7c478bd9Sstevel@tonic-gate 					argc--;
171*7c478bd9Sstevel@tonic-gate 					break;
172*7c478bd9Sstevel@tonic-gate 				case 'l':
173*7c478bd9Sstevel@tonic-gate 					lower_case_keys = argv[0];
174*7c478bd9Sstevel@tonic-gate 					break;
175*7c478bd9Sstevel@tonic-gate 				case 's':
176*7c478bd9Sstevel@tonic-gate 					security = argv[0];
177*7c478bd9Sstevel@tonic-gate 					break;
178*7c478bd9Sstevel@tonic-gate 				case 'S' :
179*7c478bd9Sstevel@tonic-gate 					strcpy(key_sep, argv[1]);
180*7c478bd9Sstevel@tonic-gate 					argv++;
181*7c478bd9Sstevel@tonic-gate 					argc--;
182*7c478bd9Sstevel@tonic-gate 					if (strlen(key_sep) != 1) {
183*7c478bd9Sstevel@tonic-gate 						fprintf(stderr,
184*7c478bd9Sstevel@tonic-gate 							"bad separator\n");
185*7c478bd9Sstevel@tonic-gate 						usage();
186*7c478bd9Sstevel@tonic-gate 					}
187*7c478bd9Sstevel@tonic-gate 					break;
188*7c478bd9Sstevel@tonic-gate 				case 'D' :
189*7c478bd9Sstevel@tonic-gate 					num_del_to_match = atoi(argv[1]);
190*7c478bd9Sstevel@tonic-gate 					argv++;
191*7c478bd9Sstevel@tonic-gate 					argc--;
192*7c478bd9Sstevel@tonic-gate 					break;
193*7c478bd9Sstevel@tonic-gate 				case 'E' :
194*7c478bd9Sstevel@tonic-gate 					count_esp = 1;
195*7c478bd9Sstevel@tonic-gate 					break;
196*7c478bd9Sstevel@tonic-gate 				case 'u':
197*7c478bd9Sstevel@tonic-gate 					unmake(argv[1]);
198*7c478bd9Sstevel@tonic-gate 					argv++;
199*7c478bd9Sstevel@tonic-gate 					argc--;
200*7c478bd9Sstevel@tonic-gate 					exit(0);
201*7c478bd9Sstevel@tonic-gate 				default:
202*7c478bd9Sstevel@tonic-gate 					usage();
203*7c478bd9Sstevel@tonic-gate 			}
204*7c478bd9Sstevel@tonic-gate 		} else if (infile == NULL)
205*7c478bd9Sstevel@tonic-gate 			infile = argv[0];
206*7c478bd9Sstevel@tonic-gate 		else if (outfile == NULL)
207*7c478bd9Sstevel@tonic-gate 			outfile = argv[0];
208*7c478bd9Sstevel@tonic-gate 		else
209*7c478bd9Sstevel@tonic-gate 			usage();
210*7c478bd9Sstevel@tonic-gate 		argv++;
211*7c478bd9Sstevel@tonic-gate 		argc--;
212*7c478bd9Sstevel@tonic-gate 	}
213*7c478bd9Sstevel@tonic-gate 	if (infile == NULL || outfile == NULL)
214*7c478bd9Sstevel@tonic-gate 		usage();
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 	/*
217*7c478bd9Sstevel@tonic-gate 	 *  do alias mapping if necessary
218*7c478bd9Sstevel@tonic-gate 	 */
219*7c478bd9Sstevel@tonic-gate 	last_slash = strrchr(outfile, '/');
220*7c478bd9Sstevel@tonic-gate 	if (last_slash) {
221*7c478bd9Sstevel@tonic-gate 		*last_slash = '\0';
222*7c478bd9Sstevel@tonic-gate 		next_to_last_slash = strrchr(outfile, '/');
223*7c478bd9Sstevel@tonic-gate 		if (next_to_last_slash) *next_to_last_slash = '\0';
224*7c478bd9Sstevel@tonic-gate 	} else next_to_last_slash = NULL;
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
227*7c478bd9Sstevel@tonic-gate 	if (last_slash) printf("last_slash=%s\n", last_slash+1);
228*7c478bd9Sstevel@tonic-gate 	if (next_to_last_slash) printf("next_to_last_slash=%s\n",
229*7c478bd9Sstevel@tonic-gate 		next_to_last_slash+1);
230*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	/* reads in alias file for system v filename translation */
233*7c478bd9Sstevel@tonic-gate #ifdef SYSVCONFIG
234*7c478bd9Sstevel@tonic-gate 	sysvconfig();
235*7c478bd9Sstevel@tonic-gate #endif
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 	if (last_slash && next_to_last_slash) {
238*7c478bd9Sstevel@tonic-gate 		if (yp_getalias(last_slash+1, outaliasmap, MAXALIASLEN) < 0) {
239*7c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= MAXALIASLEN)
240*7c478bd9Sstevel@tonic-gate 				strcpy(outaliasmap, last_slash+1);
241*7c478bd9Sstevel@tonic-gate 			else
242*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
243*7c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
244*7c478bd9Sstevel@tonic-gate 				    last_slash+1);
245*7c478bd9Sstevel@tonic-gate 		}
246*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
247*7c478bd9Sstevel@tonic-gate 		printf("%s\n", last_slash+1);
248*7c478bd9Sstevel@tonic-gate 		printf("%s\n", outaliasmap);
249*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
250*7c478bd9Sstevel@tonic-gate 		if (yp_getalias(next_to_last_slash+1, outaliasdomain,
251*7c478bd9Sstevel@tonic-gate 		    NAME_MAX) < 0) {
252*7c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= NAME_MAX)
253*7c478bd9Sstevel@tonic-gate 				strcpy(outaliasdomain, next_to_last_slash+1);
254*7c478bd9Sstevel@tonic-gate 			else
255*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
256*7c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
257*7c478bd9Sstevel@tonic-gate 				    next_to_last_slash+1);
258*7c478bd9Sstevel@tonic-gate 		}
259*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
260*7c478bd9Sstevel@tonic-gate 		printf("%s\n", next_to_last_slash+1);
261*7c478bd9Sstevel@tonic-gate 		printf("%s\n", outaliasdomain);
262*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
263*7c478bd9Sstevel@tonic-gate 		sprintf(outalias, "%s/%s/%s", outfile, outaliasdomain,
264*7c478bd9Sstevel@tonic-gate 			outaliasmap);
265*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
266*7c478bd9Sstevel@tonic-gate 		printf("outlias=%s\n", outalias);
267*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate 	} else if (last_slash) {
270*7c478bd9Sstevel@tonic-gate 		if (yp_getalias(last_slash+1, outaliasmap, MAXALIASLEN) < 0) {
271*7c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= MAXALIASLEN)
272*7c478bd9Sstevel@tonic-gate 				strcpy(outaliasmap, last_slash+1);
273*7c478bd9Sstevel@tonic-gate 			else
274*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
275*7c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
276*7c478bd9Sstevel@tonic-gate 				    last_slash+1);
277*7c478bd9Sstevel@tonic-gate 		}
278*7c478bd9Sstevel@tonic-gate 		if (yp_getalias(outfile, outaliasdomain, NAME_MAX) < 0) {
279*7c478bd9Sstevel@tonic-gate 			if ((int)strlen(outfile) <= NAME_MAX)
280*7c478bd9Sstevel@tonic-gate 				strcpy(outaliasdomain, outfile);
281*7c478bd9Sstevel@tonic-gate 			else
282*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
283*7c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
284*7c478bd9Sstevel@tonic-gate 				    last_slash+1);
285*7c478bd9Sstevel@tonic-gate 		}
286*7c478bd9Sstevel@tonic-gate 		sprintf(outalias, "%s/%s", outaliasdomain, outaliasmap);
287*7c478bd9Sstevel@tonic-gate 	} else {
288*7c478bd9Sstevel@tonic-gate 		if (yp_getalias(outfile, outalias, MAXALIASLEN) < 0) {
289*7c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= MAXALIASLEN)
290*7c478bd9Sstevel@tonic-gate 				strcpy(outalias, outfile);
291*7c478bd9Sstevel@tonic-gate 			else
292*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
293*7c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
294*7c478bd9Sstevel@tonic-gate 				    outfile);
295*7c478bd9Sstevel@tonic-gate 			}
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
298*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "outalias=%s\n", outalias);
299*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "outfile=%s\n", outfile);
300*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	strcpy(tmppagbuf, outalias);
303*7c478bd9Sstevel@tonic-gate 	strcat(tmppagbuf, ".tmp");
304*7c478bd9Sstevel@tonic-gate 	strcpy(tmpdirbuf, tmppagbuf);
305*7c478bd9Sstevel@tonic-gate 	strcat(tmpdirbuf, dbm_dir);
306*7c478bd9Sstevel@tonic-gate 	strcat(tmppagbuf, dbm_pag);
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate 	/* Loop until we can lock the tmpdirbuf file */
309*7c478bd9Sstevel@tonic-gate 	for (;;) {
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 		if (strcmp(infile, "-") != 0)
312*7c478bd9Sstevel@tonic-gate 			infp = fopen(infile, "r");
313*7c478bd9Sstevel@tonic-gate 		else if (fstat(fileno(stdin), &statbuf) == -1) {
314*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't open stdin\n");
315*7c478bd9Sstevel@tonic-gate 			exit(1);
316*7c478bd9Sstevel@tonic-gate 		} else
317*7c478bd9Sstevel@tonic-gate 			infp = stdin;
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate 		if (infp == NULL) {
320*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't open %s\n", infile);
321*7c478bd9Sstevel@tonic-gate 			exit(1);
322*7c478bd9Sstevel@tonic-gate 		}
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate 		if ((outfp = fopen(tmpdirbuf, "w")) == (FILE *)NULL) {
325*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't create %s\n",
326*7c478bd9Sstevel@tonic-gate 				tmpdirbuf);
327*7c478bd9Sstevel@tonic-gate 			exit(1);
328*7c478bd9Sstevel@tonic-gate 		}
329*7c478bd9Sstevel@tonic-gate 
330*7c478bd9Sstevel@tonic-gate 		if (lockf(fileno(outfp), F_TLOCK, 0) == 0) {
331*7c478bd9Sstevel@tonic-gate 			/* Got exclusive access; save inode and dev */
332*7c478bd9Sstevel@tonic-gate 			if (fstat(fileno(outfp), &statbuf) != 0) {
333*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "makedbm: can't fstat ");
334*7c478bd9Sstevel@tonic-gate 				perror(tmpdirbuf);
335*7c478bd9Sstevel@tonic-gate 				exit(1);
336*7c478bd9Sstevel@tonic-gate 			}
337*7c478bd9Sstevel@tonic-gate 			inode		= statbuf.st_ino;
338*7c478bd9Sstevel@tonic-gate 			dev		= statbuf.st_dev;
339*7c478bd9Sstevel@tonic-gate 			inode_dev_valid	= 1;
340*7c478bd9Sstevel@tonic-gate 			break;
341*7c478bd9Sstevel@tonic-gate 		}
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 		if (errno != EAGAIN) {
344*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't lock ");
345*7c478bd9Sstevel@tonic-gate 			perror(tmpdirbuf);
346*7c478bd9Sstevel@tonic-gate 			exit(1);
347*7c478bd9Sstevel@tonic-gate 		}
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 		/*
350*7c478bd9Sstevel@tonic-gate 		 * Someone else is holding the lock.
351*7c478bd9Sstevel@tonic-gate 		 * Close both output and input file
352*7c478bd9Sstevel@tonic-gate 		 * (the latter to ensure consistency
353*7c478bd9Sstevel@tonic-gate 		 * if the input file is updated while
354*7c478bd9Sstevel@tonic-gate 		 * we're suspended), wait a little,
355*7c478bd9Sstevel@tonic-gate 		 * and try again.
356*7c478bd9Sstevel@tonic-gate 		 */
357*7c478bd9Sstevel@tonic-gate 		if (infp != stdin)
358*7c478bd9Sstevel@tonic-gate 			(void) fclose(infp);
359*7c478bd9Sstevel@tonic-gate 		(void) fclose(outfp);
360*7c478bd9Sstevel@tonic-gate 		sleep(1);
361*7c478bd9Sstevel@tonic-gate 	}
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate 	if (fopen(tmppagbuf, "w") == (FILE *)NULL) {
364*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "makedbm: can't create %s\n", tmppagbuf);
365*7c478bd9Sstevel@tonic-gate 		exit(1);
366*7c478bd9Sstevel@tonic-gate 	}
367*7c478bd9Sstevel@tonic-gate 	strcpy(dirbuf, outalias);
368*7c478bd9Sstevel@tonic-gate 	strcat(dirbuf, ".tmp");
369*7c478bd9Sstevel@tonic-gate 	if ((fdb = dbm_open(dirbuf, O_RDWR | O_CREAT, 0644)) == NULL) {
370*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "makedbm: can't open %s\n", dirbuf);
371*7c478bd9Sstevel@tonic-gate 		exit(1);
372*7c478bd9Sstevel@tonic-gate 	}
373*7c478bd9Sstevel@tonic-gate 	strcpy(dirbuf, outalias);
374*7c478bd9Sstevel@tonic-gate 	strcpy(pagbuf, outalias);
375*7c478bd9Sstevel@tonic-gate 	strcat(dirbuf, dbm_dir);
376*7c478bd9Sstevel@tonic-gate 	strcat(pagbuf, dbm_pag);
377*7c478bd9Sstevel@tonic-gate 	while (fgets(buf, sizeof (buf), infp) != NULL) {
378*7c478bd9Sstevel@tonic-gate 		p = buf;
379*7c478bd9Sstevel@tonic-gate 		cnt = strlen(buf) - 1; /* erase trailing newline */
380*7c478bd9Sstevel@tonic-gate 		while (p[cnt-1] == '\\') {
381*7c478bd9Sstevel@tonic-gate 			p += cnt-1;
382*7c478bd9Sstevel@tonic-gate 			if (fgets(p, sizeof (buf)-(p-buf), infp) == NULL)
383*7c478bd9Sstevel@tonic-gate 				goto breakout;
384*7c478bd9Sstevel@tonic-gate 			cnt = strlen(p) - 1;
385*7c478bd9Sstevel@tonic-gate 		}
386*7c478bd9Sstevel@tonic-gate 		if (strcmp(key_sep, DEFAULT_SEP) == 0) {
387*7c478bd9Sstevel@tonic-gate 			p = any(buf, " \t\n", num_del_to_match, count_esp);
388*7c478bd9Sstevel@tonic-gate 		} else {
389*7c478bd9Sstevel@tonic-gate 			p = any(buf, key_sep, num_del_to_match, count_esp);
390*7c478bd9Sstevel@tonic-gate 		}
391*7c478bd9Sstevel@tonic-gate 		key.dptr = buf;
392*7c478bd9Sstevel@tonic-gate 		key.dsize = p - buf;
393*7c478bd9Sstevel@tonic-gate 		for (;;) {
394*7c478bd9Sstevel@tonic-gate 			if (p == NULL || *p == NULL) {
395*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
396*7c478bd9Sstevel@tonic-gate 	"makedbm: source files is garbage!\n");
397*7c478bd9Sstevel@tonic-gate 				exit(1);
398*7c478bd9Sstevel@tonic-gate 			}
399*7c478bd9Sstevel@tonic-gate 			if (*p != ' ' && *p != '\t' && *p != key_sep[0])
400*7c478bd9Sstevel@tonic-gate 				break;
401*7c478bd9Sstevel@tonic-gate 			p++;
402*7c478bd9Sstevel@tonic-gate 		}
403*7c478bd9Sstevel@tonic-gate 		content.dptr = p;
404*7c478bd9Sstevel@tonic-gate 		content.dsize = strlen(p) - 1; /* erase trailing newline */
405*7c478bd9Sstevel@tonic-gate 		if (lower_case_keys) {
406*7c478bd9Sstevel@tonic-gate 			for (i = (strncmp(key.dptr, "YP_MULTI_", 9) ? 0 : 9);
407*7c478bd9Sstevel@tonic-gate 					i < key.dsize; i++) {
408*7c478bd9Sstevel@tonic-gate 
409*7c478bd9Sstevel@tonic-gate 				ic = *(key.dptr+i);
410*7c478bd9Sstevel@tonic-gate 				if (isascii(ic) && isupper(ic))
411*7c478bd9Sstevel@tonic-gate 					*(key.dptr+i) = tolower(ic);
412*7c478bd9Sstevel@tonic-gate 			}
413*7c478bd9Sstevel@tonic-gate 		}
414*7c478bd9Sstevel@tonic-gate 		tmp = dbm_fetch(fdb, key);
415*7c478bd9Sstevel@tonic-gate 		if (tmp.dptr == NULL) {
416*7c478bd9Sstevel@tonic-gate 			if (dbm_store(fdb, key, content, 1) != 0) {
417*7c478bd9Sstevel@tonic-gate 				printf("problem storing %.*s %.*s\n",
418*7c478bd9Sstevel@tonic-gate 				    key.dsize, key.dptr,
419*7c478bd9Sstevel@tonic-gate 				    content.dsize, content.dptr);
420*7c478bd9Sstevel@tonic-gate 				exit(1);
421*7c478bd9Sstevel@tonic-gate 			}
422*7c478bd9Sstevel@tonic-gate 		}
423*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
424*7c478bd9Sstevel@tonic-gate 		else {
425*7c478bd9Sstevel@tonic-gate 			printf("duplicate: %.*s %.*s\n",
426*7c478bd9Sstevel@tonic-gate 			    key.dsize, key.dptr,
427*7c478bd9Sstevel@tonic-gate 			    content.dsize, content.dptr);
428*7c478bd9Sstevel@tonic-gate 		}
429*7c478bd9Sstevel@tonic-gate #endif
430*7c478bd9Sstevel@tonic-gate 	}
431*7c478bd9Sstevel@tonic-gate 	breakout:
432*7c478bd9Sstevel@tonic-gate 	addpair(fdb, yp_last_modified, get_date(infile));
433*7c478bd9Sstevel@tonic-gate 	if (infilename)
434*7c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_input_file, infilename);
435*7c478bd9Sstevel@tonic-gate 	if (outfilename)
436*7c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_output_file, outfilename);
437*7c478bd9Sstevel@tonic-gate 	if (domainname)
438*7c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_domain_name, domainname);
439*7c478bd9Sstevel@tonic-gate 	if (security)
440*7c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_secure, "");
441*7c478bd9Sstevel@tonic-gate 	if (interdomain_bind)
442*7c478bd9Sstevel@tonic-gate 	    addpair(fdb, yp_interdomain, "");
443*7c478bd9Sstevel@tonic-gate 	if (!mastername) {
444*7c478bd9Sstevel@tonic-gate 		sysinfo(SI_HOSTNAME, local_host, sizeof (local_host) - 1);
445*7c478bd9Sstevel@tonic-gate 		mastername = local_host;
446*7c478bd9Sstevel@tonic-gate 	}
447*7c478bd9Sstevel@tonic-gate 	addpair(fdb, yp_master_name, mastername);
448*7c478bd9Sstevel@tonic-gate 	(void) dbm_close(fdb);
449*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
450*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, ".tmp ndbm map closed. ndbm successful !\n");
451*7c478bd9Sstevel@tonic-gate #endif
452*7c478bd9Sstevel@tonic-gate 	if (rename(tmppagbuf, pagbuf) < 0) {
453*7c478bd9Sstevel@tonic-gate 		perror("makedbm: rename");
454*7c478bd9Sstevel@tonic-gate 		unlink(tmppagbuf);		/* Remove the tmp files */
455*7c478bd9Sstevel@tonic-gate 		unlink(tmpdirbuf);
456*7c478bd9Sstevel@tonic-gate 		exit(1);
457*7c478bd9Sstevel@tonic-gate 	}
458*7c478bd9Sstevel@tonic-gate 	if (rename(tmpdirbuf, dirbuf) < 0) {
459*7c478bd9Sstevel@tonic-gate 		perror("makedbm: rename");
460*7c478bd9Sstevel@tonic-gate 		unlink(tmppagbuf); /* Remove the tmp files */
461*7c478bd9Sstevel@tonic-gate 		unlink(tmpdirbuf);
462*7c478bd9Sstevel@tonic-gate 		exit(1);
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate /*
465*7c478bd9Sstevel@tonic-gate  *	sprintf(buf, "mv %s %s", tmppagbuf, pagbuf);
466*7c478bd9Sstevel@tonic-gate  *	if (system(buf) < 0)
467*7c478bd9Sstevel@tonic-gate  *		perror("makedbm: rename");
468*7c478bd9Sstevel@tonic-gate  *	sprintf(buf, "mv %s %s", tmpdirbuf, dirbuf);
469*7c478bd9Sstevel@tonic-gate  *	if (system(buf) < 0)
470*7c478bd9Sstevel@tonic-gate  *		perror("makedbm: rename");
471*7c478bd9Sstevel@tonic-gate  */
472*7c478bd9Sstevel@tonic-gate 	exit(0);
473*7c478bd9Sstevel@tonic-gate }
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate 
476*7c478bd9Sstevel@tonic-gate /*
477*7c478bd9Sstevel@tonic-gate  * scans cp, looking for a match with any character
478*7c478bd9Sstevel@tonic-gate  * in match.  Returns pointer to place in cp that matched
479*7c478bd9Sstevel@tonic-gate  * (or NULL if no match)
480*7c478bd9Sstevel@tonic-gate  *
481*7c478bd9Sstevel@tonic-gate  * It will find the num_del_to_match+1
482*7c478bd9Sstevel@tonic-gate  * matching character in the line.
483*7c478bd9Sstevel@tonic-gate  *
484*7c478bd9Sstevel@tonic-gate  * The backslash escapes a delimiter if count_esp==1
485*7c478bd9Sstevel@tonic-gate  * We don't count it as a character match if
486*7c478bd9Sstevel@tonic-gate  * an escape character precedes a matching character.
487*7c478bd9Sstevel@tonic-gate  *
488*7c478bd9Sstevel@tonic-gate  */
489*7c478bd9Sstevel@tonic-gate static char *
490*7c478bd9Sstevel@tonic-gate any(cp, match, num_del_to_match, count_esp)
491*7c478bd9Sstevel@tonic-gate 	register char *cp;
492*7c478bd9Sstevel@tonic-gate 	char *match;
493*7c478bd9Sstevel@tonic-gate 	int num_del_to_match;
494*7c478bd9Sstevel@tonic-gate 	int count_esp;
495*7c478bd9Sstevel@tonic-gate {
496*7c478bd9Sstevel@tonic-gate 	register char *mp, c, prev_char;
497*7c478bd9Sstevel@tonic-gate 	int num_del_matched;
498*7c478bd9Sstevel@tonic-gate 
499*7c478bd9Sstevel@tonic-gate 	num_del_matched = 0;
500*7c478bd9Sstevel@tonic-gate 	prev_char = ' ';
501*7c478bd9Sstevel@tonic-gate 	while (c = *cp) {
502*7c478bd9Sstevel@tonic-gate 		for (mp = match; *mp; mp++) {
503*7c478bd9Sstevel@tonic-gate 			if (*mp == c) {
504*7c478bd9Sstevel@tonic-gate 				if (!count_esp) {
505*7c478bd9Sstevel@tonic-gate 					num_del_matched++;
506*7c478bd9Sstevel@tonic-gate 				} else if (prev_char != '\\') {
507*7c478bd9Sstevel@tonic-gate 					num_del_matched++;
508*7c478bd9Sstevel@tonic-gate 				}
509*7c478bd9Sstevel@tonic-gate 				if (num_del_matched > num_del_to_match)
510*7c478bd9Sstevel@tonic-gate 					return (cp);
511*7c478bd9Sstevel@tonic-gate 			}
512*7c478bd9Sstevel@tonic-gate 		}
513*7c478bd9Sstevel@tonic-gate 		prev_char = c;
514*7c478bd9Sstevel@tonic-gate 		cp++;
515*7c478bd9Sstevel@tonic-gate 	}
516*7c478bd9Sstevel@tonic-gate 	return ((char *)0);
517*7c478bd9Sstevel@tonic-gate }
518*7c478bd9Sstevel@tonic-gate 
519*7c478bd9Sstevel@tonic-gate static char *
520*7c478bd9Sstevel@tonic-gate get_date(name)
521*7c478bd9Sstevel@tonic-gate 	char *name;
522*7c478bd9Sstevel@tonic-gate {
523*7c478bd9Sstevel@tonic-gate 	struct stat filestat;
524*7c478bd9Sstevel@tonic-gate 	static char ans[MAX_ASCII_ORDER_NUMBER_LENGTH];
525*7c478bd9Sstevel@tonic-gate 	/* ASCII numeric string */
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate 	if (strcmp(name, "-") == 0)
528*7c478bd9Sstevel@tonic-gate 		sprintf(ans, "%010ld", (long)time(0));
529*7c478bd9Sstevel@tonic-gate 	else {
530*7c478bd9Sstevel@tonic-gate 		if (stat(name, &filestat) < 0) {
531*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't stat %s\n", name);
532*7c478bd9Sstevel@tonic-gate 			exit(1);
533*7c478bd9Sstevel@tonic-gate 		}
534*7c478bd9Sstevel@tonic-gate 		sprintf(ans, "%010ld", (long)filestat.st_mtime);
535*7c478bd9Sstevel@tonic-gate 	}
536*7c478bd9Sstevel@tonic-gate 	return (ans);
537*7c478bd9Sstevel@tonic-gate }
538*7c478bd9Sstevel@tonic-gate 
539*7c478bd9Sstevel@tonic-gate void
540*7c478bd9Sstevel@tonic-gate usage()
541*7c478bd9Sstevel@tonic-gate {
542*7c478bd9Sstevel@tonic-gate 	fprintf(stderr,
543*7c478bd9Sstevel@tonic-gate "usage: makedbm -u file\n	makedbm [-b] [-l] [-s] [-i YP_INPUT_FILE] "
544*7c478bd9Sstevel@tonic-gate 	    "[-o YP_OUTPUT_FILE] [-d YP_DOMAIN_NAME] [-m YP_MASTER_NAME] "
545*7c478bd9Sstevel@tonic-gate 	    "[-S DELIMITER] [-D NUM_DELIMITER_TO_SKIP] [-E] "
546*7c478bd9Sstevel@tonic-gate 	    "infile outfile\n");
547*7c478bd9Sstevel@tonic-gate 	exit(1);
548*7c478bd9Sstevel@tonic-gate }
549*7c478bd9Sstevel@tonic-gate 
550*7c478bd9Sstevel@tonic-gate void
551*7c478bd9Sstevel@tonic-gate addpair(fdb, str1, str2)
552*7c478bd9Sstevel@tonic-gate DBM *fdb;
553*7c478bd9Sstevel@tonic-gate char *str1, *str2;
554*7c478bd9Sstevel@tonic-gate {
555*7c478bd9Sstevel@tonic-gate 	datum key;
556*7c478bd9Sstevel@tonic-gate 	datum content;
557*7c478bd9Sstevel@tonic-gate 
558*7c478bd9Sstevel@tonic-gate 	key.dptr = str1;
559*7c478bd9Sstevel@tonic-gate 	key.dsize = strlen(str1);
560*7c478bd9Sstevel@tonic-gate 	content.dptr  = str2;
561*7c478bd9Sstevel@tonic-gate 	content.dsize = strlen(str2);
562*7c478bd9Sstevel@tonic-gate 	if (dbm_store(fdb, key, content, 1) != 0) {
563*7c478bd9Sstevel@tonic-gate 		printf("makedbm: problem storing %.*s %.*s\n",
564*7c478bd9Sstevel@tonic-gate 		    key.dsize, key.dptr, content.dsize, content.dptr);
565*7c478bd9Sstevel@tonic-gate 		exit(1);
566*7c478bd9Sstevel@tonic-gate 	}
567*7c478bd9Sstevel@tonic-gate }
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate void
570*7c478bd9Sstevel@tonic-gate unmake(file)
571*7c478bd9Sstevel@tonic-gate 	char *file;
572*7c478bd9Sstevel@tonic-gate {
573*7c478bd9Sstevel@tonic-gate 	datum key, content;
574*7c478bd9Sstevel@tonic-gate 	DBM *fdb;
575*7c478bd9Sstevel@tonic-gate 
576*7c478bd9Sstevel@tonic-gate 	if (file == NULL)
577*7c478bd9Sstevel@tonic-gate 		usage();
578*7c478bd9Sstevel@tonic-gate 
579*7c478bd9Sstevel@tonic-gate 	if ((fdb = dbm_open(file, O_RDONLY, 0644)) == NULL) {
580*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "makedbm: couldn't open %s dbm file\n", file);
581*7c478bd9Sstevel@tonic-gate 		exit(1);
582*7c478bd9Sstevel@tonic-gate 	}
583*7c478bd9Sstevel@tonic-gate 
584*7c478bd9Sstevel@tonic-gate 	for (key = dbm_firstkey(fdb); key.dptr != NULL;
585*7c478bd9Sstevel@tonic-gate 		key = dbm_nextkey(fdb)) {
586*7c478bd9Sstevel@tonic-gate 		content = dbm_fetch(fdb, key);
587*7c478bd9Sstevel@tonic-gate 		printf("%.*s %.*s\n", key.dsize, key.dptr,
588*7c478bd9Sstevel@tonic-gate 		    content.dsize, content.dptr);
589*7c478bd9Sstevel@tonic-gate 	}
590*7c478bd9Sstevel@tonic-gate 
591*7c478bd9Sstevel@tonic-gate 	dbm_close(fdb);
592*7c478bd9Sstevel@tonic-gate }
593