xref: /titanic_50/usr/src/cmd/sendmail/aux/makemap.c (revision d4660949aa62dd6a963f4913b7120b383cf473c4)
17c478bd9Sstevel@tonic-gate /*
2*d4660949Sjbeck  * Copyright (c) 1998-2002, 2004, 2008 Sendmail, Inc. and its suppliers.
37c478bd9Sstevel@tonic-gate  *	All rights reserved.
47c478bd9Sstevel@tonic-gate  * Copyright (c) 1992 Eric P. Allman.  All rights reserved.
57c478bd9Sstevel@tonic-gate  * Copyright (c) 1992, 1993
67c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
97c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
107c478bd9Sstevel@tonic-gate  * the sendmail distribution.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  */
137c478bd9Sstevel@tonic-gate 
147c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate #include <sm/gen.h>
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate SM_IDSTR(copyright,
197c478bd9Sstevel@tonic-gate "@(#) Copyright (c) 1998-2002, 2004 Sendmail, Inc. and its suppliers.\n\
207c478bd9Sstevel@tonic-gate 	All rights reserved.\n\
217c478bd9Sstevel@tonic-gate      Copyright (c) 1992 Eric P. Allman.  All rights reserved.\n\
227c478bd9Sstevel@tonic-gate      Copyright (c) 1992, 1993\n\
237c478bd9Sstevel@tonic-gate 	The Regents of the University of California.  All rights reserved.\n")
247c478bd9Sstevel@tonic-gate 
25*d4660949Sjbeck SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.179 2008/04/14 02:06:16 ca Exp $")
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <sys/types.h>
297c478bd9Sstevel@tonic-gate #ifndef ISC_UNIX
307c478bd9Sstevel@tonic-gate # include <sys/file.h>
317c478bd9Sstevel@tonic-gate #endif /* ! ISC_UNIX */
327c478bd9Sstevel@tonic-gate #include <ctype.h>
337c478bd9Sstevel@tonic-gate #include <stdlib.h>
347c478bd9Sstevel@tonic-gate #include <unistd.h>
357c478bd9Sstevel@tonic-gate #ifdef EX_OK
367c478bd9Sstevel@tonic-gate # undef EX_OK		/* unistd.h may have another use for this */
377c478bd9Sstevel@tonic-gate #endif /* EX_OK */
387c478bd9Sstevel@tonic-gate #include <sysexits.h>
397c478bd9Sstevel@tonic-gate #include <sendmail/sendmail.h>
407c478bd9Sstevel@tonic-gate #include <sendmail/pathnames.h>
417c478bd9Sstevel@tonic-gate #include <libsmdb/smdb.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate uid_t	RealUid;
447c478bd9Sstevel@tonic-gate gid_t	RealGid;
457c478bd9Sstevel@tonic-gate char	*RealUserName;
467c478bd9Sstevel@tonic-gate uid_t	RunAsUid;
477800901eSjbeck gid_t	RunAsGid;
487c478bd9Sstevel@tonic-gate char	*RunAsUserName;
497c478bd9Sstevel@tonic-gate int	Verbose = 2;
507c478bd9Sstevel@tonic-gate bool	DontInitGroups = false;
517c478bd9Sstevel@tonic-gate uid_t	TrustedUid = 0;
527c478bd9Sstevel@tonic-gate BITMAP256 DontBlameSendmail;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #define BUFSIZE		1024
557c478bd9Sstevel@tonic-gate #define ISSEP(c) (sep == '\0' ? isascii(c) && isspace(c) : (c) == sep)
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate static void usage __P((char *));
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate static void
usage(progname)607c478bd9Sstevel@tonic-gate usage(progname)
617c478bd9Sstevel@tonic-gate 	char *progname;
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
647c478bd9Sstevel@tonic-gate 		      "Usage: %s [-C cffile] [-N] [-c cachesize] [-D commentchar]\n",
657c478bd9Sstevel@tonic-gate 		      progname);
667c478bd9Sstevel@tonic-gate 	sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
677c478bd9Sstevel@tonic-gate 		      "       %*s [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter]\n",
687c478bd9Sstevel@tonic-gate 		      (int) strlen(progname), "");
697c478bd9Sstevel@tonic-gate 	sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
707c478bd9Sstevel@tonic-gate 		      "       %*s [-u] [-v] type mapname\n",
717c478bd9Sstevel@tonic-gate 		      (int) strlen(progname), "");
727c478bd9Sstevel@tonic-gate 	exit(EX_USAGE);
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate int
main(argc,argv)767c478bd9Sstevel@tonic-gate main(argc, argv)
777c478bd9Sstevel@tonic-gate 	int argc;
787c478bd9Sstevel@tonic-gate 	char **argv;
797c478bd9Sstevel@tonic-gate {
807c478bd9Sstevel@tonic-gate 	char *progname;
817c478bd9Sstevel@tonic-gate 	char *cfile;
827c478bd9Sstevel@tonic-gate 	bool inclnull = false;
837c478bd9Sstevel@tonic-gate 	bool notrunc = false;
847c478bd9Sstevel@tonic-gate 	bool allowreplace = false;
857c478bd9Sstevel@tonic-gate 	bool allowempty = false;
867c478bd9Sstevel@tonic-gate 	bool verbose = false;
877c478bd9Sstevel@tonic-gate 	bool foldcase = true;
887c478bd9Sstevel@tonic-gate 	bool unmake = false;
897c478bd9Sstevel@tonic-gate 	char sep = '\0';
907c478bd9Sstevel@tonic-gate 	char comment = '#';
917c478bd9Sstevel@tonic-gate 	int exitstat;
927c478bd9Sstevel@tonic-gate 	int opt;
937c478bd9Sstevel@tonic-gate 	char *typename = NULL;
947c478bd9Sstevel@tonic-gate 	char *mapname = NULL;
957c478bd9Sstevel@tonic-gate 	unsigned int lineno;
967c478bd9Sstevel@tonic-gate 	int st;
977c478bd9Sstevel@tonic-gate 	int mode;
987c478bd9Sstevel@tonic-gate 	int smode;
997c478bd9Sstevel@tonic-gate 	int putflags = 0;
1007c478bd9Sstevel@tonic-gate 	long sff = SFF_ROOTOK|SFF_REGONLY;
1017c478bd9Sstevel@tonic-gate 	struct passwd *pw;
1027c478bd9Sstevel@tonic-gate 	SMDB_DATABASE *database;
1037c478bd9Sstevel@tonic-gate 	SMDB_CURSOR *cursor;
1047c478bd9Sstevel@tonic-gate 	SMDB_DBENT db_key, db_val;
1057c478bd9Sstevel@tonic-gate 	SMDB_DBPARAMS params;
1067c478bd9Sstevel@tonic-gate 	SMDB_USER_INFO user_info;
1077c478bd9Sstevel@tonic-gate 	char ibuf[BUFSIZE];
1087c478bd9Sstevel@tonic-gate #if HASFCHOWN
1097c478bd9Sstevel@tonic-gate 	SM_FILE_T *cfp;
1107c478bd9Sstevel@tonic-gate 	char buf[MAXLINE];
1117c478bd9Sstevel@tonic-gate #endif /* HASFCHOWN */
1127c478bd9Sstevel@tonic-gate 	static char rnamebuf[MAXNAME];	/* holds RealUserName */
1137c478bd9Sstevel@tonic-gate 	extern char *optarg;
1147c478bd9Sstevel@tonic-gate 	extern int optind;
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 	memset(&params, '\0', sizeof params);
1177c478bd9Sstevel@tonic-gate 	params.smdbp_cache_size = 1024 * 1024;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	progname = strrchr(argv[0], '/');
1207c478bd9Sstevel@tonic-gate 	if (progname != NULL)
1217c478bd9Sstevel@tonic-gate 		progname++;
1227c478bd9Sstevel@tonic-gate 	else
1237c478bd9Sstevel@tonic-gate 		progname = argv[0];
1247c478bd9Sstevel@tonic-gate 	cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	clrbitmap(DontBlameSendmail);
1277c478bd9Sstevel@tonic-gate 	RunAsUid = RealUid = getuid();
1287c478bd9Sstevel@tonic-gate 	RunAsGid = RealGid = getgid();
1297c478bd9Sstevel@tonic-gate 	pw = getpwuid(RealUid);
1307c478bd9Sstevel@tonic-gate 	if (pw != NULL)
1317c478bd9Sstevel@tonic-gate 		(void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf);
1327c478bd9Sstevel@tonic-gate 	else
1337c478bd9Sstevel@tonic-gate 		(void) sm_snprintf(rnamebuf, sizeof rnamebuf,
1347c478bd9Sstevel@tonic-gate 		    "Unknown UID %d", (int) RealUid);
1357c478bd9Sstevel@tonic-gate 	RunAsUserName = RealUserName = rnamebuf;
1367c478bd9Sstevel@tonic-gate 	user_info.smdbu_id = RunAsUid;
1377c478bd9Sstevel@tonic-gate 	user_info.smdbu_group_id = RunAsGid;
1387c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
1397c478bd9Sstevel@tonic-gate 		       SMDB_MAX_USER_NAME_LEN);
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate #define OPTIONS		"C:D:Nc:deflorst:uv"
1427c478bd9Sstevel@tonic-gate 	while ((opt = getopt(argc, argv, OPTIONS)) != -1)
1437c478bd9Sstevel@tonic-gate 	{
1447c478bd9Sstevel@tonic-gate 		switch (opt)
1457c478bd9Sstevel@tonic-gate 		{
1467c478bd9Sstevel@tonic-gate 		  case 'C':
1477c478bd9Sstevel@tonic-gate 			cfile = optarg;
1487c478bd9Sstevel@tonic-gate 			break;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 		  case 'N':
1517c478bd9Sstevel@tonic-gate 			inclnull = true;
1527c478bd9Sstevel@tonic-gate 			break;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 		  case 'c':
1557c478bd9Sstevel@tonic-gate 			params.smdbp_cache_size = atol(optarg);
1567c478bd9Sstevel@tonic-gate 			break;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 		  case 'd':
1597c478bd9Sstevel@tonic-gate 			params.smdbp_allow_dup = true;
1607c478bd9Sstevel@tonic-gate 			break;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 		  case 'e':
1637c478bd9Sstevel@tonic-gate 			allowempty = true;
1647c478bd9Sstevel@tonic-gate 			break;
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 		  case 'f':
1677c478bd9Sstevel@tonic-gate 			foldcase = false;
1687c478bd9Sstevel@tonic-gate 			break;
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 		  case 'D':
1717c478bd9Sstevel@tonic-gate 			comment = *optarg;
1727c478bd9Sstevel@tonic-gate 			break;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 		  case 'l':
1757c478bd9Sstevel@tonic-gate 			smdb_print_available_types();
1767c478bd9Sstevel@tonic-gate 			exit(EX_OK);
1777c478bd9Sstevel@tonic-gate 			break;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 		  case 'o':
1807c478bd9Sstevel@tonic-gate 			notrunc = true;
1817c478bd9Sstevel@tonic-gate 			break;
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 		  case 'r':
1847c478bd9Sstevel@tonic-gate 			allowreplace = true;
1857c478bd9Sstevel@tonic-gate 			break;
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 		  case 's':
1887c478bd9Sstevel@tonic-gate 			setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail);
1897c478bd9Sstevel@tonic-gate 			setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail);
1907c478bd9Sstevel@tonic-gate 			setbitn(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail);
1917c478bd9Sstevel@tonic-gate 			setbitn(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail);
1927c478bd9Sstevel@tonic-gate 			break;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 		  case 't':
1957c478bd9Sstevel@tonic-gate 			if (optarg == NULL || *optarg == '\0')
1967c478bd9Sstevel@tonic-gate 			{
1977c478bd9Sstevel@tonic-gate 				sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
1987c478bd9Sstevel@tonic-gate 					      "Invalid separator\n");
1997c478bd9Sstevel@tonic-gate 				break;
2007c478bd9Sstevel@tonic-gate 			}
2017c478bd9Sstevel@tonic-gate 			sep = *optarg;
2027c478bd9Sstevel@tonic-gate 			break;
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 		  case 'u':
2057c478bd9Sstevel@tonic-gate 			unmake = true;
2067c478bd9Sstevel@tonic-gate 			break;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 		  case 'v':
2097c478bd9Sstevel@tonic-gate 			verbose = true;
2107c478bd9Sstevel@tonic-gate 			break;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 		  default:
2137c478bd9Sstevel@tonic-gate 			usage(progname);
2147c478bd9Sstevel@tonic-gate 			/* NOTREACHED */
2157c478bd9Sstevel@tonic-gate 		}
2167c478bd9Sstevel@tonic-gate 	}
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
2197c478bd9Sstevel@tonic-gate 		sff |= SFF_NOSLINK;
2207c478bd9Sstevel@tonic-gate 	if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
2217c478bd9Sstevel@tonic-gate 		sff |= SFF_NOHLINK;
2227c478bd9Sstevel@tonic-gate 	if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
2237c478bd9Sstevel@tonic-gate 		sff |= SFF_NOWLINK;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	argc -= optind;
2267c478bd9Sstevel@tonic-gate 	argv += optind;
2277c478bd9Sstevel@tonic-gate 	if (argc != 2)
2287c478bd9Sstevel@tonic-gate 	{
2297c478bd9Sstevel@tonic-gate 		usage(progname);
2307c478bd9Sstevel@tonic-gate 		/* NOTREACHED */
2317c478bd9Sstevel@tonic-gate 	}
2327c478bd9Sstevel@tonic-gate 	else
2337c478bd9Sstevel@tonic-gate 	{
2347c478bd9Sstevel@tonic-gate 		typename = argv[0];
2357c478bd9Sstevel@tonic-gate 		mapname = argv[1];
2367c478bd9Sstevel@tonic-gate 	}
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate #if HASFCHOWN
2397c478bd9Sstevel@tonic-gate 	/* Find TrustedUser value in sendmail.cf */
2407c478bd9Sstevel@tonic-gate 	if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
2417c478bd9Sstevel@tonic-gate 			      NULL)) == NULL)
2427c478bd9Sstevel@tonic-gate 	{
2437c478bd9Sstevel@tonic-gate 		sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "makemap: %s: %s",
2447c478bd9Sstevel@tonic-gate 			      cfile, sm_errstring(errno));
2457c478bd9Sstevel@tonic-gate 		exit(EX_NOINPUT);
2467c478bd9Sstevel@tonic-gate 	}
2477c478bd9Sstevel@tonic-gate 	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
2487c478bd9Sstevel@tonic-gate 	{
2497c478bd9Sstevel@tonic-gate 		register char *b;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 		if ((b = strchr(buf, '\n')) != NULL)
2527c478bd9Sstevel@tonic-gate 			*b = '\0';
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 		b = buf;
2557c478bd9Sstevel@tonic-gate 		switch (*b++)
2567c478bd9Sstevel@tonic-gate 		{
2577c478bd9Sstevel@tonic-gate 		  case 'O':		/* option */
2587c478bd9Sstevel@tonic-gate 			if (strncasecmp(b, " TrustedUser", 12) == 0 &&
2597c478bd9Sstevel@tonic-gate 			    !(isascii(b[12]) && isalnum(b[12])))
2607c478bd9Sstevel@tonic-gate 			{
2617c478bd9Sstevel@tonic-gate 				b = strchr(b, '=');
2627c478bd9Sstevel@tonic-gate 				if (b == NULL)
2637c478bd9Sstevel@tonic-gate 					continue;
2647c478bd9Sstevel@tonic-gate 				while (isascii(*++b) && isspace(*b))
2657c478bd9Sstevel@tonic-gate 					continue;
2667c478bd9Sstevel@tonic-gate 				if (isascii(*b) && isdigit(*b))
2677c478bd9Sstevel@tonic-gate 					TrustedUid = atoi(b);
2687c478bd9Sstevel@tonic-gate 				else
2697c478bd9Sstevel@tonic-gate 				{
2707c478bd9Sstevel@tonic-gate 					TrustedUid = 0;
2717c478bd9Sstevel@tonic-gate 					pw = getpwnam(b);
2727c478bd9Sstevel@tonic-gate 					if (pw == NULL)
2737c478bd9Sstevel@tonic-gate 						(void) sm_io_fprintf(smioerr,
2747c478bd9Sstevel@tonic-gate 								     SM_TIME_DEFAULT,
2757c478bd9Sstevel@tonic-gate 								     "TrustedUser: unknown user %s\n", b);
2767c478bd9Sstevel@tonic-gate 					else
2777c478bd9Sstevel@tonic-gate 						TrustedUid = pw->pw_uid;
2787c478bd9Sstevel@tonic-gate 				}
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate # ifdef UID_MAX
2817c478bd9Sstevel@tonic-gate 				if (TrustedUid > UID_MAX)
2827c478bd9Sstevel@tonic-gate 				{
2837c478bd9Sstevel@tonic-gate 					(void) sm_io_fprintf(smioerr,
2847c478bd9Sstevel@tonic-gate 							     SM_TIME_DEFAULT,
2857c478bd9Sstevel@tonic-gate 							     "TrustedUser: uid value (%ld) > UID_MAX (%ld)",
2867c478bd9Sstevel@tonic-gate 						(long) TrustedUid,
2877c478bd9Sstevel@tonic-gate 						(long) UID_MAX);
2887c478bd9Sstevel@tonic-gate 					TrustedUid = 0;
2897c478bd9Sstevel@tonic-gate 				}
2907c478bd9Sstevel@tonic-gate # endif /* UID_MAX */
2917c478bd9Sstevel@tonic-gate 				break;
2927c478bd9Sstevel@tonic-gate 			}
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 		  default:
2967c478bd9Sstevel@tonic-gate 			continue;
2977c478bd9Sstevel@tonic-gate 		}
2987c478bd9Sstevel@tonic-gate 	}
2997c478bd9Sstevel@tonic-gate 	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
3007c478bd9Sstevel@tonic-gate #endif /* HASFCHOWN */
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	if (!params.smdbp_allow_dup && !allowreplace)
3037c478bd9Sstevel@tonic-gate 		putflags = SMDBF_NO_OVERWRITE;
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	if (unmake)
3067c478bd9Sstevel@tonic-gate 	{
3077c478bd9Sstevel@tonic-gate 		mode = O_RDONLY;
3087c478bd9Sstevel@tonic-gate 		smode = S_IRUSR;
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate 	else
3117c478bd9Sstevel@tonic-gate 	{
3127c478bd9Sstevel@tonic-gate 		mode = O_RDWR;
3137c478bd9Sstevel@tonic-gate 		if (!notrunc)
3147c478bd9Sstevel@tonic-gate 		{
3157c478bd9Sstevel@tonic-gate 			mode |= O_CREAT|O_TRUNC;
3167c478bd9Sstevel@tonic-gate 			sff |= SFF_CREAT;
3177c478bd9Sstevel@tonic-gate 		}
3187c478bd9Sstevel@tonic-gate 		smode = S_IWUSR;
3197c478bd9Sstevel@tonic-gate 	}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	params.smdbp_num_elements = 4096;
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	errno = smdb_open_database(&database, mapname, mode, smode, sff,
3247c478bd9Sstevel@tonic-gate 				   typename, &user_info, &params);
3257c478bd9Sstevel@tonic-gate 	if (errno != SMDBE_OK)
3267c478bd9Sstevel@tonic-gate 	{
3277c478bd9Sstevel@tonic-gate 		char *hint;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 		if (errno == SMDBE_UNSUPPORTED_DB_TYPE &&
3307c478bd9Sstevel@tonic-gate 		    (hint = smdb_db_definition(typename)) != NULL)
3317c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
3327c478bd9Sstevel@tonic-gate 					     "%s: Need to recompile with -D%s for %s support\n",
3337c478bd9Sstevel@tonic-gate 					     progname, hint, typename);
3347c478bd9Sstevel@tonic-gate 		else
3357c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
3367c478bd9Sstevel@tonic-gate 					     "%s: error opening type %s map %s: %s\n",
3377c478bd9Sstevel@tonic-gate 					     progname, typename, mapname,
3387c478bd9Sstevel@tonic-gate 					     sm_errstring(errno));
3397c478bd9Sstevel@tonic-gate 		exit(EX_CANTCREAT);
3407c478bd9Sstevel@tonic-gate 	}
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate 	(void) database->smdb_sync(database, 0);
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	if (!unmake && geteuid() == 0 && TrustedUid != 0)
3457c478bd9Sstevel@tonic-gate 	{
3467c478bd9Sstevel@tonic-gate 		errno = database->smdb_set_owner(database, TrustedUid, -1);
3477c478bd9Sstevel@tonic-gate 		if (errno != SMDBE_OK)
3487c478bd9Sstevel@tonic-gate 		{
3497c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
3507c478bd9Sstevel@tonic-gate 					     "WARNING: ownership change on %s failed %s",
3517c478bd9Sstevel@tonic-gate 					     mapname, sm_errstring(errno));
3527c478bd9Sstevel@tonic-gate 		}
3537c478bd9Sstevel@tonic-gate 	}
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	/*
3567c478bd9Sstevel@tonic-gate 	**  Copy the data
3577c478bd9Sstevel@tonic-gate 	*/
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	exitstat = EX_OK;
3607c478bd9Sstevel@tonic-gate 	if (unmake)
3617c478bd9Sstevel@tonic-gate 	{
3627c478bd9Sstevel@tonic-gate 		errno = database->smdb_cursor(database, &cursor, 0);
3637c478bd9Sstevel@tonic-gate 		if (errno != SMDBE_OK)
3647c478bd9Sstevel@tonic-gate 		{
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
3677c478bd9Sstevel@tonic-gate 					     "%s: cannot make cursor for type %s map %s\n",
3687c478bd9Sstevel@tonic-gate 					     progname, typename, mapname);
3697c478bd9Sstevel@tonic-gate 			exit(EX_SOFTWARE);
3707c478bd9Sstevel@tonic-gate 		}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 		memset(&db_key, '\0', sizeof db_key);
3737c478bd9Sstevel@tonic-gate 		memset(&db_val, '\0', sizeof db_val);
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 		for (lineno = 0; ; lineno++)
3767c478bd9Sstevel@tonic-gate 		{
3777c478bd9Sstevel@tonic-gate 			errno = cursor->smdbc_get(cursor, &db_key, &db_val,
3787c478bd9Sstevel@tonic-gate 						  SMDB_CURSOR_GET_NEXT);
3797c478bd9Sstevel@tonic-gate 			if (errno != SMDBE_OK)
3807c478bd9Sstevel@tonic-gate 				break;
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
383*d4660949Sjbeck 					     "%.*s%c%.*s\n",
3847c478bd9Sstevel@tonic-gate 					     (int) db_key.size,
3857c478bd9Sstevel@tonic-gate 					     (char *) db_key.data,
386*d4660949Sjbeck 					     (sep != '\0') ? sep : '\t',
3877c478bd9Sstevel@tonic-gate 					     (int) db_val.size,
3887c478bd9Sstevel@tonic-gate 					     (char *)db_val.data);
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 		}
3917c478bd9Sstevel@tonic-gate 		(void) cursor->smdbc_close(cursor);
3927c478bd9Sstevel@tonic-gate 	}
3937c478bd9Sstevel@tonic-gate 	else
3947c478bd9Sstevel@tonic-gate 	{
3957c478bd9Sstevel@tonic-gate 		lineno = 0;
3967c478bd9Sstevel@tonic-gate 		while (sm_io_fgets(smioin, SM_TIME_DEFAULT, ibuf, sizeof ibuf)
3977c478bd9Sstevel@tonic-gate 		       != NULL)
3987c478bd9Sstevel@tonic-gate 		{
3997c478bd9Sstevel@tonic-gate 			register char *p;
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 			lineno++;
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate 			/*
4047c478bd9Sstevel@tonic-gate 			**  Parse the line.
4057c478bd9Sstevel@tonic-gate 			*/
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 			p = strchr(ibuf, '\n');
4087c478bd9Sstevel@tonic-gate 			if (p != NULL)
4097c478bd9Sstevel@tonic-gate 				*p = '\0';
4107c478bd9Sstevel@tonic-gate 			else if (!sm_io_eof(smioin))
4117c478bd9Sstevel@tonic-gate 			{
4127c478bd9Sstevel@tonic-gate 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
4137c478bd9Sstevel@tonic-gate 						     "%s: %s: line %u: line too long (%ld bytes max)\n",
4147c478bd9Sstevel@tonic-gate 						     progname, mapname, lineno,
4157c478bd9Sstevel@tonic-gate 						     (long) sizeof ibuf);
4167c478bd9Sstevel@tonic-gate 				exitstat = EX_DATAERR;
4177c478bd9Sstevel@tonic-gate 				continue;
4187c478bd9Sstevel@tonic-gate 			}
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 			if (ibuf[0] == '\0' || ibuf[0] == comment)
4217c478bd9Sstevel@tonic-gate 				continue;
4227c478bd9Sstevel@tonic-gate 			if (sep == '\0' && isascii(ibuf[0]) && isspace(ibuf[0]))
4237c478bd9Sstevel@tonic-gate 			{
4247c478bd9Sstevel@tonic-gate 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
4257c478bd9Sstevel@tonic-gate 						     "%s: %s: line %u: syntax error (leading space)\n",
4267c478bd9Sstevel@tonic-gate 						     progname, mapname, lineno);
4277c478bd9Sstevel@tonic-gate 				exitstat = EX_DATAERR;
4287c478bd9Sstevel@tonic-gate 				continue;
4297c478bd9Sstevel@tonic-gate 			}
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate 			memset(&db_key, '\0', sizeof db_key);
4327c478bd9Sstevel@tonic-gate 			memset(&db_val, '\0', sizeof db_val);
4337c478bd9Sstevel@tonic-gate 			db_key.data = ibuf;
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 			for (p = ibuf; *p != '\0' && !(ISSEP(*p)); p++)
4367c478bd9Sstevel@tonic-gate 			{
4377c478bd9Sstevel@tonic-gate 				if (foldcase && isascii(*p) && isupper(*p))
4387c478bd9Sstevel@tonic-gate 					*p = tolower(*p);
4397c478bd9Sstevel@tonic-gate 			}
4407c478bd9Sstevel@tonic-gate 			db_key.size = p - ibuf;
4417c478bd9Sstevel@tonic-gate 			if (inclnull)
4427c478bd9Sstevel@tonic-gate 				db_key.size++;
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 			if (*p != '\0')
4457c478bd9Sstevel@tonic-gate 				*p++ = '\0';
4467c478bd9Sstevel@tonic-gate 			while (*p != '\0' && ISSEP(*p))
4477c478bd9Sstevel@tonic-gate 				p++;
4487c478bd9Sstevel@tonic-gate 			if (!allowempty && *p == '\0')
4497c478bd9Sstevel@tonic-gate 			{
4507c478bd9Sstevel@tonic-gate 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
4517c478bd9Sstevel@tonic-gate 						     "%s: %s: line %u: no RHS for LHS %s\n",
4527c478bd9Sstevel@tonic-gate 						     progname, mapname, lineno,
4537c478bd9Sstevel@tonic-gate 						     (char *) db_key.data);
4547c478bd9Sstevel@tonic-gate 				exitstat = EX_DATAERR;
4557c478bd9Sstevel@tonic-gate 				continue;
4567c478bd9Sstevel@tonic-gate 			}
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 			db_val.data = p;
4597c478bd9Sstevel@tonic-gate 			db_val.size = strlen(p);
4607c478bd9Sstevel@tonic-gate 			if (inclnull)
4617c478bd9Sstevel@tonic-gate 				db_val.size++;
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 			/*
4647c478bd9Sstevel@tonic-gate 			**  Do the database insert.
4657c478bd9Sstevel@tonic-gate 			*/
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 			if (verbose)
4687c478bd9Sstevel@tonic-gate 			{
4697c478bd9Sstevel@tonic-gate 				(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
4707c478bd9Sstevel@tonic-gate 						     "key=`%s', val=`%s'\n",
4717c478bd9Sstevel@tonic-gate 						     (char *) db_key.data,
4727c478bd9Sstevel@tonic-gate 						     (char *) db_val.data);
4737c478bd9Sstevel@tonic-gate 			}
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate 			errno = database->smdb_put(database, &db_key, &db_val,
4767c478bd9Sstevel@tonic-gate 						   putflags);
4777c478bd9Sstevel@tonic-gate 			switch (errno)
4787c478bd9Sstevel@tonic-gate 			{
4797c478bd9Sstevel@tonic-gate 			  case SMDBE_KEY_EXIST:
4807c478bd9Sstevel@tonic-gate 				st = 1;
4817c478bd9Sstevel@tonic-gate 				break;
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 			  case 0:
4847c478bd9Sstevel@tonic-gate 				st = 0;
4857c478bd9Sstevel@tonic-gate 				break;
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 			  default:
4887c478bd9Sstevel@tonic-gate 				st = -1;
4897c478bd9Sstevel@tonic-gate 				break;
4907c478bd9Sstevel@tonic-gate 			}
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 			if (st < 0)
4937c478bd9Sstevel@tonic-gate 			{
4947c478bd9Sstevel@tonic-gate 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
4957c478bd9Sstevel@tonic-gate 						     "%s: %s: line %u: key %s: put error: %s\n",
4967c478bd9Sstevel@tonic-gate 						     progname, mapname, lineno,
4977c478bd9Sstevel@tonic-gate 						     (char *) db_key.data,
4987c478bd9Sstevel@tonic-gate 						     sm_errstring(errno));
4997c478bd9Sstevel@tonic-gate 				exitstat = EX_IOERR;
5007c478bd9Sstevel@tonic-gate 			}
5017c478bd9Sstevel@tonic-gate 			else if (st > 0)
5027c478bd9Sstevel@tonic-gate 			{
5037c478bd9Sstevel@tonic-gate 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
5047c478bd9Sstevel@tonic-gate 						     "%s: %s: line %u: key %s: duplicate key\n",
5057c478bd9Sstevel@tonic-gate 						     progname, mapname,
5067c478bd9Sstevel@tonic-gate 						     lineno,
5077c478bd9Sstevel@tonic-gate 						     (char *) db_key.data);
5087c478bd9Sstevel@tonic-gate 				exitstat = EX_DATAERR;
5097c478bd9Sstevel@tonic-gate 			}
5107c478bd9Sstevel@tonic-gate 		}
5117c478bd9Sstevel@tonic-gate 	}
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	/*
5147c478bd9Sstevel@tonic-gate 	**  Now close the database.
5157c478bd9Sstevel@tonic-gate 	*/
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	errno = database->smdb_close(database);
5187c478bd9Sstevel@tonic-gate 	if (errno != SMDBE_OK)
5197c478bd9Sstevel@tonic-gate 	{
5207c478bd9Sstevel@tonic-gate 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
5217c478bd9Sstevel@tonic-gate 				     "%s: close(%s): %s\n",
5227c478bd9Sstevel@tonic-gate 				     progname, mapname, sm_errstring(errno));
5237c478bd9Sstevel@tonic-gate 		exitstat = EX_IOERR;
5247c478bd9Sstevel@tonic-gate 	}
5257c478bd9Sstevel@tonic-gate 	smdb_free_database(database);
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	exit(exitstat);
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
5307c478bd9Sstevel@tonic-gate 	return exitstat;
5317c478bd9Sstevel@tonic-gate }
532