158162a73SPeter Wemm /*
228fbd282SGregory Neil Shapiro * Copyright (c) 1998-2002, 2004, 2008, 2020 Proofpoint, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro * All rights reserved.
4c2aa98e2SPeter Wemm * Copyright (c) 1992 Eric P. Allman. All rights reserved.
558162a73SPeter Wemm * Copyright (c) 1992, 1993
658162a73SPeter Wemm * The Regents of the University of California. All rights reserved.
758162a73SPeter 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.
1158162a73SPeter Wemm *
1258162a73SPeter Wemm */
1358162a73SPeter Wemm
1440266059SGregory Neil Shapiro #include <sm/gen.h>
1540266059SGregory Neil Shapiro
1640266059SGregory Neil Shapiro SM_IDSTR(copyright,
17c1bfccf7SGregory Neil Shapiro "@(#) Copyright (c) 1998-2002, 2004 Proofpoint, Inc. and its suppliers.\n\
1806f25ae9SGregory Neil Shapiro All rights reserved.\n\
1906f25ae9SGregory Neil Shapiro Copyright (c) 1992 Eric P. Allman. All rights reserved.\n\
2006f25ae9SGregory Neil Shapiro Copyright (c) 1992, 1993\n\
2140266059SGregory Neil Shapiro The Regents of the University of California. All rights reserved.\n")
2206f25ae9SGregory Neil Shapiro
234a67213fSGregory Neil Shapiro SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.183 2013-11-22 20:51:52 ca Exp $")
2406f25ae9SGregory Neil Shapiro
2558162a73SPeter Wemm
2658162a73SPeter Wemm #include <sys/types.h>
2758162a73SPeter Wemm #ifndef ISC_UNIX
2858162a73SPeter Wemm # include <sys/file.h>
29cee0d44aSGregory Neil Shapiro #endif
3006f25ae9SGregory Neil Shapiro #include <ctype.h>
3106f25ae9SGregory Neil Shapiro #include <stdlib.h>
3206f25ae9SGregory Neil Shapiro #include <unistd.h>
3306f25ae9SGregory Neil Shapiro #ifdef EX_OK
3406f25ae9SGregory Neil Shapiro # undef EX_OK /* unistd.h may have another use for this */
35cee0d44aSGregory Neil Shapiro #endif
3606f25ae9SGregory Neil Shapiro #include <sysexits.h>
3706f25ae9SGregory Neil Shapiro #include <sendmail/sendmail.h>
38cee0d44aSGregory Neil Shapiro #include <sm/path.h>
3906f25ae9SGregory Neil Shapiro #include <sendmail/pathnames.h>
4006f25ae9SGregory Neil Shapiro #include <libsmdb/smdb.h>
4128fbd282SGregory Neil Shapiro #if USE_EAI
4228fbd282SGregory Neil Shapiro # include <sm/ixlen.h>
4328fbd282SGregory Neil Shapiro #endif
4458162a73SPeter Wemm
45f3a1fc34SPeter Wemm uid_t RealUid;
46f3a1fc34SPeter Wemm gid_t RealGid;
47f3a1fc34SPeter Wemm char *RealUserName;
48f3a1fc34SPeter Wemm uid_t RunAsUid;
49*ffb83623SGregory Neil Shapiro gid_t RunAsGid;
50f3a1fc34SPeter Wemm char *RunAsUserName;
51f3a1fc34SPeter Wemm int Verbose = 2;
5240266059SGregory Neil Shapiro bool DontInitGroups = false;
53065a643dSPeter Wemm uid_t TrustedUid = 0;
5406f25ae9SGregory Neil Shapiro BITMAP256 DontBlameSendmail;
55f3a1fc34SPeter Wemm
56850ef5aeSGregory Neil Shapiro static bool verbose = false;
57850ef5aeSGregory Neil Shapiro static int exitstat;
58850ef5aeSGregory Neil Shapiro
5958162a73SPeter Wemm #define BUFSIZE 1024
60cee0d44aSGregory Neil Shapiro #define ISASCII(c) isascii((unsigned char)(c))
61850ef5aeSGregory Neil Shapiro #define ISSPACE(c) (ISASCII(c) && isspace(c))
62cee0d44aSGregory Neil Shapiro #define ISSEP(c) (sep == '\0' ? ISASCII(c) && isspace(c) : (c) == sep)
6306f25ae9SGregory Neil Shapiro
64cee0d44aSGregory Neil Shapiro static void usage __P((const char *));
65cee0d44aSGregory Neil Shapiro static char *readcf __P((const char *, char *, bool));
66850ef5aeSGregory Neil Shapiro static void db_put __P((SMDB_DATABASE *, SMDB_DBENT, SMDB_DBENT, int, const char *, int, const char *));
67b6bacd31SGregory Neil Shapiro
6806f25ae9SGregory Neil Shapiro static void
usage(progname)6906f25ae9SGregory Neil Shapiro usage(progname)
70cee0d44aSGregory Neil Shapiro const char *progname;
7106f25ae9SGregory Neil Shapiro {
7240266059SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
73e92d3f3fSGregory Neil Shapiro "Usage: %s [-C cffile] [-N] [-c cachesize] [-D commentchar]\n",
7440266059SGregory Neil Shapiro progname);
75e92d3f3fSGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
76850ef5aeSGregory Neil Shapiro " %*s [-d] [-e] [-f] [-i type] [-l] [-o] [-r] [-s] [-t delimiter]\n",
77e92d3f3fSGregory Neil Shapiro (int) strlen(progname), "");
7828fbd282SGregory Neil Shapiro #if _FFR_TESTS
7928fbd282SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
8028fbd282SGregory Neil Shapiro " %*s [-S n]\n",
8128fbd282SGregory Neil Shapiro (int) strlen(progname), "");
8228fbd282SGregory Neil Shapiro #endif
83e92d3f3fSGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
84e92d3f3fSGregory Neil Shapiro " %*s [-u] [-v] type mapname\n",
85e92d3f3fSGregory Neil Shapiro (int) strlen(progname), "");
8606f25ae9SGregory Neil Shapiro exit(EX_USAGE);
8706f25ae9SGregory Neil Shapiro }
8858162a73SPeter Wemm
89cee0d44aSGregory Neil Shapiro /*
90850ef5aeSGregory Neil Shapiro ** DB_PUT -- do the DB insert
91850ef5aeSGregory Neil Shapiro **
92850ef5aeSGregory Neil Shapiro ** Parameters:
93850ef5aeSGregory Neil Shapiro ** database -- DB to use
94850ef5aeSGregory Neil Shapiro ** db_key -- key
95850ef5aeSGregory Neil Shapiro ** db_val -- value
96850ef5aeSGregory Neil Shapiro ** putflags -- flags for smdb_put()
97850ef5aeSGregory Neil Shapiro ** mapname -- name of map (for error reporting)
98850ef5aeSGregory Neil Shapiro ** lineno -- line number (for error reporting)
99850ef5aeSGregory Neil Shapiro ** progname -- name of program (for error reporting)
100850ef5aeSGregory Neil Shapiro **
101850ef5aeSGregory Neil Shapiro ** Returns:
102850ef5aeSGregory Neil Shapiro ** none.
103850ef5aeSGregory Neil Shapiro **
104850ef5aeSGregory Neil Shapiro ** Side effects:
105850ef5aeSGregory Neil Shapiro ** Sets exitstat so makemap exits with error if put fails
106850ef5aeSGregory Neil Shapiro */
107850ef5aeSGregory Neil Shapiro
108850ef5aeSGregory Neil Shapiro static void
db_put(database,db_key,db_val,putflags,mapname,lineno,progname)109850ef5aeSGregory Neil Shapiro db_put(database, db_key, db_val, putflags, mapname, lineno, progname)
110850ef5aeSGregory Neil Shapiro SMDB_DATABASE *database;
111850ef5aeSGregory Neil Shapiro SMDB_DBENT db_key, db_val;
112850ef5aeSGregory Neil Shapiro int putflags;
113850ef5aeSGregory Neil Shapiro const char *mapname;
114850ef5aeSGregory Neil Shapiro int lineno;
115850ef5aeSGregory Neil Shapiro const char *progname;
116850ef5aeSGregory Neil Shapiro {
117850ef5aeSGregory Neil Shapiro int errcode;
118850ef5aeSGregory Neil Shapiro
119850ef5aeSGregory Neil Shapiro if (verbose)
120850ef5aeSGregory Neil Shapiro {
121850ef5aeSGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
122850ef5aeSGregory Neil Shapiro "key=`%s', val=`%s'\n",
123850ef5aeSGregory Neil Shapiro (char *) db_key.data,
124850ef5aeSGregory Neil Shapiro (char *) db_val.data);
125850ef5aeSGregory Neil Shapiro }
126850ef5aeSGregory Neil Shapiro
127850ef5aeSGregory Neil Shapiro errcode = database->smdb_put(database, &db_key, &db_val, putflags);
128850ef5aeSGregory Neil Shapiro if (0 == errcode)
129850ef5aeSGregory Neil Shapiro return;
130850ef5aeSGregory Neil Shapiro
131850ef5aeSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s: %s: ",
132850ef5aeSGregory Neil Shapiro progname, mapname);
133850ef5aeSGregory Neil Shapiro if (lineno >= 0)
134850ef5aeSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "line %u: ",
135850ef5aeSGregory Neil Shapiro lineno);
136850ef5aeSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "key %s: ",
137850ef5aeSGregory Neil Shapiro (char *) db_key.data);
138850ef5aeSGregory Neil Shapiro if (SMDBE_KEY_EXIST == errcode)
139850ef5aeSGregory Neil Shapiro {
140850ef5aeSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
141850ef5aeSGregory Neil Shapiro "duplicate key\n");
142850ef5aeSGregory Neil Shapiro exitstat = EX_DATAERR;
143850ef5aeSGregory Neil Shapiro }
144850ef5aeSGregory Neil Shapiro else
145850ef5aeSGregory Neil Shapiro {
146850ef5aeSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
147850ef5aeSGregory Neil Shapiro "put error: %s\n", sm_errstring(errcode));
148850ef5aeSGregory Neil Shapiro exitstat = EX_IOERR;
149850ef5aeSGregory Neil Shapiro }
150850ef5aeSGregory Neil Shapiro }
151850ef5aeSGregory Neil Shapiro
152850ef5aeSGregory Neil Shapiro /*
153cee0d44aSGregory Neil Shapiro ** READCF -- read some settings from configuration file.
154cee0d44aSGregory Neil Shapiro **
155cee0d44aSGregory Neil Shapiro ** Parameters:
156cee0d44aSGregory Neil Shapiro ** cfile -- configuration file name.
157cee0d44aSGregory Neil Shapiro ** mapfile -- file name of map to look up (if not NULL/empty)
158cee0d44aSGregory Neil Shapiro ** Note: this finds the first match, so in case someone
159cee0d44aSGregory Neil Shapiro ** uses the same map file for different maps, they are
160cee0d44aSGregory Neil Shapiro ** hopefully using the same map type.
161cee0d44aSGregory Neil Shapiro ** fullpath -- compare the full paths or just the "basename"s?
162cee0d44aSGregory Neil Shapiro ** (even excluding any .ext !)
163cee0d44aSGregory Neil Shapiro **
164cee0d44aSGregory Neil Shapiro ** Returns:
165cee0d44aSGregory Neil Shapiro ** pointer to map class name (static!)
166cee0d44aSGregory Neil Shapiro */
167cee0d44aSGregory Neil Shapiro
168cee0d44aSGregory Neil Shapiro static char *
readcf(cfile,mapfile,fullpath)169cee0d44aSGregory Neil Shapiro readcf(cfile, mapfile, fullpath)
170cee0d44aSGregory Neil Shapiro const char *cfile;
171cee0d44aSGregory Neil Shapiro char *mapfile;
172cee0d44aSGregory Neil Shapiro bool fullpath;
173cee0d44aSGregory Neil Shapiro {
174cee0d44aSGregory Neil Shapiro SM_FILE_T *cfp;
175cee0d44aSGregory Neil Shapiro char buf[MAXLINE];
176cee0d44aSGregory Neil Shapiro static char classbuf[MAXLINE];
177850ef5aeSGregory Neil Shapiro char *classname, *mapname;
178cee0d44aSGregory Neil Shapiro char *p;
179cee0d44aSGregory Neil Shapiro
180cee0d44aSGregory Neil Shapiro if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile,
181cee0d44aSGregory Neil Shapiro SM_IO_RDONLY, NULL)) == NULL)
182cee0d44aSGregory Neil Shapiro {
183cee0d44aSGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
184cee0d44aSGregory Neil Shapiro "makemap: %s: %s\n",
185cee0d44aSGregory Neil Shapiro cfile, sm_errstring(errno));
186cee0d44aSGregory Neil Shapiro exit(EX_NOINPUT);
187cee0d44aSGregory Neil Shapiro }
188cee0d44aSGregory Neil Shapiro classname = NULL;
189cee0d44aSGregory Neil Shapiro classbuf[0] = '\0';
190cee0d44aSGregory Neil Shapiro
191850ef5aeSGregory Neil Shapiro mapname = mapfile;
192cee0d44aSGregory Neil Shapiro if (!fullpath && mapfile != NULL)
193cee0d44aSGregory Neil Shapiro {
194cee0d44aSGregory Neil Shapiro p = strrchr(mapfile, '/');
195cee0d44aSGregory Neil Shapiro if (p != NULL)
196cee0d44aSGregory Neil Shapiro mapfile = ++p;
197850ef5aeSGregory Neil Shapiro mapname = strdup(mapfile);
198850ef5aeSGregory Neil Shapiro if (NULL == mapname)
199850ef5aeSGregory Neil Shapiro {
200850ef5aeSGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
201850ef5aeSGregory Neil Shapiro "makemap: strdup(%s) failed: %s\n",
202850ef5aeSGregory Neil Shapiro mapfile, sm_errstring(errno));
203850ef5aeSGregory Neil Shapiro exit(EX_OSERR);
204850ef5aeSGregory Neil Shapiro }
205850ef5aeSGregory Neil Shapiro if ((p = strchr(mapname, '.')) != NULL)
206cee0d44aSGregory Neil Shapiro *p = '\0';
207cee0d44aSGregory Neil Shapiro }
208cee0d44aSGregory Neil Shapiro
209cee0d44aSGregory Neil Shapiro while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
210cee0d44aSGregory Neil Shapiro {
211cee0d44aSGregory Neil Shapiro char *b;
212cee0d44aSGregory Neil Shapiro
213cee0d44aSGregory Neil Shapiro if ((b = strchr(buf, '\n')) != NULL)
214cee0d44aSGregory Neil Shapiro *b = '\0';
215cee0d44aSGregory Neil Shapiro
216cee0d44aSGregory Neil Shapiro b = buf;
217cee0d44aSGregory Neil Shapiro switch (*b++)
218cee0d44aSGregory Neil Shapiro {
219cee0d44aSGregory Neil Shapiro case 'O': /* option */
220cee0d44aSGregory Neil Shapiro #if HASFCHOWN
221cee0d44aSGregory Neil Shapiro if (strncasecmp(b, " TrustedUser", 12) == 0 &&
222cee0d44aSGregory Neil Shapiro !(ISASCII(b[12]) && isalnum(b[12])))
223cee0d44aSGregory Neil Shapiro {
224cee0d44aSGregory Neil Shapiro b = strchr(b, '=');
225cee0d44aSGregory Neil Shapiro if (b == NULL)
226cee0d44aSGregory Neil Shapiro continue;
227cee0d44aSGregory Neil Shapiro while (ISASCII(*++b) && isspace(*b))
228cee0d44aSGregory Neil Shapiro continue;
229cee0d44aSGregory Neil Shapiro if (ISASCII(*b) && isdigit(*b))
230cee0d44aSGregory Neil Shapiro TrustedUid = atoi(b);
231cee0d44aSGregory Neil Shapiro else
232cee0d44aSGregory Neil Shapiro {
233cee0d44aSGregory Neil Shapiro struct passwd *pw;
234cee0d44aSGregory Neil Shapiro
235cee0d44aSGregory Neil Shapiro TrustedUid = 0;
236cee0d44aSGregory Neil Shapiro pw = getpwnam(b);
237cee0d44aSGregory Neil Shapiro if (pw == NULL)
238cee0d44aSGregory Neil Shapiro (void) sm_io_fprintf(smioerr,
239cee0d44aSGregory Neil Shapiro SM_TIME_DEFAULT,
240cee0d44aSGregory Neil Shapiro "TrustedUser: unknown user %s\n", b);
241cee0d44aSGregory Neil Shapiro else
242cee0d44aSGregory Neil Shapiro TrustedUid = pw->pw_uid;
243cee0d44aSGregory Neil Shapiro }
244cee0d44aSGregory Neil Shapiro
245cee0d44aSGregory Neil Shapiro # ifdef UID_MAX
246cee0d44aSGregory Neil Shapiro if (TrustedUid > UID_MAX)
247cee0d44aSGregory Neil Shapiro {
248cee0d44aSGregory Neil Shapiro (void) sm_io_fprintf(smioerr,
249cee0d44aSGregory Neil Shapiro SM_TIME_DEFAULT,
250cee0d44aSGregory Neil Shapiro "TrustedUser: uid value (%ld) > UID_MAX (%ld)",
251cee0d44aSGregory Neil Shapiro (long) TrustedUid,
252cee0d44aSGregory Neil Shapiro (long) UID_MAX);
253cee0d44aSGregory Neil Shapiro TrustedUid = 0;
254cee0d44aSGregory Neil Shapiro }
255cee0d44aSGregory Neil Shapiro # endif /* UID_MAX */
256cee0d44aSGregory Neil Shapiro }
257cee0d44aSGregory Neil Shapiro #endif /* HASFCHOWN */
258cee0d44aSGregory Neil Shapiro break;
259cee0d44aSGregory Neil Shapiro
260cee0d44aSGregory Neil Shapiro case 'K': /* Keyfile (map) */
261cee0d44aSGregory Neil Shapiro if (classname != NULL) /* found it already */
262cee0d44aSGregory Neil Shapiro continue;
263850ef5aeSGregory Neil Shapiro if (mapname == NULL || *mapname == '\0')
264cee0d44aSGregory Neil Shapiro continue;
265cee0d44aSGregory Neil Shapiro
266cee0d44aSGregory Neil Shapiro /* cut off trailing spaces */
267850ef5aeSGregory Neil Shapiro for (p = buf + strlen(buf) - 1;
268850ef5aeSGregory Neil Shapiro ISASCII(*p) && isspace(*p) && p > buf; p--)
269cee0d44aSGregory Neil Shapiro *p = '\0';
270cee0d44aSGregory Neil Shapiro
271cee0d44aSGregory Neil Shapiro /* find the last argument */
272cee0d44aSGregory Neil Shapiro p = strrchr(buf, ' ');
273cee0d44aSGregory Neil Shapiro if (p == NULL)
274cee0d44aSGregory Neil Shapiro continue;
275850ef5aeSGregory Neil Shapiro b = strstr(p, mapname);
276cee0d44aSGregory Neil Shapiro if (b == NULL)
277cee0d44aSGregory Neil Shapiro continue;
278cee0d44aSGregory Neil Shapiro if (b <= buf)
279cee0d44aSGregory Neil Shapiro continue;
280cee0d44aSGregory Neil Shapiro if (!fullpath)
281cee0d44aSGregory Neil Shapiro {
282cee0d44aSGregory Neil Shapiro p = strrchr(b, '.');
283cee0d44aSGregory Neil Shapiro if (p != NULL)
284cee0d44aSGregory Neil Shapiro *p = '\0';
285cee0d44aSGregory Neil Shapiro }
286cee0d44aSGregory Neil Shapiro
287cee0d44aSGregory Neil Shapiro /* allow trailing white space? */
288850ef5aeSGregory Neil Shapiro if (strcmp(mapname, b) != 0)
289cee0d44aSGregory Neil Shapiro continue;
290cee0d44aSGregory Neil Shapiro /* SM_ASSERT(b > buf); */
291cee0d44aSGregory Neil Shapiro --b;
292cee0d44aSGregory Neil Shapiro if (!ISASCII(*b))
293cee0d44aSGregory Neil Shapiro continue;
294cee0d44aSGregory Neil Shapiro if (!isspace(*b) && fullpath)
295cee0d44aSGregory Neil Shapiro continue;
296cee0d44aSGregory Neil Shapiro if (!fullpath && !(SM_IS_DIR_DELIM(*b) || isspace(*b)))
297cee0d44aSGregory Neil Shapiro continue;
298cee0d44aSGregory Neil Shapiro
299cee0d44aSGregory Neil Shapiro /* basically from readcf.c */
300cee0d44aSGregory Neil Shapiro for (b = buf + 1; ISASCII(*b) && isspace(*b); b++)
301cee0d44aSGregory Neil Shapiro ;
302cee0d44aSGregory Neil Shapiro if (!(ISASCII(*b) && isalnum(*b)))
303cee0d44aSGregory Neil Shapiro {
304cee0d44aSGregory Neil Shapiro /* syserr("readcf: config K line: no map name"); */
305cee0d44aSGregory Neil Shapiro return NULL;
306cee0d44aSGregory Neil Shapiro }
307cee0d44aSGregory Neil Shapiro
308cee0d44aSGregory Neil Shapiro while ((ISASCII(*++b) && isalnum(*b)) || *b == '_' || *b == '.')
309cee0d44aSGregory Neil Shapiro ;
310cee0d44aSGregory Neil Shapiro if (*b != '\0')
311cee0d44aSGregory Neil Shapiro *b++ = '\0';
312cee0d44aSGregory Neil Shapiro while (ISASCII(*b) && isspace(*b))
313cee0d44aSGregory Neil Shapiro b++;
314cee0d44aSGregory Neil Shapiro if (!(ISASCII(*b) && isalnum(*b)))
315cee0d44aSGregory Neil Shapiro {
316cee0d44aSGregory Neil Shapiro /* syserr("readcf: config K line, map %s: no map class", b); */
317cee0d44aSGregory Neil Shapiro return NULL;
318cee0d44aSGregory Neil Shapiro }
319cee0d44aSGregory Neil Shapiro classname = b;
320cee0d44aSGregory Neil Shapiro while (ISASCII(*++b) && isalnum(*b))
321cee0d44aSGregory Neil Shapiro ;
322cee0d44aSGregory Neil Shapiro if (*b != '\0')
323cee0d44aSGregory Neil Shapiro *b++ = '\0';
324cee0d44aSGregory Neil Shapiro (void) sm_strlcpy(classbuf, classname, sizeof classbuf);
325cee0d44aSGregory Neil Shapiro break;
326cee0d44aSGregory Neil Shapiro
327cee0d44aSGregory Neil Shapiro default:
328cee0d44aSGregory Neil Shapiro continue;
329cee0d44aSGregory Neil Shapiro }
330cee0d44aSGregory Neil Shapiro }
331cee0d44aSGregory Neil Shapiro (void) sm_io_close(cfp, SM_TIME_DEFAULT);
332cee0d44aSGregory Neil Shapiro
333850ef5aeSGregory Neil Shapiro /* not really needed because it is just a "one time leak" */
334850ef5aeSGregory Neil Shapiro if (mapname != mapfile && mapname != NULL)
335850ef5aeSGregory Neil Shapiro {
336850ef5aeSGregory Neil Shapiro free(mapname);
337850ef5aeSGregory Neil Shapiro mapname = NULL;
338850ef5aeSGregory Neil Shapiro }
339cee0d44aSGregory Neil Shapiro return classbuf;
340cee0d44aSGregory Neil Shapiro }
341cee0d44aSGregory Neil Shapiro
342c2aa98e2SPeter Wemm int
main(argc,argv)34358162a73SPeter Wemm main(argc, argv)
34458162a73SPeter Wemm int argc;
34558162a73SPeter Wemm char **argv;
34658162a73SPeter Wemm {
34758162a73SPeter Wemm char *progname;
348c2aa98e2SPeter Wemm char *cfile;
34940266059SGregory Neil Shapiro bool inclnull = false;
35040266059SGregory Neil Shapiro bool notrunc = false;
35140266059SGregory Neil Shapiro bool allowreplace = false;
35240266059SGregory Neil Shapiro bool allowempty = false;
35340266059SGregory Neil Shapiro bool foldcase = true;
35440266059SGregory Neil Shapiro bool unmake = false;
355850ef5aeSGregory Neil Shapiro #if _FFR_MM_ALIASES
356850ef5aeSGregory Neil Shapiro /*
357850ef5aeSGregory Neil Shapiro ** NOTE: this does not work properly:
358850ef5aeSGregory Neil Shapiro ** sendmail does address rewriting which is not done here.
359850ef5aeSGregory Neil Shapiro */
360850ef5aeSGregory Neil Shapiro
361850ef5aeSGregory Neil Shapiro bool aliases = false;
362850ef5aeSGregory Neil Shapiro #endif
363cee0d44aSGregory Neil Shapiro bool didreadcf = false;
36406f25ae9SGregory Neil Shapiro char sep = '\0';
36540266059SGregory Neil Shapiro char comment = '#';
36658162a73SPeter Wemm int opt;
367065a643dSPeter Wemm char *typename = NULL;
368cee0d44aSGregory Neil Shapiro char *fallback = NULL;
369065a643dSPeter Wemm char *mapname = NULL;
37040266059SGregory Neil Shapiro unsigned int lineno;
37158162a73SPeter Wemm int mode;
37206f25ae9SGregory Neil Shapiro int smode;
373065a643dSPeter Wemm int putflags = 0;
37406f25ae9SGregory Neil Shapiro long sff = SFF_ROOTOK|SFF_REGONLY;
375c2aa98e2SPeter Wemm struct passwd *pw;
37606f25ae9SGregory Neil Shapiro SMDB_DATABASE *database;
37706f25ae9SGregory Neil Shapiro SMDB_CURSOR *cursor;
37806f25ae9SGregory Neil Shapiro SMDB_DBENT db_key, db_val;
37906f25ae9SGregory Neil Shapiro SMDB_DBPARAMS params;
38006f25ae9SGregory Neil Shapiro SMDB_USER_INFO user_info;
38158162a73SPeter Wemm char ibuf[BUFSIZE];
382f3a1fc34SPeter Wemm static char rnamebuf[MAXNAME]; /* holds RealUserName */
38358162a73SPeter Wemm extern char *optarg;
38458162a73SPeter Wemm extern int optind;
38528fbd282SGregory Neil Shapiro #if USE_EAI
38628fbd282SGregory Neil Shapiro bool ascii = true;
38728fbd282SGregory Neil Shapiro #endif
38828fbd282SGregory Neil Shapiro #if _FFR_TESTS
38928fbd282SGregory Neil Shapiro int slp = 0;
39028fbd282SGregory Neil Shapiro #endif
39158162a73SPeter Wemm
39206f25ae9SGregory Neil Shapiro memset(¶ms, '\0', sizeof params);
39306f25ae9SGregory Neil Shapiro params.smdbp_cache_size = 1024 * 1024;
39406f25ae9SGregory Neil Shapiro
39506f25ae9SGregory Neil Shapiro progname = strrchr(argv[0], '/');
39606f25ae9SGregory Neil Shapiro if (progname != NULL)
39706f25ae9SGregory Neil Shapiro progname++;
39806f25ae9SGregory Neil Shapiro else
39958162a73SPeter Wemm progname = argv[0];
40040266059SGregory Neil Shapiro cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
40158162a73SPeter Wemm
40206f25ae9SGregory Neil Shapiro clrbitmap(DontBlameSendmail);
403f3a1fc34SPeter Wemm RunAsUid = RealUid = getuid();
404f3a1fc34SPeter Wemm RunAsGid = RealGid = getgid();
405f3a1fc34SPeter Wemm pw = getpwuid(RealUid);
406f3a1fc34SPeter Wemm if (pw != NULL)
40740266059SGregory Neil Shapiro (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf);
408f3a1fc34SPeter Wemm else
40940266059SGregory Neil Shapiro (void) sm_snprintf(rnamebuf, sizeof rnamebuf,
41040266059SGregory Neil Shapiro "Unknown UID %d", (int) RealUid);
411f3a1fc34SPeter Wemm RunAsUserName = RealUserName = rnamebuf;
41206f25ae9SGregory Neil Shapiro user_info.smdbu_id = RunAsUid;
41306f25ae9SGregory Neil Shapiro user_info.smdbu_group_id = RunAsGid;
41440266059SGregory Neil Shapiro (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
41506f25ae9SGregory Neil Shapiro SMDB_MAX_USER_NAME_LEN);
416f3a1fc34SPeter Wemm
417cee0d44aSGregory Neil Shapiro #define OPTIONS "C:D:Nc:defi:Llorst:uvx"
418850ef5aeSGregory Neil Shapiro #if _FFR_MM_ALIASES
419850ef5aeSGregory Neil Shapiro # define A_OPTIONS "a"
420850ef5aeSGregory Neil Shapiro #else
421850ef5aeSGregory Neil Shapiro # define A_OPTIONS
422850ef5aeSGregory Neil Shapiro #endif
42328fbd282SGregory Neil Shapiro #if _FFR_TESTS
42428fbd282SGregory Neil Shapiro # define X_OPTIONS "S:"
42528fbd282SGregory Neil Shapiro #else
42628fbd282SGregory Neil Shapiro # define X_OPTIONS
42728fbd282SGregory Neil Shapiro #endif
428850ef5aeSGregory Neil Shapiro while ((opt = getopt(argc, argv, A_OPTIONS OPTIONS X_OPTIONS)) != -1)
42958162a73SPeter Wemm {
43058162a73SPeter Wemm switch (opt)
43158162a73SPeter Wemm {
432c2aa98e2SPeter Wemm case 'C':
433c2aa98e2SPeter Wemm cfile = optarg;
434c2aa98e2SPeter Wemm break;
435c2aa98e2SPeter Wemm
43658162a73SPeter Wemm case 'N':
43740266059SGregory Neil Shapiro inclnull = true;
43858162a73SPeter Wemm break;
43958162a73SPeter Wemm
440850ef5aeSGregory Neil Shapiro #if _FFR_MM_ALIASES
441850ef5aeSGregory Neil Shapiro case 'a':
442850ef5aeSGregory Neil Shapiro /* Note: this doesn't verify e-mail addresses */
443850ef5aeSGregory Neil Shapiro sep = ':';
444850ef5aeSGregory Neil Shapiro aliases = true;
445850ef5aeSGregory Neil Shapiro break;
446850ef5aeSGregory Neil Shapiro #endif
447850ef5aeSGregory Neil Shapiro
448fcf445deSPeter Wemm case 'c':
44906f25ae9SGregory Neil Shapiro params.smdbp_cache_size = atol(optarg);
450fcf445deSPeter Wemm break;
451fcf445deSPeter Wemm
45258162a73SPeter Wemm case 'd':
45340266059SGregory Neil Shapiro params.smdbp_allow_dup = true;
45406f25ae9SGregory Neil Shapiro break;
45506f25ae9SGregory Neil Shapiro
45606f25ae9SGregory Neil Shapiro case 'e':
45740266059SGregory Neil Shapiro allowempty = true;
45858162a73SPeter Wemm break;
45958162a73SPeter Wemm
46058162a73SPeter Wemm case 'f':
46140266059SGregory Neil Shapiro foldcase = false;
46258162a73SPeter Wemm break;
46358162a73SPeter Wemm
464cee0d44aSGregory Neil Shapiro case 'i':
465cee0d44aSGregory Neil Shapiro fallback =optarg;
466cee0d44aSGregory Neil Shapiro break;
467cee0d44aSGregory Neil Shapiro
46840266059SGregory Neil Shapiro case 'D':
46940266059SGregory Neil Shapiro comment = *optarg;
47040266059SGregory Neil Shapiro break;
47140266059SGregory Neil Shapiro
472cee0d44aSGregory Neil Shapiro case 'L':
473cee0d44aSGregory Neil Shapiro smdb_print_available_types(false);
474cee0d44aSGregory Neil Shapiro sm_io_fprintf(smioout, SM_TIME_DEFAULT,
475cee0d44aSGregory Neil Shapiro "cf\nCF\n");
476cee0d44aSGregory Neil Shapiro exit(EX_OK);
477cee0d44aSGregory Neil Shapiro break;
478cee0d44aSGregory Neil Shapiro
479065a643dSPeter Wemm case 'l':
480cee0d44aSGregory Neil Shapiro smdb_print_available_types(false);
481065a643dSPeter Wemm exit(EX_OK);
482065a643dSPeter Wemm break;
483065a643dSPeter Wemm
48458162a73SPeter Wemm case 'o':
48540266059SGregory Neil Shapiro notrunc = true;
48658162a73SPeter Wemm break;
48758162a73SPeter Wemm
48858162a73SPeter Wemm case 'r':
48940266059SGregory Neil Shapiro allowreplace = true;
49058162a73SPeter Wemm break;
49158162a73SPeter Wemm
49228fbd282SGregory Neil Shapiro #if _FFR_TESTS
49328fbd282SGregory Neil Shapiro case 'S':
49428fbd282SGregory Neil Shapiro slp = atoi(optarg);
49528fbd282SGregory Neil Shapiro break;
49628fbd282SGregory Neil Shapiro #endif
49728fbd282SGregory Neil Shapiro
498f3a1fc34SPeter Wemm case 's':
49906f25ae9SGregory Neil Shapiro setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail);
50006f25ae9SGregory Neil Shapiro setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail);
50106f25ae9SGregory Neil Shapiro setbitn(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail);
50206f25ae9SGregory Neil Shapiro setbitn(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail);
50306f25ae9SGregory Neil Shapiro break;
50406f25ae9SGregory Neil Shapiro
50506f25ae9SGregory Neil Shapiro case 't':
50606f25ae9SGregory Neil Shapiro if (optarg == NULL || *optarg == '\0')
50706f25ae9SGregory Neil Shapiro {
50840266059SGregory Neil Shapiro sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
50940266059SGregory Neil Shapiro "Invalid separator\n");
51006f25ae9SGregory Neil Shapiro break;
51106f25ae9SGregory Neil Shapiro }
51206f25ae9SGregory Neil Shapiro sep = *optarg;
51306f25ae9SGregory Neil Shapiro break;
51406f25ae9SGregory Neil Shapiro
51506f25ae9SGregory Neil Shapiro case 'u':
51640266059SGregory Neil Shapiro unmake = true;
517f3a1fc34SPeter Wemm break;
518f3a1fc34SPeter Wemm
51958162a73SPeter Wemm case 'v':
52040266059SGregory Neil Shapiro verbose = true;
52158162a73SPeter Wemm break;
52258162a73SPeter Wemm
523cee0d44aSGregory Neil Shapiro case 'x':
524cee0d44aSGregory Neil Shapiro smdb_print_available_types(true);
525cee0d44aSGregory Neil Shapiro exit(EX_OK);
526cee0d44aSGregory Neil Shapiro break;
527cee0d44aSGregory Neil Shapiro
52858162a73SPeter Wemm default:
52906f25ae9SGregory Neil Shapiro usage(progname);
53006f25ae9SGregory Neil Shapiro /* NOTREACHED */
53158162a73SPeter Wemm }
53258162a73SPeter Wemm }
53358162a73SPeter Wemm
53406f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
535c2aa98e2SPeter Wemm sff |= SFF_NOSLINK;
53606f25ae9SGregory Neil Shapiro if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
537c2aa98e2SPeter Wemm sff |= SFF_NOHLINK;
53806f25ae9SGregory Neil Shapiro if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
539c2aa98e2SPeter Wemm sff |= SFF_NOWLINK;
540c2aa98e2SPeter Wemm
54158162a73SPeter Wemm argc -= optind;
54258162a73SPeter Wemm argv += optind;
54358162a73SPeter Wemm if (argc != 2)
54406f25ae9SGregory Neil Shapiro {
54506f25ae9SGregory Neil Shapiro usage(progname);
54606f25ae9SGregory Neil Shapiro /* NOTREACHED */
54706f25ae9SGregory Neil Shapiro }
54858162a73SPeter Wemm else
54958162a73SPeter Wemm {
55058162a73SPeter Wemm typename = argv[0];
55158162a73SPeter Wemm mapname = argv[1];
55258162a73SPeter Wemm }
55358162a73SPeter Wemm
554cee0d44aSGregory Neil Shapiro #define TYPEFROMCF (strcasecmp(typename, "cf") == 0)
555cee0d44aSGregory Neil Shapiro #define FULLPATHFROMCF (strcmp(typename, "cf") == 0)
556cee0d44aSGregory Neil Shapiro
55706f25ae9SGregory Neil Shapiro #if HASFCHOWN
558cee0d44aSGregory Neil Shapiro if (geteuid() == 0)
559c1bfccf7SGregory Neil Shapiro {
560cee0d44aSGregory Neil Shapiro if (TYPEFROMCF)
561cee0d44aSGregory Neil Shapiro typename = readcf(cfile, mapname, FULLPATHFROMCF);
562c2aa98e2SPeter Wemm else
563cee0d44aSGregory Neil Shapiro (void) readcf(cfile, NULL, false);
564cee0d44aSGregory Neil Shapiro didreadcf = true;
565c2aa98e2SPeter Wemm }
56606f25ae9SGregory Neil Shapiro #endif /* HASFCHOWN */
56706f25ae9SGregory Neil Shapiro
56806f25ae9SGregory Neil Shapiro if (!params.smdbp_allow_dup && !allowreplace)
56906f25ae9SGregory Neil Shapiro putflags = SMDBF_NO_OVERWRITE;
57006f25ae9SGregory Neil Shapiro
57106f25ae9SGregory Neil Shapiro if (unmake)
57258162a73SPeter Wemm {
57306f25ae9SGregory Neil Shapiro mode = O_RDONLY;
57406f25ae9SGregory Neil Shapiro smode = S_IRUSR;
575c2aa98e2SPeter Wemm }
576606a9934SPeter Wemm else
577c2aa98e2SPeter Wemm {
57858162a73SPeter Wemm mode = O_RDWR;
57958162a73SPeter Wemm if (!notrunc)
58006f25ae9SGregory Neil Shapiro {
58158162a73SPeter Wemm mode |= O_CREAT|O_TRUNC;
58206f25ae9SGregory Neil Shapiro sff |= SFF_CREAT;
58358162a73SPeter Wemm }
58406f25ae9SGregory Neil Shapiro smode = S_IWUSR;
585ff37c899SPeter Wemm }
58606f25ae9SGregory Neil Shapiro
58706f25ae9SGregory Neil Shapiro params.smdbp_num_elements = 4096;
58806f25ae9SGregory Neil Shapiro
589cee0d44aSGregory Neil Shapiro if (!didreadcf && TYPEFROMCF)
590cee0d44aSGregory Neil Shapiro {
591cee0d44aSGregory Neil Shapiro typename = readcf(cfile, mapname, FULLPATHFROMCF);
592cee0d44aSGregory Neil Shapiro didreadcf = true;
593cee0d44aSGregory Neil Shapiro }
594cee0d44aSGregory Neil Shapiro if (didreadcf && (typename == NULL || *typename == '\0'))
595cee0d44aSGregory Neil Shapiro {
596cee0d44aSGregory Neil Shapiro if (fallback != NULL && *fallback != '\0')
597cee0d44aSGregory Neil Shapiro {
598cee0d44aSGregory Neil Shapiro typename = fallback;
599cee0d44aSGregory Neil Shapiro if (verbose)
600cee0d44aSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
601cee0d44aSGregory Neil Shapiro "%s: mapfile %s: not found in %s, using fallback %s\n",
602cee0d44aSGregory Neil Shapiro progname, mapname, cfile, fallback);
603cee0d44aSGregory Neil Shapiro }
604cee0d44aSGregory Neil Shapiro else
605cee0d44aSGregory Neil Shapiro {
606cee0d44aSGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
607cee0d44aSGregory Neil Shapiro "%s: mapfile %s: not found in %s\n",
608cee0d44aSGregory Neil Shapiro progname, mapname, cfile);
609cee0d44aSGregory Neil Shapiro exit(EX_DATAERR);
610cee0d44aSGregory Neil Shapiro }
611cee0d44aSGregory Neil Shapiro }
612cee0d44aSGregory Neil Shapiro
613cee0d44aSGregory Neil Shapiro /*
614cee0d44aSGregory Neil Shapiro ** Note: if "implicit" is selected it does not work like
615cee0d44aSGregory Neil Shapiro ** sendmail: it will just use the first available DB type,
616cee0d44aSGregory Neil Shapiro ** it won't try several (for -u) to find one that "works".
617cee0d44aSGregory Neil Shapiro */
618cee0d44aSGregory Neil Shapiro
61906f25ae9SGregory Neil Shapiro errno = smdb_open_database(&database, mapname, mode, smode, sff,
62006f25ae9SGregory Neil Shapiro typename, &user_info, ¶ms);
62106f25ae9SGregory Neil Shapiro if (errno != SMDBE_OK)
622f3a1fc34SPeter Wemm {
62306f25ae9SGregory Neil Shapiro char *hint;
62406f25ae9SGregory Neil Shapiro
62506f25ae9SGregory Neil Shapiro if (errno == SMDBE_UNSUPPORTED_DB_TYPE &&
62606f25ae9SGregory Neil Shapiro (hint = smdb_db_definition(typename)) != NULL)
62740266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
62806f25ae9SGregory Neil Shapiro "%s: Need to recompile with -D%s for %s support\n",
62906f25ae9SGregory Neil Shapiro progname, hint, typename);
63006f25ae9SGregory Neil Shapiro else
63140266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
63206f25ae9SGregory Neil Shapiro "%s: error opening type %s map %s: %s\n",
63340266059SGregory Neil Shapiro progname, typename, mapname,
63440266059SGregory Neil Shapiro sm_errstring(errno));
635f3a1fc34SPeter Wemm exit(EX_CANTCREAT);
636f3a1fc34SPeter Wemm }
63706f25ae9SGregory Neil Shapiro
63806f25ae9SGregory Neil Shapiro (void) database->smdb_sync(database, 0);
63906f25ae9SGregory Neil Shapiro
64042e5d165SGregory Neil Shapiro if (!unmake && geteuid() == 0 && TrustedUid != 0)
641c2aa98e2SPeter Wemm {
64206f25ae9SGregory Neil Shapiro errno = database->smdb_set_owner(database, TrustedUid, -1);
64306f25ae9SGregory Neil Shapiro if (errno != SMDBE_OK)
644c2aa98e2SPeter Wemm {
64540266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
64606f25ae9SGregory Neil Shapiro "WARNING: ownership change on %s failed %s",
64740266059SGregory Neil Shapiro mapname, sm_errstring(errno));
648c2aa98e2SPeter Wemm }
649c2aa98e2SPeter Wemm }
65058162a73SPeter Wemm
65158162a73SPeter Wemm /*
65258162a73SPeter Wemm ** Copy the data
65358162a73SPeter Wemm */
65458162a73SPeter Wemm
65558162a73SPeter Wemm exitstat = EX_OK;
65606f25ae9SGregory Neil Shapiro if (unmake)
65706f25ae9SGregory Neil Shapiro {
65806f25ae9SGregory Neil Shapiro errno = database->smdb_cursor(database, &cursor, 0);
65906f25ae9SGregory Neil Shapiro if (errno != SMDBE_OK)
66006f25ae9SGregory Neil Shapiro {
66106f25ae9SGregory Neil Shapiro
66240266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
66306f25ae9SGregory Neil Shapiro "%s: cannot make cursor for type %s map %s\n",
66406f25ae9SGregory Neil Shapiro progname, typename, mapname);
66506f25ae9SGregory Neil Shapiro exit(EX_SOFTWARE);
66606f25ae9SGregory Neil Shapiro }
66706f25ae9SGregory Neil Shapiro
66806f25ae9SGregory Neil Shapiro memset(&db_key, '\0', sizeof db_key);
66906f25ae9SGregory Neil Shapiro memset(&db_val, '\0', sizeof db_val);
67006f25ae9SGregory Neil Shapiro
671193538b7SGregory Neil Shapiro for (lineno = 0; ; lineno++)
67206f25ae9SGregory Neil Shapiro {
67306f25ae9SGregory Neil Shapiro errno = cursor->smdbc_get(cursor, &db_key, &db_val,
67406f25ae9SGregory Neil Shapiro SMDB_CURSOR_GET_NEXT);
67506f25ae9SGregory Neil Shapiro if (errno != SMDBE_OK)
676193538b7SGregory Neil Shapiro break;
677193538b7SGregory Neil Shapiro
67840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
679e8e0e582SGregory Neil Shapiro "%.*s%c%.*s\n",
680193538b7SGregory Neil Shapiro (int) db_key.size,
681193538b7SGregory Neil Shapiro (char *) db_key.data,
682e8e0e582SGregory Neil Shapiro (sep != '\0') ? sep : '\t',
683193538b7SGregory Neil Shapiro (int) db_val.size,
684193538b7SGregory Neil Shapiro (char *)db_val.data);
68506f25ae9SGregory Neil Shapiro
68606f25ae9SGregory Neil Shapiro }
68706f25ae9SGregory Neil Shapiro (void) cursor->smdbc_close(cursor);
68806f25ae9SGregory Neil Shapiro }
68906f25ae9SGregory Neil Shapiro else
69006f25ae9SGregory Neil Shapiro {
69106f25ae9SGregory Neil Shapiro lineno = 0;
69240266059SGregory Neil Shapiro while (sm_io_fgets(smioin, SM_TIME_DEFAULT, ibuf, sizeof ibuf)
693e388eeddSGregory Neil Shapiro >= 0)
69458162a73SPeter Wemm {
69558162a73SPeter Wemm register char *p;
69658162a73SPeter Wemm
69758162a73SPeter Wemm lineno++;
69858162a73SPeter Wemm
69958162a73SPeter Wemm /*
70058162a73SPeter Wemm ** Parse the line.
70158162a73SPeter Wemm */
70258162a73SPeter Wemm
70358162a73SPeter Wemm p = strchr(ibuf, '\n');
70458162a73SPeter Wemm if (p != NULL)
70558162a73SPeter Wemm *p = '\0';
70640266059SGregory Neil Shapiro else if (!sm_io_eof(smioin))
70758162a73SPeter Wemm {
70840266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
70940266059SGregory Neil Shapiro "%s: %s: line %u: line too long (%ld bytes max)\n",
71040266059SGregory Neil Shapiro progname, mapname, lineno,
71140266059SGregory Neil Shapiro (long) sizeof ibuf);
71206f25ae9SGregory Neil Shapiro exitstat = EX_DATAERR;
71358162a73SPeter Wemm continue;
71458162a73SPeter Wemm }
71558162a73SPeter Wemm
71640266059SGregory Neil Shapiro if (ibuf[0] == '\0' || ibuf[0] == comment)
71758162a73SPeter Wemm continue;
718cee0d44aSGregory Neil Shapiro if (sep == '\0' && ISASCII(ibuf[0]) && isspace(ibuf[0]))
71958162a73SPeter Wemm {
72040266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
72140266059SGregory Neil Shapiro "%s: %s: line %u: syntax error (leading space)\n",
72258162a73SPeter Wemm progname, mapname, lineno);
72306f25ae9SGregory Neil Shapiro exitstat = EX_DATAERR;
72458162a73SPeter Wemm continue;
72558162a73SPeter Wemm }
726c2aa98e2SPeter Wemm
72706f25ae9SGregory Neil Shapiro memset(&db_key, '\0', sizeof db_key);
72806f25ae9SGregory Neil Shapiro memset(&db_val, '\0', sizeof db_val);
729193538b7SGregory Neil Shapiro db_key.data = ibuf;
73006f25ae9SGregory Neil Shapiro
73128fbd282SGregory Neil Shapiro #if USE_EAI
73228fbd282SGregory Neil Shapiro db_key.size = 0;
73328fbd282SGregory Neil Shapiro if (foldcase)
73428fbd282SGregory Neil Shapiro {
73528fbd282SGregory Neil Shapiro for (p = ibuf; *p != '\0' && !ISSEP(*p); p++)
73628fbd282SGregory Neil Shapiro {
73728fbd282SGregory Neil Shapiro if (!ISASCII(*p))
73828fbd282SGregory Neil Shapiro ascii = false;
73928fbd282SGregory Neil Shapiro }
74028fbd282SGregory Neil Shapiro if (!ascii)
74128fbd282SGregory Neil Shapiro {
74228fbd282SGregory Neil Shapiro char sep;
74328fbd282SGregory Neil Shapiro char *lkey;
74428fbd282SGregory Neil Shapiro
74528fbd282SGregory Neil Shapiro sep = *p;
74628fbd282SGregory Neil Shapiro *p = '\0';
74728fbd282SGregory Neil Shapiro
74828fbd282SGregory Neil Shapiro lkey = sm_lowercase(ibuf);
74928fbd282SGregory Neil Shapiro db_key.data = lkey;
75028fbd282SGregory Neil Shapiro db_key.size = strlen(lkey);
75128fbd282SGregory Neil Shapiro *p = sep;
75228fbd282SGregory Neil Shapiro }
75328fbd282SGregory Neil Shapiro }
75428fbd282SGregory Neil Shapiro if (ascii)
75528fbd282SGregory Neil Shapiro #endif /* USE_EAI */
75628fbd282SGregory Neil Shapiro /* NOTE: see if () above! */
75728fbd282SGregory Neil Shapiro for (p = ibuf; *p != '\0' && !ISSEP(*p); p++)
758c2aa98e2SPeter Wemm {
759cee0d44aSGregory Neil Shapiro if (foldcase && ISASCII(*p) && isupper(*p))
76058162a73SPeter Wemm *p = tolower(*p);
76158162a73SPeter Wemm }
76228fbd282SGregory Neil Shapiro #if USE_EAI
76328fbd282SGregory Neil Shapiro if (0 == db_key.size)
76428fbd282SGregory Neil Shapiro #endif
765193538b7SGregory Neil Shapiro db_key.size = p - ibuf;
76658162a73SPeter Wemm if (inclnull)
767193538b7SGregory Neil Shapiro db_key.size++;
76806f25ae9SGregory Neil Shapiro
76958162a73SPeter Wemm if (*p != '\0')
77058162a73SPeter Wemm *p++ = '\0';
77140266059SGregory Neil Shapiro while (*p != '\0' && ISSEP(*p))
77258162a73SPeter Wemm p++;
773850ef5aeSGregory Neil Shapiro #if _FFR_MM_ALIASES
774850ef5aeSGregory Neil Shapiro while (aliases && *p != '\0' && ISSPACE(*p))
775850ef5aeSGregory Neil Shapiro p++;
776850ef5aeSGregory Neil Shapiro #endif
77706f25ae9SGregory Neil Shapiro if (!allowempty && *p == '\0')
77858162a73SPeter Wemm {
77940266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
78040266059SGregory Neil Shapiro "%s: %s: line %u: no RHS for LHS %s\n",
78106f25ae9SGregory Neil Shapiro progname, mapname, lineno,
782193538b7SGregory Neil Shapiro (char *) db_key.data);
78306f25ae9SGregory Neil Shapiro exitstat = EX_DATAERR;
78458162a73SPeter Wemm continue;
78558162a73SPeter Wemm }
78606f25ae9SGregory Neil Shapiro
787193538b7SGregory Neil Shapiro db_val.data = p;
788193538b7SGregory Neil Shapiro db_val.size = strlen(p);
78958162a73SPeter Wemm if (inclnull)
790193538b7SGregory Neil Shapiro db_val.size++;
79158162a73SPeter Wemm
79258162a73SPeter Wemm /*
79358162a73SPeter Wemm ** Do the database insert.
79458162a73SPeter Wemm */
79558162a73SPeter Wemm
796850ef5aeSGregory Neil Shapiro db_put(database, db_key, db_val, putflags, mapname,
797850ef5aeSGregory Neil Shapiro lineno, progname);
798850ef5aeSGregory Neil Shapiro }
799850ef5aeSGregory Neil Shapiro #if _FFR_MM_ALIASES
800850ef5aeSGregory Neil Shapiro if (aliases)
80158162a73SPeter Wemm {
802850ef5aeSGregory Neil Shapiro char magic[2] = "@";
80358162a73SPeter Wemm
804850ef5aeSGregory Neil Shapiro db_key.data = magic;
805850ef5aeSGregory Neil Shapiro db_val.data = magic;
806850ef5aeSGregory Neil Shapiro db_key.size = 1;
807850ef5aeSGregory Neil Shapiro db_val.size = 1;
808850ef5aeSGregory Neil Shapiro db_put(database, db_key, db_val, putflags, mapname, -1,
809850ef5aeSGregory Neil Shapiro progname);
810c2aa98e2SPeter Wemm }
811850ef5aeSGregory Neil Shapiro #endif /* _FFR_MM_ALIASES */
81258162a73SPeter Wemm }
81358162a73SPeter Wemm
81428fbd282SGregory Neil Shapiro #if _FFR_TESTS
81528fbd282SGregory Neil Shapiro if (slp > 0)
81628fbd282SGregory Neil Shapiro sleep(slp);
81728fbd282SGregory Neil Shapiro #endif
81828fbd282SGregory Neil Shapiro
81958162a73SPeter Wemm /*
82058162a73SPeter Wemm ** Now close the database.
82158162a73SPeter Wemm */
82258162a73SPeter Wemm
82306f25ae9SGregory Neil Shapiro errno = database->smdb_close(database);
82406f25ae9SGregory Neil Shapiro if (errno != SMDBE_OK)
82558162a73SPeter Wemm {
82640266059SGregory Neil Shapiro (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
82740266059SGregory Neil Shapiro "%s: close(%s): %s\n",
82840266059SGregory Neil Shapiro progname, mapname, sm_errstring(errno));
82958162a73SPeter Wemm exitstat = EX_IOERR;
83058162a73SPeter Wemm }
83106f25ae9SGregory Neil Shapiro smdb_free_database(database);
83258162a73SPeter Wemm
83358162a73SPeter Wemm exit(exitstat);
83440266059SGregory Neil Shapiro
83506f25ae9SGregory Neil Shapiro /* NOTREACHED */
83606f25ae9SGregory Neil Shapiro return exitstat;
83758162a73SPeter Wemm }
838