138032Speter/* 2261363Sgshapiro * Copyright (c) 1998-2002, 2004, 2008 Proofpoint, Inc. and its suppliers. 364565Sgshapiro * All rights reserved. 438032Speter * Copyright (c) 1992 Eric P. Allman. All rights reserved. 538032Speter * Copyright (c) 1992, 1993 638032Speter * The Regents of the University of California. All rights reserved. 738032Speter * 838032Speter * By using this file, you agree to the terms and conditions set 938032Speter * forth in the LICENSE file which can be found at the top level of 1038032Speter * the sendmail distribution. 1138032Speter * 1238032Speter */ 1338032Speter 1490795Sgshapiro#include <sm/gen.h> 1590795Sgshapiro 1690795SgshapiroSM_IDSTR(copyright, 17261363Sgshapiro"@(#) Copyright (c) 1998-2002, 2004 Proofpoint, Inc. and its suppliers.\n\ 1864565Sgshapiro All rights reserved.\n\ 1964565Sgshapiro Copyright (c) 1992 Eric P. Allman. All rights reserved.\n\ 2064565Sgshapiro Copyright (c) 1992, 1993\n\ 2190795Sgshapiro The Regents of the University of California. All rights reserved.\n") 2238032Speter 23266692SgshapiroSM_IDSTR(id, "@(#)$Id: makemap.c,v 8.183 2013-11-22 20:51:52 ca Exp $") 2464565Sgshapiro 25111367Sgshapiro 2638032Speter#include <sys/types.h> 2738032Speter#ifndef ISC_UNIX 2838032Speter# include <sys/file.h> 2964565Sgshapiro#endif /* ! ISC_UNIX */ 3064565Sgshapiro#include <ctype.h> 3164565Sgshapiro#include <stdlib.h> 3264565Sgshapiro#include <unistd.h> 3364565Sgshapiro#ifdef EX_OK 3464565Sgshapiro# undef EX_OK /* unistd.h may have another use for this */ 3564565Sgshapiro#endif /* EX_OK */ 3664565Sgshapiro#include <sysexits.h> 3764565Sgshapiro#include <sendmail/sendmail.h> 3864565Sgshapiro#include <sendmail/pathnames.h> 3964565Sgshapiro#include <libsmdb/smdb.h> 4038032Speter 4138032Speteruid_t RealUid; 4238032Spetergid_t RealGid; 4338032Speterchar *RealUserName; 4438032Speteruid_t RunAsUid; 45173343Sgshapirogid_t RunAsGid; 4638032Speterchar *RunAsUserName; 4738032Speterint Verbose = 2; 4890795Sgshapirobool DontInitGroups = false; 4942580Speteruid_t TrustedUid = 0; 5064565SgshapiroBITMAP256 DontBlameSendmail; 5138032Speter 5238032Speter#define BUFSIZE 1024 5390795Sgshapiro#define ISSEP(c) (sep == '\0' ? isascii(c) && isspace(c) : (c) == sep) 5438032Speter 55141862Sgshapirostatic void usage __P((char *)); 56141862Sgshapiro 5764565Sgshapirostatic void 5864565Sgshapirousage(progname) 5964565Sgshapiro char *progname; 6064565Sgshapiro{ 6190795Sgshapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 62132946Sgshapiro "Usage: %s [-C cffile] [-N] [-c cachesize] [-D commentchar]\n", 63132946Sgshapiro progname); 64132946Sgshapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 65132946Sgshapiro " %*s [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter]\n", 66132946Sgshapiro (int) strlen(progname), ""); 67132946Sgshapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 68132946Sgshapiro " %*s [-u] [-v] type mapname\n", 69132946Sgshapiro (int) strlen(progname), ""); 7064565Sgshapiro exit(EX_USAGE); 7164565Sgshapiro} 7264565Sgshapiro 7338032Speterint 7438032Spetermain(argc, argv) 7538032Speter int argc; 7638032Speter char **argv; 7738032Speter{ 7838032Speter char *progname; 7938032Speter char *cfile; 8090795Sgshapiro bool inclnull = false; 8190795Sgshapiro bool notrunc = false; 8290795Sgshapiro bool allowreplace = false; 8390795Sgshapiro bool allowempty = false; 8490795Sgshapiro bool verbose = false; 8590795Sgshapiro bool foldcase = true; 8690795Sgshapiro bool unmake = false; 8764565Sgshapiro char sep = '\0'; 8890795Sgshapiro char comment = '#'; 8938032Speter int exitstat; 9038032Speter int opt; 9142580Speter char *typename = NULL; 9242580Speter char *mapname = NULL; 9390795Sgshapiro unsigned int lineno; 9438032Speter int st; 9538032Speter int mode; 9664565Sgshapiro int smode; 9742580Speter int putflags = 0; 9864565Sgshapiro long sff = SFF_ROOTOK|SFF_REGONLY; 9938032Speter struct passwd *pw; 10064565Sgshapiro SMDB_DATABASE *database; 10164565Sgshapiro SMDB_CURSOR *cursor; 10264565Sgshapiro SMDB_DBENT db_key, db_val; 10364565Sgshapiro SMDB_DBPARAMS params; 10464565Sgshapiro SMDB_USER_INFO user_info; 10538032Speter char ibuf[BUFSIZE]; 10664565Sgshapiro#if HASFCHOWN 10790795Sgshapiro SM_FILE_T *cfp; 10838032Speter char buf[MAXLINE]; 10964565Sgshapiro#endif /* HASFCHOWN */ 11038032Speter static char rnamebuf[MAXNAME]; /* holds RealUserName */ 11138032Speter extern char *optarg; 11238032Speter extern int optind; 11338032Speter 11464565Sgshapiro memset(¶ms, '\0', sizeof params); 11564565Sgshapiro params.smdbp_cache_size = 1024 * 1024; 11664565Sgshapiro 11764565Sgshapiro progname = strrchr(argv[0], '/'); 11864565Sgshapiro if (progname != NULL) 11964565Sgshapiro progname++; 12064565Sgshapiro else 12164565Sgshapiro progname = argv[0]; 12290795Sgshapiro cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); 12338032Speter 12464565Sgshapiro clrbitmap(DontBlameSendmail); 12538032Speter RunAsUid = RealUid = getuid(); 12638032Speter RunAsGid = RealGid = getgid(); 12738032Speter pw = getpwuid(RealUid); 12838032Speter if (pw != NULL) 12990795Sgshapiro (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf); 13038032Speter else 13190795Sgshapiro (void) sm_snprintf(rnamebuf, sizeof rnamebuf, 13290795Sgshapiro "Unknown UID %d", (int) RealUid); 13338032Speter RunAsUserName = RealUserName = rnamebuf; 13464565Sgshapiro user_info.smdbu_id = RunAsUid; 13564565Sgshapiro user_info.smdbu_group_id = RunAsGid; 13690795Sgshapiro (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, 13764565Sgshapiro SMDB_MAX_USER_NAME_LEN); 13838032Speter 13990795Sgshapiro#define OPTIONS "C:D:Nc:deflorst:uv" 14038076Speter while ((opt = getopt(argc, argv, OPTIONS)) != -1) 14138032Speter { 14238032Speter switch (opt) 14338032Speter { 14438032Speter case 'C': 14538032Speter cfile = optarg; 14638032Speter break; 14738032Speter 14838032Speter case 'N': 14990795Sgshapiro inclnull = true; 15038032Speter break; 15138032Speter 15238032Speter case 'c': 15364565Sgshapiro params.smdbp_cache_size = atol(optarg); 15438032Speter break; 15538032Speter 15638032Speter case 'd': 15790795Sgshapiro params.smdbp_allow_dup = true; 15838032Speter break; 15938032Speter 16064565Sgshapiro case 'e': 16190795Sgshapiro allowempty = true; 16264565Sgshapiro break; 16364565Sgshapiro 16438032Speter case 'f': 16590795Sgshapiro foldcase = false; 16638032Speter break; 16738032Speter 16890795Sgshapiro case 'D': 16990795Sgshapiro comment = *optarg; 17090795Sgshapiro break; 17190795Sgshapiro 17242580Speter case 'l': 17364565Sgshapiro smdb_print_available_types(); 17442580Speter exit(EX_OK); 17542580Speter break; 17642580Speter 17738032Speter case 'o': 17890795Sgshapiro notrunc = true; 17938032Speter break; 18038032Speter 18138032Speter case 'r': 18290795Sgshapiro allowreplace = true; 18338032Speter break; 18438032Speter 18538032Speter case 's': 18664565Sgshapiro setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail); 18764565Sgshapiro setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail); 18864565Sgshapiro setbitn(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail); 18964565Sgshapiro setbitn(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail); 19038032Speter break; 19138032Speter 19264565Sgshapiro case 't': 19364565Sgshapiro if (optarg == NULL || *optarg == '\0') 19464565Sgshapiro { 19590795Sgshapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 19690795Sgshapiro "Invalid separator\n"); 19764565Sgshapiro break; 19864565Sgshapiro } 19964565Sgshapiro sep = *optarg; 20064565Sgshapiro break; 20164565Sgshapiro 20264565Sgshapiro case 'u': 20390795Sgshapiro unmake = true; 20464565Sgshapiro break; 20564565Sgshapiro 20638032Speter case 'v': 20790795Sgshapiro verbose = true; 20838032Speter break; 20938032Speter 21038032Speter default: 21164565Sgshapiro usage(progname); 21264565Sgshapiro /* NOTREACHED */ 21338032Speter } 21438032Speter } 21538032Speter 21664565Sgshapiro if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail)) 21738032Speter sff |= SFF_NOSLINK; 21864565Sgshapiro if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail)) 21938032Speter sff |= SFF_NOHLINK; 22064565Sgshapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) 22138032Speter sff |= SFF_NOWLINK; 22238032Speter 22338032Speter argc -= optind; 22438032Speter argv += optind; 22538032Speter if (argc != 2) 22664565Sgshapiro { 22764565Sgshapiro usage(progname); 22864565Sgshapiro /* NOTREACHED */ 22964565Sgshapiro } 23038032Speter else 23138032Speter { 23238032Speter typename = argv[0]; 23338032Speter mapname = argv[1]; 23438032Speter } 23538032Speter 23664565Sgshapiro#if HASFCHOWN 237285303Sgshapiro /* Find TrustedUser value in sendmail.cf */ 238285303Sgshapiro if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, 239285303Sgshapiro NULL)) == NULL) 24038032Speter { 241285303Sgshapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "makemap: %s: %s\n", 242285303Sgshapiro cfile, sm_errstring(errno)); 243285303Sgshapiro exit(EX_NOINPUT); 244285303Sgshapiro } 245285303Sgshapiro while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0) 246285303Sgshapiro { 247285303Sgshapiro register char *b; 24838032Speter 249285303Sgshapiro if ((b = strchr(buf, '\n')) != NULL) 250285303Sgshapiro *b = '\0'; 25138032Speter 252285303Sgshapiro b = buf; 253285303Sgshapiro switch (*b++) 254285303Sgshapiro { 255285303Sgshapiro case 'O': /* option */ 256285303Sgshapiro if (strncasecmp(b, " TrustedUser", 12) == 0 && 257285303Sgshapiro !(isascii(b[12]) && isalnum(b[12]))) 25838032Speter { 259285303Sgshapiro b = strchr(b, '='); 260285303Sgshapiro if (b == NULL) 261285303Sgshapiro continue; 262285303Sgshapiro while (isascii(*++b) && isspace(*b)) 263285303Sgshapiro continue; 264285303Sgshapiro if (isascii(*b) && isdigit(*b)) 265285303Sgshapiro TrustedUid = atoi(b); 266285303Sgshapiro else 26738032Speter { 268285303Sgshapiro TrustedUid = 0; 269285303Sgshapiro pw = getpwnam(b); 270285303Sgshapiro if (pw == NULL) 271285303Sgshapiro (void) sm_io_fprintf(smioerr, 272285303Sgshapiro SM_TIME_DEFAULT, 273285303Sgshapiro "TrustedUser: unknown user %s\n", b); 27438032Speter else 275285303Sgshapiro TrustedUid = pw->pw_uid; 276285303Sgshapiro } 27764565Sgshapiro 27838032Speter# ifdef UID_MAX 279285303Sgshapiro if (TrustedUid > UID_MAX) 280285303Sgshapiro { 281285303Sgshapiro (void) sm_io_fprintf(smioerr, 282285303Sgshapiro SM_TIME_DEFAULT, 283285303Sgshapiro "TrustedUser: uid value (%ld) > UID_MAX (%ld)", 284285303Sgshapiro (long) TrustedUid, 285285303Sgshapiro (long) UID_MAX); 286285303Sgshapiro TrustedUid = 0; 287285303Sgshapiro } 288261363Sgshapiro# endif /* UID_MAX */ 289285303Sgshapiro break; 290285303Sgshapiro } 29138032Speter 29238032Speter 293285303Sgshapiro default: 294285303Sgshapiro continue; 29538032Speter } 29638032Speter } 297285303Sgshapiro (void) sm_io_close(cfp, SM_TIME_DEFAULT); 29864565Sgshapiro#endif /* HASFCHOWN */ 29938032Speter 30064565Sgshapiro if (!params.smdbp_allow_dup && !allowreplace) 30164565Sgshapiro putflags = SMDBF_NO_OVERWRITE; 30238032Speter 30364565Sgshapiro if (unmake) 30464565Sgshapiro { 30564565Sgshapiro mode = O_RDONLY; 30664565Sgshapiro smode = S_IRUSR; 30764565Sgshapiro } 30864565Sgshapiro else 30964565Sgshapiro { 31064565Sgshapiro mode = O_RDWR; 31164565Sgshapiro if (!notrunc) 31238032Speter { 31364565Sgshapiro mode |= O_CREAT|O_TRUNC; 31464565Sgshapiro sff |= SFF_CREAT; 31538032Speter } 31664565Sgshapiro smode = S_IWUSR; 31738032Speter } 31838032Speter 31964565Sgshapiro params.smdbp_num_elements = 4096; 32038032Speter 32164565Sgshapiro errno = smdb_open_database(&database, mapname, mode, smode, sff, 32264565Sgshapiro typename, &user_info, ¶ms); 32364565Sgshapiro if (errno != SMDBE_OK) 32438032Speter { 32564565Sgshapiro char *hint; 32638032Speter 32764565Sgshapiro if (errno == SMDBE_UNSUPPORTED_DB_TYPE && 32864565Sgshapiro (hint = smdb_db_definition(typename)) != NULL) 32990795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 33090795Sgshapiro "%s: Need to recompile with -D%s for %s support\n", 33190795Sgshapiro progname, hint, typename); 33264565Sgshapiro else 33390795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 33490795Sgshapiro "%s: error opening type %s map %s: %s\n", 33590795Sgshapiro progname, typename, mapname, 33690795Sgshapiro sm_errstring(errno)); 33764565Sgshapiro exit(EX_CANTCREAT); 33838032Speter } 33938032Speter 34064565Sgshapiro (void) database->smdb_sync(database, 0); 34164565Sgshapiro 34266497Sgshapiro if (!unmake && geteuid() == 0 && TrustedUid != 0) 34338032Speter { 34464565Sgshapiro errno = database->smdb_set_owner(database, TrustedUid, -1); 34564565Sgshapiro if (errno != SMDBE_OK) 34638032Speter { 34790795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 34890795Sgshapiro "WARNING: ownership change on %s failed %s", 34990795Sgshapiro mapname, sm_errstring(errno)); 35038032Speter } 35138032Speter } 35238032Speter 35338032Speter /* 35464565Sgshapiro ** Copy the data 35538032Speter */ 35638032Speter 35764565Sgshapiro exitstat = EX_OK; 35864565Sgshapiro if (unmake) 35938032Speter { 36064565Sgshapiro errno = database->smdb_cursor(database, &cursor, 0); 36164565Sgshapiro if (errno != SMDBE_OK) 36238032Speter { 36364565Sgshapiro 36490795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 36590795Sgshapiro "%s: cannot make cursor for type %s map %s\n", 36690795Sgshapiro progname, typename, mapname); 36764565Sgshapiro exit(EX_SOFTWARE); 36838032Speter } 36964565Sgshapiro 37064565Sgshapiro memset(&db_key, '\0', sizeof db_key); 37164565Sgshapiro memset(&db_val, '\0', sizeof db_val); 37264565Sgshapiro 37371348Sgshapiro for (lineno = 0; ; lineno++) 37438032Speter { 37564565Sgshapiro errno = cursor->smdbc_get(cursor, &db_key, &db_val, 37664565Sgshapiro SMDB_CURSOR_GET_NEXT); 37764565Sgshapiro if (errno != SMDBE_OK) 37871348Sgshapiro break; 37964565Sgshapiro 38090795Sgshapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 381182352Sgshapiro "%.*s%c%.*s\n", 38290795Sgshapiro (int) db_key.size, 38390795Sgshapiro (char *) db_key.data, 384182352Sgshapiro (sep != '\0') ? sep : '\t', 38590795Sgshapiro (int) db_val.size, 38690795Sgshapiro (char *)db_val.data); 38771348Sgshapiro 38838032Speter } 38964565Sgshapiro (void) cursor->smdbc_close(cursor); 39064565Sgshapiro } 39164565Sgshapiro else 39264565Sgshapiro { 39364565Sgshapiro lineno = 0; 39490795Sgshapiro while (sm_io_fgets(smioin, SM_TIME_DEFAULT, ibuf, sizeof ibuf) 395249729Sgshapiro >= 0) 39664565Sgshapiro { 39764565Sgshapiro register char *p; 39838032Speter 39964565Sgshapiro lineno++; 40038032Speter 40164565Sgshapiro /* 40264565Sgshapiro ** Parse the line. 40364565Sgshapiro */ 40464565Sgshapiro 40564565Sgshapiro p = strchr(ibuf, '\n'); 40664565Sgshapiro if (p != NULL) 40764565Sgshapiro *p = '\0'; 40890795Sgshapiro else if (!sm_io_eof(smioin)) 40938032Speter { 41090795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 41190795Sgshapiro "%s: %s: line %u: line too long (%ld bytes max)\n", 41290795Sgshapiro progname, mapname, lineno, 41390795Sgshapiro (long) sizeof ibuf); 41464565Sgshapiro exitstat = EX_DATAERR; 41564565Sgshapiro continue; 41638032Speter } 41764565Sgshapiro 41890795Sgshapiro if (ibuf[0] == '\0' || ibuf[0] == comment) 41964565Sgshapiro continue; 42090795Sgshapiro if (sep == '\0' && isascii(ibuf[0]) && isspace(ibuf[0])) 42138032Speter { 42290795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 42390795Sgshapiro "%s: %s: line %u: syntax error (leading space)\n", 42490795Sgshapiro progname, mapname, lineno); 42564565Sgshapiro exitstat = EX_DATAERR; 42664565Sgshapiro continue; 42738032Speter } 42838032Speter 42964565Sgshapiro memset(&db_key, '\0', sizeof db_key); 43064565Sgshapiro memset(&db_val, '\0', sizeof db_val); 43171348Sgshapiro db_key.data = ibuf; 43238032Speter 43364565Sgshapiro for (p = ibuf; *p != '\0' && !(ISSEP(*p)); p++) 43438032Speter { 43564565Sgshapiro if (foldcase && isascii(*p) && isupper(*p)) 43664565Sgshapiro *p = tolower(*p); 43738032Speter } 43871348Sgshapiro db_key.size = p - ibuf; 43964565Sgshapiro if (inclnull) 44071348Sgshapiro db_key.size++; 44164565Sgshapiro 44264565Sgshapiro if (*p != '\0') 44364565Sgshapiro *p++ = '\0'; 44490795Sgshapiro while (*p != '\0' && ISSEP(*p)) 44564565Sgshapiro p++; 44664565Sgshapiro if (!allowempty && *p == '\0') 44738032Speter { 44890795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 44990795Sgshapiro "%s: %s: line %u: no RHS for LHS %s\n", 45090795Sgshapiro progname, mapname, lineno, 45190795Sgshapiro (char *) db_key.data); 45264565Sgshapiro exitstat = EX_DATAERR; 45364565Sgshapiro continue; 45438032Speter } 45538032Speter 45671348Sgshapiro db_val.data = p; 45771348Sgshapiro db_val.size = strlen(p); 45864565Sgshapiro if (inclnull) 45971348Sgshapiro db_val.size++; 46038032Speter 46164565Sgshapiro /* 46264565Sgshapiro ** Do the database insert. 46364565Sgshapiro */ 46438032Speter 46564565Sgshapiro if (verbose) 46664565Sgshapiro { 46790795Sgshapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, 46890795Sgshapiro "key=`%s', val=`%s'\n", 46990795Sgshapiro (char *) db_key.data, 47090795Sgshapiro (char *) db_val.data); 47164565Sgshapiro } 47238032Speter 47364565Sgshapiro errno = database->smdb_put(database, &db_key, &db_val, 47464565Sgshapiro putflags); 47538032Speter switch (errno) 47638032Speter { 47764565Sgshapiro case SMDBE_KEY_EXIST: 47838032Speter st = 1; 47938032Speter break; 48038032Speter 48138032Speter case 0: 48238032Speter st = 0; 48338032Speter break; 48438032Speter 48538032Speter default: 48638032Speter st = -1; 48738032Speter break; 48838032Speter } 48938032Speter 49064565Sgshapiro if (st < 0) 49164565Sgshapiro { 49290795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 49390795Sgshapiro "%s: %s: line %u: key %s: put error: %s\n", 49490795Sgshapiro progname, mapname, lineno, 49590795Sgshapiro (char *) db_key.data, 49690795Sgshapiro sm_errstring(errno)); 49764565Sgshapiro exitstat = EX_IOERR; 49864565Sgshapiro } 49964565Sgshapiro else if (st > 0) 50064565Sgshapiro { 50190795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 50290795Sgshapiro "%s: %s: line %u: key %s: duplicate key\n", 50390795Sgshapiro progname, mapname, 50490795Sgshapiro lineno, 50590795Sgshapiro (char *) db_key.data); 50664565Sgshapiro exitstat = EX_DATAERR; 50764565Sgshapiro } 50838032Speter } 50938032Speter } 51038032Speter 51138032Speter /* 51238032Speter ** Now close the database. 51338032Speter */ 51438032Speter 51564565Sgshapiro errno = database->smdb_close(database); 51664565Sgshapiro if (errno != SMDBE_OK) 51738032Speter { 51890795Sgshapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, 51990795Sgshapiro "%s: close(%s): %s\n", 52090795Sgshapiro progname, mapname, sm_errstring(errno)); 52164565Sgshapiro exitstat = EX_IOERR; 52238032Speter } 52364565Sgshapiro smdb_free_database(database); 52438032Speter 52564565Sgshapiro exit(exitstat); 52690795Sgshapiro 52764565Sgshapiro /* NOTREACHED */ 52864565Sgshapiro return exitstat; 52938032Speter} 530