10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Copyright (c) 1998-2002, 2004 Sendmail, Inc. and its suppliers. 30Sstevel@tonic-gate * All rights reserved. 40Sstevel@tonic-gate * Copyright (c) 1992 Eric P. Allman. All rights reserved. 50Sstevel@tonic-gate * Copyright (c) 1992, 1993 60Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * By using this file, you agree to the terms and conditions set 90Sstevel@tonic-gate * forth in the LICENSE file which can be found at the top level of 100Sstevel@tonic-gate * the sendmail distribution. 110Sstevel@tonic-gate * 120Sstevel@tonic-gate */ 130Sstevel@tonic-gate 140Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 150Sstevel@tonic-gate 160Sstevel@tonic-gate #include <sm/gen.h> 170Sstevel@tonic-gate 180Sstevel@tonic-gate SM_IDSTR(copyright, 190Sstevel@tonic-gate "@(#) Copyright (c) 1998-2002, 2004 Sendmail, Inc. and its suppliers.\n\ 200Sstevel@tonic-gate All rights reserved.\n\ 210Sstevel@tonic-gate Copyright (c) 1992 Eric P. Allman. All rights reserved.\n\ 220Sstevel@tonic-gate Copyright (c) 1992, 1993\n\ 230Sstevel@tonic-gate The Regents of the University of California. All rights reserved.\n") 240Sstevel@tonic-gate 25*5402Sjbeck SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.178 2007/05/11 18:45:39 ca Exp $") 260Sstevel@tonic-gate 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <sys/types.h> 290Sstevel@tonic-gate #ifndef ISC_UNIX 300Sstevel@tonic-gate # include <sys/file.h> 310Sstevel@tonic-gate #endif /* ! ISC_UNIX */ 320Sstevel@tonic-gate #include <ctype.h> 330Sstevel@tonic-gate #include <stdlib.h> 340Sstevel@tonic-gate #include <unistd.h> 350Sstevel@tonic-gate #ifdef EX_OK 360Sstevel@tonic-gate # undef EX_OK /* unistd.h may have another use for this */ 370Sstevel@tonic-gate #endif /* EX_OK */ 380Sstevel@tonic-gate #include <sysexits.h> 390Sstevel@tonic-gate #include <sendmail/sendmail.h> 400Sstevel@tonic-gate #include <sendmail/pathnames.h> 410Sstevel@tonic-gate #include <libsmdb/smdb.h> 420Sstevel@tonic-gate 430Sstevel@tonic-gate uid_t RealUid; 440Sstevel@tonic-gate gid_t RealGid; 450Sstevel@tonic-gate char *RealUserName; 460Sstevel@tonic-gate uid_t RunAsUid; 47*5402Sjbeck gid_t RunAsGid; 480Sstevel@tonic-gate char *RunAsUserName; 490Sstevel@tonic-gate int Verbose = 2; 500Sstevel@tonic-gate bool DontInitGroups = false; 510Sstevel@tonic-gate uid_t TrustedUid = 0; 520Sstevel@tonic-gate BITMAP256 DontBlameSendmail; 530Sstevel@tonic-gate 540Sstevel@tonic-gate #define BUFSIZE 1024 550Sstevel@tonic-gate #define ISSEP(c) (sep == '\0' ? isascii(c) && isspace(c) : (c) == sep) 560Sstevel@tonic-gate 570Sstevel@tonic-gate static void usage __P((char *)); 580Sstevel@tonic-gate 590Sstevel@tonic-gate static void 600Sstevel@tonic-gate usage(progname) 610Sstevel@tonic-gate char *progname; 620Sstevel@tonic-gate { 630Sstevel@tonic-gate sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 640Sstevel@tonic-gate "Usage: %s [-C cffile] [-N] [-c cachesize] [-D commentchar]\n", 650Sstevel@tonic-gate progname); 660Sstevel@tonic-gate sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 670Sstevel@tonic-gate " %*s [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter]\n", 680Sstevel@tonic-gate (int) strlen(progname), ""); 690Sstevel@tonic-gate sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 700Sstevel@tonic-gate " %*s [-u] [-v] type mapname\n", 710Sstevel@tonic-gate (int) strlen(progname), ""); 720Sstevel@tonic-gate exit(EX_USAGE); 730Sstevel@tonic-gate } 740Sstevel@tonic-gate 750Sstevel@tonic-gate int 760Sstevel@tonic-gate main(argc, argv) 770Sstevel@tonic-gate int argc; 780Sstevel@tonic-gate char **argv; 790Sstevel@tonic-gate { 800Sstevel@tonic-gate char *progname; 810Sstevel@tonic-gate char *cfile; 820Sstevel@tonic-gate bool inclnull = false; 830Sstevel@tonic-gate bool notrunc = false; 840Sstevel@tonic-gate bool allowreplace = false; 850Sstevel@tonic-gate bool allowempty = false; 860Sstevel@tonic-gate bool verbose = false; 870Sstevel@tonic-gate bool foldcase = true; 880Sstevel@tonic-gate bool unmake = false; 890Sstevel@tonic-gate char sep = '\0'; 900Sstevel@tonic-gate char comment = '#'; 910Sstevel@tonic-gate int exitstat; 920Sstevel@tonic-gate int opt; 930Sstevel@tonic-gate char *typename = NULL; 940Sstevel@tonic-gate char *mapname = NULL; 950Sstevel@tonic-gate unsigned int lineno; 960Sstevel@tonic-gate int st; 970Sstevel@tonic-gate int mode; 980Sstevel@tonic-gate int smode; 990Sstevel@tonic-gate int putflags = 0; 1000Sstevel@tonic-gate long sff = SFF_ROOTOK|SFF_REGONLY; 1010Sstevel@tonic-gate struct passwd *pw; 1020Sstevel@tonic-gate SMDB_DATABASE *database; 1030Sstevel@tonic-gate SMDB_CURSOR *cursor; 1040Sstevel@tonic-gate SMDB_DBENT db_key, db_val; 1050Sstevel@tonic-gate SMDB_DBPARAMS params; 1060Sstevel@tonic-gate SMDB_USER_INFO user_info; 1070Sstevel@tonic-gate char ibuf[BUFSIZE]; 1080Sstevel@tonic-gate #if HASFCHOWN 1090Sstevel@tonic-gate SM_FILE_T *cfp; 1100Sstevel@tonic-gate char buf[MAXLINE]; 1110Sstevel@tonic-gate #endif /* HASFCHOWN */ 1120Sstevel@tonic-gate static char rnamebuf[MAXNAME]; /* holds RealUserName */ 1130Sstevel@tonic-gate extern char *optarg; 1140Sstevel@tonic-gate extern int optind; 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate memset(¶ms, '\0', sizeof params); 1170Sstevel@tonic-gate params.smdbp_cache_size = 1024 * 1024; 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate progname = strrchr(argv[0], '/'); 1200Sstevel@tonic-gate if (progname != NULL) 1210Sstevel@tonic-gate progname++; 1220Sstevel@tonic-gate else 1230Sstevel@tonic-gate progname = argv[0]; 1240Sstevel@tonic-gate cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate clrbitmap(DontBlameSendmail); 1270Sstevel@tonic-gate RunAsUid = RealUid = getuid(); 1280Sstevel@tonic-gate RunAsGid = RealGid = getgid(); 1290Sstevel@tonic-gate pw = getpwuid(RealUid); 1300Sstevel@tonic-gate if (pw != NULL) 1310Sstevel@tonic-gate (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf); 1320Sstevel@tonic-gate else 1330Sstevel@tonic-gate (void) sm_snprintf(rnamebuf, sizeof rnamebuf, 1340Sstevel@tonic-gate "Unknown UID %d", (int) RealUid); 1350Sstevel@tonic-gate RunAsUserName = RealUserName = rnamebuf; 1360Sstevel@tonic-gate user_info.smdbu_id = RunAsUid; 1370Sstevel@tonic-gate user_info.smdbu_group_id = RunAsGid; 1380Sstevel@tonic-gate (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, 1390Sstevel@tonic-gate SMDB_MAX_USER_NAME_LEN); 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate #define OPTIONS "C:D:Nc:deflorst:uv" 1420Sstevel@tonic-gate while ((opt = getopt(argc, argv, OPTIONS)) != -1) 1430Sstevel@tonic-gate { 1440Sstevel@tonic-gate switch (opt) 1450Sstevel@tonic-gate { 1460Sstevel@tonic-gate case 'C': 1470Sstevel@tonic-gate cfile = optarg; 1480Sstevel@tonic-gate break; 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate case 'N': 1510Sstevel@tonic-gate inclnull = true; 1520Sstevel@tonic-gate break; 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate case 'c': 1550Sstevel@tonic-gate params.smdbp_cache_size = atol(optarg); 1560Sstevel@tonic-gate break; 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate case 'd': 1590Sstevel@tonic-gate params.smdbp_allow_dup = true; 1600Sstevel@tonic-gate break; 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate case 'e': 1630Sstevel@tonic-gate allowempty = true; 1640Sstevel@tonic-gate break; 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate case 'f': 1670Sstevel@tonic-gate foldcase = false; 1680Sstevel@tonic-gate break; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate case 'D': 1710Sstevel@tonic-gate comment = *optarg; 1720Sstevel@tonic-gate break; 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate case 'l': 1750Sstevel@tonic-gate smdb_print_available_types(); 1760Sstevel@tonic-gate exit(EX_OK); 1770Sstevel@tonic-gate break; 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate case 'o': 1800Sstevel@tonic-gate notrunc = true; 1810Sstevel@tonic-gate break; 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate case 'r': 1840Sstevel@tonic-gate allowreplace = true; 1850Sstevel@tonic-gate break; 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate case 's': 1880Sstevel@tonic-gate setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail); 1890Sstevel@tonic-gate setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail); 1900Sstevel@tonic-gate setbitn(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail); 1910Sstevel@tonic-gate setbitn(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail); 1920Sstevel@tonic-gate break; 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate case 't': 1950Sstevel@tonic-gate if (optarg == NULL || *optarg == '\0') 1960Sstevel@tonic-gate { 1970Sstevel@tonic-gate sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 1980Sstevel@tonic-gate "Invalid separator\n"); 1990Sstevel@tonic-gate break; 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate sep = *optarg; 2020Sstevel@tonic-gate break; 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate case 'u': 2050Sstevel@tonic-gate unmake = true; 2060Sstevel@tonic-gate break; 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate case 'v': 2090Sstevel@tonic-gate verbose = true; 2100Sstevel@tonic-gate break; 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate default: 2130Sstevel@tonic-gate usage(progname); 2140Sstevel@tonic-gate /* NOTREACHED */ 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail)) 2190Sstevel@tonic-gate sff |= SFF_NOSLINK; 2200Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail)) 2210Sstevel@tonic-gate sff |= SFF_NOHLINK; 2220Sstevel@tonic-gate if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) 2230Sstevel@tonic-gate sff |= SFF_NOWLINK; 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate argc -= optind; 2260Sstevel@tonic-gate argv += optind; 2270Sstevel@tonic-gate if (argc != 2) 2280Sstevel@tonic-gate { 2290Sstevel@tonic-gate usage(progname); 2300Sstevel@tonic-gate /* NOTREACHED */ 2310Sstevel@tonic-gate } 2320Sstevel@tonic-gate else 2330Sstevel@tonic-gate { 2340Sstevel@tonic-gate typename = argv[0]; 2350Sstevel@tonic-gate mapname = argv[1]; 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate #if HASFCHOWN 2390Sstevel@tonic-gate /* Find TrustedUser value in sendmail.cf */ 2400Sstevel@tonic-gate if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, 2410Sstevel@tonic-gate NULL)) == NULL) 2420Sstevel@tonic-gate { 2430Sstevel@tonic-gate sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "makemap: %s: %s", 2440Sstevel@tonic-gate cfile, sm_errstring(errno)); 2450Sstevel@tonic-gate exit(EX_NOINPUT); 2460Sstevel@tonic-gate } 2470Sstevel@tonic-gate while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL) 2480Sstevel@tonic-gate { 2490Sstevel@tonic-gate register char *b; 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate if ((b = strchr(buf, '\n')) != NULL) 2520Sstevel@tonic-gate *b = '\0'; 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate b = buf; 2550Sstevel@tonic-gate switch (*b++) 2560Sstevel@tonic-gate { 2570Sstevel@tonic-gate case 'O': /* option */ 2580Sstevel@tonic-gate if (strncasecmp(b, " TrustedUser", 12) == 0 && 2590Sstevel@tonic-gate !(isascii(b[12]) && isalnum(b[12]))) 2600Sstevel@tonic-gate { 2610Sstevel@tonic-gate b = strchr(b, '='); 2620Sstevel@tonic-gate if (b == NULL) 2630Sstevel@tonic-gate continue; 2640Sstevel@tonic-gate while (isascii(*++b) && isspace(*b)) 2650Sstevel@tonic-gate continue; 2660Sstevel@tonic-gate if (isascii(*b) && isdigit(*b)) 2670Sstevel@tonic-gate TrustedUid = atoi(b); 2680Sstevel@tonic-gate else 2690Sstevel@tonic-gate { 2700Sstevel@tonic-gate TrustedUid = 0; 2710Sstevel@tonic-gate pw = getpwnam(b); 2720Sstevel@tonic-gate if (pw == NULL) 2730Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, 2740Sstevel@tonic-gate SM_TIME_DEFAULT, 2750Sstevel@tonic-gate "TrustedUser: unknown user %s\n", b); 2760Sstevel@tonic-gate else 2770Sstevel@tonic-gate TrustedUid = pw->pw_uid; 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate # ifdef UID_MAX 2810Sstevel@tonic-gate if (TrustedUid > UID_MAX) 2820Sstevel@tonic-gate { 2830Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, 2840Sstevel@tonic-gate SM_TIME_DEFAULT, 2850Sstevel@tonic-gate "TrustedUser: uid value (%ld) > UID_MAX (%ld)", 2860Sstevel@tonic-gate (long) TrustedUid, 2870Sstevel@tonic-gate (long) UID_MAX); 2880Sstevel@tonic-gate TrustedUid = 0; 2890Sstevel@tonic-gate } 2900Sstevel@tonic-gate # endif /* UID_MAX */ 2910Sstevel@tonic-gate break; 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate default: 2960Sstevel@tonic-gate continue; 2970Sstevel@tonic-gate } 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate (void) sm_io_close(cfp, SM_TIME_DEFAULT); 3000Sstevel@tonic-gate #endif /* HASFCHOWN */ 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate if (!params.smdbp_allow_dup && !allowreplace) 3030Sstevel@tonic-gate putflags = SMDBF_NO_OVERWRITE; 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate if (unmake) 3060Sstevel@tonic-gate { 3070Sstevel@tonic-gate mode = O_RDONLY; 3080Sstevel@tonic-gate smode = S_IRUSR; 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate else 3110Sstevel@tonic-gate { 3120Sstevel@tonic-gate mode = O_RDWR; 3130Sstevel@tonic-gate if (!notrunc) 3140Sstevel@tonic-gate { 3150Sstevel@tonic-gate mode |= O_CREAT|O_TRUNC; 3160Sstevel@tonic-gate sff |= SFF_CREAT; 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate smode = S_IWUSR; 3190Sstevel@tonic-gate } 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate params.smdbp_num_elements = 4096; 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate errno = smdb_open_database(&database, mapname, mode, smode, sff, 3240Sstevel@tonic-gate typename, &user_info, ¶ms); 3250Sstevel@tonic-gate if (errno != SMDBE_OK) 3260Sstevel@tonic-gate { 3270Sstevel@tonic-gate char *hint; 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate if (errno == SMDBE_UNSUPPORTED_DB_TYPE && 3300Sstevel@tonic-gate (hint = smdb_db_definition(typename)) != NULL) 3310Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 3320Sstevel@tonic-gate "%s: Need to recompile with -D%s for %s support\n", 3330Sstevel@tonic-gate progname, hint, typename); 3340Sstevel@tonic-gate else 3350Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 3360Sstevel@tonic-gate "%s: error opening type %s map %s: %s\n", 3370Sstevel@tonic-gate progname, typename, mapname, 3380Sstevel@tonic-gate sm_errstring(errno)); 3390Sstevel@tonic-gate exit(EX_CANTCREAT); 3400Sstevel@tonic-gate } 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate (void) database->smdb_sync(database, 0); 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate if (!unmake && geteuid() == 0 && TrustedUid != 0) 3450Sstevel@tonic-gate { 3460Sstevel@tonic-gate errno = database->smdb_set_owner(database, TrustedUid, -1); 3470Sstevel@tonic-gate if (errno != SMDBE_OK) 3480Sstevel@tonic-gate { 3490Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 3500Sstevel@tonic-gate "WARNING: ownership change on %s failed %s", 3510Sstevel@tonic-gate mapname, sm_errstring(errno)); 3520Sstevel@tonic-gate } 3530Sstevel@tonic-gate } 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate /* 3560Sstevel@tonic-gate ** Copy the data 3570Sstevel@tonic-gate */ 3580Sstevel@tonic-gate 3590Sstevel@tonic-gate exitstat = EX_OK; 3600Sstevel@tonic-gate if (unmake) 3610Sstevel@tonic-gate { 3620Sstevel@tonic-gate errno = database->smdb_cursor(database, &cursor, 0); 3630Sstevel@tonic-gate if (errno != SMDBE_OK) 3640Sstevel@tonic-gate { 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 3670Sstevel@tonic-gate "%s: cannot make cursor for type %s map %s\n", 3680Sstevel@tonic-gate progname, typename, mapname); 3690Sstevel@tonic-gate exit(EX_SOFTWARE); 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate memset(&db_key, '\0', sizeof db_key); 3730Sstevel@tonic-gate memset(&db_val, '\0', sizeof db_val); 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate for (lineno = 0; ; lineno++) 3760Sstevel@tonic-gate { 3770Sstevel@tonic-gate errno = cursor->smdbc_get(cursor, &db_key, &db_val, 3780Sstevel@tonic-gate SMDB_CURSOR_GET_NEXT); 3790Sstevel@tonic-gate if (errno != SMDBE_OK) 3800Sstevel@tonic-gate break; 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 3830Sstevel@tonic-gate "%.*s\t%.*s\n", 3840Sstevel@tonic-gate (int) db_key.size, 3850Sstevel@tonic-gate (char *) db_key.data, 3860Sstevel@tonic-gate (int) db_val.size, 3870Sstevel@tonic-gate (char *)db_val.data); 3880Sstevel@tonic-gate 3890Sstevel@tonic-gate } 3900Sstevel@tonic-gate (void) cursor->smdbc_close(cursor); 3910Sstevel@tonic-gate } 3920Sstevel@tonic-gate else 3930Sstevel@tonic-gate { 3940Sstevel@tonic-gate lineno = 0; 3950Sstevel@tonic-gate while (sm_io_fgets(smioin, SM_TIME_DEFAULT, ibuf, sizeof ibuf) 3960Sstevel@tonic-gate != NULL) 3970Sstevel@tonic-gate { 3980Sstevel@tonic-gate register char *p; 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate lineno++; 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate /* 4030Sstevel@tonic-gate ** Parse the line. 4040Sstevel@tonic-gate */ 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate p = strchr(ibuf, '\n'); 4070Sstevel@tonic-gate if (p != NULL) 4080Sstevel@tonic-gate *p = '\0'; 4090Sstevel@tonic-gate else if (!sm_io_eof(smioin)) 4100Sstevel@tonic-gate { 4110Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 4120Sstevel@tonic-gate "%s: %s: line %u: line too long (%ld bytes max)\n", 4130Sstevel@tonic-gate progname, mapname, lineno, 4140Sstevel@tonic-gate (long) sizeof ibuf); 4150Sstevel@tonic-gate exitstat = EX_DATAERR; 4160Sstevel@tonic-gate continue; 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate if (ibuf[0] == '\0' || ibuf[0] == comment) 4200Sstevel@tonic-gate continue; 4210Sstevel@tonic-gate if (sep == '\0' && isascii(ibuf[0]) && isspace(ibuf[0])) 4220Sstevel@tonic-gate { 4230Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 4240Sstevel@tonic-gate "%s: %s: line %u: syntax error (leading space)\n", 4250Sstevel@tonic-gate progname, mapname, lineno); 4260Sstevel@tonic-gate exitstat = EX_DATAERR; 4270Sstevel@tonic-gate continue; 4280Sstevel@tonic-gate } 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate memset(&db_key, '\0', sizeof db_key); 4310Sstevel@tonic-gate memset(&db_val, '\0', sizeof db_val); 4320Sstevel@tonic-gate db_key.data = ibuf; 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate for (p = ibuf; *p != '\0' && !(ISSEP(*p)); p++) 4350Sstevel@tonic-gate { 4360Sstevel@tonic-gate if (foldcase && isascii(*p) && isupper(*p)) 4370Sstevel@tonic-gate *p = tolower(*p); 4380Sstevel@tonic-gate } 4390Sstevel@tonic-gate db_key.size = p - ibuf; 4400Sstevel@tonic-gate if (inclnull) 4410Sstevel@tonic-gate db_key.size++; 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate if (*p != '\0') 4440Sstevel@tonic-gate *p++ = '\0'; 4450Sstevel@tonic-gate while (*p != '\0' && ISSEP(*p)) 4460Sstevel@tonic-gate p++; 4470Sstevel@tonic-gate if (!allowempty && *p == '\0') 4480Sstevel@tonic-gate { 4490Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 4500Sstevel@tonic-gate "%s: %s: line %u: no RHS for LHS %s\n", 4510Sstevel@tonic-gate progname, mapname, lineno, 4520Sstevel@tonic-gate (char *) db_key.data); 4530Sstevel@tonic-gate exitstat = EX_DATAERR; 4540Sstevel@tonic-gate continue; 4550Sstevel@tonic-gate } 4560Sstevel@tonic-gate 4570Sstevel@tonic-gate db_val.data = p; 4580Sstevel@tonic-gate db_val.size = strlen(p); 4590Sstevel@tonic-gate if (inclnull) 4600Sstevel@tonic-gate db_val.size++; 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate /* 4630Sstevel@tonic-gate ** Do the database insert. 4640Sstevel@tonic-gate */ 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate if (verbose) 4670Sstevel@tonic-gate { 4680Sstevel@tonic-gate (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 4690Sstevel@tonic-gate "key=`%s', val=`%s'\n", 4700Sstevel@tonic-gate (char *) db_key.data, 4710Sstevel@tonic-gate (char *) db_val.data); 4720Sstevel@tonic-gate } 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate errno = database->smdb_put(database, &db_key, &db_val, 4750Sstevel@tonic-gate putflags); 4760Sstevel@tonic-gate switch (errno) 4770Sstevel@tonic-gate { 4780Sstevel@tonic-gate case SMDBE_KEY_EXIST: 4790Sstevel@tonic-gate st = 1; 4800Sstevel@tonic-gate break; 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate case 0: 4830Sstevel@tonic-gate st = 0; 4840Sstevel@tonic-gate break; 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate default: 4870Sstevel@tonic-gate st = -1; 4880Sstevel@tonic-gate break; 4890Sstevel@tonic-gate } 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate if (st < 0) 4920Sstevel@tonic-gate { 4930Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 4940Sstevel@tonic-gate "%s: %s: line %u: key %s: put error: %s\n", 4950Sstevel@tonic-gate progname, mapname, lineno, 4960Sstevel@tonic-gate (char *) db_key.data, 4970Sstevel@tonic-gate sm_errstring(errno)); 4980Sstevel@tonic-gate exitstat = EX_IOERR; 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate else if (st > 0) 5010Sstevel@tonic-gate { 5020Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 5030Sstevel@tonic-gate "%s: %s: line %u: key %s: duplicate key\n", 5040Sstevel@tonic-gate progname, mapname, 5050Sstevel@tonic-gate lineno, 5060Sstevel@tonic-gate (char *) db_key.data); 5070Sstevel@tonic-gate exitstat = EX_DATAERR; 5080Sstevel@tonic-gate } 5090Sstevel@tonic-gate } 5100Sstevel@tonic-gate } 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate /* 5130Sstevel@tonic-gate ** Now close the database. 5140Sstevel@tonic-gate */ 5150Sstevel@tonic-gate 5160Sstevel@tonic-gate errno = database->smdb_close(database); 5170Sstevel@tonic-gate if (errno != SMDBE_OK) 5180Sstevel@tonic-gate { 5190Sstevel@tonic-gate (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 5200Sstevel@tonic-gate "%s: close(%s): %s\n", 5210Sstevel@tonic-gate progname, mapname, sm_errstring(errno)); 5220Sstevel@tonic-gate exitstat = EX_IOERR; 5230Sstevel@tonic-gate } 5240Sstevel@tonic-gate smdb_free_database(database); 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate exit(exitstat); 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate /* NOTREACHED */ 5290Sstevel@tonic-gate return exitstat; 5300Sstevel@tonic-gate } 531