xref: /illumos-gate/usr/src/cmd/ypcmd/makedbm.c (revision a506a34c)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  *
22*a506a34cSth  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved   */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
317c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of
327c478bd9Sstevel@tonic-gate  * California.
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #undef NULL
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate #include <sys/types.h>
407c478bd9Sstevel@tonic-gate #include <sys/file.h>
417c478bd9Sstevel@tonic-gate #include <sys/param.h>
427c478bd9Sstevel@tonic-gate #include <sys/stat.h>
437c478bd9Sstevel@tonic-gate #include <ctype.h>
447c478bd9Sstevel@tonic-gate #include <limits.h>
457c478bd9Sstevel@tonic-gate #include <string.h>
467c478bd9Sstevel@tonic-gate #include <unistd.h>
477c478bd9Sstevel@tonic-gate #include <stdlib.h>
487c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
497c478bd9Sstevel@tonic-gate #include <dlfcn.h>
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #include "ypdefs.h"
527c478bd9Sstevel@tonic-gate #include "ypsym.h"
537c478bd9Sstevel@tonic-gate USE_YP_MASTER_NAME
547c478bd9Sstevel@tonic-gate USE_YP_LAST_MODIFIED
557c478bd9Sstevel@tonic-gate USE_YP_INPUT_FILE
567c478bd9Sstevel@tonic-gate USE_YP_OUTPUT_NAME
577c478bd9Sstevel@tonic-gate USE_YP_DOMAIN_NAME
587c478bd9Sstevel@tonic-gate USE_YP_SECURE
597c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN
607c478bd9Sstevel@tonic-gate USE_DBM
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate #ifdef SYSVCONFIG
637c478bd9Sstevel@tonic-gate extern void sysvconfig();
647c478bd9Sstevel@tonic-gate #endif
657c478bd9Sstevel@tonic-gate extern int yp_getalias();
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate #define	MAXLINE 4096		/* max length of input line */
687c478bd9Sstevel@tonic-gate #define	DEFAULT_SEP	" "
697c478bd9Sstevel@tonic-gate static char *get_date();
707c478bd9Sstevel@tonic-gate static char *any();
717c478bd9Sstevel@tonic-gate static void addpair();
727c478bd9Sstevel@tonic-gate static void unmake();
737c478bd9Sstevel@tonic-gate static void usage();
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate int   inode_dev_valid = 0;
767c478bd9Sstevel@tonic-gate ino_t inode;
777c478bd9Sstevel@tonic-gate dev_t dev;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate  * Interpose _close(2) to enable us to keep one of the output
817c478bd9Sstevel@tonic-gate  * files open until process exit.
827c478bd9Sstevel@tonic-gate  */
837c478bd9Sstevel@tonic-gate int
847c478bd9Sstevel@tonic-gate _close(int filedes) {
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	struct stat	sb;
877c478bd9Sstevel@tonic-gate 	static int	(*fptr)() = 0;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	if (fptr == 0) {
907c478bd9Sstevel@tonic-gate 		fptr = (int (*)())dlsym(RTLD_NEXT, "_close");
917c478bd9Sstevel@tonic-gate 		if (fptr == 0) {
927c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: dlopen(_close): %s\n",
937c478bd9Sstevel@tonic-gate 				dlerror());
947c478bd9Sstevel@tonic-gate 			errno = ELIBACC;
957c478bd9Sstevel@tonic-gate 			return (-1);
967c478bd9Sstevel@tonic-gate 		}
977c478bd9Sstevel@tonic-gate 	}
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	if (inode_dev_valid != 0 && fstat(filedes, &sb) == 0) {
1007c478bd9Sstevel@tonic-gate 		if (sb.st_ino == inode && sb.st_dev == dev) {
1017c478bd9Sstevel@tonic-gate 			/* Keep open; pretend successful */
1027c478bd9Sstevel@tonic-gate 			return (0);
1037c478bd9Sstevel@tonic-gate 		}
1047c478bd9Sstevel@tonic-gate 	}
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	return ((*fptr)(filedes));
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
109*a506a34cSth int
1107c478bd9Sstevel@tonic-gate main(argc, argv)
1117c478bd9Sstevel@tonic-gate 	int argc;
1127c478bd9Sstevel@tonic-gate 	char **argv;
1137c478bd9Sstevel@tonic-gate {
1147c478bd9Sstevel@tonic-gate 	FILE *infp, *outfp;
1157c478bd9Sstevel@tonic-gate 	datum key, content, tmp;
1167c478bd9Sstevel@tonic-gate 	char buf[MAXLINE];
1177c478bd9Sstevel@tonic-gate 	char pagbuf[MAXPATHLEN];
1187c478bd9Sstevel@tonic-gate 	char tmppagbuf[MAXPATHLEN];
1197c478bd9Sstevel@tonic-gate 	char dirbuf[MAXPATHLEN];
1207c478bd9Sstevel@tonic-gate 	char tmpdirbuf[MAXPATHLEN];
1217c478bd9Sstevel@tonic-gate 	char *p, ic;
1227c478bd9Sstevel@tonic-gate 	char *infile, *outfile;
1237c478bd9Sstevel@tonic-gate 	char outalias[MAXPATHLEN];
1247c478bd9Sstevel@tonic-gate 	char outaliasmap[MAXNAMLEN];
1257c478bd9Sstevel@tonic-gate 	char outaliasdomain[MAXNAMLEN];
1267c478bd9Sstevel@tonic-gate 	char *last_slash, *next_to_last_slash;
1277c478bd9Sstevel@tonic-gate 	char *infilename, *outfilename, *mastername, *domainname,
1287c478bd9Sstevel@tonic-gate 	    *interdomain_bind, *security, *lower_case_keys;
1297c478bd9Sstevel@tonic-gate 	char *key_sep = DEFAULT_SEP;
1307c478bd9Sstevel@tonic-gate 	char local_host[MAX_MASTER_NAME];
1317c478bd9Sstevel@tonic-gate 	int cnt, i;
1327c478bd9Sstevel@tonic-gate 	DBM *fdb;
1337c478bd9Sstevel@tonic-gate 	struct stat statbuf;
1347c478bd9Sstevel@tonic-gate 	int num_del_to_match = 0;
1357c478bd9Sstevel@tonic-gate 	/* flag to indicate if matching char can be escaped */
1367c478bd9Sstevel@tonic-gate 	int count_esp = 0;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	/* Ignore existing umask, always force 077 (owner rw only) */
1397c478bd9Sstevel@tonic-gate 	umask(077);
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	infile = outfile = NULL; /* where to get files */
1427c478bd9Sstevel@tonic-gate 	/* name to imbed in database */
1437c478bd9Sstevel@tonic-gate 	infilename = outfilename = mastername = domainname = interdomain_bind =
1447c478bd9Sstevel@tonic-gate 	    security = lower_case_keys = NULL;
1457c478bd9Sstevel@tonic-gate 	argv++;
1467c478bd9Sstevel@tonic-gate 	argc--;
1477c478bd9Sstevel@tonic-gate 	while (argc > 0) {
1487c478bd9Sstevel@tonic-gate 		if (argv[0][0] == '-' && argv[0][1]) {
1497c478bd9Sstevel@tonic-gate 			switch (argv[0][1]) {
1507c478bd9Sstevel@tonic-gate 				case 'i':
1517c478bd9Sstevel@tonic-gate 					infilename = argv[1];
1527c478bd9Sstevel@tonic-gate 					argv++;
1537c478bd9Sstevel@tonic-gate 					argc--;
1547c478bd9Sstevel@tonic-gate 					break;
1557c478bd9Sstevel@tonic-gate 				case 'o':
1567c478bd9Sstevel@tonic-gate 					outfilename = argv[1];
1577c478bd9Sstevel@tonic-gate 					argv++;
1587c478bd9Sstevel@tonic-gate 					argc--;
1597c478bd9Sstevel@tonic-gate 					break;
1607c478bd9Sstevel@tonic-gate 				case 'm':
1617c478bd9Sstevel@tonic-gate 					mastername = argv[1];
1627c478bd9Sstevel@tonic-gate 					argv++;
1637c478bd9Sstevel@tonic-gate 					argc--;
1647c478bd9Sstevel@tonic-gate 					break;
1657c478bd9Sstevel@tonic-gate 				case 'b':
1667c478bd9Sstevel@tonic-gate 					interdomain_bind = argv[0];
1677c478bd9Sstevel@tonic-gate 					break;
1687c478bd9Sstevel@tonic-gate 				case 'd':
1697c478bd9Sstevel@tonic-gate 					domainname = argv[1];
1707c478bd9Sstevel@tonic-gate 					argv++;
1717c478bd9Sstevel@tonic-gate 					argc--;
1727c478bd9Sstevel@tonic-gate 					break;
1737c478bd9Sstevel@tonic-gate 				case 'l':
1747c478bd9Sstevel@tonic-gate 					lower_case_keys = argv[0];
1757c478bd9Sstevel@tonic-gate 					break;
1767c478bd9Sstevel@tonic-gate 				case 's':
1777c478bd9Sstevel@tonic-gate 					security = argv[0];
1787c478bd9Sstevel@tonic-gate 					break;
1797c478bd9Sstevel@tonic-gate 				case 'S' :
1807c478bd9Sstevel@tonic-gate 					strcpy(key_sep, argv[1]);
1817c478bd9Sstevel@tonic-gate 					argv++;
1827c478bd9Sstevel@tonic-gate 					argc--;
1837c478bd9Sstevel@tonic-gate 					if (strlen(key_sep) != 1) {
1847c478bd9Sstevel@tonic-gate 						fprintf(stderr,
1857c478bd9Sstevel@tonic-gate 							"bad separator\n");
1867c478bd9Sstevel@tonic-gate 						usage();
1877c478bd9Sstevel@tonic-gate 					}
1887c478bd9Sstevel@tonic-gate 					break;
1897c478bd9Sstevel@tonic-gate 				case 'D' :
1907c478bd9Sstevel@tonic-gate 					num_del_to_match = atoi(argv[1]);
1917c478bd9Sstevel@tonic-gate 					argv++;
1927c478bd9Sstevel@tonic-gate 					argc--;
1937c478bd9Sstevel@tonic-gate 					break;
1947c478bd9Sstevel@tonic-gate 				case 'E' :
1957c478bd9Sstevel@tonic-gate 					count_esp = 1;
1967c478bd9Sstevel@tonic-gate 					break;
1977c478bd9Sstevel@tonic-gate 				case 'u':
1987c478bd9Sstevel@tonic-gate 					unmake(argv[1]);
1997c478bd9Sstevel@tonic-gate 					argv++;
2007c478bd9Sstevel@tonic-gate 					argc--;
2017c478bd9Sstevel@tonic-gate 					exit(0);
2027c478bd9Sstevel@tonic-gate 				default:
2037c478bd9Sstevel@tonic-gate 					usage();
2047c478bd9Sstevel@tonic-gate 			}
2057c478bd9Sstevel@tonic-gate 		} else if (infile == NULL)
2067c478bd9Sstevel@tonic-gate 			infile = argv[0];
2077c478bd9Sstevel@tonic-gate 		else if (outfile == NULL)
2087c478bd9Sstevel@tonic-gate 			outfile = argv[0];
2097c478bd9Sstevel@tonic-gate 		else
2107c478bd9Sstevel@tonic-gate 			usage();
2117c478bd9Sstevel@tonic-gate 		argv++;
2127c478bd9Sstevel@tonic-gate 		argc--;
2137c478bd9Sstevel@tonic-gate 	}
2147c478bd9Sstevel@tonic-gate 	if (infile == NULL || outfile == NULL)
2157c478bd9Sstevel@tonic-gate 		usage();
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	/*
2187c478bd9Sstevel@tonic-gate 	 *  do alias mapping if necessary
2197c478bd9Sstevel@tonic-gate 	 */
2207c478bd9Sstevel@tonic-gate 	last_slash = strrchr(outfile, '/');
2217c478bd9Sstevel@tonic-gate 	if (last_slash) {
2227c478bd9Sstevel@tonic-gate 		*last_slash = '\0';
2237c478bd9Sstevel@tonic-gate 		next_to_last_slash = strrchr(outfile, '/');
2247c478bd9Sstevel@tonic-gate 		if (next_to_last_slash) *next_to_last_slash = '\0';
2257c478bd9Sstevel@tonic-gate 	} else next_to_last_slash = NULL;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate #ifdef DEBUG
2287c478bd9Sstevel@tonic-gate 	if (last_slash) printf("last_slash=%s\n", last_slash+1);
2297c478bd9Sstevel@tonic-gate 	if (next_to_last_slash) printf("next_to_last_slash=%s\n",
2307c478bd9Sstevel@tonic-gate 		next_to_last_slash+1);
2317c478bd9Sstevel@tonic-gate #endif /* DEBUG */
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	/* reads in alias file for system v filename translation */
2347c478bd9Sstevel@tonic-gate #ifdef SYSVCONFIG
2357c478bd9Sstevel@tonic-gate 	sysvconfig();
2367c478bd9Sstevel@tonic-gate #endif
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate 	if (last_slash && next_to_last_slash) {
2397c478bd9Sstevel@tonic-gate 		if (yp_getalias(last_slash+1, outaliasmap, MAXALIASLEN) < 0) {
2407c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= MAXALIASLEN)
2417c478bd9Sstevel@tonic-gate 				strcpy(outaliasmap, last_slash+1);
2427c478bd9Sstevel@tonic-gate 			else
2437c478bd9Sstevel@tonic-gate 				fprintf(stderr,
2447c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
2457c478bd9Sstevel@tonic-gate 				    last_slash+1);
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate #ifdef DEBUG
2487c478bd9Sstevel@tonic-gate 		printf("%s\n", last_slash+1);
2497c478bd9Sstevel@tonic-gate 		printf("%s\n", outaliasmap);
2507c478bd9Sstevel@tonic-gate #endif /* DEBUG */
2517c478bd9Sstevel@tonic-gate 		if (yp_getalias(next_to_last_slash+1, outaliasdomain,
2527c478bd9Sstevel@tonic-gate 		    NAME_MAX) < 0) {
2537c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= NAME_MAX)
2547c478bd9Sstevel@tonic-gate 				strcpy(outaliasdomain, next_to_last_slash+1);
2557c478bd9Sstevel@tonic-gate 			else
2567c478bd9Sstevel@tonic-gate 				fprintf(stderr,
2577c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
2587c478bd9Sstevel@tonic-gate 				    next_to_last_slash+1);
2597c478bd9Sstevel@tonic-gate 		}
2607c478bd9Sstevel@tonic-gate #ifdef DEBUG
2617c478bd9Sstevel@tonic-gate 		printf("%s\n", next_to_last_slash+1);
2627c478bd9Sstevel@tonic-gate 		printf("%s\n", outaliasdomain);
2637c478bd9Sstevel@tonic-gate #endif /* DEBUG */
2647c478bd9Sstevel@tonic-gate 		sprintf(outalias, "%s/%s/%s", outfile, outaliasdomain,
2657c478bd9Sstevel@tonic-gate 			outaliasmap);
2667c478bd9Sstevel@tonic-gate #ifdef DEBUG
2677c478bd9Sstevel@tonic-gate 		printf("outlias=%s\n", outalias);
2687c478bd9Sstevel@tonic-gate #endif /* DEBUG */
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	} else if (last_slash) {
2717c478bd9Sstevel@tonic-gate 		if (yp_getalias(last_slash+1, outaliasmap, MAXALIASLEN) < 0) {
2727c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= MAXALIASLEN)
2737c478bd9Sstevel@tonic-gate 				strcpy(outaliasmap, last_slash+1);
2747c478bd9Sstevel@tonic-gate 			else
2757c478bd9Sstevel@tonic-gate 				fprintf(stderr,
2767c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
2777c478bd9Sstevel@tonic-gate 				    last_slash+1);
2787c478bd9Sstevel@tonic-gate 		}
2797c478bd9Sstevel@tonic-gate 		if (yp_getalias(outfile, outaliasdomain, NAME_MAX) < 0) {
2807c478bd9Sstevel@tonic-gate 			if ((int)strlen(outfile) <= NAME_MAX)
2817c478bd9Sstevel@tonic-gate 				strcpy(outaliasdomain, outfile);
2827c478bd9Sstevel@tonic-gate 			else
2837c478bd9Sstevel@tonic-gate 				fprintf(stderr,
2847c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
2857c478bd9Sstevel@tonic-gate 				    last_slash+1);
2867c478bd9Sstevel@tonic-gate 		}
2877c478bd9Sstevel@tonic-gate 		sprintf(outalias, "%s/%s", outaliasdomain, outaliasmap);
2887c478bd9Sstevel@tonic-gate 	} else {
2897c478bd9Sstevel@tonic-gate 		if (yp_getalias(outfile, outalias, MAXALIASLEN) < 0) {
2907c478bd9Sstevel@tonic-gate 			if ((int)strlen(last_slash+1) <= MAXALIASLEN)
2917c478bd9Sstevel@tonic-gate 				strcpy(outalias, outfile);
2927c478bd9Sstevel@tonic-gate 			else
2937c478bd9Sstevel@tonic-gate 				fprintf(stderr,
2947c478bd9Sstevel@tonic-gate 				    "makedbm: warning: no alias for %s\n",
2957c478bd9Sstevel@tonic-gate 				    outfile);
2967c478bd9Sstevel@tonic-gate 			}
2977c478bd9Sstevel@tonic-gate 	}
2987c478bd9Sstevel@tonic-gate #ifdef DEBUG
2997c478bd9Sstevel@tonic-gate 	fprintf(stderr, "outalias=%s\n", outalias);
3007c478bd9Sstevel@tonic-gate 	fprintf(stderr, "outfile=%s\n", outfile);
3017c478bd9Sstevel@tonic-gate #endif /* DEBUG */
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	strcpy(tmppagbuf, outalias);
3047c478bd9Sstevel@tonic-gate 	strcat(tmppagbuf, ".tmp");
3057c478bd9Sstevel@tonic-gate 	strcpy(tmpdirbuf, tmppagbuf);
3067c478bd9Sstevel@tonic-gate 	strcat(tmpdirbuf, dbm_dir);
3077c478bd9Sstevel@tonic-gate 	strcat(tmppagbuf, dbm_pag);
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	/* Loop until we can lock the tmpdirbuf file */
3107c478bd9Sstevel@tonic-gate 	for (;;) {
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 		if (strcmp(infile, "-") != 0)
3137c478bd9Sstevel@tonic-gate 			infp = fopen(infile, "r");
3147c478bd9Sstevel@tonic-gate 		else if (fstat(fileno(stdin), &statbuf) == -1) {
3157c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't open stdin\n");
3167c478bd9Sstevel@tonic-gate 			exit(1);
3177c478bd9Sstevel@tonic-gate 		} else
3187c478bd9Sstevel@tonic-gate 			infp = stdin;
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 		if (infp == NULL) {
3217c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't open %s\n", infile);
3227c478bd9Sstevel@tonic-gate 			exit(1);
3237c478bd9Sstevel@tonic-gate 		}
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 		if ((outfp = fopen(tmpdirbuf, "w")) == (FILE *)NULL) {
3267c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't create %s\n",
3277c478bd9Sstevel@tonic-gate 				tmpdirbuf);
3287c478bd9Sstevel@tonic-gate 			exit(1);
3297c478bd9Sstevel@tonic-gate 		}
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 		if (lockf(fileno(outfp), F_TLOCK, 0) == 0) {
3327c478bd9Sstevel@tonic-gate 			/* Got exclusive access; save inode and dev */
3337c478bd9Sstevel@tonic-gate 			if (fstat(fileno(outfp), &statbuf) != 0) {
3347c478bd9Sstevel@tonic-gate 				fprintf(stderr, "makedbm: can't fstat ");
3357c478bd9Sstevel@tonic-gate 				perror(tmpdirbuf);
3367c478bd9Sstevel@tonic-gate 				exit(1);
3377c478bd9Sstevel@tonic-gate 			}
3387c478bd9Sstevel@tonic-gate 			inode		= statbuf.st_ino;
3397c478bd9Sstevel@tonic-gate 			dev		= statbuf.st_dev;
3407c478bd9Sstevel@tonic-gate 			inode_dev_valid	= 1;
3417c478bd9Sstevel@tonic-gate 			break;
3427c478bd9Sstevel@tonic-gate 		}
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 		if (errno != EAGAIN) {
3457c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't lock ");
3467c478bd9Sstevel@tonic-gate 			perror(tmpdirbuf);
3477c478bd9Sstevel@tonic-gate 			exit(1);
3487c478bd9Sstevel@tonic-gate 		}
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 		/*
3517c478bd9Sstevel@tonic-gate 		 * Someone else is holding the lock.
3527c478bd9Sstevel@tonic-gate 		 * Close both output and input file
3537c478bd9Sstevel@tonic-gate 		 * (the latter to ensure consistency
3547c478bd9Sstevel@tonic-gate 		 * if the input file is updated while
3557c478bd9Sstevel@tonic-gate 		 * we're suspended), wait a little,
3567c478bd9Sstevel@tonic-gate 		 * and try again.
3577c478bd9Sstevel@tonic-gate 		 */
3587c478bd9Sstevel@tonic-gate 		if (infp != stdin)
3597c478bd9Sstevel@tonic-gate 			(void) fclose(infp);
3607c478bd9Sstevel@tonic-gate 		(void) fclose(outfp);
3617c478bd9Sstevel@tonic-gate 		sleep(1);
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	if (fopen(tmppagbuf, "w") == (FILE *)NULL) {
3657c478bd9Sstevel@tonic-gate 		fprintf(stderr, "makedbm: can't create %s\n", tmppagbuf);
3667c478bd9Sstevel@tonic-gate 		exit(1);
3677c478bd9Sstevel@tonic-gate 	}
3687c478bd9Sstevel@tonic-gate 	strcpy(dirbuf, outalias);
3697c478bd9Sstevel@tonic-gate 	strcat(dirbuf, ".tmp");
3707c478bd9Sstevel@tonic-gate 	if ((fdb = dbm_open(dirbuf, O_RDWR | O_CREAT, 0644)) == NULL) {
3717c478bd9Sstevel@tonic-gate 		fprintf(stderr, "makedbm: can't open %s\n", dirbuf);
3727c478bd9Sstevel@tonic-gate 		exit(1);
3737c478bd9Sstevel@tonic-gate 	}
3747c478bd9Sstevel@tonic-gate 	strcpy(dirbuf, outalias);
3757c478bd9Sstevel@tonic-gate 	strcpy(pagbuf, outalias);
3767c478bd9Sstevel@tonic-gate 	strcat(dirbuf, dbm_dir);
3777c478bd9Sstevel@tonic-gate 	strcat(pagbuf, dbm_pag);
3787c478bd9Sstevel@tonic-gate 	while (fgets(buf, sizeof (buf), infp) != NULL) {
3797c478bd9Sstevel@tonic-gate 		p = buf;
3807c478bd9Sstevel@tonic-gate 		cnt = strlen(buf) - 1; /* erase trailing newline */
3817c478bd9Sstevel@tonic-gate 		while (p[cnt-1] == '\\') {
3827c478bd9Sstevel@tonic-gate 			p += cnt-1;
3837c478bd9Sstevel@tonic-gate 			if (fgets(p, sizeof (buf)-(p-buf), infp) == NULL)
3847c478bd9Sstevel@tonic-gate 				goto breakout;
3857c478bd9Sstevel@tonic-gate 			cnt = strlen(p) - 1;
3867c478bd9Sstevel@tonic-gate 		}
3877c478bd9Sstevel@tonic-gate 		if (strcmp(key_sep, DEFAULT_SEP) == 0) {
3887c478bd9Sstevel@tonic-gate 			p = any(buf, " \t\n", num_del_to_match, count_esp);
3897c478bd9Sstevel@tonic-gate 		} else {
3907c478bd9Sstevel@tonic-gate 			p = any(buf, key_sep, num_del_to_match, count_esp);
3917c478bd9Sstevel@tonic-gate 		}
3927c478bd9Sstevel@tonic-gate 		key.dptr = buf;
3937c478bd9Sstevel@tonic-gate 		key.dsize = p - buf;
3947c478bd9Sstevel@tonic-gate 		for (;;) {
3957c478bd9Sstevel@tonic-gate 			if (p == NULL || *p == NULL) {
3967c478bd9Sstevel@tonic-gate 				fprintf(stderr,
3977c478bd9Sstevel@tonic-gate 	"makedbm: source files is garbage!\n");
3987c478bd9Sstevel@tonic-gate 				exit(1);
3997c478bd9Sstevel@tonic-gate 			}
4007c478bd9Sstevel@tonic-gate 			if (*p != ' ' && *p != '\t' && *p != key_sep[0])
4017c478bd9Sstevel@tonic-gate 				break;
4027c478bd9Sstevel@tonic-gate 			p++;
4037c478bd9Sstevel@tonic-gate 		}
4047c478bd9Sstevel@tonic-gate 		content.dptr = p;
4057c478bd9Sstevel@tonic-gate 		content.dsize = strlen(p) - 1; /* erase trailing newline */
4067c478bd9Sstevel@tonic-gate 		if (lower_case_keys) {
4077c478bd9Sstevel@tonic-gate 			for (i = (strncmp(key.dptr, "YP_MULTI_", 9) ? 0 : 9);
4087c478bd9Sstevel@tonic-gate 					i < key.dsize; i++) {
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 				ic = *(key.dptr+i);
4117c478bd9Sstevel@tonic-gate 				if (isascii(ic) && isupper(ic))
4127c478bd9Sstevel@tonic-gate 					*(key.dptr+i) = tolower(ic);
4137c478bd9Sstevel@tonic-gate 			}
4147c478bd9Sstevel@tonic-gate 		}
4157c478bd9Sstevel@tonic-gate 		tmp = dbm_fetch(fdb, key);
4167c478bd9Sstevel@tonic-gate 		if (tmp.dptr == NULL) {
4177c478bd9Sstevel@tonic-gate 			if (dbm_store(fdb, key, content, 1) != 0) {
4187c478bd9Sstevel@tonic-gate 				printf("problem storing %.*s %.*s\n",
4197c478bd9Sstevel@tonic-gate 				    key.dsize, key.dptr,
4207c478bd9Sstevel@tonic-gate 				    content.dsize, content.dptr);
4217c478bd9Sstevel@tonic-gate 				exit(1);
4227c478bd9Sstevel@tonic-gate 			}
4237c478bd9Sstevel@tonic-gate 		}
4247c478bd9Sstevel@tonic-gate #ifdef DEBUG
4257c478bd9Sstevel@tonic-gate 		else {
4267c478bd9Sstevel@tonic-gate 			printf("duplicate: %.*s %.*s\n",
4277c478bd9Sstevel@tonic-gate 			    key.dsize, key.dptr,
4287c478bd9Sstevel@tonic-gate 			    content.dsize, content.dptr);
4297c478bd9Sstevel@tonic-gate 		}
4307c478bd9Sstevel@tonic-gate #endif
4317c478bd9Sstevel@tonic-gate 	}
4327c478bd9Sstevel@tonic-gate 	breakout:
4337c478bd9Sstevel@tonic-gate 	addpair(fdb, yp_last_modified, get_date(infile));
4347c478bd9Sstevel@tonic-gate 	if (infilename)
4357c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_input_file, infilename);
4367c478bd9Sstevel@tonic-gate 	if (outfilename)
4377c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_output_file, outfilename);
4387c478bd9Sstevel@tonic-gate 	if (domainname)
4397c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_domain_name, domainname);
4407c478bd9Sstevel@tonic-gate 	if (security)
4417c478bd9Sstevel@tonic-gate 		addpair(fdb, yp_secure, "");
4427c478bd9Sstevel@tonic-gate 	if (interdomain_bind)
4437c478bd9Sstevel@tonic-gate 	    addpair(fdb, yp_interdomain, "");
4447c478bd9Sstevel@tonic-gate 	if (!mastername) {
4457c478bd9Sstevel@tonic-gate 		sysinfo(SI_HOSTNAME, local_host, sizeof (local_host) - 1);
4467c478bd9Sstevel@tonic-gate 		mastername = local_host;
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate 	addpair(fdb, yp_master_name, mastername);
4497c478bd9Sstevel@tonic-gate 	(void) dbm_close(fdb);
4507c478bd9Sstevel@tonic-gate #ifdef DEBUG
4517c478bd9Sstevel@tonic-gate 	fprintf(stderr, ".tmp ndbm map closed. ndbm successful !\n");
4527c478bd9Sstevel@tonic-gate #endif
4537c478bd9Sstevel@tonic-gate 	if (rename(tmppagbuf, pagbuf) < 0) {
4547c478bd9Sstevel@tonic-gate 		perror("makedbm: rename");
4557c478bd9Sstevel@tonic-gate 		unlink(tmppagbuf);		/* Remove the tmp files */
4567c478bd9Sstevel@tonic-gate 		unlink(tmpdirbuf);
4577c478bd9Sstevel@tonic-gate 		exit(1);
4587c478bd9Sstevel@tonic-gate 	}
4597c478bd9Sstevel@tonic-gate 	if (rename(tmpdirbuf, dirbuf) < 0) {
4607c478bd9Sstevel@tonic-gate 		perror("makedbm: rename");
4617c478bd9Sstevel@tonic-gate 		unlink(tmppagbuf); /* Remove the tmp files */
4627c478bd9Sstevel@tonic-gate 		unlink(tmpdirbuf);
4637c478bd9Sstevel@tonic-gate 		exit(1);
4647c478bd9Sstevel@tonic-gate 	}
4657c478bd9Sstevel@tonic-gate /*
4667c478bd9Sstevel@tonic-gate  *	sprintf(buf, "mv %s %s", tmppagbuf, pagbuf);
4677c478bd9Sstevel@tonic-gate  *	if (system(buf) < 0)
4687c478bd9Sstevel@tonic-gate  *		perror("makedbm: rename");
4697c478bd9Sstevel@tonic-gate  *	sprintf(buf, "mv %s %s", tmpdirbuf, dirbuf);
4707c478bd9Sstevel@tonic-gate  *	if (system(buf) < 0)
4717c478bd9Sstevel@tonic-gate  *		perror("makedbm: rename");
4727c478bd9Sstevel@tonic-gate  */
4737c478bd9Sstevel@tonic-gate 	exit(0);
4747c478bd9Sstevel@tonic-gate }
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate /*
4787c478bd9Sstevel@tonic-gate  * scans cp, looking for a match with any character
4797c478bd9Sstevel@tonic-gate  * in match.  Returns pointer to place in cp that matched
4807c478bd9Sstevel@tonic-gate  * (or NULL if no match)
4817c478bd9Sstevel@tonic-gate  *
4827c478bd9Sstevel@tonic-gate  * It will find the num_del_to_match+1
4837c478bd9Sstevel@tonic-gate  * matching character in the line.
4847c478bd9Sstevel@tonic-gate  *
4857c478bd9Sstevel@tonic-gate  * The backslash escapes a delimiter if count_esp==1
4867c478bd9Sstevel@tonic-gate  * We don't count it as a character match if
4877c478bd9Sstevel@tonic-gate  * an escape character precedes a matching character.
4887c478bd9Sstevel@tonic-gate  *
4897c478bd9Sstevel@tonic-gate  */
4907c478bd9Sstevel@tonic-gate static char *
4917c478bd9Sstevel@tonic-gate any(cp, match, num_del_to_match, count_esp)
4927c478bd9Sstevel@tonic-gate 	register char *cp;
4937c478bd9Sstevel@tonic-gate 	char *match;
4947c478bd9Sstevel@tonic-gate 	int num_del_to_match;
4957c478bd9Sstevel@tonic-gate 	int count_esp;
4967c478bd9Sstevel@tonic-gate {
4977c478bd9Sstevel@tonic-gate 	register char *mp, c, prev_char;
4987c478bd9Sstevel@tonic-gate 	int num_del_matched;
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	num_del_matched = 0;
5017c478bd9Sstevel@tonic-gate 	prev_char = ' ';
5027c478bd9Sstevel@tonic-gate 	while (c = *cp) {
5037c478bd9Sstevel@tonic-gate 		for (mp = match; *mp; mp++) {
5047c478bd9Sstevel@tonic-gate 			if (*mp == c) {
5057c478bd9Sstevel@tonic-gate 				if (!count_esp) {
5067c478bd9Sstevel@tonic-gate 					num_del_matched++;
5077c478bd9Sstevel@tonic-gate 				} else if (prev_char != '\\') {
5087c478bd9Sstevel@tonic-gate 					num_del_matched++;
5097c478bd9Sstevel@tonic-gate 				}
5107c478bd9Sstevel@tonic-gate 				if (num_del_matched > num_del_to_match)
5117c478bd9Sstevel@tonic-gate 					return (cp);
5127c478bd9Sstevel@tonic-gate 			}
5137c478bd9Sstevel@tonic-gate 		}
5147c478bd9Sstevel@tonic-gate 		prev_char = c;
5157c478bd9Sstevel@tonic-gate 		cp++;
5167c478bd9Sstevel@tonic-gate 	}
5177c478bd9Sstevel@tonic-gate 	return ((char *)0);
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate static char *
5217c478bd9Sstevel@tonic-gate get_date(name)
5227c478bd9Sstevel@tonic-gate 	char *name;
5237c478bd9Sstevel@tonic-gate {
5247c478bd9Sstevel@tonic-gate 	struct stat filestat;
5257c478bd9Sstevel@tonic-gate 	static char ans[MAX_ASCII_ORDER_NUMBER_LENGTH];
5267c478bd9Sstevel@tonic-gate 	/* ASCII numeric string */
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 	if (strcmp(name, "-") == 0)
5297c478bd9Sstevel@tonic-gate 		sprintf(ans, "%010ld", (long)time(0));
5307c478bd9Sstevel@tonic-gate 	else {
5317c478bd9Sstevel@tonic-gate 		if (stat(name, &filestat) < 0) {
5327c478bd9Sstevel@tonic-gate 			fprintf(stderr, "makedbm: can't stat %s\n", name);
5337c478bd9Sstevel@tonic-gate 			exit(1);
5347c478bd9Sstevel@tonic-gate 		}
5357c478bd9Sstevel@tonic-gate 		sprintf(ans, "%010ld", (long)filestat.st_mtime);
5367c478bd9Sstevel@tonic-gate 	}
5377c478bd9Sstevel@tonic-gate 	return (ans);
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate void
5417c478bd9Sstevel@tonic-gate usage()
5427c478bd9Sstevel@tonic-gate {
5437c478bd9Sstevel@tonic-gate 	fprintf(stderr,
5447c478bd9Sstevel@tonic-gate "usage: makedbm -u file\n	makedbm [-b] [-l] [-s] [-i YP_INPUT_FILE] "
5457c478bd9Sstevel@tonic-gate 	    "[-o YP_OUTPUT_FILE] [-d YP_DOMAIN_NAME] [-m YP_MASTER_NAME] "
5467c478bd9Sstevel@tonic-gate 	    "[-S DELIMITER] [-D NUM_DELIMITER_TO_SKIP] [-E] "
5477c478bd9Sstevel@tonic-gate 	    "infile outfile\n");
5487c478bd9Sstevel@tonic-gate 	exit(1);
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate void
5527c478bd9Sstevel@tonic-gate addpair(fdb, str1, str2)
5537c478bd9Sstevel@tonic-gate DBM *fdb;
5547c478bd9Sstevel@tonic-gate char *str1, *str2;
5557c478bd9Sstevel@tonic-gate {
5567c478bd9Sstevel@tonic-gate 	datum key;
5577c478bd9Sstevel@tonic-gate 	datum content;
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 	key.dptr = str1;
5607c478bd9Sstevel@tonic-gate 	key.dsize = strlen(str1);
5617c478bd9Sstevel@tonic-gate 	content.dptr  = str2;
5627c478bd9Sstevel@tonic-gate 	content.dsize = strlen(str2);
5637c478bd9Sstevel@tonic-gate 	if (dbm_store(fdb, key, content, 1) != 0) {
5647c478bd9Sstevel@tonic-gate 		printf("makedbm: problem storing %.*s %.*s\n",
5657c478bd9Sstevel@tonic-gate 		    key.dsize, key.dptr, content.dsize, content.dptr);
5667c478bd9Sstevel@tonic-gate 		exit(1);
5677c478bd9Sstevel@tonic-gate 	}
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate void
5717c478bd9Sstevel@tonic-gate unmake(file)
5727c478bd9Sstevel@tonic-gate 	char *file;
5737c478bd9Sstevel@tonic-gate {
5747c478bd9Sstevel@tonic-gate 	datum key, content;
5757c478bd9Sstevel@tonic-gate 	DBM *fdb;
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate 	if (file == NULL)
5787c478bd9Sstevel@tonic-gate 		usage();
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 	if ((fdb = dbm_open(file, O_RDONLY, 0644)) == NULL) {
5817c478bd9Sstevel@tonic-gate 		fprintf(stderr, "makedbm: couldn't open %s dbm file\n", file);
5827c478bd9Sstevel@tonic-gate 		exit(1);
5837c478bd9Sstevel@tonic-gate 	}
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 	for (key = dbm_firstkey(fdb); key.dptr != NULL;
5867c478bd9Sstevel@tonic-gate 		key = dbm_nextkey(fdb)) {
5877c478bd9Sstevel@tonic-gate 		content = dbm_fetch(fdb, key);
5887c478bd9Sstevel@tonic-gate 		printf("%.*s %.*s\n", key.dsize, key.dptr,
5897c478bd9Sstevel@tonic-gate 		    content.dsize, content.dptr);
5907c478bd9Sstevel@tonic-gate 	}
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate 	dbm_close(fdb);
5937c478bd9Sstevel@tonic-gate }
594