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