kernel - close holes in autoconf's run_interrupt_driven_config_hooks()
[dragonfly.git] / contrib / sendmail-8.14 / praliases / praliases.c
blob984981ff77a9f41c1281e15ee983ff03ef6ab952
1 /*
2 * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1983 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
14 #include <sm/gen.h>
16 SM_IDSTR(copyright,
17 "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
18 All rights reserved.\n\
19 Copyright (c) 1983 Eric P. Allman. All rights reserved.\n\
20 Copyright (c) 1988, 1993\n\
21 The Regents of the University of California. All rights reserved.\n")
23 SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.94 2007/05/11 18:50:36 ca Exp $")
25 #include <sys/types.h>
26 #include <ctype.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #ifdef EX_OK
30 # undef EX_OK /* unistd.h may have another use for this */
31 #endif /* EX_OK */
32 #include <sysexits.h>
35 #ifndef NOT_SENDMAIL
36 # define NOT_SENDMAIL
37 #endif /* ! NOT_SENDMAIL */
38 #include <sendmail/sendmail.h>
39 #include <sendmail/pathnames.h>
40 #include <libsmdb/smdb.h>
42 static void praliases __P((char *, int, char **));
44 uid_t RealUid;
45 gid_t RealGid;
46 char *RealUserName;
47 uid_t RunAsUid;
48 gid_t RunAsGid;
49 char *RunAsUserName;
50 int Verbose = 2;
51 bool DontInitGroups = false;
52 uid_t TrustedUid = 0;
53 BITMAP256 DontBlameSendmail;
55 # define DELIMITERS " ,/"
56 # define PATH_SEPARATOR ':'
58 int
59 main(argc, argv)
60 int argc;
61 char **argv;
63 char *cfile;
64 char *filename = NULL;
65 SM_FILE_T *cfp;
66 int ch;
67 char afilebuf[MAXLINE];
68 char buf[MAXLINE];
69 struct passwd *pw;
70 static char rnamebuf[MAXNAME];
71 extern char *optarg;
72 extern int optind;
74 clrbitmap(DontBlameSendmail);
75 RunAsUid = RealUid = getuid();
76 RunAsGid = RealGid = getgid();
77 pw = getpwuid(RealUid);
78 if (pw != NULL)
80 if (strlen(pw->pw_name) > MAXNAME - 1)
81 pw->pw_name[MAXNAME] = 0;
82 sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
84 else
85 (void) sm_snprintf(rnamebuf, sizeof rnamebuf,
86 "Unknown UID %d", (int) RealUid);
87 RunAsUserName = RealUserName = rnamebuf;
89 cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
90 while ((ch = getopt(argc, argv, "C:f:")) != -1)
92 switch ((char)ch) {
93 case 'C':
94 cfile = optarg;
95 break;
96 case 'f':
97 filename = optarg;
98 break;
99 case '?':
100 default:
101 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
102 "usage: praliases [-C cffile] [-f aliasfile]\n");
103 exit(EX_USAGE);
106 argc -= optind;
107 argv += optind;
109 if (filename != NULL)
111 praliases(filename, argc, argv);
112 exit(EX_OK);
115 if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
116 NULL)) == NULL)
118 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
119 "praliases: %s: %s\n", cfile,
120 sm_errstring(errno));
121 exit(EX_NOINPUT);
124 while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
126 register char *b, *p;
128 b = strchr(buf, '\n');
129 if (b != NULL)
130 *b = '\0';
132 b = buf;
133 switch (*b++)
135 case 'O': /* option -- see if alias file */
136 if (sm_strncasecmp(b, " AliasFile", 10) == 0 &&
137 !(isascii(b[10]) && isalnum(b[10])))
139 /* new form -- find value */
140 b = strchr(b, '=');
141 if (b == NULL)
142 continue;
143 while (isascii(*++b) && isspace(*b))
144 continue;
146 else if (*b++ != 'A')
148 /* something else boring */
149 continue;
152 /* this is the A or AliasFile option -- save it */
153 if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >=
154 sizeof afilebuf)
156 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
157 "praliases: AliasFile filename too long: %.30s\n",
159 (void) sm_io_close(cfp, SM_TIME_DEFAULT);
160 exit(EX_CONFIG);
162 b = afilebuf;
164 for (p = b; p != NULL; )
166 while (isascii(*p) && isspace(*p))
167 p++;
168 if (*p == '\0')
169 break;
170 b = p;
172 p = strpbrk(p, DELIMITERS);
174 /* find end of spec */
175 if (p != NULL)
177 bool quoted = false;
179 for (; *p != '\0'; p++)
182 ** Don't break into a quoted
183 ** string.
186 if (*p == '"')
187 quoted = !quoted;
188 else if (*p == ',' && !quoted)
189 break;
192 /* No more alias specs follow */
193 if (*p == '\0')
195 /* chop trailing whitespace */
196 while (isascii(*p) &&
197 isspace(*p) &&
198 p > b)
199 p--;
200 *p = '\0';
201 p = NULL;
205 if (p != NULL)
207 char *e = p - 1;
209 /* chop trailing whitespace */
210 while (isascii(*e) &&
211 isspace(*e) &&
212 e > b)
213 e--;
214 *++e = '\0';
215 *p++ = '\0';
217 praliases(b, argc, argv);
220 default:
221 continue;
224 (void) sm_io_close(cfp, SM_TIME_DEFAULT);
225 exit(EX_OK);
226 /* NOTREACHED */
227 return EX_OK;
230 static void
231 praliases(filename, argc, argv)
232 char *filename;
233 int argc;
234 char **argv;
236 int result;
237 char *colon;
238 char *db_name;
239 char *db_type;
240 SMDB_DATABASE *database = NULL;
241 SMDB_CURSOR *cursor = NULL;
242 SMDB_DBENT db_key, db_value;
243 SMDB_DBPARAMS params;
244 SMDB_USER_INFO user_info;
246 colon = strchr(filename, PATH_SEPARATOR);
247 if (colon == NULL)
249 db_name = filename;
250 db_type = SMDB_TYPE_DEFAULT;
252 else
254 *colon = '\0';
255 db_name = colon + 1;
256 db_type = filename;
259 /* clean off arguments */
260 for (;;)
262 while (isascii(*db_name) && isspace(*db_name))
263 db_name++;
265 if (*db_name != '-')
266 break;
267 while (*db_name != '\0' &&
268 !(isascii(*db_name) && isspace(*db_name)))
269 db_name++;
272 /* Skip non-file based DB types */
273 if (db_type != NULL && *db_type != '\0')
275 if (db_type != SMDB_TYPE_DEFAULT &&
276 strcmp(db_type, "hash") != 0 &&
277 strcmp(db_type, "btree") != 0 &&
278 strcmp(db_type, "dbm") != 0)
280 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
281 "praliases: Skipping non-file based alias type %s\n",
282 db_type);
283 return;
287 if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
289 if (colon != NULL)
290 *colon = ':';
291 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
292 "praliases: illegal alias specification: %s\n", filename);
293 goto fatal;
296 memset(&params, '\0', sizeof params);
297 params.smdbp_cache_size = 1024 * 1024;
299 user_info.smdbu_id = RunAsUid;
300 user_info.smdbu_group_id = RunAsGid;
301 (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
302 SMDB_MAX_USER_NAME_LEN);
304 result = smdb_open_database(&database, db_name, O_RDONLY, 0,
305 SFF_ROOTOK, db_type, &user_info, &params);
306 if (result != SMDBE_OK)
308 sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
309 "praliases: %s: open: %s\n",
310 db_name, sm_errstring(result));
311 goto fatal;
314 if (argc == 0)
316 memset(&db_key, '\0', sizeof db_key);
317 memset(&db_value, '\0', sizeof db_value);
319 result = database->smdb_cursor(database, &cursor, 0);
320 if (result != SMDBE_OK)
322 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
323 "praliases: %s: set cursor: %s\n", db_name,
324 sm_errstring(result));
325 goto fatal;
328 while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
329 SMDB_CURSOR_GET_NEXT)) ==
330 SMDBE_OK)
332 #if 0
333 /* skip magic @:@ entry */
334 if (db_key.size == 2 &&
335 db_key.data[0] == '@' &&
336 db_key.data[1] == '\0' &&
337 db_value.size == 2 &&
338 db_value.data[0] == '@' &&
339 db_value.data[1] == '\0')
340 continue;
341 #endif /* 0 */
343 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
344 "%.*s:%.*s\n",
345 (int) db_key.size,
346 (char *) db_key.data,
347 (int) db_value.size,
348 (char *) db_value.data);
351 if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
353 (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
354 "praliases: %s: get value at cursor: %s\n",
355 db_name, sm_errstring(result));
356 goto fatal;
359 else for (; *argv != NULL; ++argv)
361 int get_res;
363 memset(&db_key, '\0', sizeof db_key);
364 memset(&db_value, '\0', sizeof db_value);
365 db_key.data = *argv;
366 db_key.size = strlen(*argv);
367 get_res = database->smdb_get(database, &db_key, &db_value, 0);
368 if (get_res == SMDBE_NOT_FOUND)
370 db_key.size++;
371 get_res = database->smdb_get(database, &db_key,
372 &db_value, 0);
374 if (get_res == SMDBE_OK)
376 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
377 "%.*s:%.*s\n",
378 (int) db_key.size,
379 (char *) db_key.data,
380 (int) db_value.size,
381 (char *) db_value.data);
383 else
384 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
385 "%s: No such key\n",
386 (char *)db_key.data);
389 fatal:
390 if (cursor != NULL)
391 (void) cursor->smdbc_close(cursor);
392 if (database != NULL)
393 (void) database->smdb_close(database);
394 if (colon != NULL)
395 *colon = ':';
396 return;