1c2aa98e2SPeter Wemm /*
22fb4f839SGregory Neil Shapiro * Copyright (c) 1998-2002, 2004, 2008, 2020 Proofpoint, Inc. and its suppliers.
33299c2f1SGregory Neil Shapiro * All rights reserved.
4c2aa98e2SPeter Wemm * Copyright (c) 1992 Eric P. Allman. All rights reserved.
5c2aa98e2SPeter Wemm * Copyright (c) 1992, 1993
6c2aa98e2SPeter Wemm * The Regents of the University of California. All rights reserved.
7c2aa98e2SPeter Wemm *
8c2aa98e2SPeter Wemm * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm * the sendmail distribution.
11c2aa98e2SPeter Wemm *
12c2aa98e2SPeter Wemm */
13c2aa98e2SPeter Wemm
1412ed1c7cSGregory Neil Shapiro #include <sm/gen.h>
1512ed1c7cSGregory Neil Shapiro
1612ed1c7cSGregory Neil Shapiro SM_IDSTR(copyright,
175dd76dd0SGregory Neil Shapiro "@(#) Copyright (c) 1998-2002, 2004 Proofpoint, Inc. and its suppliers.\n\
183299c2f1SGregory Neil Shapiro All rights reserved.\n\
193299c2f1SGregory Neil Shapiro Copyright (c) 1992 Eric P. Allman. All rights reserved.\n\
203299c2f1SGregory Neil Shapiro Copyright (c) 1992, 1993\n\
2112ed1c7cSGregory Neil Shapiro The Regents of the University of California. All rights reserved.\n")
223299c2f1SGregory Neil Shapiro
234313cc83SGregory Neil Shapiro SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.183 2013-11-22 20:51:52 ca Exp $")
243299c2f1SGregory Neil Shapiro
25e0e1e2d0SGregory Neil Shapiro
26c2aa98e2SPeter Wemm #include <sys/types.h>
27c2aa98e2SPeter Wemm #ifndef ISC_UNIX
28c2aa98e2SPeter Wemm # include <sys/file.h>
295b0945b5SGregory Neil Shapiro #endif
303299c2f1SGregory Neil Shapiro #include <ctype.h>
313299c2f1SGregory Neil Shapiro #include <stdlib.h>
323299c2f1SGregory Neil Shapiro #include <unistd.h>
333299c2f1SGregory Neil Shapiro #ifdef EX_OK
343299c2f1SGregory Neil Shapiro # undef EX_OK /* unistd.h may have another use for this */
355b0945b5SGregory Neil Shapiro #endif
363299c2f1SGregory Neil Shapiro #include <sysexits.h>
373299c2f1SGregory Neil Shapiro #include <sendmail/sendmail.h>
385b0945b5SGregory Neil Shapiro #include <sm/path.h>
393299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h>
403299c2f1SGregory Neil Shapiro #include <libsmdb/smdb.h>
412fb4f839SGregory Neil Shapiro #if USE_EAI
422fb4f839SGregory Neil Shapiro # include <sm/ixlen.h>
432fb4f839SGregory Neil Shapiro #endif
44c2aa98e2SPeter Wemm
45c2aa98e2SPeter Wemm uid_t RealUid;
46c2aa98e2SPeter Wemm gid_t RealGid;
47c2aa98e2SPeter Wemm char *RealUserName;
48c2aa98e2SPeter Wemm uid_t RunAsUid;
4941f3d2ceSGregory Neil Shapiro gid_t RunAsGid;
50c2aa98e2SPeter Wemm char *RunAsUserName;
51c2aa98e2SPeter Wemm int Verbose = 2;
5212ed1c7cSGregory Neil Shapiro bool DontInitGroups = false;
5376b7bf71SPeter Wemm uid_t TrustedUid = 0;
543299c2f1SGregory Neil Shapiro BITMAP256 DontBlameSendmail;
55c2aa98e2SPeter Wemm
56*d39bd2c1SGregory Neil Shapiro static bool verbose = false;
57*d39bd2c1SGregory Neil Shapiro static int exitstat;
58*d39bd2c1SGregory Neil Shapiro
59c2aa98e2SPeter Wemm #define BUFSIZE 1024
605b0945b5SGregory Neil Shapiro #define ISASCII(c) isascii((unsigned char)(c))
61*d39bd2c1SGregory Neil Shapiro #define ISSPACE(c) (ISASCII(c) && isspace(c))
625b0945b5SGregory Neil Shapiro #define ISSEP(c) (sep == '\0' ? ISASCII(c) && isspace(c) : (c) == sep)
633299c2f1SGregory Neil Shapiro
645b0945b5SGregory Neil Shapiro static void usage __P((const char *));
655b0945b5SGregory Neil Shapiro static char *readcf __P((const char *, char *, bool));
66*d39bd2c1SGregory Neil Shapiro static void db_put __P((SMDB_DATABASE *, SMDB_DBENT, SMDB_DBENT, int, const char *, int, const char *));
67684b2a5fSGregory Neil Shapiro
683299c2f1SGregory Neil Shapiro static void
usage(progname)693299c2f1SGregory Neil Shapiro usage(progname)
705b0945b5SGregory Neil Shapiro const char *progname;
713299c2f1SGregory Neil Shapiro {
7212ed1c7cSGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
73bfb62e91SGregory Neil Shapiro "Usage: %s [-C cffile] [-N] [-c cachesize] [-D commentchar]\n",
7412ed1c7cSGregory Neil Shapiro progname);
75bfb62e91SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
76*d39bd2c1SGregory Neil Shapiro " %*s [-d] [-e] [-f] [-i type] [-l] [-o] [-r] [-s] [-t delimiter]\n",
77bfb62e91SGregory Neil Shapiro (int) strlen(progname), "");
782fb4f839SGregory Neil Shapiro #if _FFR_TESTS
792fb4f839SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
802fb4f839SGregory Neil Shapiro " %*s [-S n]\n",
812fb4f839SGregory Neil Shapiro (int) strlen(progname), "");
822fb4f839SGregory Neil Shapiro #endif
83bfb62e91SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
84bfb62e91SGregory Neil Shapiro " %*s [-u] [-v] type mapname\n",
85bfb62e91SGregory Neil Shapiro (int) strlen(progname), "");
863299c2f1SGregory Neil Shapiro exit(EX_USAGE);
873299c2f1SGregory Neil Shapiro }
88c2aa98e2SPeter Wemm
895b0945b5SGregory Neil Shapiro /*
90*d39bd2c1SGregory Neil Shapiro ** DB_PUT -- do the DB insert
91*d39bd2c1SGregory Neil Shapiro **
92*d39bd2c1SGregory Neil Shapiro ** Parameters:
93*d39bd2c1SGregory Neil Shapiro ** database -- DB to use
94*d39bd2c1SGregory Neil Shapiro ** db_key -- key
95*d39bd2c1SGregory Neil Shapiro ** db_val -- value
96*d39bd2c1SGregory Neil Shapiro ** putflags -- flags for smdb_put()
97*d39bd2c1SGregory Neil Shapiro ** mapname -- name of map (for error reporting)
98*d39bd2c1SGregory Neil Shapiro ** lineno -- line number (for error reporting)
99*d39bd2c1SGregory Neil Shapiro ** progname -- name of program (for error reporting)
100*d39bd2c1SGregory Neil Shapiro **
101*d39bd2c1SGregory Neil Shapiro ** Returns:
102*d39bd2c1SGregory Neil Shapiro ** none.
103*d39bd2c1SGregory Neil Shapiro **
104*d39bd2c1SGregory Neil Shapiro ** Side effects:
105*d39bd2c1SGregory Neil Shapiro ** Sets exitstat so makemap exits with error if put fails
106*d39bd2c1SGregory Neil Shapiro */
107*d39bd2c1SGregory Neil Shapiro
108*d39bd2c1SGregory Neil Shapiro static void
db_put(database,db_key,db_val,putflags,mapname,lineno,progname)109*d39bd2c1SGregory Neil Shapiro db_put(database, db_key, db_val, putflags, mapname, lineno, progname)
110*d39bd2c1SGregory Neil Shapiro SMDB_DATABASE *database;
111*d39bd2c1SGregory Neil Shapiro SMDB_DBENT db_key, db_val;
112*d39bd2c1SGregory Neil Shapiro int putflags;
113*d39bd2c1SGregory Neil Shapiro const char *mapname;
114*d39bd2c1SGregory Neil Shapiro int lineno;
115*d39bd2c1SGregory Neil Shapiro const char *progname;
116*d39bd2c1SGregory Neil Shapiro {
117*d39bd2c1SGregory Neil Shapiro int errcode;
118*d39bd2c1SGregory Neil Shapiro
119*d39bd2c1SGregory Neil Shapiro if (verbose)
120*d39bd2c1SGregory Neil Shapiro {
121*d39bd2c1SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
122*d39bd2c1SGregory Neil Shapiro "key=`%s', val=`%s'\n",
123*d39bd2c1SGregory Neil Shapiro (char *) db_key.data,
124*d39bd2c1SGregory Neil Shapiro (char *) db_val.data);
125*d39bd2c1SGregory Neil Shapiro }
126*d39bd2c1SGregory Neil Shapiro
127*d39bd2c1SGregory Neil Shapiro errcode = database->smdb_put(database, &db_key, &db_val, putflags);
128*d39bd2c1SGregory Neil Shapiro if (0 == errcode)
129*d39bd2c1SGregory Neil Shapiro return;
130*d39bd2c1SGregory Neil Shapiro
131*d39bd2c1SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s: %s: ",
132*d39bd2c1SGregory Neil Shapiro progname, mapname);
133*d39bd2c1SGregory Neil Shapiro if (lineno >= 0)
134*d39bd2c1SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "line %u: ",
135*d39bd2c1SGregory Neil Shapiro lineno);
136*d39bd2c1SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "key %s: ",
137*d39bd2c1SGregory Neil Shapiro (char *) db_key.data);
138*d39bd2c1SGregory Neil Shapiro if (SMDBE_KEY_EXIST == errcode)
139*d39bd2c1SGregory Neil Shapiro {
140*d39bd2c1SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
141*d39bd2c1SGregory Neil Shapiro "duplicate key\n");
142*d39bd2c1SGregory Neil Shapiro exitstat = EX_DATAERR;
143*d39bd2c1SGregory Neil Shapiro }
144*d39bd2c1SGregory Neil Shapiro else
145*d39bd2c1SGregory Neil Shapiro {
146*d39bd2c1SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
147*d39bd2c1SGregory Neil Shapiro "put error: %s\n", sm_errstring(errcode));
148*d39bd2c1SGregory Neil Shapiro exitstat = EX_IOERR;
149*d39bd2c1SGregory Neil Shapiro }
150*d39bd2c1SGregory Neil Shapiro }
151*d39bd2c1SGregory Neil Shapiro
152*d39bd2c1SGregory Neil Shapiro /*
1535b0945b5SGregory Neil Shapiro ** READCF -- read some settings from configuration file.
1545b0945b5SGregory Neil Shapiro **
1555b0945b5SGregory Neil Shapiro ** Parameters:
1565b0945b5SGregory Neil Shapiro ** cfile -- configuration file name.
1575b0945b5SGregory Neil Shapiro ** mapfile -- file name of map to look up (if not NULL/empty)
1585b0945b5SGregory Neil Shapiro ** Note: this finds the first match, so in case someone
1595b0945b5SGregory Neil Shapiro ** uses the same map file for different maps, they are
1605b0945b5SGregory Neil Shapiro ** hopefully using the same map type.
1615b0945b5SGregory Neil Shapiro ** fullpath -- compare the full paths or just the "basename"s?
1625b0945b5SGregory Neil Shapiro ** (even excluding any .ext !)
1635b0945b5SGregory Neil Shapiro **
1645b0945b5SGregory Neil Shapiro ** Returns:
1655b0945b5SGregory Neil Shapiro ** pointer to map class name (static!)
1665b0945b5SGregory Neil Shapiro */
1675b0945b5SGregory Neil Shapiro
1685b0945b5SGregory Neil Shapiro static char *
readcf(cfile,mapfile,fullpath)1695b0945b5SGregory Neil Shapiro readcf(cfile, mapfile, fullpath)
1705b0945b5SGregory Neil Shapiro const char *cfile;
1715b0945b5SGregory Neil Shapiro char *mapfile;
1725b0945b5SGregory Neil Shapiro bool fullpath;
1735b0945b5SGregory Neil Shapiro {
1745b0945b5SGregory Neil Shapiro SM_FILE_T *cfp;
1755b0945b5SGregory Neil Shapiro char buf[MAXLINE];
1765b0945b5SGregory Neil Shapiro static char classbuf[MAXLINE];
177*d39bd2c1SGregory Neil Shapiro char *classname, *mapname;
1785b0945b5SGregory Neil Shapiro char *p;
1795b0945b5SGregory Neil Shapiro
1805b0945b5SGregory Neil Shapiro if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile,
1815b0945b5SGregory Neil Shapiro SM_IO_RDONLY, NULL)) == NULL)
1825b0945b5SGregory Neil Shapiro {
1835b0945b5SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
1845b0945b5SGregory Neil Shapiro "makemap: %s: %s\n",
1855b0945b5SGregory Neil Shapiro cfile, sm_errstring(errno));
1865b0945b5SGregory Neil Shapiro exit(EX_NOINPUT);
1875b0945b5SGregory Neil Shapiro }
1885b0945b5SGregory Neil Shapiro classname = NULL;
1895b0945b5SGregory Neil Shapiro classbuf[0] = '\0';
1905b0945b5SGregory Neil Shapiro
191*d39bd2c1SGregory Neil Shapiro mapname = mapfile;
1925b0945b5SGregory Neil Shapiro if (!fullpath && mapfile != NULL)
1935b0945b5SGregory Neil Shapiro {
1945b0945b5SGregory Neil Shapiro p = strrchr(mapfile, '/');
1955b0945b5SGregory Neil Shapiro if (p != NULL)
1965b0945b5SGregory Neil Shapiro mapfile = ++p;
197*d39bd2c1SGregory Neil Shapiro mapname = strdup(mapfile);
198*d39bd2c1SGregory Neil Shapiro if (NULL == mapname)
199*d39bd2c1SGregory Neil Shapiro {
200*d39bd2c1SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
201*d39bd2c1SGregory Neil Shapiro "makemap: strdup(%s) failed: %s\n",
202*d39bd2c1SGregory Neil Shapiro mapfile, sm_errstring(errno));
203*d39bd2c1SGregory Neil Shapiro exit(EX_OSERR);
204*d39bd2c1SGregory Neil Shapiro }
205*d39bd2c1SGregory Neil Shapiro if ((p = strchr(mapname, '.')) != NULL)
2065b0945b5SGregory Neil Shapiro *p = '\0';
2075b0945b5SGregory Neil Shapiro }
2085b0945b5SGregory Neil Shapiro
2095b0945b5SGregory Neil Shapiro while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
2105b0945b5SGregory Neil Shapiro {
2115b0945b5SGregory Neil Shapiro char *b;
2125b0945b5SGregory Neil Shapiro
2135b0945b5SGregory Neil Shapiro if ((b = strchr(buf, '\n')) != NULL)
2145b0945b5SGregory Neil Shapiro *b = '\0';
2155b0945b5SGregory Neil Shapiro
2165b0945b5SGregory Neil Shapiro b = buf;
2175b0945b5SGregory Neil Shapiro switch (*b++)
2185b0945b5SGregory Neil Shapiro {
2195b0945b5SGregory Neil Shapiro case 'O': /* option */
2205b0945b5SGregory Neil Shapiro #if HASFCHOWN
2215b0945b5SGregory Neil Shapiro if (strncasecmp(b, " TrustedUser", 12) == 0 &&
2225b0945b5SGregory Neil Shapiro !(ISASCII(b[12]) && isalnum(b[12])))
2235b0945b5SGregory Neil Shapiro {
2245b0945b5SGregory Neil Shapiro b = strchr(b, '=');
2255b0945b5SGregory Neil Shapiro if (b == NULL)
2265b0945b5SGregory Neil Shapiro continue;
2275b0945b5SGregory Neil Shapiro while (ISASCII(*++b) && isspace(*b))
2285b0945b5SGregory Neil Shapiro continue;
2295b0945b5SGregory Neil Shapiro if (ISASCII(*b) && isdigit(*b))
2305b0945b5SGregory Neil Shapiro TrustedUid = atoi(b);
2315b0945b5SGregory Neil Shapiro else
2325b0945b5SGregory Neil Shapiro {
2335b0945b5SGregory Neil Shapiro struct passwd *pw;
2345b0945b5SGregory Neil Shapiro
2355b0945b5SGregory Neil Shapiro TrustedUid = 0;
2365b0945b5SGregory Neil Shapiro pw = getpwnam(b);
2375b0945b5SGregory Neil Shapiro if (pw == NULL)
2385b0945b5SGregory Neil Shapiro (void) sm_io_fprintf(smioerr,
2395b0945b5SGregory Neil Shapiro SM_TIME_DEFAULT,
2405b0945b5SGregory Neil Shapiro "TrustedUser: unknown user %s\n", b);
2415b0945b5SGregory Neil Shapiro else
2425b0945b5SGregory Neil Shapiro TrustedUid = pw->pw_uid;
2435b0945b5SGregory Neil Shapiro }
2445b0945b5SGregory Neil Shapiro
2455b0945b5SGregory Neil Shapiro # ifdef UID_MAX
2465b0945b5SGregory Neil Shapiro if (TrustedUid > UID_MAX)
2475b0945b5SGregory Neil Shapiro {
2485b0945b5SGregory Neil Shapiro (void) sm_io_fprintf(smioerr,
2495b0945b5SGregory Neil Shapiro SM_TIME_DEFAULT,
2505b0945b5SGregory Neil Shapiro "TrustedUser: uid value (%ld) > UID_MAX (%ld)",
2515b0945b5SGregory Neil Shapiro (long) TrustedUid,
2525b0945b5SGregory Neil Shapiro (long) UID_MAX);
2535b0945b5SGregory Neil Shapiro TrustedUid = 0;
2545b0945b5SGregory Neil Shapiro }
2555b0945b5SGregory Neil Shapiro # endif /* UID_MAX */
2565b0945b5SGregory Neil Shapiro }
2575b0945b5SGregory Neil Shapiro #endif /* HASFCHOWN */
2585b0945b5SGregory Neil Shapiro break;
2595b0945b5SGregory Neil Shapiro
2605b0945b5SGregory Neil Shapiro case 'K': /* Keyfile (map) */
2615b0945b5SGregory Neil Shapiro if (classname != NULL) /* found it already */
2625b0945b5SGregory Neil Shapiro continue;
263*d39bd2c1SGregory Neil Shapiro if (mapname == NULL || *mapname == '\0')
2645b0945b5SGregory Neil Shapiro continue;
2655b0945b5SGregory Neil Shapiro
2665b0945b5SGregory Neil Shapiro /* cut off trailing spaces */
267*d39bd2c1SGregory Neil Shapiro for (p = buf + strlen(buf) - 1;
268*d39bd2c1SGregory Neil Shapiro ISASCII(*p) && isspace(*p) && p > buf; p--)
2695b0945b5SGregory Neil Shapiro *p = '\0';
2705b0945b5SGregory Neil Shapiro
2715b0945b5SGregory Neil Shapiro /* find the last argument */
2725b0945b5SGregory Neil Shapiro p = strrchr(buf, ' ');
2735b0945b5SGregory Neil Shapiro if (p == NULL)
2745b0945b5SGregory Neil Shapiro continue;
275*d39bd2c1SGregory Neil Shapiro b = strstr(p, mapname);
2765b0945b5SGregory Neil Shapiro if (b == NULL)
2775b0945b5SGregory Neil Shapiro continue;
2785b0945b5SGregory Neil Shapiro if (b <= buf)
2795b0945b5SGregory Neil Shapiro continue;
2805b0945b5SGregory Neil Shapiro if (!fullpath)
2815b0945b5SGregory Neil Shapiro {
2825b0945b5SGregory Neil Shapiro p = strrchr(b, '.');
2835b0945b5SGregory Neil Shapiro if (p != NULL)
2845b0945b5SGregory Neil Shapiro *p = '\0';
2855b0945b5SGregory Neil Shapiro }
2865b0945b5SGregory Neil Shapiro
2875b0945b5SGregory Neil Shapiro /* allow trailing white space? */
288*d39bd2c1SGregory Neil Shapiro if (strcmp(mapname, b) != 0)
2895b0945b5SGregory Neil Shapiro continue;
2905b0945b5SGregory Neil Shapiro /* SM_ASSERT(b > buf); */
2915b0945b5SGregory Neil Shapiro --b;
2925b0945b5SGregory Neil Shapiro if (!ISASCII(*b))
2935b0945b5SGregory Neil Shapiro continue;
2945b0945b5SGregory Neil Shapiro if (!isspace(*b) && fullpath)
2955b0945b5SGregory Neil Shapiro continue;
2965b0945b5SGregory Neil Shapiro if (!fullpath && !(SM_IS_DIR_DELIM(*b) || isspace(*b)))
2975b0945b5SGregory Neil Shapiro continue;
2985b0945b5SGregory Neil Shapiro
2995b0945b5SGregory Neil Shapiro /* basically from readcf.c */
3005b0945b5SGregory Neil Shapiro for (b = buf + 1; ISASCII(*b) && isspace(*b); b++)
3015b0945b5SGregory Neil Shapiro ;
3025b0945b5SGregory Neil Shapiro if (!(ISASCII(*b) && isalnum(*b)))
3035b0945b5SGregory Neil Shapiro {
3045b0945b5SGregory Neil Shapiro /* syserr("readcf: config K line: no map name"); */
3055b0945b5SGregory Neil Shapiro return NULL;
3065b0945b5SGregory Neil Shapiro }
3075b0945b5SGregory Neil Shapiro
3085b0945b5SGregory Neil Shapiro while ((ISASCII(*++b) && isalnum(*b)) || *b == '_' || *b == '.')
3095b0945b5SGregory Neil Shapiro ;
3105b0945b5SGregory Neil Shapiro if (*b != '\0')
3115b0945b5SGregory Neil Shapiro *b++ = '\0';
3125b0945b5SGregory Neil Shapiro while (ISASCII(*b) && isspace(*b))
3135b0945b5SGregory Neil Shapiro b++;
3145b0945b5SGregory Neil Shapiro if (!(ISASCII(*b) && isalnum(*b)))
3155b0945b5SGregory Neil Shapiro {
3165b0945b5SGregory Neil Shapiro /* syserr("readcf: config K line, map %s: no map class", b); */
3175b0945b5SGregory Neil Shapiro return NULL;
3185b0945b5SGregory Neil Shapiro }
3195b0945b5SGregory Neil Shapiro classname = b;
3205b0945b5SGregory Neil Shapiro while (ISASCII(*++b) && isalnum(*b))
3215b0945b5SGregory Neil Shapiro ;
3225b0945b5SGregory Neil Shapiro if (*b != '\0')
3235b0945b5SGregory Neil Shapiro *b++ = '\0';
3245b0945b5SGregory Neil Shapiro (void) sm_strlcpy(classbuf, classname, sizeof classbuf);
3255b0945b5SGregory Neil Shapiro break;
3265b0945b5SGregory Neil Shapiro
3275b0945b5SGregory Neil Shapiro default:
3285b0945b5SGregory Neil Shapiro continue;
3295b0945b5SGregory Neil Shapiro }
3305b0945b5SGregory Neil Shapiro }
3315b0945b5SGregory Neil Shapiro (void) sm_io_close(cfp, SM_TIME_DEFAULT);
3325b0945b5SGregory Neil Shapiro
333*d39bd2c1SGregory Neil Shapiro /* not really needed because it is just a "one time leak" */
334*d39bd2c1SGregory Neil Shapiro if (mapname != mapfile && mapname != NULL)
335*d39bd2c1SGregory Neil Shapiro {
336*d39bd2c1SGregory Neil Shapiro free(mapname);
337*d39bd2c1SGregory Neil Shapiro mapname = NULL;
338*d39bd2c1SGregory Neil Shapiro }
3395b0945b5SGregory Neil Shapiro return classbuf;
3405b0945b5SGregory Neil Shapiro }
3415b0945b5SGregory Neil Shapiro
342c2aa98e2SPeter Wemm int
main(argc,argv)343c2aa98e2SPeter Wemm main(argc, argv)
344c2aa98e2SPeter Wemm int argc;
345c2aa98e2SPeter Wemm char **argv;
346c2aa98e2SPeter Wemm {
347c2aa98e2SPeter Wemm char *progname;
348c2aa98e2SPeter Wemm char *cfile;
34912ed1c7cSGregory Neil Shapiro bool inclnull = false;
35012ed1c7cSGregory Neil Shapiro bool notrunc = false;
35112ed1c7cSGregory Neil Shapiro bool allowreplace = false;
35212ed1c7cSGregory Neil Shapiro bool allowempty = false;
35312ed1c7cSGregory Neil Shapiro bool foldcase = true;
35412ed1c7cSGregory Neil Shapiro bool unmake = false;
355*d39bd2c1SGregory Neil Shapiro #if _FFR_MM_ALIASES
356*d39bd2c1SGregory Neil Shapiro /*
357*d39bd2c1SGregory Neil Shapiro ** NOTE: this does not work properly:
358*d39bd2c1SGregory Neil Shapiro ** sendmail does address rewriting which is not done here.
359*d39bd2c1SGregory Neil Shapiro */
360*d39bd2c1SGregory Neil Shapiro
361*d39bd2c1SGregory Neil Shapiro bool aliases = false;
362*d39bd2c1SGregory Neil Shapiro #endif
3635b0945b5SGregory Neil Shapiro bool didreadcf = false;
3643299c2f1SGregory Neil Shapiro char sep = '\0';
36512ed1c7cSGregory Neil Shapiro char comment = '#';
366c2aa98e2SPeter Wemm int opt;
36776b7bf71SPeter Wemm char *typename = NULL;
3685b0945b5SGregory Neil Shapiro char *fallback = NULL;
36976b7bf71SPeter Wemm char *mapname = NULL;
37012ed1c7cSGregory Neil Shapiro unsigned int lineno;
371c2aa98e2SPeter Wemm int mode;
3723299c2f1SGregory Neil Shapiro int smode;
37376b7bf71SPeter Wemm int putflags = 0;
3743299c2f1SGregory Neil Shapiro long sff = SFF_ROOTOK|SFF_REGONLY;
375c2aa98e2SPeter Wemm struct passwd *pw;
3763299c2f1SGregory Neil Shapiro SMDB_DATABASE *database;
3773299c2f1SGregory Neil Shapiro SMDB_CURSOR *cursor;
3783299c2f1SGregory Neil Shapiro SMDB_DBENT db_key, db_val;
3793299c2f1SGregory Neil Shapiro SMDB_DBPARAMS params;
3803299c2f1SGregory Neil Shapiro SMDB_USER_INFO user_info;
381c2aa98e2SPeter Wemm char ibuf[BUFSIZE];
382c2aa98e2SPeter Wemm static char rnamebuf[MAXNAME]; /* holds RealUserName */
383c2aa98e2SPeter Wemm extern char *optarg;
384c2aa98e2SPeter Wemm extern int optind;
3852fb4f839SGregory Neil Shapiro #if USE_EAI
3862fb4f839SGregory Neil Shapiro bool ascii = true;
3872fb4f839SGregory Neil Shapiro #endif
3882fb4f839SGregory Neil Shapiro #if _FFR_TESTS
3892fb4f839SGregory Neil Shapiro int slp = 0;
3902fb4f839SGregory Neil Shapiro #endif
391c2aa98e2SPeter Wemm
3923299c2f1SGregory Neil Shapiro memset(¶ms, '\0', sizeof params);
3933299c2f1SGregory Neil Shapiro params.smdbp_cache_size = 1024 * 1024;
3943299c2f1SGregory Neil Shapiro
3953299c2f1SGregory Neil Shapiro progname = strrchr(argv[0], '/');
3963299c2f1SGregory Neil Shapiro if (progname != NULL)
3973299c2f1SGregory Neil Shapiro progname++;
3983299c2f1SGregory Neil Shapiro else
399c2aa98e2SPeter Wemm progname = argv[0];
40012ed1c7cSGregory Neil Shapiro cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
401c2aa98e2SPeter Wemm
4023299c2f1SGregory Neil Shapiro clrbitmap(DontBlameSendmail);
403c2aa98e2SPeter Wemm RunAsUid = RealUid = getuid();
404c2aa98e2SPeter Wemm RunAsGid = RealGid = getgid();
405c2aa98e2SPeter Wemm pw = getpwuid(RealUid);
406c2aa98e2SPeter Wemm if (pw != NULL)
40712ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf);
408c2aa98e2SPeter Wemm else
40912ed1c7cSGregory Neil Shapiro (void) sm_snprintf(rnamebuf, sizeof rnamebuf,
41012ed1c7cSGregory Neil Shapiro "Unknown UID %d", (int) RealUid);
411c2aa98e2SPeter Wemm RunAsUserName = RealUserName = rnamebuf;
4123299c2f1SGregory Neil Shapiro user_info.smdbu_id = RunAsUid;
4133299c2f1SGregory Neil Shapiro user_info.smdbu_group_id = RunAsGid;
41412ed1c7cSGregory Neil Shapiro (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
4153299c2f1SGregory Neil Shapiro SMDB_MAX_USER_NAME_LEN);
416c2aa98e2SPeter Wemm
4175b0945b5SGregory Neil Shapiro #define OPTIONS "C:D:Nc:defi:Llorst:uvx"
418*d39bd2c1SGregory Neil Shapiro #if _FFR_MM_ALIASES
419*d39bd2c1SGregory Neil Shapiro # define A_OPTIONS "a"
420*d39bd2c1SGregory Neil Shapiro #else
421*d39bd2c1SGregory Neil Shapiro # define A_OPTIONS
422*d39bd2c1SGregory Neil Shapiro #endif
4232fb4f839SGregory Neil Shapiro #if _FFR_TESTS
4242fb4f839SGregory Neil Shapiro # define X_OPTIONS "S:"
4252fb4f839SGregory Neil Shapiro #else
4262fb4f839SGregory Neil Shapiro # define X_OPTIONS
4272fb4f839SGregory Neil Shapiro #endif
428*d39bd2c1SGregory Neil Shapiro while ((opt = getopt(argc, argv, A_OPTIONS OPTIONS X_OPTIONS)) != -1)
429c2aa98e2SPeter Wemm {
430c2aa98e2SPeter Wemm switch (opt)
431c2aa98e2SPeter Wemm {
432c2aa98e2SPeter Wemm case 'C':
433c2aa98e2SPeter Wemm cfile = optarg;
434c2aa98e2SPeter Wemm break;
435c2aa98e2SPeter Wemm
436c2aa98e2SPeter Wemm case 'N':
43712ed1c7cSGregory Neil Shapiro inclnull = true;
438c2aa98e2SPeter Wemm break;
439c2aa98e2SPeter Wemm
440*d39bd2c1SGregory Neil Shapiro #if _FFR_MM_ALIASES
441*d39bd2c1SGregory Neil Shapiro case 'a':
442*d39bd2c1SGregory Neil Shapiro /* Note: this doesn't verify e-mail addresses */
443*d39bd2c1SGregory Neil Shapiro sep = ':';
444*d39bd2c1SGregory Neil Shapiro aliases = true;
445*d39bd2c1SGregory Neil Shapiro break;
446*d39bd2c1SGregory Neil Shapiro #endif
447*d39bd2c1SGregory Neil Shapiro
448c2aa98e2SPeter Wemm case 'c':
4493299c2f1SGregory Neil Shapiro params.smdbp_cache_size = atol(optarg);
450c2aa98e2SPeter Wemm break;
451c2aa98e2SPeter Wemm
452c2aa98e2SPeter Wemm case 'd':
45312ed1c7cSGregory Neil Shapiro params.smdbp_allow_dup = true;
4543299c2f1SGregory Neil Shapiro break;
4553299c2f1SGregory Neil Shapiro
4563299c2f1SGregory Neil Shapiro case 'e':
45712ed1c7cSGregory Neil Shapiro allowempty = true;
458c2aa98e2SPeter Wemm break;
459c2aa98e2SPeter Wemm
460c2aa98e2SPeter Wemm case 'f':
46112ed1c7cSGregory Neil Shapiro foldcase = false;
462c2aa98e2SPeter Wemm break;
463c2aa98e2SPeter Wemm
4645b0945b5SGregory Neil Shapiro case 'i':
4655b0945b5SGregory Neil Shapiro fallback =optarg;
4665b0945b5SGregory Neil Shapiro break;
4675b0945b5SGregory Neil Shapiro
46812ed1c7cSGregory Neil Shapiro case 'D':
46912ed1c7cSGregory Neil Shapiro comment = *optarg;
47012ed1c7cSGregory Neil Shapiro break;
47112ed1c7cSGregory Neil Shapiro
4725b0945b5SGregory Neil Shapiro case 'L':
4735b0945b5SGregory Neil Shapiro smdb_print_available_types(false);
4745b0945b5SGregory Neil Shapiro sm_io_fprintf(smioout, SM_TIME_DEFAULT,
4755b0945b5SGregory Neil Shapiro "cf\nCF\n");
4765b0945b5SGregory Neil Shapiro exit(EX_OK);
4775b0945b5SGregory Neil Shapiro break;
4785b0945b5SGregory Neil Shapiro
47976b7bf71SPeter Wemm case 'l':
4805b0945b5SGregory Neil Shapiro smdb_print_available_types(false);
48176b7bf71SPeter Wemm exit(EX_OK);
48276b7bf71SPeter Wemm break;
48376b7bf71SPeter Wemm
484c2aa98e2SPeter Wemm case 'o':
48512ed1c7cSGregory Neil Shapiro notrunc = true;
486c2aa98e2SPeter Wemm break;
487c2aa98e2SPeter Wemm
488c2aa98e2SPeter Wemm case 'r':
48912ed1c7cSGregory Neil Shapiro allowreplace = true;
490c2aa98e2SPeter Wemm break;
491c2aa98e2SPeter Wemm
4922fb4f839SGregory Neil Shapiro #if _FFR_TESTS
4932fb4f839SGregory Neil Shapiro case 'S':
4942fb4f839SGregory Neil Shapiro slp = atoi(optarg);
4952fb4f839SGregory Neil Shapiro break;
4962fb4f839SGregory Neil Shapiro #endif
4972fb4f839SGregory Neil Shapiro
498c2aa98e2SPeter Wemm case 's':
4993299c2f1SGregory Neil Shapiro setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail);
5003299c2f1SGregory Neil Shapiro setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail);
5013299c2f1SGregory Neil Shapiro setbitn(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail);
5023299c2f1SGregory Neil Shapiro setbitn(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail);
5033299c2f1SGregory Neil Shapiro break;
5043299c2f1SGregory Neil Shapiro
5053299c2f1SGregory Neil Shapiro case 't':
5063299c2f1SGregory Neil Shapiro if (optarg == NULL || *optarg == '\0')
5073299c2f1SGregory Neil Shapiro {
50812ed1c7cSGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
50912ed1c7cSGregory Neil Shapiro "Invalid separator\n");
5103299c2f1SGregory Neil Shapiro break;
5113299c2f1SGregory Neil Shapiro }
5123299c2f1SGregory Neil Shapiro sep = *optarg;
5133299c2f1SGregory Neil Shapiro break;
5143299c2f1SGregory Neil Shapiro
5153299c2f1SGregory Neil Shapiro case 'u':
51612ed1c7cSGregory Neil Shapiro unmake = true;
517c2aa98e2SPeter Wemm break;
518c2aa98e2SPeter Wemm
519c2aa98e2SPeter Wemm case 'v':
52012ed1c7cSGregory Neil Shapiro verbose = true;
521c2aa98e2SPeter Wemm break;
522c2aa98e2SPeter Wemm
5235b0945b5SGregory Neil Shapiro case 'x':
5245b0945b5SGregory Neil Shapiro smdb_print_available_types(true);
5255b0945b5SGregory Neil Shapiro exit(EX_OK);
5265b0945b5SGregory Neil Shapiro break;
5275b0945b5SGregory Neil Shapiro
528c2aa98e2SPeter Wemm default:
5293299c2f1SGregory Neil Shapiro usage(progname);
5303299c2f1SGregory Neil Shapiro /* NOTREACHED */
531c2aa98e2SPeter Wemm }
532c2aa98e2SPeter Wemm }
533c2aa98e2SPeter Wemm
5343299c2f1SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
535c2aa98e2SPeter Wemm sff |= SFF_NOSLINK;
5363299c2f1SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
537c2aa98e2SPeter Wemm sff |= SFF_NOHLINK;
5383299c2f1SGregory Neil Shapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
539c2aa98e2SPeter Wemm sff |= SFF_NOWLINK;
540c2aa98e2SPeter Wemm
541c2aa98e2SPeter Wemm argc -= optind;
542c2aa98e2SPeter Wemm argv += optind;
543c2aa98e2SPeter Wemm if (argc != 2)
5443299c2f1SGregory Neil Shapiro {
5453299c2f1SGregory Neil Shapiro usage(progname);
5463299c2f1SGregory Neil Shapiro /* NOTREACHED */
5473299c2f1SGregory Neil Shapiro }
548c2aa98e2SPeter Wemm else
549c2aa98e2SPeter Wemm {
550c2aa98e2SPeter Wemm typename = argv[0];
551c2aa98e2SPeter Wemm mapname = argv[1];
552c2aa98e2SPeter Wemm }
553c2aa98e2SPeter Wemm
5545b0945b5SGregory Neil Shapiro #define TYPEFROMCF (strcasecmp(typename, "cf") == 0)
5555b0945b5SGregory Neil Shapiro #define FULLPATHFROMCF (strcmp(typename, "cf") == 0)
5565b0945b5SGregory Neil Shapiro
5573299c2f1SGregory Neil Shapiro #if HASFCHOWN
5585b0945b5SGregory Neil Shapiro if (geteuid() == 0)
5595dd76dd0SGregory Neil Shapiro {
5605b0945b5SGregory Neil Shapiro if (TYPEFROMCF)
5615b0945b5SGregory Neil Shapiro typename = readcf(cfile, mapname, FULLPATHFROMCF);
562c2aa98e2SPeter Wemm else
5635b0945b5SGregory Neil Shapiro (void) readcf(cfile, NULL, false);
5645b0945b5SGregory Neil Shapiro didreadcf = true;
565c2aa98e2SPeter Wemm }
5663299c2f1SGregory Neil Shapiro #endif /* HASFCHOWN */
5673299c2f1SGregory Neil Shapiro
5683299c2f1SGregory Neil Shapiro if (!params.smdbp_allow_dup && !allowreplace)
5693299c2f1SGregory Neil Shapiro putflags = SMDBF_NO_OVERWRITE;
5703299c2f1SGregory Neil Shapiro
5713299c2f1SGregory Neil Shapiro if (unmake)
572c2aa98e2SPeter Wemm {
5733299c2f1SGregory Neil Shapiro mode = O_RDONLY;
5743299c2f1SGregory Neil Shapiro smode = S_IRUSR;
575c2aa98e2SPeter Wemm }
576c2aa98e2SPeter Wemm else
577c2aa98e2SPeter Wemm {
578c2aa98e2SPeter Wemm mode = O_RDWR;
579c2aa98e2SPeter Wemm if (!notrunc)
5803299c2f1SGregory Neil Shapiro {
581c2aa98e2SPeter Wemm mode |= O_CREAT|O_TRUNC;
5823299c2f1SGregory Neil Shapiro sff |= SFF_CREAT;
583c2aa98e2SPeter Wemm }
5843299c2f1SGregory Neil Shapiro smode = S_IWUSR;
585c2aa98e2SPeter Wemm }
5863299c2f1SGregory Neil Shapiro
5873299c2f1SGregory Neil Shapiro params.smdbp_num_elements = 4096;
5883299c2f1SGregory Neil Shapiro
5895b0945b5SGregory Neil Shapiro if (!didreadcf && TYPEFROMCF)
5905b0945b5SGregory Neil Shapiro {
5915b0945b5SGregory Neil Shapiro typename = readcf(cfile, mapname, FULLPATHFROMCF);
5925b0945b5SGregory Neil Shapiro didreadcf = true;
5935b0945b5SGregory Neil Shapiro }
5945b0945b5SGregory Neil Shapiro if (didreadcf && (typename == NULL || *typename == '\0'))
5955b0945b5SGregory Neil Shapiro {
5965b0945b5SGregory Neil Shapiro if (fallback != NULL && *fallback != '\0')
5975b0945b5SGregory Neil Shapiro {
5985b0945b5SGregory Neil Shapiro typename = fallback;
5995b0945b5SGregory Neil Shapiro if (verbose)
6005b0945b5SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
6015b0945b5SGregory Neil Shapiro "%s: mapfile %s: not found in %s, using fallback %s\n",
6025b0945b5SGregory Neil Shapiro progname, mapname, cfile, fallback);
6035b0945b5SGregory Neil Shapiro }
6045b0945b5SGregory Neil Shapiro else
6055b0945b5SGregory Neil Shapiro {
6065b0945b5SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
6075b0945b5SGregory Neil Shapiro "%s: mapfile %s: not found in %s\n",
6085b0945b5SGregory Neil Shapiro progname, mapname, cfile);
6095b0945b5SGregory Neil Shapiro exit(EX_DATAERR);
6105b0945b5SGregory Neil Shapiro }
6115b0945b5SGregory Neil Shapiro }
6125b0945b5SGregory Neil Shapiro
6135b0945b5SGregory Neil Shapiro /*
6145b0945b5SGregory Neil Shapiro ** Note: if "implicit" is selected it does not work like
6155b0945b5SGregory Neil Shapiro ** sendmail: it will just use the first available DB type,
6165b0945b5SGregory Neil Shapiro ** it won't try several (for -u) to find one that "works".
6175b0945b5SGregory Neil Shapiro */
6185b0945b5SGregory Neil Shapiro
6193299c2f1SGregory Neil Shapiro errno = smdb_open_database(&database, mapname, mode, smode, sff,
6203299c2f1SGregory Neil Shapiro typename, &user_info, ¶ms);
6213299c2f1SGregory Neil Shapiro if (errno != SMDBE_OK)
622c2aa98e2SPeter Wemm {
6233299c2f1SGregory Neil Shapiro char *hint;
6243299c2f1SGregory Neil Shapiro
6253299c2f1SGregory Neil Shapiro if (errno == SMDBE_UNSUPPORTED_DB_TYPE &&
6263299c2f1SGregory Neil Shapiro (hint = smdb_db_definition(typename)) != NULL)
62712ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
6283299c2f1SGregory Neil Shapiro "%s: Need to recompile with -D%s for %s support\n",
6293299c2f1SGregory Neil Shapiro progname, hint, typename);
6303299c2f1SGregory Neil Shapiro else
63112ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
6323299c2f1SGregory Neil Shapiro "%s: error opening type %s map %s: %s\n",
63312ed1c7cSGregory Neil Shapiro progname, typename, mapname,
63412ed1c7cSGregory Neil Shapiro sm_errstring(errno));
635c2aa98e2SPeter Wemm exit(EX_CANTCREAT);
636c2aa98e2SPeter Wemm }
6373299c2f1SGregory Neil Shapiro
6383299c2f1SGregory Neil Shapiro (void) database->smdb_sync(database, 0);
6393299c2f1SGregory Neil Shapiro
640d995d2baSGregory Neil Shapiro if (!unmake && geteuid() == 0 && TrustedUid != 0)
641c2aa98e2SPeter Wemm {
6423299c2f1SGregory Neil Shapiro errno = database->smdb_set_owner(database, TrustedUid, -1);
6433299c2f1SGregory Neil Shapiro if (errno != SMDBE_OK)
644c2aa98e2SPeter Wemm {
64512ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
6463299c2f1SGregory Neil Shapiro "WARNING: ownership change on %s failed %s",
64712ed1c7cSGregory Neil Shapiro mapname, sm_errstring(errno));
648c2aa98e2SPeter Wemm }
649c2aa98e2SPeter Wemm }
650c2aa98e2SPeter Wemm
651c2aa98e2SPeter Wemm /*
652c2aa98e2SPeter Wemm ** Copy the data
653c2aa98e2SPeter Wemm */
654c2aa98e2SPeter Wemm
655c2aa98e2SPeter Wemm exitstat = EX_OK;
6563299c2f1SGregory Neil Shapiro if (unmake)
6573299c2f1SGregory Neil Shapiro {
6583299c2f1SGregory Neil Shapiro errno = database->smdb_cursor(database, &cursor, 0);
6593299c2f1SGregory Neil Shapiro if (errno != SMDBE_OK)
6603299c2f1SGregory Neil Shapiro {
6613299c2f1SGregory Neil Shapiro
66212ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
6633299c2f1SGregory Neil Shapiro "%s: cannot make cursor for type %s map %s\n",
6643299c2f1SGregory Neil Shapiro progname, typename, mapname);
6653299c2f1SGregory Neil Shapiro exit(EX_SOFTWARE);
6663299c2f1SGregory Neil Shapiro }
6673299c2f1SGregory Neil Shapiro
6683299c2f1SGregory Neil Shapiro memset(&db_key, '\0', sizeof db_key);
6693299c2f1SGregory Neil Shapiro memset(&db_val, '\0', sizeof db_val);
6703299c2f1SGregory Neil Shapiro
671c46d91b7SGregory Neil Shapiro for (lineno = 0; ; lineno++)
6723299c2f1SGregory Neil Shapiro {
6733299c2f1SGregory Neil Shapiro errno = cursor->smdbc_get(cursor, &db_key, &db_val,
6743299c2f1SGregory Neil Shapiro SMDB_CURSOR_GET_NEXT);
6753299c2f1SGregory Neil Shapiro if (errno != SMDBE_OK)
676c46d91b7SGregory Neil Shapiro break;
677c46d91b7SGregory Neil Shapiro
67812ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
679e3793f76SGregory Neil Shapiro "%.*s%c%.*s\n",
680c46d91b7SGregory Neil Shapiro (int) db_key.size,
681c46d91b7SGregory Neil Shapiro (char *) db_key.data,
682e3793f76SGregory Neil Shapiro (sep != '\0') ? sep : '\t',
683c46d91b7SGregory Neil Shapiro (int) db_val.size,
684c46d91b7SGregory Neil Shapiro (char *)db_val.data);
6853299c2f1SGregory Neil Shapiro
6863299c2f1SGregory Neil Shapiro }
6873299c2f1SGregory Neil Shapiro (void) cursor->smdbc_close(cursor);
6883299c2f1SGregory Neil Shapiro }
6893299c2f1SGregory Neil Shapiro else
6903299c2f1SGregory Neil Shapiro {
6913299c2f1SGregory Neil Shapiro lineno = 0;
69212ed1c7cSGregory Neil Shapiro while (sm_io_fgets(smioin, SM_TIME_DEFAULT, ibuf, sizeof ibuf)
693552d4955SGregory Neil Shapiro >= 0)
694c2aa98e2SPeter Wemm {
695c2aa98e2SPeter Wemm register char *p;
696c2aa98e2SPeter Wemm
697c2aa98e2SPeter Wemm lineno++;
698c2aa98e2SPeter Wemm
699c2aa98e2SPeter Wemm /*
700c2aa98e2SPeter Wemm ** Parse the line.
701c2aa98e2SPeter Wemm */
702c2aa98e2SPeter Wemm
703c2aa98e2SPeter Wemm p = strchr(ibuf, '\n');
704c2aa98e2SPeter Wemm if (p != NULL)
705c2aa98e2SPeter Wemm *p = '\0';
70612ed1c7cSGregory Neil Shapiro else if (!sm_io_eof(smioin))
707c2aa98e2SPeter Wemm {
70812ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
70912ed1c7cSGregory Neil Shapiro "%s: %s: line %u: line too long (%ld bytes max)\n",
71012ed1c7cSGregory Neil Shapiro progname, mapname, lineno,
71112ed1c7cSGregory Neil Shapiro (long) sizeof ibuf);
7123299c2f1SGregory Neil Shapiro exitstat = EX_DATAERR;
713c2aa98e2SPeter Wemm continue;
714c2aa98e2SPeter Wemm }
715c2aa98e2SPeter Wemm
71612ed1c7cSGregory Neil Shapiro if (ibuf[0] == '\0' || ibuf[0] == comment)
717c2aa98e2SPeter Wemm continue;
7185b0945b5SGregory Neil Shapiro if (sep == '\0' && ISASCII(ibuf[0]) && isspace(ibuf[0]))
719c2aa98e2SPeter Wemm {
72012ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
72112ed1c7cSGregory Neil Shapiro "%s: %s: line %u: syntax error (leading space)\n",
722c2aa98e2SPeter Wemm progname, mapname, lineno);
7233299c2f1SGregory Neil Shapiro exitstat = EX_DATAERR;
724c2aa98e2SPeter Wemm continue;
725c2aa98e2SPeter Wemm }
726c2aa98e2SPeter Wemm
7273299c2f1SGregory Neil Shapiro memset(&db_key, '\0', sizeof db_key);
7283299c2f1SGregory Neil Shapiro memset(&db_val, '\0', sizeof db_val);
729c46d91b7SGregory Neil Shapiro db_key.data = ibuf;
7303299c2f1SGregory Neil Shapiro
7312fb4f839SGregory Neil Shapiro #if USE_EAI
7322fb4f839SGregory Neil Shapiro db_key.size = 0;
7332fb4f839SGregory Neil Shapiro if (foldcase)
7342fb4f839SGregory Neil Shapiro {
7352fb4f839SGregory Neil Shapiro for (p = ibuf; *p != '\0' && !ISSEP(*p); p++)
7362fb4f839SGregory Neil Shapiro {
7372fb4f839SGregory Neil Shapiro if (!ISASCII(*p))
7382fb4f839SGregory Neil Shapiro ascii = false;
7392fb4f839SGregory Neil Shapiro }
7402fb4f839SGregory Neil Shapiro if (!ascii)
7412fb4f839SGregory Neil Shapiro {
7422fb4f839SGregory Neil Shapiro char sep;
7432fb4f839SGregory Neil Shapiro char *lkey;
7442fb4f839SGregory Neil Shapiro
7452fb4f839SGregory Neil Shapiro sep = *p;
7462fb4f839SGregory Neil Shapiro *p = '\0';
7472fb4f839SGregory Neil Shapiro
7482fb4f839SGregory Neil Shapiro lkey = sm_lowercase(ibuf);
7492fb4f839SGregory Neil Shapiro db_key.data = lkey;
7502fb4f839SGregory Neil Shapiro db_key.size = strlen(lkey);
7512fb4f839SGregory Neil Shapiro *p = sep;
7522fb4f839SGregory Neil Shapiro }
7532fb4f839SGregory Neil Shapiro }
7542fb4f839SGregory Neil Shapiro if (ascii)
7552fb4f839SGregory Neil Shapiro #endif /* USE_EAI */
7562fb4f839SGregory Neil Shapiro /* NOTE: see if () above! */
7572fb4f839SGregory Neil Shapiro for (p = ibuf; *p != '\0' && !ISSEP(*p); p++)
758c2aa98e2SPeter Wemm {
7595b0945b5SGregory Neil Shapiro if (foldcase && ISASCII(*p) && isupper(*p))
760c2aa98e2SPeter Wemm *p = tolower(*p);
761c2aa98e2SPeter Wemm }
7622fb4f839SGregory Neil Shapiro #if USE_EAI
7632fb4f839SGregory Neil Shapiro if (0 == db_key.size)
7642fb4f839SGregory Neil Shapiro #endif
765c46d91b7SGregory Neil Shapiro db_key.size = p - ibuf;
766c2aa98e2SPeter Wemm if (inclnull)
767c46d91b7SGregory Neil Shapiro db_key.size++;
7683299c2f1SGregory Neil Shapiro
769c2aa98e2SPeter Wemm if (*p != '\0')
770c2aa98e2SPeter Wemm *p++ = '\0';
77112ed1c7cSGregory Neil Shapiro while (*p != '\0' && ISSEP(*p))
772c2aa98e2SPeter Wemm p++;
773*d39bd2c1SGregory Neil Shapiro #if _FFR_MM_ALIASES
774*d39bd2c1SGregory Neil Shapiro while (aliases && *p != '\0' && ISSPACE(*p))
775*d39bd2c1SGregory Neil Shapiro p++;
776*d39bd2c1SGregory Neil Shapiro #endif
7773299c2f1SGregory Neil Shapiro if (!allowempty && *p == '\0')
778c2aa98e2SPeter Wemm {
77912ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
78012ed1c7cSGregory Neil Shapiro "%s: %s: line %u: no RHS for LHS %s\n",
7813299c2f1SGregory Neil Shapiro progname, mapname, lineno,
782c46d91b7SGregory Neil Shapiro (char *) db_key.data);
7833299c2f1SGregory Neil Shapiro exitstat = EX_DATAERR;
784c2aa98e2SPeter Wemm continue;
785c2aa98e2SPeter Wemm }
7863299c2f1SGregory Neil Shapiro
787c46d91b7SGregory Neil Shapiro db_val.data = p;
788c46d91b7SGregory Neil Shapiro db_val.size = strlen(p);
789c2aa98e2SPeter Wemm if (inclnull)
790c46d91b7SGregory Neil Shapiro db_val.size++;
791c2aa98e2SPeter Wemm
792c2aa98e2SPeter Wemm /*
793c2aa98e2SPeter Wemm ** Do the database insert.
794c2aa98e2SPeter Wemm */
795c2aa98e2SPeter Wemm
796*d39bd2c1SGregory Neil Shapiro db_put(database, db_key, db_val, putflags, mapname,
797*d39bd2c1SGregory Neil Shapiro lineno, progname);
798*d39bd2c1SGregory Neil Shapiro }
799*d39bd2c1SGregory Neil Shapiro #if _FFR_MM_ALIASES
800*d39bd2c1SGregory Neil Shapiro if (aliases)
801c2aa98e2SPeter Wemm {
802*d39bd2c1SGregory Neil Shapiro char magic[2] = "@";
803c2aa98e2SPeter Wemm
804*d39bd2c1SGregory Neil Shapiro db_key.data = magic;
805*d39bd2c1SGregory Neil Shapiro db_val.data = magic;
806*d39bd2c1SGregory Neil Shapiro db_key.size = 1;
807*d39bd2c1SGregory Neil Shapiro db_val.size = 1;
808*d39bd2c1SGregory Neil Shapiro db_put(database, db_key, db_val, putflags, mapname, -1,
809*d39bd2c1SGregory Neil Shapiro progname);
810c2aa98e2SPeter Wemm }
811*d39bd2c1SGregory Neil Shapiro #endif /* _FFR_MM_ALIASES */
812c2aa98e2SPeter Wemm }
813c2aa98e2SPeter Wemm
8142fb4f839SGregory Neil Shapiro #if _FFR_TESTS
8152fb4f839SGregory Neil Shapiro if (slp > 0)
8162fb4f839SGregory Neil Shapiro sleep(slp);
8172fb4f839SGregory Neil Shapiro #endif
8182fb4f839SGregory Neil Shapiro
819c2aa98e2SPeter Wemm /*
820c2aa98e2SPeter Wemm ** Now close the database.
821c2aa98e2SPeter Wemm */
822c2aa98e2SPeter Wemm
8233299c2f1SGregory Neil Shapiro errno = database->smdb_close(database);
8243299c2f1SGregory Neil Shapiro if (errno != SMDBE_OK)
825c2aa98e2SPeter Wemm {
82612ed1c7cSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
82712ed1c7cSGregory Neil Shapiro "%s: close(%s): %s\n",
82812ed1c7cSGregory Neil Shapiro progname, mapname, sm_errstring(errno));
829c2aa98e2SPeter Wemm exitstat = EX_IOERR;
830c2aa98e2SPeter Wemm }
8313299c2f1SGregory Neil Shapiro smdb_free_database(database);
832c2aa98e2SPeter Wemm
833c2aa98e2SPeter Wemm exit(exitstat);
83412ed1c7cSGregory Neil Shapiro
8353299c2f1SGregory Neil Shapiro /* NOTREACHED */
8363299c2f1SGregory Neil Shapiro return exitstat;
837c2aa98e2SPeter Wemm }
838