Avoid re-expansion in ${sort }
[exim.git] / src / src / exim.c
CommitLineData
059ec3d9
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
f9ba5e22 5/* Copyright (c) University of Cambridge 1995 - 2018 */
059ec3d9
PH
6/* See the file NOTICE for conditions of use and distribution. */
7
8
9/* The main function: entry point, initialization, and high-level control.
10Also a few functions that don't naturally fit elsewhere. */
11
12
13#include "exim.h"
14
98913c8e 15#if defined(__GLIBC__) && !defined(__UCLIBC__)
01f3091a
JH
16# include <gnu/libc-version.h>
17#endif
18
f797c123
JH
19#ifdef USE_GNUTLS
20# include <gnutls/gnutls.h>
21# if GNUTLS_VERSION_NUMBER < 0x030103 && !defined(DISABLE_OCSP)
22# define DISABLE_OCSP
23# endif
24#endif
25
6545de78
PP
26extern void init_lookup_list(void);
27
059ec3d9
PH
28
29
30/*************************************************
31* Function interface to store functions *
32*************************************************/
33
34/* We need some real functions to pass to the PCRE regular expression library
35for store allocation via Exim's store manager. The normal calls are actually
36macros that pass over location information to make tracing easier. These
37functions just interface to the standard macro calls. A good compiler will
38optimize out the tail recursion and so not make them too expensive. There
39are two sets of functions; one for use when we want to retain the compiled
40regular expression for a long time; the other for short-term use. */
41
42static void *
43function_store_get(size_t size)
44{
45return store_get((int)size);
46}
47
48static void
49function_dummy_free(void *block) { block = block; }
50
51static void *
52function_store_malloc(size_t size)
53{
54return store_malloc((int)size);
55}
56
57static void
58function_store_free(void *block)
59{
60store_free(block);
61}
62
63
64
65
66/*************************************************
98a90c36
PP
67* Enums for cmdline interface *
68*************************************************/
69
70enum commandline_info { CMDINFO_NONE=0,
36a3ae5f 71 CMDINFO_HELP, CMDINFO_SIEVE, CMDINFO_DSCP };
98a90c36
PP
72
73
74
75
76/*************************************************
059ec3d9
PH
77* Compile regular expression and panic on fail *
78*************************************************/
79
80/* This function is called when failure to compile a regular expression leads
81to a panic exit. In other cases, pcre_compile() is called directly. In many
82cases where this function is used, the results of the compilation are to be
83placed in long-lived store, so we temporarily reset the store management
84functions that PCRE uses if the use_malloc flag is set.
85
86Argument:
87 pattern the pattern to compile
88 caseless TRUE if caseless matching is required
89 use_malloc TRUE if compile into malloc store
90
91Returns: pointer to the compiled pattern
92*/
93
94const pcre *
476be7e2 95regex_must_compile(const uschar *pattern, BOOL caseless, BOOL use_malloc)
059ec3d9
PH
96{
97int offset;
98int options = PCRE_COPT;
99const pcre *yield;
100const uschar *error;
101if (use_malloc)
102 {
103 pcre_malloc = function_store_malloc;
104 pcre_free = function_store_free;
105 }
106if (caseless) options |= PCRE_CASELESS;
476be7e2 107yield = pcre_compile(CCS pattern, options, (const char **)&error, &offset, NULL);
059ec3d9
PH
108pcre_malloc = function_store_get;
109pcre_free = function_dummy_free;
110if (yield == NULL)
111 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "regular expression error: "
112 "%s at offset %d while compiling %s", error, offset, pattern);
113return yield;
114}
115
116
117
118
119/*************************************************
120* Execute regular expression and set strings *
121*************************************************/
122
123/* This function runs a regular expression match, and sets up the pointers to
124the matched substrings.
125
126Arguments:
127 re the compiled expression
128 subject the subject string
129 options additional PCRE options
130 setup if < 0 do full setup
131 if >= 0 setup from setup+1 onwards,
132 excluding the full matched string
133
134Returns: TRUE or FALSE
135*/
136
137BOOL
1dc92d5a 138regex_match_and_setup(const pcre *re, const uschar *subject, int options, int setup)
059ec3d9
PH
139{
140int ovector[3*(EXPAND_MAXN+1)];
1dc92d5a
JH
141uschar * s = string_copy(subject); /* de-constifying */
142int n = pcre_exec(re, NULL, CS s, Ustrlen(s), 0,
ee8b8090 143 PCRE_EOPT | options, ovector, nelem(ovector));
059ec3d9
PH
144BOOL yield = n >= 0;
145if (n == 0) n = EXPAND_MAXN + 1;
146if (yield)
147 {
ee8b8090 148 expand_nmax = setup < 0 ? 0 : setup + 1;
d7978c0f 149 for (int nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
059ec3d9 150 {
1dc92d5a 151 expand_nstring[expand_nmax] = s + ovector[nn];
059ec3d9
PH
152 expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
153 }
154 expand_nmax--;
155 }
156return yield;
157}
158
159
160
161
162/*************************************************
921b12ca
TF
163* Set up processing details *
164*************************************************/
165
166/* Save a text string for dumping when SIGUSR1 is received.
167Do checks for overruns.
168
169Arguments: format and arguments, as for printf()
170Returns: nothing
171*/
172
173void
174set_process_info(const char *format, ...)
175{
d12746bc
JH
176gstring gs = { .size = PROCESS_INFO_SIZE - 2, .ptr = 0, .s = process_info };
177gstring * g;
178int len;
921b12ca 179va_list ap;
d12746bc
JH
180
181g = string_fmt_append(&gs, "%5d ", (int)getpid());
182len = g->ptr;
921b12ca 183va_start(ap, format);
d12746bc
JH
184if (!string_vformat(g, FALSE, format, ap))
185 {
186 gs.ptr = len;
187 g = string_cat(&gs, US"**** string overflowed buffer ****");
188 }
189g = string_catn(g, US"\n", 1);
190string_from_gstring(g);
191process_info_len = g->ptr;
921b12ca
TF
192DEBUG(D_process_info) debug_printf("set_process_info: %s", process_info);
193va_end(ap);
194}
195
830832c9
HSHR
196/***********************************************
197* Handler for SIGTERM *
198***********************************************/
921b12ca 199
830832c9
HSHR
200static void
201term_handler(int sig)
202{
203 exit(1);
204}
921b12ca
TF
205
206
207/*************************************************
059ec3d9
PH
208* Handler for SIGUSR1 *
209*************************************************/
210
211/* SIGUSR1 causes any exim process to write to the process log details of
212what it is currently doing. It will only be used if the OS is capable of
213setting up a handler that causes automatic restarting of any system call
214that is in progress at the time.
215
921b12ca
TF
216This function takes care to be signal-safe.
217
059ec3d9
PH
218Argument: the signal number (SIGUSR1)
219Returns: nothing
220*/
221
222static void
223usr1_handler(int sig)
224{
921b12ca
TF
225int fd;
226
227os_restarting_signal(sig, usr1_handler);
228
cab0c277 229if ((fd = Uopen(process_log_path, O_APPEND|O_WRONLY, LOG_MODE)) < 0)
921b12ca
TF
230 {
231 /* If we are already running as the Exim user, try to create it in the
232 current process (assuming spool_directory exists). Otherwise, if we are
233 root, do the creation in an exim:exim subprocess. */
234
235 int euid = geteuid();
236 if (euid == exim_uid)
237 fd = Uopen(process_log_path, O_CREAT|O_APPEND|O_WRONLY, LOG_MODE);
238 else if (euid == root_uid)
239 fd = log_create_as_exim(process_log_path);
240 }
241
242/* If we are neither exim nor root, or if we failed to create the log file,
243give up. There is not much useful we can do with errors, since we don't want
244to disrupt whatever is going on outside the signal handler. */
245
246if (fd < 0) return;
247
2f21487f 248(void)write(fd, process_info, process_info_len);
921b12ca 249(void)close(fd);
059ec3d9
PH
250}
251
252
253
254/*************************************************
255* Timeout handler *
256*************************************************/
257
258/* This handler is enabled most of the time that Exim is running. The handler
259doesn't actually get used unless alarm() has been called to set a timer, to
260place a time limit on a system call of some kind. When the handler is run, it
261re-enables itself.
262
263There are some other SIGALRM handlers that are used in special cases when more
264than just a flag setting is required; for example, when reading a message's
265input. These are normally set up in the code module that uses them, and the
266SIGALRM handler is reset to this one afterwards.
267
268Argument: the signal value (SIGALRM)
269Returns: nothing
270*/
271
272void
273sigalrm_handler(int sig)
274{
275sig = sig; /* Keep picky compilers happy */
276sigalrm_seen = TRUE;
277os_non_restarting_signal(SIGALRM, sigalrm_handler);
278}
279
280
281
282/*************************************************
283* Sleep for a fractional time interval *
284*************************************************/
285
286/* This function is called by millisleep() and exim_wait_tick() to wait for a
287period of time that may include a fraction of a second. The coding is somewhat
eb2c0248
PH
288tedious. We do not expect setitimer() ever to fail, but if it does, the process
289will wait for ever, so we panic in this instance. (There was a case of this
290when a bug in a function that calls milliwait() caused it to pass invalid data.
7086e875 291That's when I added the check. :-)
059ec3d9 292
0f8ba377
JH
293We assume it to be not worth sleeping for under 100us; this value will
294require revisiting as hardware advances. This avoids the issue of
295a zero-valued timer setting meaning "never fire".
296
059ec3d9
PH
297Argument: an itimerval structure containing the interval
298Returns: nothing
299*/
300
301static void
302milliwait(struct itimerval *itval)
303{
304sigset_t sigmask;
305sigset_t old_sigmask;
0f8ba377
JH
306
307if (itval->it_value.tv_usec < 100 && itval->it_value.tv_sec == 0)
308 return;
059ec3d9
PH
309(void)sigemptyset(&sigmask); /* Empty mask */
310(void)sigaddset(&sigmask, SIGALRM); /* Add SIGALRM */
311(void)sigprocmask(SIG_BLOCK, &sigmask, &old_sigmask); /* Block SIGALRM */
7086e875 312if (setitimer(ITIMER_REAL, itval, NULL) < 0) /* Start timer */
eb2c0248
PH
313 log_write(0, LOG_MAIN|LOG_PANIC_DIE,
314 "setitimer() failed: %s", strerror(errno));
059ec3d9
PH
315(void)sigfillset(&sigmask); /* All signals */
316(void)sigdelset(&sigmask, SIGALRM); /* Remove SIGALRM */
317(void)sigsuspend(&sigmask); /* Until SIGALRM */
318(void)sigprocmask(SIG_SETMASK, &old_sigmask, NULL); /* Restore mask */
319}
320
321
322
323
324/*************************************************
325* Millisecond sleep function *
326*************************************************/
327
328/* The basic sleep() function has a granularity of 1 second, which is too rough
329in some cases - for example, when using an increasing delay to slow down
330spammers.
331
332Argument: number of millseconds
333Returns: nothing
334*/
335
336void
337millisleep(int msec)
338{
339struct itimerval itval;
340itval.it_interval.tv_sec = 0;
341itval.it_interval.tv_usec = 0;
342itval.it_value.tv_sec = msec/1000;
343itval.it_value.tv_usec = (msec % 1000) * 1000;
344milliwait(&itval);
345}
346
347
348
349/*************************************************
350* Compare microsecond times *
351*************************************************/
352
353/*
354Arguments:
355 tv1 the first time
356 tv2 the second time
357
358Returns: -1, 0, or +1
359*/
360
32dfdf8b 361static int
059ec3d9
PH
362exim_tvcmp(struct timeval *t1, struct timeval *t2)
363{
364if (t1->tv_sec > t2->tv_sec) return +1;
365if (t1->tv_sec < t2->tv_sec) return -1;
366if (t1->tv_usec > t2->tv_usec) return +1;
367if (t1->tv_usec < t2->tv_usec) return -1;
368return 0;
369}
370
371
372
373
374/*************************************************
375* Clock tick wait function *
376*************************************************/
377
378/* Exim uses a time + a pid to generate a unique identifier in two places: its
379message IDs, and in file names for maildir deliveries. Because some OS now
380re-use pids within the same second, sub-second times are now being used.
4c04137d 381However, for absolute certainty, we must ensure the clock has ticked before
059ec3d9
PH
382allowing the relevant process to complete. At the time of implementation of
383this code (February 2003), the speed of processors is such that the clock will
384invariably have ticked already by the time a process has done its job. This
385function prepares for the time when things are faster - and it also copes with
386clocks that go backwards.
387
388Arguments:
389 then_tv A timeval which was used to create uniqueness; its usec field
390 has been rounded down to the value of the resolution.
391 We want to be sure the current time is greater than this.
392 resolution The resolution that was used to divide the microseconds
393 (1 for maildir, larger for message ids)
394
395Returns: nothing
396*/
397
398void
399exim_wait_tick(struct timeval *then_tv, int resolution)
400{
401struct timeval now_tv;
402long int now_true_usec;
403
404(void)gettimeofday(&now_tv, NULL);
405now_true_usec = now_tv.tv_usec;
406now_tv.tv_usec = (now_true_usec/resolution) * resolution;
407
408if (exim_tvcmp(&now_tv, then_tv) <= 0)
409 {
410 struct itimerval itval;
411 itval.it_interval.tv_sec = 0;
412 itval.it_interval.tv_usec = 0;
413 itval.it_value.tv_sec = then_tv->tv_sec - now_tv.tv_sec;
414 itval.it_value.tv_usec = then_tv->tv_usec + resolution - now_true_usec;
415
416 /* We know that, overall, "now" is less than or equal to "then". Therefore, a
417 negative value for the microseconds is possible only in the case when "now"
418 is more than a second less than "then". That means that itval.it_value.tv_sec
419 is greater than zero. The following correction is therefore safe. */
420
421 if (itval.it_value.tv_usec < 0)
422 {
423 itval.it_value.tv_usec += 1000000;
424 itval.it_value.tv_sec -= 1;
425 }
426
427 DEBUG(D_transport|D_receive)
428 {
8768d548 429 if (!f.running_in_test_harness)
059ec3d9 430 {
d0291a0a 431 debug_printf("tick check: " TIME_T_FMT ".%06lu " TIME_T_FMT ".%06lu\n",
7437665e
JH
432 then_tv->tv_sec, (long) then_tv->tv_usec,
433 now_tv.tv_sec, (long) now_tv.tv_usec);
d0291a0a
JH
434 debug_printf("waiting " TIME_T_FMT ".%06lu\n",
435 itval.it_value.tv_sec, (long) itval.it_value.tv_usec);
059ec3d9
PH
436 }
437 }
438
439 milliwait(&itval);
440 }
441}
442
443
444
445
446/*************************************************
2632889e
PH
447* Call fopen() with umask 777 and adjust mode *
448*************************************************/
449
450/* Exim runs with umask(0) so that files created with open() have the mode that
451is specified in the open() call. However, there are some files, typically in
452the spool directory, that are created with fopen(). They end up world-writeable
453if no precautions are taken. Although the spool directory is not accessible to
454the world, this is an untidiness. So this is a wrapper function for fopen()
455that sorts out the mode of the created file.
456
457Arguments:
458 filename the file name
459 options the fopen() options
460 mode the required mode
461
462Returns: the fopened FILE or NULL
463*/
464
465FILE *
1ba28e2b 466modefopen(const uschar *filename, const char *options, mode_t mode)
2632889e 467{
67d175de
PH
468mode_t saved_umask = umask(0777);
469FILE *f = Ufopen(filename, options);
470(void)umask(saved_umask);
2632889e
PH
471if (f != NULL) (void)fchmod(fileno(f), mode);
472return f;
473}
474
475
2632889e 476/*************************************************
059ec3d9
PH
477* Ensure stdin, stdout, and stderr exist *
478*************************************************/
479
480/* Some operating systems grumble if an exec() happens without a standard
481input, output, and error (fds 0, 1, 2) being defined. The worry is that some
482file will be opened and will use these fd values, and then some other bit of
483code will assume, for example, that it can write error messages to stderr.
484This function ensures that fds 0, 1, and 2 are open if they do not already
485exist, by connecting them to /dev/null.
486
487This function is also used to ensure that std{in,out,err} exist at all times,
488so that if any library that Exim calls tries to use them, it doesn't crash.
489
490Arguments: None
491Returns: Nothing
492*/
493
494void
495exim_nullstd(void)
496{
059ec3d9
PH
497int devnull = -1;
498struct stat statbuf;
d7978c0f 499for (int i = 0; i <= 2; i++)
059ec3d9
PH
500 {
501 if (fstat(i, &statbuf) < 0 && errno == EBADF)
502 {
503 if (devnull < 0) devnull = open("/dev/null", O_RDWR);
504 if (devnull < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
505 string_open_failed(errno, "/dev/null"));
1fe64dcc 506 if (devnull != i) (void)dup2(devnull, i);
059ec3d9
PH
507 }
508 }
1fe64dcc 509if (devnull > 2) (void)close(devnull);
059ec3d9
PH
510}
511
512
513
514
515/*************************************************
516* Close unwanted file descriptors for delivery *
517*************************************************/
518
519/* This function is called from a new process that has been forked to deliver
520an incoming message, either directly, or using exec.
521
522We want any smtp input streams to be closed in this new process. However, it
523has been observed that using fclose() here causes trouble. When reading in -bS
524input, duplicate copies of messages have been seen. The files will be sharing a
525file pointer with the parent process, and it seems that fclose() (at least on
526some systems - I saw this on Solaris 2.5.1) messes with that file pointer, at
527least sometimes. Hence we go for closing the underlying file descriptors.
528
529If TLS is active, we want to shut down the TLS library, but without molesting
530the parent's SSL connection.
531
532For delivery of a non-SMTP message, we want to close stdin and stdout (and
533stderr unless debugging) because the calling process might have set them up as
534pipes and be waiting for them to close before it waits for the submission
535process to terminate. If they aren't closed, they hold up the calling process
536until the initial delivery process finishes, which is not what we want.
537
538Exception: We do want it for synchronous delivery!
539
540And notwithstanding all the above, if D_resolver is set, implying resolver
541debugging, leave stdout open, because that's where the resolver writes its
542debugging output.
543
544When we close stderr (which implies we've also closed stdout), we also get rid
545of any controlling terminal.
546
547Arguments: None
548Returns: Nothing
549*/
550
551static void
552close_unwanted(void)
553{
554if (smtp_input)
555 {
01603eec 556#ifndef DISABLE_TLS
74f1a423
JH
557 tls_close(NULL, TLS_NO_SHUTDOWN); /* Shut down the TLS library */
558#endif
1fe64dcc
PH
559 (void)close(fileno(smtp_in));
560 (void)close(fileno(smtp_out));
059ec3d9
PH
561 smtp_in = NULL;
562 }
563else
564 {
1fe64dcc
PH
565 (void)close(0); /* stdin */
566 if ((debug_selector & D_resolver) == 0) (void)close(1); /* stdout */
567 if (debug_selector == 0) /* stderr */
059ec3d9 568 {
8768d548 569 if (!f.synchronous_delivery)
059ec3d9 570 {
1fe64dcc 571 (void)close(2);
059ec3d9
PH
572 log_stderr = NULL;
573 }
574 (void)setsid();
575 }
576 }
577}
578
579
580
581
582/*************************************************
583* Set uid and gid *
584*************************************************/
585
586/* This function sets a new uid and gid permanently, optionally calling
587initgroups() to set auxiliary groups. There are some special cases when running
588Exim in unprivileged modes. In these situations the effective uid will not be
589root; if we already have the right effective uid/gid, and don't need to
590initialize any groups, leave things as they are.
591
592Arguments:
593 uid the uid
594 gid the gid
595 igflag TRUE if initgroups() wanted
596 msg text to use in debugging output and failure log
597
598Returns: nothing; bombs out on failure
599*/
600
601void
602exim_setugid(uid_t uid, gid_t gid, BOOL igflag, uschar *msg)
603{
604uid_t euid = geteuid();
605gid_t egid = getegid();
606
607if (euid == root_uid || euid != uid || egid != gid || igflag)
608 {
609 /* At least one OS returns +1 for initgroups failure, so just check for
610 non-zero. */
611
612 if (igflag)
613 {
614 struct passwd *pw = getpwuid(uid);
9af3c549
JH
615 if (!pw)
616 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "cannot run initgroups(): "
617 "no passwd entry for uid=%ld", (long int)uid);
618
619 if (initgroups(pw->pw_name, gid) != 0)
620 log_write(0,LOG_MAIN|LOG_PANIC_DIE,"initgroups failed for uid=%ld: %s",
621 (long int)uid, strerror(errno));
059ec3d9
PH
622 }
623
624 if (setgid(gid) < 0 || setuid(uid) < 0)
059ec3d9
PH
625 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "unable to set gid=%ld or uid=%ld "
626 "(euid=%ld): %s", (long int)gid, (long int)uid, (long int)euid, msg);
059ec3d9
PH
627 }
628
629/* Debugging output included uid/gid and all groups */
630
631DEBUG(D_uid)
632 {
cd59ab18 633 int group_count, save_errno;
157d73b5 634 gid_t group_list[EXIM_GROUPLIST_SIZE];
059ec3d9
PH
635 debug_printf("changed uid/gid: %s\n uid=%ld gid=%ld pid=%ld\n", msg,
636 (long int)geteuid(), (long int)getegid(), (long int)getpid());
157d73b5 637 group_count = getgroups(nelem(group_list), group_list);
cd59ab18 638 save_errno = errno;
059ec3d9
PH
639 debug_printf(" auxiliary group list:");
640 if (group_count > 0)
d7978c0f 641 for (int i = 0; i < group_count; i++) debug_printf(" %d", (int)group_list[i]);
cd59ab18
PP
642 else if (group_count < 0)
643 debug_printf(" <error: %s>", strerror(save_errno));
059ec3d9
PH
644 else debug_printf(" <none>");
645 debug_printf("\n");
646 }
647}
648
649
650
651
652/*************************************************
653* Exit point *
654*************************************************/
655
656/* Exim exits via this function so that it always clears up any open
657databases.
658
659Arguments:
660 rc return code
661
662Returns: does not return
663*/
664
665void
9bfb7e1b 666exim_exit(int rc, const uschar * process)
059ec3d9
PH
667{
668search_tidyup();
669DEBUG(D_any)
9bfb7e1b
JH
670 debug_printf(">>>>>>>>>>>>>>>> Exim pid=%d %s%s%sterminating with rc=%d "
671 ">>>>>>>>>>>>>>>>\n", (int)getpid(),
672 process ? "(" : "", process, process ? ") " : "", rc);
059ec3d9
PH
673exit(rc);
674}
675
676
677
9af3c549
JH
678/* Print error string, then die */
679static void
680exim_fail(const char * fmt, ...)
681{
682va_list ap;
683va_start(ap, fmt);
684vfprintf(stderr, fmt, ap);
685exit(EXIT_FAILURE);
686}
687
b66fecb4
HSHR
688/* exim_chown_failure() called from exim_chown()/exim_fchown() on failure
689of chown()/fchown(). See src/functions.h for more explanation */
690int
691exim_chown_failure(int fd, const uschar *name, uid_t owner, gid_t group)
692{
ecf14f2a 693int saved_errno = errno; /* from the preceeding chown call */
b66fecb4
HSHR
694#if 1
695log_write(0, LOG_MAIN|LOG_PANIC,
696 __FILE__ ":%d: chown(%s, %d:%d) failed (%s)."
697 " Please contact the authors and refer to https://bugs.exim.org/show_bug.cgi?id=2391",
698 __LINE__, name?name:US"<unknown>", owner, group, strerror(errno));
699#else
700/* I leave this here, commented, in case the "bug"(?) comes up again.
701 It is not an Exim bug, but we can provide a workaround.
702 See Bug 2391
703 HS 2019-04-18 */
704
b66fecb4
HSHR
705struct stat buf;
706
707if (0 == (fd < 0 ? stat(name, &buf) : fstat(fd, &buf)))
708{
709 if (buf.st_uid == owner && buf.st_gid == group) return 0;
710 log_write(0, LOG_MAIN|LOG_PANIC, "Wrong ownership on %s", name);
711}
712else log_write(0, LOG_MAIN|LOG_PANIC, "Stat failed on %s: %s", name, strerror(errno));
713
ecf14f2a 714#endif
b66fecb4
HSHR
715errno = saved_errno;
716return -1;
b66fecb4 717}
9af3c549 718
059ec3d9
PH
719
720/*************************************************
721* Extract port from host address *
722*************************************************/
723
724/* Called to extract the port from the values given to -oMa and -oMi.
b90c388a
PH
725It also checks the syntax of the address, and terminates it before the
726port data when a port is extracted.
059ec3d9
PH
727
728Argument:
729 address the address, with possible port on the end
730
731Returns: the port, or zero if there isn't one
732 bombs out on a syntax error
733*/
734
735static int
736check_port(uschar *address)
737{
7cd1141b 738int port = host_address_extract_port(address);
8e669ac1 739if (string_is_ip_address(address, NULL) == 0)
9af3c549 740 exim_fail("exim abandoned: \"%s\" is not an IP address\n", address);
059ec3d9
PH
741return port;
742}
743
744
745
746/*************************************************
747* Test/verify an address *
748*************************************************/
749
750/* This function is called by the -bv and -bt code. It extracts a working
751address from a full RFC 822 address. This isn't really necessary per se, but it
752has the effect of collapsing source routes.
753
754Arguments:
755 s the address string
756 flags flag bits for verify_address()
757 exit_value to be set for failures
758
a5a28604 759Returns: nothing
059ec3d9
PH
760*/
761
762static void
763test_address(uschar *s, int flags, int *exit_value)
764{
765int start, end, domain;
766uschar *parse_error = NULL;
767uschar *address = parse_extract_address(s, &parse_error, &start, &end, &domain,
768 FALSE);
769if (address == NULL)
770 {
771 fprintf(stdout, "syntax error: %s\n", parse_error);
772 *exit_value = 2;
773 }
774else
775 {
776 int rc = verify_address(deliver_make_addr(address,TRUE), stdout, flags, -1,
4deaf07d 777 -1, -1, NULL, NULL, NULL);
059ec3d9
PH
778 if (rc == FAIL) *exit_value = 2;
779 else if (rc == DEFER && *exit_value == 0) *exit_value = 1;
780 }
781}
782
783
784
785/*************************************************
059ec3d9
PH
786* Show supported features *
787*************************************************/
788
059ec3d9 789static void
96508de1 790show_db_version(FILE * f)
059ec3d9
PH
791{
792#ifdef DB_VERSION_STRING
96508de1
JH
793DEBUG(D_any)
794 {
795 fprintf(f, "Library version: BDB: Compile: %s\n", DB_VERSION_STRING);
796 fprintf(f, " Runtime: %s\n",
797 db_version(NULL, NULL, NULL));
798 }
799else
800 fprintf(f, "Berkeley DB: %s\n", DB_VERSION_STRING);
801
059ec3d9
PH
802#elif defined(BTREEVERSION) && defined(HASHVERSION)
803 #ifdef USE_DB
804 fprintf(f, "Probably Berkeley DB version 1.8x (native mode)\n");
805 #else
806 fprintf(f, "Probably Berkeley DB version 1.8x (compatibility mode)\n");
807 #endif
96508de1 808
059ec3d9
PH
809#elif defined(_DBM_RDONLY) || defined(dbm_dirfno)
810fprintf(f, "Probably ndbm\n");
811#elif defined(USE_TDB)
812fprintf(f, "Using tdb\n");
813#else
814 #ifdef USE_GDBM
815 fprintf(f, "Probably GDBM (native mode)\n");
816 #else
817 fprintf(f, "Probably GDBM (compatibility mode)\n");
818 #endif
819#endif
96508de1
JH
820}
821
822
823/* This function is called for -bV/--version and for -d to output the optional
824features of the current Exim binary.
825
826Arguments: a FILE for printing
827Returns: nothing
828*/
829
830static void
8768d548 831show_whats_supported(FILE * fp)
96508de1 832{
8768d548 833DEBUG(D_any) {} else show_db_version(fp);
059ec3d9 834
8768d548 835fprintf(fp, "Support for:");
9cec981f 836#ifdef SUPPORT_CRYPTEQ
8768d548 837 fprintf(fp, " crypteq");
9cec981f 838#endif
059ec3d9 839#if HAVE_ICONV
8768d548 840 fprintf(fp, " iconv()");
059ec3d9
PH
841#endif
842#if HAVE_IPV6
8768d548 843 fprintf(fp, " IPv6");
059ec3d9 844#endif
79378e0f 845#ifdef HAVE_SETCLASSRESOURCES
8768d548 846 fprintf(fp, " use_setclassresources");
929ba01c 847#endif
059ec3d9 848#ifdef SUPPORT_PAM
8768d548 849 fprintf(fp, " PAM");
059ec3d9
PH
850#endif
851#ifdef EXIM_PERL
8768d548 852 fprintf(fp, " Perl");
059ec3d9 853#endif
1a46a8c5 854#ifdef EXPAND_DLFUNC
8768d548 855 fprintf(fp, " Expand_dlfunc");
1a46a8c5 856#endif
059ec3d9 857#ifdef USE_TCP_WRAPPERS
8768d548 858 fprintf(fp, " TCPwrappers");
059ec3d9 859#endif
de517fd3 860#ifdef USE_GNUTLS
8768d548 861 fprintf(fp, " GnuTLS");
de517fd3
JH
862#endif
863#ifdef USE_OPENSSL
8768d548 864 fprintf(fp, " OpenSSL");
059ec3d9 865#endif
b2f5a032 866#ifdef SUPPORT_TRANSLATE_IP_ADDRESS
8768d548 867 fprintf(fp, " translate_ip_address");
b2f5a032 868#endif
f174f16e 869#ifdef SUPPORT_MOVE_FROZEN_MESSAGES
8768d548 870 fprintf(fp, " move_frozen_messages");
f174f16e 871#endif
8523533c 872#ifdef WITH_CONTENT_SCAN
8768d548 873 fprintf(fp, " Content_Scanning");
8523533c 874#endif
c0635b6d 875#ifdef SUPPORT_DANE
8768d548 876 fprintf(fp, " DANE");
c0635b6d 877#endif
74f150bf 878#ifndef DISABLE_DKIM
8768d548 879 fprintf(fp, " DKIM");
74f150bf 880#endif
ef1bbb27 881#ifndef DISABLE_DNSSEC
8768d548 882 fprintf(fp, " DNSSEC");
ef1bbb27 883#endif
0cbf2b82 884#ifndef DISABLE_EVENT
8768d548 885 fprintf(fp, " Event");
0cbf2b82 886#endif
8c5d388a 887#ifdef SUPPORT_I18N
8768d548 888 fprintf(fp, " I18N");
8c5d388a 889#endif
74f150bf 890#ifndef DISABLE_OCSP
8768d548 891 fprintf(fp, " OCSP");
74f150bf 892#endif
4e48d56c
JH
893#ifdef SUPPORT_PIPE_CONNECT
894 fprintf(fp, " PIPE_CONNECT");
895#endif
4d832da1 896#ifndef DISABLE_PRDR
8768d548 897 fprintf(fp, " PRDR");
4d832da1 898#endif
cee5f132 899#ifdef SUPPORT_PROXY
8768d548 900 fprintf(fp, " PROXY");
cee5f132 901#endif
f0989ec0 902#ifdef SUPPORT_SOCKS
8768d548 903 fprintf(fp, " SOCKS");
f2de3a33 904#endif
7952eef9 905#ifdef SUPPORT_SPF
8768d548 906 fprintf(fp, " SPF");
7952eef9 907#endif
1a2dfad5 908#ifdef TCP_FASTOPEN
10ac8d7f 909 deliver_init();
8768d548 910 if (f.tcp_fastopen_ok) fprintf(fp, " TCP_Fast_Open");
1a2dfad5 911#endif
5bde3efa 912#ifdef EXPERIMENTAL_LMDB
8768d548 913 fprintf(fp, " Experimental_LMDB");
5bde3efa 914#endif
3369a853 915#ifdef EXPERIMENTAL_QUEUEFILE
8768d548 916 fprintf(fp, " Experimental_QUEUEFILE");
3369a853 917#endif
8523533c 918#ifdef EXPERIMENTAL_SRS
8768d548 919 fprintf(fp, " Experimental_SRS");
8523533c 920#endif
617d3932 921#ifdef EXPERIMENTAL_ARC
8768d548 922 fprintf(fp, " Experimental_ARC");
617d3932 923#endif
8523533c 924#ifdef EXPERIMENTAL_BRIGHTMAIL
8768d548 925 fprintf(fp, " Experimental_Brightmail");
8523533c 926#endif
6a8f9482 927#ifdef EXPERIMENTAL_DCC
8768d548 928 fprintf(fp, " Experimental_DCC");
6a8f9482 929#endif
4840604e 930#ifdef EXPERIMENTAL_DMARC
8768d548 931 fprintf(fp, " Experimental_DMARC");
4840604e 932#endif
895fbaf2 933#ifdef EXPERIMENTAL_DSN_INFO
8768d548 934 fprintf(fp, " Experimental_DSN_info");
895fbaf2 935#endif
b10c87b3
JH
936#ifdef EXPERIMENTAL_TLS_RESUME
937 fprintf(fp, " Experimental_TLS_resume");
938#endif
8768d548 939fprintf(fp, "\n");
059ec3d9 940
8768d548 941fprintf(fp, "Lookups (built-in):");
e6d225ae 942#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
8768d548 943 fprintf(fp, " lsearch wildlsearch nwildlsearch iplsearch");
059ec3d9 944#endif
e6d225ae 945#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
8768d548 946 fprintf(fp, " cdb");
059ec3d9 947#endif
e6d225ae 948#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
8768d548 949 fprintf(fp, " dbm dbmjz dbmnz");
059ec3d9 950#endif
e6d225ae 951#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
8768d548 952 fprintf(fp, " dnsdb");
059ec3d9 953#endif
e6d225ae 954#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
8768d548 955 fprintf(fp, " dsearch");
059ec3d9 956#endif
e6d225ae 957#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
8768d548 958 fprintf(fp, " ibase");
059ec3d9 959#endif
ffc92d69
JH
960#if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
961 fprintf(fp, " json");
962#endif
e6d225ae 963#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
8768d548 964 fprintf(fp, " ldap ldapdn ldapm");
059ec3d9 965#endif
5bde3efa 966#ifdef EXPERIMENTAL_LMDB
8768d548 967 fprintf(fp, " lmdb");
5bde3efa 968#endif
e6d225ae 969#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
8768d548 970 fprintf(fp, " mysql");
059ec3d9 971#endif
e6d225ae 972#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
8768d548 973 fprintf(fp, " nis nis0");
059ec3d9 974#endif
e6d225ae 975#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
8768d548 976 fprintf(fp, " nisplus");
059ec3d9 977#endif
e6d225ae 978#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
8768d548 979 fprintf(fp, " oracle");
059ec3d9 980#endif
e6d225ae 981#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
8768d548 982 fprintf(fp, " passwd");
059ec3d9 983#endif
e6d225ae 984#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
8768d548 985 fprintf(fp, " pgsql");
059ec3d9 986#endif
de78e2d5 987#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
8768d548 988 fprintf(fp, " redis");
de78e2d5 989#endif
e6d225ae 990#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
8768d548 991 fprintf(fp, " sqlite");
13b685f9 992#endif
e6d225ae 993#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
8768d548 994 fprintf(fp, " testdb");
059ec3d9 995#endif
e6d225ae 996#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
8768d548 997 fprintf(fp, " whoson");
059ec3d9 998#endif
8768d548 999fprintf(fp, "\n");
059ec3d9 1000
8768d548
JH
1001auth_show_supported(fp);
1002route_show_supported(fp);
1003transport_show_supported(fp);
059ec3d9 1004
c11d665d 1005#ifdef WITH_CONTENT_SCAN
8768d548 1006malware_show_supported(fp);
c11d665d
JH
1007#endif
1008
059ec3d9
PH
1009if (fixed_never_users[0] > 0)
1010 {
1011 int i;
8768d548 1012 fprintf(fp, "Fixed never_users: ");
059ec3d9 1013 for (i = 1; i <= (int)fixed_never_users[0] - 1; i++)
8768d548
JH
1014 fprintf(fp, "%d:", (unsigned int)fixed_never_users[i]);
1015 fprintf(fp, "%d\n", (unsigned int)fixed_never_users[i]);
059ec3d9 1016 }
21c28500 1017
8768d548 1018fprintf(fp, "Configure owner: %d:%d\n", config_uid, config_gid);
19bfe9e7 1019
8768d548 1020fprintf(fp, "Size of off_t: " SIZE_T_FMT "\n", sizeof(off_t));
36f12725 1021
6545de78
PP
1022/* Everything else is details which are only worth reporting when debugging.
1023Perhaps the tls_version_report should move into this too. */
1024DEBUG(D_any) do {
1025
b3c261f7
PP
1026/* clang defines __GNUC__ (at least, for me) so test for it first */
1027#if defined(__clang__)
8768d548 1028 fprintf(fp, "Compiler: CLang [%s]\n", __clang_version__);
b3c261f7 1029#elif defined(__GNUC__)
8768d548 1030 fprintf(fp, "Compiler: GCC [%s]\n",
b3c261f7
PP
1031# ifdef __VERSION__
1032 __VERSION__
1033# else
1034 "? unknown version ?"
1035# endif
1036 );
1037#else
8768d548 1038 fprintf(fp, "Compiler: <unknown>\n");
b3c261f7
PP
1039#endif
1040
98913c8e 1041#if defined(__GLIBC__) && !defined(__UCLIBC__)
8768d548 1042 fprintf(fp, "Library version: Glibc: Compile: %d.%d\n",
01f3091a
JH
1043 __GLIBC__, __GLIBC_MINOR__);
1044 if (__GLIBC_PREREQ(2, 1))
8768d548 1045 fprintf(fp, " Runtime: %s\n",
01f3091a
JH
1046 gnu_get_libc_version());
1047#endif
1048
8768d548 1049show_db_version(fp);
96508de1 1050
01603eec 1051#ifndef DISABLE_TLS
8768d548 1052 tls_version_report(fp);
754a0503 1053#endif
8c5d388a 1054#ifdef SUPPORT_I18N
8768d548 1055 utf8_version_report(fp);
b04be5e7 1056#endif
754a0503 1057
d7978c0f 1058 for (auth_info * authi = auths_available; *authi->driver_name != '\0'; ++authi)
fc362fc5 1059 if (authi->version_report)
8768d548 1060 (*authi->version_report)(fp);
6545de78 1061
decd95cb 1062 /* PCRE_PRERELEASE is either defined and empty or a bare sequence of
6475bd82
PP
1063 characters; unless it's an ancient version of PCRE in which case it
1064 is not defined. */
1065#ifndef PCRE_PRERELEASE
01f3091a 1066# define PCRE_PRERELEASE
6475bd82
PP
1067#endif
1068#define QUOTE(X) #X
1069#define EXPAND_AND_QUOTE(X) QUOTE(X)
8768d548 1070 fprintf(fp, "Library version: PCRE: Compile: %d.%d%s\n"
6545de78
PP
1071 " Runtime: %s\n",
1072 PCRE_MAJOR, PCRE_MINOR,
6475bd82 1073 EXPAND_AND_QUOTE(PCRE_PRERELEASE) "",
6545de78 1074 pcre_version());
6475bd82
PP
1075#undef QUOTE
1076#undef EXPAND_AND_QUOTE
6545de78
PP
1077
1078 init_lookup_list();
d7978c0f 1079 for (int i = 0; i < lookup_list_count; i++)
6545de78 1080 if (lookup_list[i]->version_report)
8768d548 1081 lookup_list[i]->version_report(fp);
6545de78 1082
b70d2586 1083#ifdef WHITELIST_D_MACROS
8768d548 1084 fprintf(fp, "WHITELIST_D_MACROS: \"%s\"\n", WHITELIST_D_MACROS);
b70d2586 1085#else
8768d548 1086 fprintf(fp, "WHITELIST_D_MACROS unset\n");
b70d2586
PP
1087#endif
1088#ifdef TRUSTED_CONFIG_LIST
8768d548 1089 fprintf(fp, "TRUSTED_CONFIG_LIST: \"%s\"\n", TRUSTED_CONFIG_LIST);
b70d2586 1090#else
8768d548 1091 fprintf(fp, "TRUSTED_CONFIG_LIST unset\n");
b70d2586
PP
1092#endif
1093
6545de78 1094} while (0);
059ec3d9
PH
1095}
1096
1097
98a90c36
PP
1098/*************************************************
1099* Show auxiliary information about Exim *
1100*************************************************/
1101
1102static void
1103show_exim_information(enum commandline_info request, FILE *stream)
1104{
98a90c36
PP
1105switch(request)
1106 {
1107 case CMDINFO_NONE:
1108 fprintf(stream, "Oops, something went wrong.\n");
1109 return;
1110 case CMDINFO_HELP:
1111 fprintf(stream,
1112"The -bI: flag takes a string indicating which information to provide.\n"
1113"If the string is not recognised, you'll get this help (on stderr).\n"
1114"\n"
1115" exim -bI:help this information\n"
030caf2a
JS
1116" exim -bI:dscp list of known dscp value keywords\n"
1117" exim -bI:sieve list of supported sieve extensions\n"
98a90c36
PP
1118);
1119 return;
1120 case CMDINFO_SIEVE:
d7978c0f 1121 for (const uschar ** pp = exim_sieve_extension_list; *pp; ++pp)
98a90c36
PP
1122 fprintf(stream, "%s\n", *pp);
1123 return;
36a3ae5f
PP
1124 case CMDINFO_DSCP:
1125 dscp_list_to_stream(stream);
1126 return;
98a90c36
PP
1127 }
1128}
059ec3d9
PH
1129
1130
1131/*************************************************
1132* Quote a local part *
1133*************************************************/
1134
1135/* This function is used when a sender address or a From: or Sender: header
1136line is being created from the caller's login, or from an authenticated_id. It
1137applies appropriate quoting rules for a local part.
1138
1139Argument: the local part
1140Returns: the local part, quoted if necessary
1141*/
1142
1143uschar *
1144local_part_quote(uschar *lpart)
1145{
1146BOOL needs_quote = FALSE;
acec9514 1147gstring * g;
059ec3d9 1148
d7978c0f 1149for (uschar * t = lpart; !needs_quote && *t != 0; t++)
059ec3d9
PH
1150 {
1151 needs_quote = !isalnum(*t) && strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL &&
1152 (*t != '.' || t == lpart || t[1] == 0);
1153 }
1154
1155if (!needs_quote) return lpart;
1156
acec9514 1157g = string_catn(NULL, US"\"", 1);
059ec3d9
PH
1158
1159for (;;)
1160 {
1161 uschar *nq = US Ustrpbrk(lpart, "\\\"");
1162 if (nq == NULL)
1163 {
acec9514 1164 g = string_cat(g, lpart);
059ec3d9
PH
1165 break;
1166 }
acec9514
JH
1167 g = string_catn(g, lpart, nq - lpart);
1168 g = string_catn(g, US"\\", 1);
1169 g = string_catn(g, nq, 1);
059ec3d9
PH
1170 lpart = nq + 1;
1171 }
1172
acec9514
JH
1173g = string_catn(g, US"\"", 1);
1174return string_from_gstring(g);
059ec3d9
PH
1175}
1176
1177
1178
1179#ifdef USE_READLINE
1180/*************************************************
1181* Load readline() functions *
1182*************************************************/
1183
1184/* This function is called from testing executions that read data from stdin,
1185but only when running as the calling user. Currently, only -be does this. The
1186function loads the readline() function library and passes back the functions.
1187On some systems, it needs the curses library, so load that too, but try without
1188it if loading fails. All this functionality has to be requested at build time.
1189
1190Arguments:
1191 fn_readline_ptr pointer to where to put the readline pointer
1192 fn_addhist_ptr pointer to where to put the addhistory function
1193
1194Returns: the dlopen handle or NULL on failure
1195*/
1196
1197static void *
1ba28e2b
PP
1198set_readline(char * (**fn_readline_ptr)(const char *),
1199 void (**fn_addhist_ptr)(const char *))
059ec3d9
PH
1200{
1201void *dlhandle;
e12f8c32 1202void *dlhandle_curses = dlopen("libcurses." DYNLIB_FN_EXT, RTLD_GLOBAL|RTLD_LAZY);
059ec3d9 1203
e12f8c32 1204dlhandle = dlopen("libreadline." DYNLIB_FN_EXT, RTLD_GLOBAL|RTLD_NOW);
059ec3d9
PH
1205if (dlhandle_curses != NULL) dlclose(dlhandle_curses);
1206
1207if (dlhandle != NULL)
1208 {
1ba28e2b
PP
1209 /* Checked manual pages; at least in GNU Readline 6.1, the prototypes are:
1210 * char * readline (const char *prompt);
1211 * void add_history (const char *string);
1212 */
1213 *fn_readline_ptr = (char *(*)(const char*))dlsym(dlhandle, "readline");
1214 *fn_addhist_ptr = (void(*)(const char*))dlsym(dlhandle, "add_history");
059ec3d9
PH
1215 }
1216else
1217 {
1218 DEBUG(D_any) debug_printf("failed to load readline: %s\n", dlerror());
1219 }
1220
1221return dlhandle;
1222}
1223#endif
1224
1225
1226
1227/*************************************************
1228* Get a line from stdin for testing things *
1229*************************************************/
1230
1231/* This function is called when running tests that can take a number of lines
1232of input (for example, -be and -bt). It handles continuations and trailing
1233spaces. And prompting and a blank line output on eof. If readline() is in use,
1234the arguments are non-NULL and provide the relevant functions.
1235
1236Arguments:
1237 fn_readline readline function or NULL
1238 fn_addhist addhist function or NULL
1239
1240Returns: pointer to dynamic memory, or NULL at end of file
1241*/
1242
1243static uschar *
1ba28e2b 1244get_stdinput(char *(*fn_readline)(const char *), void(*fn_addhist)(const char *))
059ec3d9 1245{
acec9514 1246gstring * g = NULL;
059ec3d9 1247
acec9514 1248if (!fn_readline) { printf("> "); fflush(stdout); }
059ec3d9 1249
d7978c0f 1250for (int i = 0;; i++)
059ec3d9
PH
1251 {
1252 uschar buffer[1024];
1253 uschar *p, *ss;
1254
1255 #ifdef USE_READLINE
1256 char *readline_line = NULL;
1257 if (fn_readline != NULL)
1258 {
1259 if ((readline_line = fn_readline((i > 0)? "":"> ")) == NULL) break;
1260 if (*readline_line != 0 && fn_addhist != NULL) fn_addhist(readline_line);
1261 p = US readline_line;
1262 }
1263 else
1264 #endif
1265
1266 /* readline() not in use */
1267
1268 {
1269 if (Ufgets(buffer, sizeof(buffer), stdin) == NULL) break;
1270 p = buffer;
1271 }
1272
1273 /* Handle the line */
1274
1275 ss = p + (int)Ustrlen(p);
1276 while (ss > p && isspace(ss[-1])) ss--;
1277
1278 if (i > 0)
1279 {
1280 while (p < ss && isspace(*p)) p++; /* leading space after cont */
1281 }
1282
acec9514 1283 g = string_catn(g, p, ss - p);
059ec3d9
PH
1284
1285 #ifdef USE_READLINE
acec9514 1286 if (fn_readline) free(readline_line);
059ec3d9
PH
1287 #endif
1288
acec9514
JH
1289 /* g can only be NULL if ss==p */
1290 if (ss == p || g->s[g->ptr-1] != '\\')
059ec3d9 1291 break;
acec9514
JH
1292
1293 --g->ptr;
1294 (void) string_from_gstring(g);
059ec3d9
PH
1295 }
1296
acec9514
JH
1297if (!g) printf("\n");
1298return string_from_gstring(g);
059ec3d9
PH
1299}
1300
1301
1302
1303/*************************************************
81ea09ca
NM
1304* Output usage information for the program *
1305*************************************************/
1306
1307/* This function is called when there are no recipients
1308 or a specific --help argument was added.
1309
1310Arguments:
1311 progname information on what name we were called by
1312
1313Returns: DOES NOT RETURN
1314*/
1315
1316static void
1317exim_usage(uschar *progname)
1318{
1319
4c04137d 1320/* Handle specific program invocation variants */
81ea09ca 1321if (Ustrcmp(progname, US"-mailq") == 0)
9af3c549 1322 exim_fail(
e765a0f1 1323 "mailq - list the contents of the mail queue\n\n"
81ea09ca 1324 "For a list of options, see the Exim documentation.\n");
81ea09ca
NM
1325
1326/* Generic usage - we output this whatever happens */
9af3c549 1327exim_fail(
81ea09ca
NM
1328 "Exim is a Mail Transfer Agent. It is normally called by Mail User Agents,\n"
1329 "not directly from a shell command line. Options and/or arguments control\n"
1330 "what it does when called. For a list of options, see the Exim documentation.\n");
81ea09ca
NM
1331}
1332
1333
1334
1335/*************************************************
a7cbbf50
PP
1336* Validate that the macros given are okay *
1337*************************************************/
1338
1339/* Typically, Exim will drop privileges if macros are supplied. In some
1340cases, we want to not do so.
1341
a4034eb8 1342Arguments: opt_D_used - true if the commandline had a "-D" option
a7cbbf50
PP
1343Returns: true if trusted, false otherwise
1344*/
1345
1346static BOOL
a4034eb8 1347macros_trusted(BOOL opt_D_used)
a7cbbf50
PP
1348{
1349#ifdef WHITELIST_D_MACROS
d7978c0f 1350uschar *whitelisted, *end, *p, **whites;
a7cbbf50
PP
1351int white_count, i, n;
1352size_t len;
1353BOOL prev_char_item, found;
1354#endif
1355
a4034eb8 1356if (!opt_D_used)
a7cbbf50
PP
1357 return TRUE;
1358#ifndef WHITELIST_D_MACROS
1359return FALSE;
1360#else
1361
66581d1e
PP
1362/* We only trust -D overrides for some invoking users:
1363root, the exim run-time user, the optional config owner user.
1364I don't know why config-owner would be needed, but since they can own the
1365config files anyway, there's no security risk to letting them override -D. */
1366if ( ! ((real_uid == root_uid)
1367 || (real_uid == exim_uid)
1368#ifdef CONFIGURE_OWNER
1369 || (real_uid == config_uid)
1370#endif
1371 ))
1372 {
1373 debug_printf("macros_trusted rejecting macros for uid %d\n", (int) real_uid);
1374 return FALSE;
1375 }
1376
a7cbbf50
PP
1377/* Get a list of macros which are whitelisted */
1378whitelisted = string_copy_malloc(US WHITELIST_D_MACROS);
1379prev_char_item = FALSE;
1380white_count = 0;
1381for (p = whitelisted; *p != '\0'; ++p)
1382 {
1383 if (*p == ':' || isspace(*p))
1384 {
1385 *p = '\0';
1386 if (prev_char_item)
1387 ++white_count;
1388 prev_char_item = FALSE;
1389 continue;
1390 }
1391 if (!prev_char_item)
1392 prev_char_item = TRUE;
1393 }
1394end = p;
1395if (prev_char_item)
1396 ++white_count;
1397if (!white_count)
1398 return FALSE;
1399whites = store_malloc(sizeof(uschar *) * (white_count+1));
1400for (p = whitelisted, i = 0; (p != end) && (i < white_count); ++p)
1401 {
1402 if (*p != '\0')
1403 {
1404 whites[i++] = p;
1405 if (i == white_count)
1406 break;
1407 while (*p != '\0' && p < end)
1408 ++p;
1409 }
1410 }
1411whites[i] = NULL;
1412
1a7c9a48
JH
1413/* The list of commandline macros should be very short.
1414Accept the N*M complexity. */
d7978c0f 1415for (macro_item * m = macros_user; m; m = m->next) if (m->command_line)
1a7c9a48
JH
1416 {
1417 found = FALSE;
d7978c0f 1418 for (uschar ** w = whites; *w; ++w)
1a7c9a48
JH
1419 if (Ustrcmp(*w, m->name) == 0)
1420 {
1421 found = TRUE;
1422 break;
1423 }
1424 if (!found)
1425 return FALSE;
1426 if (!m->replacement)
1427 continue;
1428 if ((len = m->replen) == 0)
1429 continue;
1430 n = pcre_exec(regex_whitelisted_macro, NULL, CS m->replacement, len,
1431 0, PCRE_EOPT, NULL, 0);
1432 if (n < 0)
1433 {
1434 if (n != PCRE_ERROR_NOMATCH)
1435 debug_printf("macros_trusted checking %s returned %d\n", m->name, n);
1436 return FALSE;
1437 }
1438 }
43236f35 1439DEBUG(D_any) debug_printf("macros_trusted overridden to true by whitelisting\n");
a7cbbf50
PP
1440return TRUE;
1441#endif
1442}
1443
1444
1445/*************************************************
9650d98a
JH
1446* Expansion testing *
1447*************************************************/
1448
1449/* Expand and print one item, doing macro-processing.
1450
1451Arguments:
1452 item line for expansion
1453*/
1454
1455static void
1456expansion_test_line(uschar * line)
1457{
1458int len;
1459BOOL dummy_macexp;
1460
1461Ustrncpy(big_buffer, line, big_buffer_size);
1462big_buffer[big_buffer_size-1] = '\0';
1463len = Ustrlen(big_buffer);
1464
1465(void) macros_expand(0, &len, &dummy_macexp);
1466
1467if (isupper(big_buffer[0]))
1468 {
1469 if (macro_read_assignment(big_buffer))
1a7c9a48 1470 printf("Defined macro '%s'\n", mlast->name);
9650d98a
JH
1471 }
1472else
1473 if ((line = expand_string(big_buffer))) printf("%s\n", CS line);
1474 else printf("Failed: %s\n", expand_string_message);
1475}
1476
1477
9af3c549 1478
9650d98a 1479/*************************************************
059ec3d9
PH
1480* Entry point and high-level code *
1481*************************************************/
1482
1483/* Entry point for the Exim mailer. Analyse the arguments and arrange to take
1484the appropriate action. All the necessary functions are present in the one
1485binary. I originally thought one should split it up, but it turns out that so
1486much of the apparatus is needed in each chunk that one might as well just have
1487it all available all the time, which then makes the coding easier as well.
1488
1489Arguments:
1490 argc count of entries in argv
1491 argv argument strings, with argv[0] being the program name
1492
1493Returns: EXIT_SUCCESS if terminated successfully
1494 EXIT_FAILURE otherwise, except when a message has been sent
1495 to the sender, and -oee was given
1496*/
1497
1498int
1499main(int argc, char **cargv)
1500{
1501uschar **argv = USS cargv;
1502int arg_receive_timeout = -1;
1503int arg_smtp_receive_timeout = -1;
1504int arg_error_handling = error_handling;
f05da2e8
PH
1505int filter_sfd = -1;
1506int filter_ufd = -1;
059ec3d9 1507int group_count;
1670ef10 1508int i, rv;
059ec3d9
PH
1509int list_queue_option = 0;
1510int msg_action = 0;
1511int msg_action_arg = -1;
1512int namelen = (argv[0] == NULL)? 0 : Ustrlen(argv[0]);
1513int queue_only_reason = 0;
1514#ifdef EXIM_PERL
1515int perl_start_option = 0;
1516#endif
1517int recipients_arg = argc;
1518int sender_address_domain = 0;
1519int test_retry_arg = -1;
1520int test_rewrite_arg = -1;
3b7ac02c 1521gid_t original_egid;
059ec3d9
PH
1522BOOL arg_queue_only = FALSE;
1523BOOL bi_option = FALSE;
1524BOOL checking = FALSE;
1525BOOL count_queue = FALSE;
1526BOOL expansion_test = FALSE;
1527BOOL extract_recipients = FALSE;
f4ee74ac 1528BOOL flag_G = FALSE;
12f69989 1529BOOL flag_n = FALSE;
059ec3d9
PH
1530BOOL forced_delivery = FALSE;
1531BOOL f_end_dot = FALSE;
1532BOOL deliver_give_up = FALSE;
1533BOOL list_queue = FALSE;
1534BOOL list_options = FALSE;
bf3c2c6b 1535BOOL list_config = FALSE;
059ec3d9
PH
1536BOOL local_queue_only;
1537BOOL more = TRUE;
1538BOOL one_msg_action = FALSE;
4ab69ec7 1539BOOL opt_D_used = FALSE;
059ec3d9
PH
1540BOOL queue_only_set = FALSE;
1541BOOL receiving_message = TRUE;
33d73e3b 1542BOOL sender_ident_set = FALSE;
8669f003 1543BOOL session_local_queue_only;
059ec3d9
PH
1544BOOL unprivileged;
1545BOOL removed_privilege = FALSE;
81ea09ca 1546BOOL usage_wanted = FALSE;
059ec3d9
PH
1547BOOL verify_address_mode = FALSE;
1548BOOL verify_as_sender = FALSE;
1549BOOL version_printed = FALSE;
1550uschar *alias_arg = NULL;
1551uschar *called_as = US"";
a3fb9793 1552uschar *cmdline_syslog_name = NULL;
059ec3d9
PH
1553uschar *start_queue_run_id = NULL;
1554uschar *stop_queue_run_id = NULL;
328895cc 1555uschar *expansion_test_message = NULL;
059ec3d9
PH
1556uschar *ftest_domain = NULL;
1557uschar *ftest_localpart = NULL;
1558uschar *ftest_prefix = NULL;
1559uschar *ftest_suffix = NULL;
0ad2e0fc 1560uschar *log_oneline = NULL;
8544e77a 1561uschar *malware_test_file = NULL;
059ec3d9
PH
1562uschar *real_sender_address;
1563uschar *originator_home = US"/";
a3fb9793 1564size_t sz;
059ec3d9
PH
1565void *reset_point;
1566
1567struct passwd *pw;
1568struct stat statbuf;
1569pid_t passed_qr_pid = (pid_t)0;
1570int passed_qr_pipe = -1;
157d73b5 1571gid_t group_list[EXIM_GROUPLIST_SIZE];
059ec3d9 1572
98a90c36
PP
1573/* For the -bI: flag */
1574enum commandline_info info_flag = CMDINFO_NONE;
1575BOOL info_stdout = FALSE;
1576
059ec3d9
PH
1577/* Possible options for -R and -S */
1578
1579static uschar *rsopts[] = { US"f", US"ff", US"r", US"rf", US"rff" };
1580
1581/* Need to define this in case we need to change the environment in order
1582to get rid of a bogus time zone. We have to make it char rather than uschar
1583because some OS define it in /usr/include/unistd.h. */
1584
1585extern char **environ;
1586
35edf2ff 1587/* If the Exim user and/or group and/or the configuration file owner/group were
059ec3d9
PH
1588defined by ref:name at build time, we must now find the actual uid/gid values.
1589This is a feature to make the lives of binary distributors easier. */
1590
1591#ifdef EXIM_USERNAME
1592if (route_finduser(US EXIM_USERNAME, &pw, &exim_uid))
1593 {
10385c15 1594 if (exim_uid == 0)
9af3c549
JH
1595 exim_fail("exim: refusing to run with uid 0 for \"%s\"\n", EXIM_USERNAME);
1596
084c1d8c
PP
1597 /* If ref:name uses a number as the name, route_finduser() returns
1598 TRUE with exim_uid set and pw coerced to NULL. */
1599 if (pw)
1600 exim_gid = pw->pw_gid;
1601#ifndef EXIM_GROUPNAME
1602 else
9af3c549 1603 exim_fail(
084c1d8c
PP
1604 "exim: ref:name should specify a usercode, not a group.\n"
1605 "exim: can't let you get away with it unless you also specify a group.\n");
084c1d8c 1606#endif
059ec3d9
PH
1607 }
1608else
9af3c549 1609 exim_fail("exim: failed to find uid for user name \"%s\"\n", EXIM_USERNAME);
059ec3d9
PH
1610#endif
1611
1612#ifdef EXIM_GROUPNAME
1613if (!route_findgroup(US EXIM_GROUPNAME, &exim_gid))
9af3c549 1614 exim_fail("exim: failed to find gid for group name \"%s\"\n", EXIM_GROUPNAME);
059ec3d9
PH
1615#endif
1616
1617#ifdef CONFIGURE_OWNERNAME
1618if (!route_finduser(US CONFIGURE_OWNERNAME, NULL, &config_uid))
9af3c549 1619 exim_fail("exim: failed to find uid for user name \"%s\"\n",
059ec3d9 1620 CONFIGURE_OWNERNAME);
059ec3d9
PH
1621#endif
1622
79d4bc3d
PP
1623/* We default the system_filter_user to be the Exim run-time user, as a
1624sane non-root value. */
1625system_filter_uid = exim_uid;
1626
35edf2ff
PH
1627#ifdef CONFIGURE_GROUPNAME
1628if (!route_findgroup(US CONFIGURE_GROUPNAME, &config_gid))
9af3c549 1629 exim_fail("exim: failed to find gid for group name \"%s\"\n",
35edf2ff 1630 CONFIGURE_GROUPNAME);
35edf2ff
PH
1631#endif
1632
92e6a3d9
JH
1633/* In the Cygwin environment, some initialization used to need doing.
1634It was fudged in by means of this macro; now no longer but we'll leave
1635it in case of others. */
059ec3d9
PH
1636
1637#ifdef OS_INIT
1638OS_INIT
1639#endif
1640
1641/* Check a field which is patched when we are running Exim within its
1642testing harness; do a fast initial check, and then the whole thing. */
1643
8768d548 1644f.running_in_test_harness =
059ec3d9 1645 *running_status == '<' && Ustrcmp(running_status, "<<<testing>>>") == 0;
8768d548 1646if (f.running_in_test_harness)
65a32f85 1647 debug_store = TRUE;
059ec3d9
PH
1648
1649/* The C standard says that the equivalent of setlocale(LC_ALL, "C") is obeyed
1650at the start of a program; however, it seems that some environments do not
1651follow this. A "strange" locale can affect the formatting of timestamps, so we
1652make quite sure. */
1653
1654setlocale(LC_ALL, "C");
1655
1656/* Set up the default handler for timing using alarm(). */
1657
1658os_non_restarting_signal(SIGALRM, sigalrm_handler);
1659
1660/* Ensure we have a buffer for constructing log entries. Use malloc directly,
1661because store_malloc writes a log entry on failure. */
1662
40c90bca 1663if (!(log_buffer = US malloc(LOG_BUFFER_SIZE)))
9af3c549 1664 exim_fail("exim: failed to get store for log buffer\n");
059ec3d9 1665
6c6d6e48
TF
1666/* Initialize the default log options. */
1667
1668bits_set(log_selector, log_selector_size, log_default);
1669
059ec3d9
PH
1670/* Set log_stderr to stderr, provided that stderr exists. This gets reset to
1671NULL when the daemon is run and the file is closed. We have to use this
1672indirection, because some systems don't allow writing to the variable "stderr".
1673*/
1674
1675if (fstat(fileno(stderr), &statbuf) >= 0) log_stderr = stderr;
1676
1677/* Arrange for the PCRE regex library to use our store functions. Note that
1678the normal calls are actually macros that add additional arguments for
1679debugging purposes so we have to assign specially constructed functions here.
1680The default is to use store in the stacking pool, but this is overridden in the
1681regex_must_compile() function. */
1682
1683pcre_malloc = function_store_get;
1684pcre_free = function_dummy_free;
1685
1686/* Ensure there is a big buffer for temporary use in several places. It is put
1687in malloc store so that it can be freed for enlargement if necessary. */
1688
1689big_buffer = store_malloc(big_buffer_size);
1690
1691/* Set up the handler for the data request signal, and set the initial
1692descriptive text. */
1693
1694set_process_info("initializing");
1695os_restarting_signal(SIGUSR1, usr1_handler);
1696
830832c9
HSHR
1697/* If running in a dockerized environment, the TERM signal is only
1698delegated to the PID 1 if we request it by setting an signal handler */
1699if (getpid() == 1) signal(SIGTERM, term_handler);
1700
059ec3d9
PH
1701/* SIGHUP is used to get the daemon to reconfigure. It gets set as appropriate
1702in the daemon code. For the rest of Exim's uses, we ignore it. */
1703
1704signal(SIGHUP, SIG_IGN);
1705
1706/* We don't want to die on pipe errors as the code is written to handle
1707the write error instead. */
1708
1709signal(SIGPIPE, SIG_IGN);
1710
1711/* Under some circumstance on some OS, Exim can get called with SIGCHLD
1712set to SIG_IGN. This causes subprocesses that complete before the parent
1713process waits for them not to hang around, so when Exim calls wait(), nothing
1714is there. The wait() code has been made robust against this, but let's ensure
1715that SIGCHLD is set to SIG_DFL, because it's tidier to wait and get a process
1716ending status. We use sigaction rather than plain signal() on those OS where
1717SA_NOCLDWAIT exists, because we want to be sure it is turned off. (There was a
1718problem on AIX with this.) */
1719
1720#ifdef SA_NOCLDWAIT
1721 {
1722 struct sigaction act;
1723 act.sa_handler = SIG_DFL;
1724 sigemptyset(&(act.sa_mask));
1725 act.sa_flags = 0;
1726 sigaction(SIGCHLD, &act, NULL);
1727 }
1728#else
1729signal(SIGCHLD, SIG_DFL);
1730#endif
1731
1732/* Save the arguments for use if we re-exec exim as a daemon after receiving
1733SIGHUP. */
1734
1735sighup_argv = argv;
1736
1737/* Set up the version number. Set up the leading 'E' for the external form of
1738message ids, set the pointer to the internal form, and initialize it to
1739indicate no message being processed. */
1740
1741version_init();
1742message_id_option[0] = '-';
1743message_id_external = message_id_option + 1;
1744message_id_external[0] = 'E';
1745message_id = message_id_external + 1;
1746message_id[0] = 0;
1747
67d175de 1748/* Set the umask to zero so that any files Exim creates using open() are
2632889e
PH
1749created with the modes that it specifies. NOTE: Files created with fopen() have
1750a problem, which was not recognized till rather late (February 2006). With this
1751umask, such files will be world writeable. (They are all content scanning files
1752in the spool directory, which isn't world-accessible, so this is not a
1753disaster, but it's untidy.) I don't want to change this overall setting,
1754however, because it will interact badly with the open() calls. Instead, there's
1755now a function called modefopen() that fiddles with the umask while calling
1756fopen(). */
059ec3d9 1757
67d175de 1758(void)umask(0);
059ec3d9
PH
1759
1760/* Precompile the regular expression for matching a message id. Keep this in
1761step with the code that generates ids in the accept.c module. We need to do
1762this here, because the -M options check their arguments for syntactic validity
1763using mac_ismsgid, which uses this. */
1764
1765regex_ismsgid =
1766 regex_must_compile(US"^(?:[^\\W_]{6}-){2}[^\\W_]{2}$", FALSE, TRUE);
1767
a5bd321b 1768/* Precompile the regular expression that is used for matching an SMTP error
d6a96edc
PH
1769code, possibly extended, at the start of an error message. Note that the
1770terminating whitespace character is included. */
a5bd321b
PH
1771
1772regex_smtp_code =
1773 regex_must_compile(US"^\\d\\d\\d\\s(?:\\d\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\s)?",
1774 FALSE, TRUE);
1775
a7cbbf50
PP
1776#ifdef WHITELIST_D_MACROS
1777/* Precompile the regular expression used to filter the content of macros
1778given to -D for permissibility. */
1779
1780regex_whitelisted_macro =
1781 regex_must_compile(US"^[A-Za-z0-9_/.-]*$", FALSE, TRUE);
1782#endif
1783
f38917cc
JH
1784for (i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
1785
059ec3d9
PH
1786/* If the program is called as "mailq" treat it as equivalent to "exim -bp";
1787this seems to be a generally accepted convention, since one finds symbolic
1788links called "mailq" in standard OS configurations. */
1789
1790if ((namelen == 5 && Ustrcmp(argv[0], "mailq") == 0) ||
1791 (namelen > 5 && Ustrncmp(argv[0] + namelen - 6, "/mailq", 6) == 0))
1792 {
1793 list_queue = TRUE;
1794 receiving_message = FALSE;
1795 called_as = US"-mailq";
1796 }
1797
1798/* If the program is called as "rmail" treat it as equivalent to
1799"exim -i -oee", thus allowing UUCP messages to be input using non-SMTP mode,
1800i.e. preventing a single dot on a line from terminating the message, and
1801returning with zero return code, even in cases of error (provided an error
1802message has been sent). */
1803
1804if ((namelen == 5 && Ustrcmp(argv[0], "rmail") == 0) ||
1805 (namelen > 5 && Ustrncmp(argv[0] + namelen - 6, "/rmail", 6) == 0))
1806 {
8768d548 1807 f.dot_ends = FALSE;
059ec3d9
PH
1808 called_as = US"-rmail";
1809 errors_sender_rc = EXIT_SUCCESS;
1810 }
1811
1812/* If the program is called as "rsmtp" treat it as equivalent to "exim -bS";
1813this is a smail convention. */
1814
1815if ((namelen == 5 && Ustrcmp(argv[0], "rsmtp") == 0) ||
1816 (namelen > 5 && Ustrncmp(argv[0] + namelen - 6, "/rsmtp", 6) == 0))
1817 {
1818 smtp_input = smtp_batched_input = TRUE;
1819 called_as = US"-rsmtp";
1820 }
1821
1822/* If the program is called as "runq" treat it as equivalent to "exim -q";
1823this is a smail convention. */
1824
1825if ((namelen == 4 && Ustrcmp(argv[0], "runq") == 0) ||
1826 (namelen > 4 && Ustrncmp(argv[0] + namelen - 5, "/runq", 5) == 0))
1827 {
1828 queue_interval = 0;
1829 receiving_message = FALSE;
1830 called_as = US"-runq";
1831 }
1832
1833/* If the program is called as "newaliases" treat it as equivalent to
1834"exim -bi"; this is a sendmail convention. */
1835
1836if ((namelen == 10 && Ustrcmp(argv[0], "newaliases") == 0) ||
1837 (namelen > 10 && Ustrncmp(argv[0] + namelen - 11, "/newaliases", 11) == 0))
1838 {
1839 bi_option = TRUE;
1840 receiving_message = FALSE;
1841 called_as = US"-newaliases";
1842 }
1843
1844/* Save the original effective uid for a couple of uses later. It should
1845normally be root, but in some esoteric environments it may not be. */
1846
1847original_euid = geteuid();
3b7ac02c 1848original_egid = getegid();
059ec3d9
PH
1849
1850/* Get the real uid and gid. If the caller is root, force the effective uid/gid
1851to be the same as the real ones. This makes a difference only if Exim is setuid
1852(or setgid) to something other than root, which could be the case in some
1853special configurations. */
1854
1855real_uid = getuid();
1856real_gid = getgid();
1857
1858if (real_uid == root_uid)
1859 {
9af3c549
JH
1860 if ((rv = setgid(real_gid)))
1861 exim_fail("exim: setgid(%ld) failed: %s\n",
1670ef10 1862 (long int)real_gid, strerror(errno));
9af3c549
JH
1863 if ((rv = setuid(real_uid)))
1864 exim_fail("exim: setuid(%ld) failed: %s\n",
1670ef10 1865 (long int)real_uid, strerror(errno));
059ec3d9
PH
1866 }
1867
1868/* If neither the original real uid nor the original euid was root, Exim is
1869running in an unprivileged state. */
1870
1871unprivileged = (real_uid != root_uid && original_euid != root_uid);
1872
059ec3d9
PH
1873/* Scan the program's arguments. Some can be dealt with right away; others are
1874simply recorded for checking and handling afterwards. Do a high-level switch
1875on the second character (the one after '-'), to save some effort. */
1876
1877for (i = 1; i < argc; i++)
1878 {
1879 BOOL badarg = FALSE;
1880 uschar *arg = argv[i];
1881 uschar *argrest;
1882 int switchchar;
1883
1884 /* An argument not starting with '-' is the start of a recipients list;
1885 break out of the options-scanning loop. */
1886
1887 if (arg[0] != '-')
1888 {
1889 recipients_arg = i;
1890 break;
1891 }
1892
4c04137d 1893 /* An option consisting of -- terminates the options */
059ec3d9
PH
1894
1895 if (Ustrcmp(arg, "--") == 0)
1896 {
1897 recipients_arg = i + 1;
1898 break;
1899 }
1900
1901 /* Handle flagged options */
1902
1903 switchchar = arg[1];
1904 argrest = arg+2;
1905
1906 /* Make all -ex options synonymous with -oex arguments, since that
1907 is assumed by various callers. Also make -qR options synonymous with -R
1908 options, as that seems to be required as well. Allow for -qqR too, and
1909 the same for -S options. */
1910
1911 if (Ustrncmp(arg+1, "oe", 2) == 0 ||
1912 Ustrncmp(arg+1, "qR", 2) == 0 ||
1913 Ustrncmp(arg+1, "qS", 2) == 0)
1914 {
1915 switchchar = arg[2];
1916 argrest++;
1917 }
1918 else if (Ustrncmp(arg+1, "qqR", 3) == 0 || Ustrncmp(arg+1, "qqS", 3) == 0)
1919 {
1920 switchchar = arg[3];
1921 argrest += 2;
8768d548 1922 f.queue_2stage = TRUE;
059ec3d9
PH
1923 }
1924
1925 /* Make -r synonymous with -f, since it is a documented alias */
1926
1927 else if (arg[1] == 'r') switchchar = 'f';
1928
1929 /* Make -ov synonymous with -v */
1930
1931 else if (Ustrcmp(arg, "-ov") == 0)
1932 {
1933 switchchar = 'v';
1934 argrest++;
1935 }
1936
4b2241d2
PP
1937 /* deal with --option_aliases */
1938 else if (switchchar == '-')
1939 {
1940 if (Ustrcmp(argrest, "help") == 0)
1941 {
1942 usage_wanted = TRUE;
1943 break;
1944 }
1945 else if (Ustrcmp(argrest, "version") == 0)
1946 {
1947 switchchar = 'b';
73a46702 1948 argrest = US"V";
4b2241d2
PP
1949 }
1950 }
1951
059ec3d9
PH
1952 /* High-level switch on active initial letter */
1953
1954 switch(switchchar)
1955 {
a3fb9793
PP
1956
1957 /* sendmail uses -Ac and -Am to control which .cf file is used;
1958 we ignore them. */
1959 case 'A':
1960 if (*argrest == '\0') { badarg = TRUE; break; }
1961 else
1962 {
1963 BOOL ignore = FALSE;
1964 switch (*argrest)
1965 {
1966 case 'c':
1967 case 'm':
1968 if (*(argrest + 1) == '\0')
1969 ignore = TRUE;
1970 break;
1971 }
1972 if (!ignore) { badarg = TRUE; break; }
1973 }
1974 break;
1975
059ec3d9
PH
1976 /* -Btype is a sendmail option for 7bit/8bit setting. Exim is 8-bit clean
1977 so has no need of it. */
1978
1979 case 'B':
1980 if (*argrest == 0) i++; /* Skip over the type */
1981 break;
1982
1983
1984 case 'b':
1985 receiving_message = FALSE; /* Reset TRUE for -bm, -bS, -bs below */
1986
1987 /* -bd: Run in daemon mode, awaiting SMTP connections.
1988 -bdf: Ditto, but in the foreground.
1989 */
1990
1991 if (*argrest == 'd')
1992 {
8768d548
JH
1993 f.daemon_listen = TRUE;
1994 if (*(++argrest) == 'f') f.background_daemon = FALSE;
059ec3d9
PH
1995 else if (*argrest != 0) { badarg = TRUE; break; }
1996 }
1997
328895cc
PH
1998 /* -be: Run in expansion test mode
1999 -bem: Ditto, but read a message from a file first
2000 */
059ec3d9
PH
2001
2002 else if (*argrest == 'e')
328895cc 2003 {
059ec3d9 2004 expansion_test = checking = TRUE;
328895cc
PH
2005 if (argrest[1] == 'm')
2006 {
2007 if (++i >= argc) { badarg = TRUE; break; }
2008 expansion_test_message = argv[i];
2009 argrest++;
2010 }
2011 if (argrest[1] != 0) { badarg = TRUE; break; }
2012 }
059ec3d9 2013
f05da2e8
PH
2014 /* -bF: Run system filter test */
2015
2016 else if (*argrest == 'F')
2017 {
34e86e20 2018 filter_test |= checking = FTEST_SYSTEM;
f05da2e8
PH
2019 if (*(++argrest) != 0) { badarg = TRUE; break; }
2020 if (++i < argc) filter_test_sfile = argv[i]; else
9af3c549 2021 exim_fail("exim: file name expected after %s\n", argv[i-1]);
f05da2e8
PH
2022 }
2023
2024 /* -bf: Run user filter test
059ec3d9
PH
2025 -bfd: Set domain for filter testing
2026 -bfl: Set local part for filter testing
2027 -bfp: Set prefix for filter testing
2028 -bfs: Set suffix for filter testing
2029 */
2030
f05da2e8 2031 else if (*argrest == 'f')
059ec3d9 2032 {
f05da2e8 2033 if (*(++argrest) == 0)
059ec3d9 2034 {
34e86e20 2035 filter_test |= checking = FTEST_USER;
f05da2e8 2036 if (++i < argc) filter_test_ufile = argv[i]; else
9af3c549 2037 exim_fail("exim: file name expected after %s\n", argv[i-1]);
059ec3d9
PH
2038 }
2039 else
2040 {
2041 if (++i >= argc)
9af3c549 2042 exim_fail("exim: string expected after %s\n", arg);
059ec3d9
PH
2043 if (Ustrcmp(argrest, "d") == 0) ftest_domain = argv[i];
2044 else if (Ustrcmp(argrest, "l") == 0) ftest_localpart = argv[i];
2045 else if (Ustrcmp(argrest, "p") == 0) ftest_prefix = argv[i];
2046 else if (Ustrcmp(argrest, "s") == 0) ftest_suffix = argv[i];
2047 else { badarg = TRUE; break; }
2048 }
2049 }
2050
2051 /* -bh: Host checking - an IP address must follow. */
2052
2053 else if (Ustrcmp(argrest, "h") == 0 || Ustrcmp(argrest, "hc") == 0)
2054 {
2055 if (++i >= argc) { badarg = TRUE; break; }
2056 sender_host_address = argv[i];
8768d548
JH
2057 host_checking = checking = f.log_testing_mode = TRUE;
2058 f.host_checking_callout = argrest[1] == 'c';
1a6230a3 2059 message_logs = FALSE;
059ec3d9
PH
2060 }
2061
2062 /* -bi: This option is used by sendmail to initialize *the* alias file,
2063 though it has the -oA option to specify a different file. Exim has no
2064 concept of *the* alias file, but since Sun's YP make script calls
2065 sendmail this way, some support must be provided. */
2066
2067 else if (Ustrcmp(argrest, "i") == 0) bi_option = TRUE;
2068
98a90c36
PP
2069 /* -bI: provide information, of the type to follow after a colon.
2070 This is an Exim flag. */
2071
2072 else if (argrest[0] == 'I' && Ustrlen(argrest) >= 2 && argrest[1] == ':')
2073 {
2074 uschar *p = &argrest[2];
2075 info_flag = CMDINFO_HELP;
2076 if (Ustrlen(p))
2077 {
2078 if (strcmpic(p, CUS"sieve") == 0)
2079 {
2080 info_flag = CMDINFO_SIEVE;
2081 info_stdout = TRUE;
2082 }
36a3ae5f
PP
2083 else if (strcmpic(p, CUS"dscp") == 0)
2084 {
2085 info_flag = CMDINFO_DSCP;
2086 info_stdout = TRUE;
2087 }
98a90c36
PP
2088 else if (strcmpic(p, CUS"help") == 0)
2089 {
2090 info_stdout = TRUE;
2091 }
2092 }
2093 }
2094
059ec3d9
PH
2095 /* -bm: Accept and deliver message - the default option. Reinstate
2096 receiving_message, which got turned off for all -b options. */
2097
2098 else if (Ustrcmp(argrest, "m") == 0) receiving_message = TRUE;
2099
8544e77a
PP
2100 /* -bmalware: test the filename given for malware */
2101
2102 else if (Ustrcmp(argrest, "malware") == 0)
2103 {
2104 if (++i >= argc) { badarg = TRUE; break; }
34e86e20 2105 checking = TRUE;
8544e77a
PP
2106 malware_test_file = argv[i];
2107 }
2108
059ec3d9
PH
2109 /* -bnq: For locally originating messages, do not qualify unqualified
2110 addresses. In the envelope, this causes errors; in header lines they
2111 just get left. */
2112
2113 else if (Ustrcmp(argrest, "nq") == 0)
2114 {
8768d548
JH
2115 f.allow_unqualified_sender = FALSE;
2116 f.allow_unqualified_recipient = FALSE;
059ec3d9
PH
2117 }
2118
2119 /* -bpxx: List the contents of the mail queue, in various forms. If
2120 the option is -bpc, just a queue count is needed. Otherwise, if the
2121 first letter after p is r, then order is random. */
2122
2123 else if (*argrest == 'p')
2124 {
2125 if (*(++argrest) == 'c')
2126 {
2127 count_queue = TRUE;
2128 if (*(++argrest) != 0) badarg = TRUE;
2129 break;
2130 }
2131
2132 if (*argrest == 'r')
2133 {
2134 list_queue_option = 8;
2135 argrest++;
2136 }
2137 else list_queue_option = 0;
2138
2139 list_queue = TRUE;
2140
2141 /* -bp: List the contents of the mail queue, top-level only */
2142
2143 if (*argrest == 0) {}
2144
2145 /* -bpu: List the contents of the mail queue, top-level undelivered */
2146
2147 else if (Ustrcmp(argrest, "u") == 0) list_queue_option += 1;
2148
2149 /* -bpa: List the contents of the mail queue, including all delivered */
2150
2151 else if (Ustrcmp(argrest, "a") == 0) list_queue_option += 2;
2152
2153 /* Unknown after -bp[r] */
2154
2155 else
2156 {
2157 badarg = TRUE;
2158 break;
2159 }
2160 }
2161
2162
2163 /* -bP: List the configuration variables given as the address list.
2164 Force -v, so configuration errors get displayed. */
2165
2166 else if (Ustrcmp(argrest, "P") == 0)
2167 {
bf3c2c6b
HSHR
2168 /* -bP config: we need to setup here, because later,
2169 * when list_options is checked, the config is read already */
2170 if (argv[i+1] && Ustrcmp(argv[i+1], "config") == 0)
2171 {
2172 list_config = TRUE;
2173 readconf_save_config(version_string);
2174 }
2175 else
2176 {
2177 list_options = TRUE;
2178 debug_selector |= D_v;
2179 debug_file = stderr;
2180 }
059ec3d9
PH
2181 }
2182
2183 /* -brt: Test retry configuration lookup */
2184
2185 else if (Ustrcmp(argrest, "rt") == 0)
2186 {
34e86e20 2187 checking = TRUE;
059ec3d9
PH
2188 test_retry_arg = i + 1;
2189 goto END_ARG;
2190 }
2191
2192 /* -brw: Test rewrite configuration */
2193
2194 else if (Ustrcmp(argrest, "rw") == 0)
2195 {
34e86e20 2196 checking = TRUE;
059ec3d9
PH
2197 test_rewrite_arg = i + 1;
2198 goto END_ARG;
2199 }
2200
2201 /* -bS: Read SMTP commands on standard input, but produce no replies -
2202 all errors are reported by sending messages. */
2203
2204 else if (Ustrcmp(argrest, "S") == 0)
2205 smtp_input = smtp_batched_input = receiving_message = TRUE;
2206
2207 /* -bs: Read SMTP commands on standard input and produce SMTP replies
2208 on standard output. */
2209
2210 else if (Ustrcmp(argrest, "s") == 0) smtp_input = receiving_message = TRUE;
2211
2212 /* -bt: address testing mode */
2213
2214 else if (Ustrcmp(argrest, "t") == 0)
8768d548 2215 f.address_test_mode = checking = f.log_testing_mode = TRUE;
059ec3d9
PH
2216
2217 /* -bv: verify addresses */
2218
2219 else if (Ustrcmp(argrest, "v") == 0)
8768d548 2220 verify_address_mode = checking = f.log_testing_mode = TRUE;
059ec3d9
PH
2221
2222 /* -bvs: verify sender addresses */
2223
2224 else if (Ustrcmp(argrest, "vs") == 0)
2225 {
8768d548 2226 verify_address_mode = checking = f.log_testing_mode = TRUE;
059ec3d9
PH
2227 verify_as_sender = TRUE;
2228 }
2229
2230 /* -bV: Print version string and support details */
2231
2232 else if (Ustrcmp(argrest, "V") == 0)
2233 {
2234 printf("Exim version %s #%s built %s\n", version_string,
2235 version_cnumber, version_date);
2236 printf("%s\n", CS version_copyright);
2237 version_printed = TRUE;
2238 show_whats_supported(stdout);
8768d548 2239 f.log_testing_mode = TRUE;
059ec3d9
PH
2240 }
2241
9ee44efb
PP
2242 /* -bw: inetd wait mode, accept a listening socket as stdin */
2243
2244 else if (*argrest == 'w')
2245 {
8768d548
JH
2246 f.inetd_wait_mode = TRUE;
2247 f.background_daemon = FALSE;
2248 f.daemon_listen = TRUE;
9ee44efb 2249 if (*(++argrest) != '\0')
9af3c549
JH
2250 if ((inetd_wait_timeout = readconf_readtime(argrest, 0, FALSE)) <= 0)
2251 exim_fail("exim: bad time value %s: abandoned\n", argv[i]);
9ee44efb
PP
2252 }
2253
059ec3d9
PH
2254 else badarg = TRUE;
2255 break;
2256
2257
2258 /* -C: change configuration file list; ignore if it isn't really
2259 a change! Enforce a prefix check if required. */
2260
2261 case 'C':
2262 if (*argrest == 0)
2263 {
2264 if(++i < argc) argrest = argv[i]; else
2265 { badarg = TRUE; break; }
2266 }
2267 if (Ustrcmp(config_main_filelist, argrest) != 0)
2268 {
2269 #ifdef ALT_CONFIG_PREFIX
2270 int sep = 0;
2271 int len = Ustrlen(ALT_CONFIG_PREFIX);
863bd541 2272 const uschar *list = argrest;
059ec3d9
PH
2273 uschar *filename;
2274 while((filename = string_nextinlist(&list, &sep, big_buffer,
2275 big_buffer_size)) != NULL)
2276 {
2277 if ((Ustrlen(filename) < len ||
2278 Ustrncmp(filename, ALT_CONFIG_PREFIX, len) != 0 ||
2279 Ustrstr(filename, "/../") != NULL) &&
2280 (Ustrcmp(filename, "/dev/null") != 0 || real_uid != root_uid))
9af3c549 2281 exim_fail("-C Permission denied\n");
059ec3d9
PH
2282 }
2283 #endif
261dc43e
DW
2284 if (real_uid != root_uid)
2285 {
90b6341f 2286 #ifdef TRUSTED_CONFIG_LIST
261dc43e 2287
90b6341f
DW
2288 if (real_uid != exim_uid
2289 #ifdef CONFIGURE_OWNER
2290 && real_uid != config_uid
2291 #endif
2292 )
8768d548 2293 f.trusted_config = FALSE;
261dc43e
DW
2294 else
2295 {
90b6341f 2296 FILE *trust_list = Ufopen(TRUSTED_CONFIG_LIST, "rb");
261dc43e
DW
2297 if (trust_list)
2298 {
2299 struct stat statbuf;
2300
2301 if (fstat(fileno(trust_list), &statbuf) != 0 ||
2302 (statbuf.st_uid != root_uid /* owner not root */
2303 #ifdef CONFIGURE_OWNER
2304 && statbuf.st_uid != config_uid /* owner not the special one */
2305 #endif
2306 ) || /* or */
2307 (statbuf.st_gid != root_gid /* group not root */
2308 #ifdef CONFIGURE_GROUP
2309 && statbuf.st_gid != config_gid /* group not the special one */
2310 #endif
2311 && (statbuf.st_mode & 020) != 0 /* group writeable */
2312 ) || /* or */
2313 (statbuf.st_mode & 2) != 0) /* world writeable */
2314 {
8768d548 2315 f.trusted_config = FALSE;
261dc43e
DW
2316 fclose(trust_list);
2317 }
2318 else
2319 {
2320 /* Well, the trust list at least is up to scratch... */
2321 void *reset_point = store_get(0);
90b6341f
DW
2322 uschar *trusted_configs[32];
2323 int nr_configs = 0;
261dc43e
DW
2324 int i = 0;
2325
2326 while (Ufgets(big_buffer, big_buffer_size, trust_list))
2327 {
2328 uschar *start = big_buffer, *nl;
2329 while (*start && isspace(*start))
2330 start++;
1e83d68b 2331 if (*start != '/')
261dc43e
DW
2332 continue;
2333 nl = Ustrchr(start, '\n');
2334 if (nl)
2335 *nl = 0;
90b6341f
DW
2336 trusted_configs[nr_configs++] = string_copy(start);
2337 if (nr_configs == 32)
261dc43e
DW
2338 break;
2339 }
2340 fclose(trust_list);
2341
90b6341f 2342 if (nr_configs)
261dc43e
DW
2343 {
2344 int sep = 0;
55414b25 2345 const uschar *list = argrest;
261dc43e 2346 uschar *filename;
8768d548 2347 while (f.trusted_config && (filename = string_nextinlist(&list,
261dc43e
DW
2348 &sep, big_buffer, big_buffer_size)) != NULL)
2349 {
90b6341f 2350 for (i=0; i < nr_configs; i++)
261dc43e 2351 {
90b6341f 2352 if (Ustrcmp(filename, trusted_configs[i]) == 0)
261dc43e
DW
2353 break;
2354 }
90b6341f 2355 if (i == nr_configs)
261dc43e 2356 {
8768d548 2357 f.trusted_config = FALSE;
261dc43e
DW
2358 break;
2359 }
2360 }
1e83d68b 2361 store_reset(reset_point);
261dc43e
DW
2362 }
2363 else
2364 {
2365 /* No valid prefixes found in trust_list file. */
8768d548 2366 f.trusted_config = FALSE;
261dc43e
DW
2367 }
2368 }
2369 }
2370 else
2371 {
2372 /* Could not open trust_list file. */
8768d548 2373 f.trusted_config = FALSE;
261dc43e
DW
2374 }
2375 }
2376 #else
2377 /* Not root; don't trust config */
8768d548 2378 f.trusted_config = FALSE;
261dc43e
DW
2379 #endif
2380 }
059ec3d9
PH
2381
2382 config_main_filelist = argrest;
8768d548 2383 f.config_changed = TRUE;
059ec3d9
PH
2384 }
2385 break;
2386
2387
2388 /* -D: set up a macro definition */
2389
2390 case 'D':
9af3c549
JH
2391#ifdef DISABLE_D_OPTION
2392 exim_fail("exim: -D is not available in this Exim binary\n");
2393#else
059ec3d9
PH
2394 {
2395 int ptr = 0;
059ec3d9
PH
2396 macro_item *m;
2397 uschar name[24];
2398 uschar *s = argrest;
2399
4ab69ec7 2400 opt_D_used = TRUE;
059ec3d9
PH
2401 while (isspace(*s)) s++;
2402
2403 if (*s < 'A' || *s > 'Z')
9af3c549 2404 exim_fail("exim: macro name set by -D must start with "
059ec3d9 2405 "an upper case letter\n");
059ec3d9
PH
2406
2407 while (isalnum(*s) || *s == '_')
2408 {
2409 if (ptr < sizeof(name)-1) name[ptr++] = *s;
2410 s++;
2411 }
2412 name[ptr] = 0;
2413 if (ptr == 0) { badarg = TRUE; break; }
2414 while (isspace(*s)) s++;
2415 if (*s != 0)
2416 {
2417 if (*s++ != '=') { badarg = TRUE; break; }
2418 while (isspace(*s)) s++;
2419 }
2420
85e03244 2421 for (m = macros_user; m; m = m->next)
1a7c9a48 2422 if (Ustrcmp(m->name, name) == 0)
9af3c549 2423 exim_fail("exim: duplicated -D in command line\n");
059ec3d9 2424
85e03244 2425 m = macro_create(name, s, TRUE);
059ec3d9
PH
2426
2427 if (clmacro_count >= MAX_CLMACROS)
9af3c549 2428 exim_fail("exim: too many -D options on command line\n");
1a7c9a48
JH
2429 clmacros[clmacro_count++] = string_sprintf("-D%s=%s", m->name,
2430 m->replacement);
059ec3d9
PH
2431 }
2432 #endif
2433 break;
2434
2435 /* -d: Set debug level (see also -v below) or set the drop_cr option.
8e669ac1 2436 The latter is now a no-op, retained for compatibility only. If -dd is used,
3d235903 2437 debugging subprocesses of the daemon is disabled. */
059ec3d9
PH
2438
2439 case 'd':
2440 if (Ustrcmp(argrest, "ropcr") == 0)
2441 {
2442 /* drop_cr = TRUE; */
2443 }
2444
2445 /* Use an intermediate variable so that we don't set debugging while
2446 decoding the debugging bits. */
2447
2448 else
2449 {
2450 unsigned int selector = D_default;
2451 debug_selector = 0;
2452 debug_file = NULL;
3d235903
PH
2453 if (*argrest == 'd')
2454 {
8768d548 2455 f.debug_daemon = TRUE;
3d235903
PH
2456 argrest++;
2457 }
059ec3d9 2458 if (*argrest != 0)
6c6d6e48
TF
2459 decode_bits(&selector, 1, debug_notall, argrest,
2460 debug_options, debug_options_count, US"debug", 0);
059ec3d9
PH
2461 debug_selector = selector;
2462 }
2463 break;
2464
2465
2466 /* -E: This is a local error message. This option is not intended for
2467 external use at all, but is not restricted to trusted callers because it
2468 does no harm (just suppresses certain error messages) and if Exim is run
2469 not setuid root it won't always be trusted when it generates error
2470 messages using this option. If there is a message id following -E, point
2471 message_reference at it, for logging. */
2472
2473 case 'E':
8768d548 2474 f.local_error_message = TRUE;
059ec3d9
PH
2475 if (mac_ismsgid(argrest)) message_reference = argrest;
2476 break;
2477
2478
2479 /* -ex: The vacation program calls sendmail with the undocumented "-eq"
2480 option, so it looks as if historically the -oex options are also callable
2481 without the leading -o. So we have to accept them. Before the switch,
2482 anything starting -oe has been converted to -e. Exim does not support all
2483 of the sendmail error options. */
2484
2485 case 'e':
2486 if (Ustrcmp(argrest, "e") == 0)
2487 {
2488 arg_error_handling = ERRORS_SENDER;
2489 errors_sender_rc = EXIT_SUCCESS;
2490 }
2491 else if (Ustrcmp(argrest, "m") == 0) arg_error_handling = ERRORS_SENDER;
2492 else if (Ustrcmp(argrest, "p") == 0) arg_error_handling = ERRORS_STDERR;
2493 else if (Ustrcmp(argrest, "q") == 0) arg_error_handling = ERRORS_STDERR;
2494 else if (Ustrcmp(argrest, "w") == 0) arg_error_handling = ERRORS_SENDER;
2495 else badarg = TRUE;
2496 break;
2497
2498
2499 /* -F: Set sender's full name, used instead of the gecos entry from
2500 the password file. Since users can usually alter their gecos entries,
2501 there's no security involved in using this instead. The data can follow
2502 the -F or be in the next argument. */
2503
2504 case 'F':
2505 if (*argrest == 0)
2506 {
2507 if(++i < argc) argrest = argv[i]; else
2508 { badarg = TRUE; break; }
2509 }
2510 originator_name = argrest;
8768d548 2511 f.sender_name_forced = TRUE;
059ec3d9
PH
2512 break;
2513
2514
2515 /* -f: Set sender's address - this value is only actually used if Exim is
2516 run by a trusted user, or if untrusted_set_sender is set and matches the
2517 address, except that the null address can always be set by any user. The
2518 test for this happens later, when the value given here is ignored when not
2519 permitted. For an untrusted user, the actual sender is still put in Sender:
2520 if it doesn't match the From: header (unless no_local_from_check is set).
2521 The data can follow the -f or be in the next argument. The -r switch is an
2522 obsolete form of -f but since there appear to be programs out there that
2523 use anything that sendmail has ever supported, better accept it - the
2524 synonymizing is done before the switch above.
2525
2526 At this stage, we must allow domain literal addresses, because we don't
2527 know what the setting of allow_domain_literals is yet. Ditto for trailing
2528 dots and strip_trailing_dot. */
2529
2530 case 'f':
2531 {
250b6871 2532 int dummy_start, dummy_end;
059ec3d9
PH
2533 uschar *errmess;
2534 if (*argrest == 0)
2535 {
2536 if (i+1 < argc) argrest = argv[++i]; else
2537 { badarg = TRUE; break; }
2538 }
2539 if (*argrest == 0)
059ec3d9 2540 sender_address = string_sprintf(""); /* Ensure writeable memory */
059ec3d9
PH
2541 else
2542 {
2543 uschar *temp = argrest + Ustrlen(argrest) - 1;
2544 while (temp >= argrest && isspace(*temp)) temp--;
2545 if (temp >= argrest && *temp == '.') f_end_dot = TRUE;
2546 allow_domain_literals = TRUE;
2547 strip_trailing_dot = TRUE;
8c5d388a 2548#ifdef SUPPORT_I18N
250b6871
JH
2549 allow_utf8_domains = TRUE;
2550#endif
2551 sender_address = parse_extract_address(argrest, &errmess,
2552 &dummy_start, &dummy_end, &sender_address_domain, TRUE);
8c5d388a 2553#ifdef SUPPORT_I18N
250b6871
JH
2554 message_smtputf8 = string_is_utf8(sender_address);
2555 allow_utf8_domains = FALSE;
2556#endif
059ec3d9
PH
2557 allow_domain_literals = FALSE;
2558 strip_trailing_dot = FALSE;
9af3c549
JH
2559 if (!sender_address)
2560 exim_fail("exim: bad -f address \"%s\": %s\n", argrest, errmess);
059ec3d9 2561 }
8768d548 2562 f.sender_address_forced = TRUE;
059ec3d9
PH
2563 }
2564 break;
2565
a3fb9793 2566 /* -G: sendmail invocation to specify that it's a gateway submission and
f4ee74ac
PP
2567 sendmail may complain about problems instead of fixing them.
2568 We make it equivalent to an ACL "control = suppress_local_fixups" and do
2569 not at this time complain about problems. */
059ec3d9
PH
2570
2571 case 'G':
f4ee74ac 2572 flag_G = TRUE;
059ec3d9
PH
2573 break;
2574
2575 /* -h: Set the hop count for an incoming message. Exim does not currently
2576 support this; it always computes it by counting the Received: headers.
2577 To put it in will require a change to the spool header file format. */
2578
2579 case 'h':
2580 if (*argrest == 0)
2581 {
2582 if(++i < argc) argrest = argv[i]; else
2583 { badarg = TRUE; break; }
2584 }
2585 if (!isdigit(*argrest)) badarg = TRUE;
2586 break;
2587
2588
2589 /* -i: Set flag so dot doesn't end non-SMTP input (same as -oi, seems
2590 not to be documented for sendmail but mailx (at least) uses it) */
2591
2592 case 'i':
8768d548 2593 if (*argrest == 0) f.dot_ends = FALSE; else badarg = TRUE;
059ec3d9
PH
2594 break;
2595
2596
a3fb9793
PP
2597 /* -L: set the identifier used for syslog; equivalent to setting
2598 syslog_processname in the config file, but needs to be an admin option. */
2599
2600 case 'L':
2601 if (*argrest == '\0')
2602 {
2603 if(++i < argc) argrest = argv[i]; else
2604 { badarg = TRUE; break; }
2605 }
9af3c549
JH
2606 if ((sz = Ustrlen(argrest)) > 32)
2607 exim_fail("exim: the -L syslog name is too long: \"%s\"\n", argrest);
a3fb9793 2608 if (sz < 1)
9af3c549 2609 exim_fail("exim: the -L syslog name is too short\n");
a3fb9793
PP
2610 cmdline_syslog_name = argrest;
2611 break;
2612
059ec3d9
PH
2613 case 'M':
2614 receiving_message = FALSE;
2615
2616 /* -MC: continue delivery of another message via an existing open
2617 file descriptor. This option is used for an internal call by the
2618 smtp transport when there is a pending message waiting to go to an
2619 address to which it has got a connection. Five subsequent arguments are
2620 required: transport name, host name, IP address, sequence number, and
2621 message_id. Transports may decline to create new processes if the sequence
2622 number gets too big. The channel is stdin. This (-MC) must be the last
2623 argument. There's a subsequent check that the real-uid is privileged.
2624
2625 If we are running in the test harness. delay for a bit, to let the process
2626 that set this one up complete. This makes for repeatability of the logging,
2627 etc. output. */
2628
2629 if (Ustrcmp(argrest, "C") == 0)
2630 {
41c7c167
PH
2631 union sockaddr_46 interface_sock;
2632 EXIM_SOCKLEN_T size = sizeof(interface_sock);
2633
059ec3d9 2634 if (argc != i + 6)
9af3c549 2635 exim_fail("exim: too many or too few arguments after -MC\n");
059ec3d9
PH
2636
2637 if (msg_action_arg >= 0)
9af3c549 2638 exim_fail("exim: incompatible arguments\n");
059ec3d9
PH
2639
2640 continue_transport = argv[++i];
2641 continue_hostname = argv[++i];
2642 continue_host_address = argv[++i];
2643 continue_sequence = Uatoi(argv[++i]);
2644 msg_action = MSG_DELIVER;
2645 msg_action_arg = ++i;
2646 forced_delivery = TRUE;
2647 queue_run_pid = passed_qr_pid;
2648 queue_run_pipe = passed_qr_pipe;
2649
2650 if (!mac_ismsgid(argv[i]))
9af3c549 2651 exim_fail("exim: malformed message id %s after -MC option\n",
059ec3d9 2652 argv[i]);
059ec3d9 2653
875512a3
JH
2654 /* Set up $sending_ip_address and $sending_port, unless proxied */
2655
5013d912 2656 if (!continue_proxy_cipher)
875512a3
JH
2657 if (getsockname(fileno(stdin), (struct sockaddr *)(&interface_sock),
2658 &size) == 0)
2659 sending_ip_address = host_ntoa(-1, &interface_sock, NULL,
2660 &sending_port);
2661 else
9af3c549 2662 exim_fail("exim: getsockname() failed after -MC option: %s\n",
875512a3 2663 strerror(errno));
41c7c167 2664
8768d548 2665 if (f.running_in_test_harness) millisleep(500);
059ec3d9
PH
2666 break;
2667 }
2668
2d14f397
JH
2669 else if (*argrest == 'C' && argrest[1] && !argrest[2])
2670 {
875512a3 2671 switch(argrest[1])
2d14f397 2672 {
059ec3d9
PH
2673 /* -MCA: set the smtp_authenticated flag; this is useful only when it
2674 precedes -MC (see above). The flag indicates that the host to which
2675 Exim is connected has accepted an AUTH sequence. */
2676
8768d548 2677 case 'A': f.smtp_authenticated = TRUE; break;
059ec3d9 2678
6c1c3d1d
WB
2679 /* -MCD: set the smtp_use_dsn flag; this indicates that the host
2680 that exim is connected to supports the esmtp extension DSN */
28b3821f 2681
14de8063 2682 case 'D': smtp_peer_options |= OPTION_DSN; break;
6c1c3d1d 2683
e37f8a84 2684 /* -MCG: set the queue name, to a non-default value */
28b3821f 2685
2d14f397
JH
2686 case 'G': if (++i < argc) queue_name = string_copy(argv[i]);
2687 else badarg = TRUE;
2688 break;
2689
2690 /* -MCK: the peer offered CHUNKING. Must precede -MC */
2691
14de8063 2692 case 'K': smtp_peer_options |= OPTION_CHUNKING; break;
28b3821f 2693
059ec3d9
PH
2694 /* -MCP: set the smtp_use_pipelining flag; this is useful only when
2695 it preceded -MC (see above) */
2696
14de8063 2697 case 'P': smtp_peer_options |= OPTION_PIPE; break;
059ec3d9
PH
2698
2699 /* -MCQ: pass on the pid of the queue-running process that started
2700 this chain of deliveries and the fd of its synchronizing pipe; this
2701 is useful only when it precedes -MC (see above) */
2702
2d14f397
JH
2703 case 'Q': if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i]));
2704 else badarg = TRUE;
2705 if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i]));
2706 else badarg = TRUE;
2707 break;
059ec3d9
PH
2708
2709 /* -MCS: set the smtp_use_size flag; this is useful only when it
2710 precedes -MC (see above) */
2711
14de8063 2712 case 'S': smtp_peer_options |= OPTION_SIZE; break;
059ec3d9 2713
01603eec 2714#ifndef DISABLE_TLS
875512a3 2715 /* -MCt: similar to -MCT below but the connection is still open
aded2255 2716 via a proxy process which handles the TLS context and coding.
5013d912
JH
2717 Require three arguments for the proxied local address and port,
2718 and the TLS cipher. */
875512a3 2719
5013d912 2720 case 't': if (++i < argc) sending_ip_address = argv[i];
875512a3
JH
2721 else badarg = TRUE;
2722 if (++i < argc) sending_port = (int)(Uatol(argv[i]));
2723 else badarg = TRUE;
5013d912
JH
2724 if (++i < argc) continue_proxy_cipher = argv[i];
2725 else badarg = TRUE;
875512a3
JH
2726 /*FALLTHROUGH*/
2727
059ec3d9
PH
2728 /* -MCT: set the tls_offered flag; this is useful only when it
2729 precedes -MC (see above). The flag indicates that the host to which
2730 Exim is connected has offered TLS support. */
2731
14de8063 2732 case 'T': smtp_peer_options |= OPTION_TLS; break;
2d14f397
JH
2733#endif
2734
2735 default: badarg = TRUE; break;
2736 }
8ac90765
JH
2737 break;
2738 }
2739
059ec3d9
PH
2740 /* -M[x]: various operations on the following list of message ids:
2741 -M deliver the messages, ignoring next retry times and thawing
2742 -Mc deliver the messages, checking next retry times, no thawing
2743 -Mf freeze the messages
2744 -Mg give up on the messages
2745 -Mt thaw the messages
2746 -Mrm remove the messages
2747 In the above cases, this must be the last option. There are also the
2748 following options which are followed by a single message id, and which
2749 act on that message. Some of them use the "recipient" addresses as well.
2750 -Mar add recipient(s)
2751 -Mmad mark all recipients delivered
2752 -Mmd mark recipients(s) delivered
2753 -Mes edit sender
0ef732d9 2754 -Mset load a message for use with -be
059ec3d9 2755 -Mvb show body
a96603a0 2756 -Mvc show copy (of whole message, in RFC 2822 format)
059ec3d9
PH
2757 -Mvh show header
2758 -Mvl show log
2759 */
2760
2761 else if (*argrest == 0)
2762 {
2763 msg_action = MSG_DELIVER;
8768d548 2764 forced_delivery = f.deliver_force_thaw = TRUE;
059ec3d9
PH
2765 }
2766 else if (Ustrcmp(argrest, "ar") == 0)
2767 {
2768 msg_action = MSG_ADD_RECIPIENT;
2769 one_msg_action = TRUE;
2770 }
2771 else if (Ustrcmp(argrest, "c") == 0) msg_action = MSG_DELIVER;
2772 else if (Ustrcmp(argrest, "es") == 0)
2773 {
2774 msg_action = MSG_EDIT_SENDER;
2775 one_msg_action = TRUE;
2776 }
2777 else if (Ustrcmp(argrest, "f") == 0) msg_action = MSG_FREEZE;
2778 else if (Ustrcmp(argrest, "g") == 0)
2779 {
2780 msg_action = MSG_DELIVER;
2781 deliver_give_up = TRUE;
2782 }
2783 else if (Ustrcmp(argrest, "mad") == 0)
2784 {
2785 msg_action = MSG_MARK_ALL_DELIVERED;
2786 }
2787 else if (Ustrcmp(argrest, "md") == 0)
2788 {
2789 msg_action = MSG_MARK_DELIVERED;
2790 one_msg_action = TRUE;
2791 }
2792 else if (Ustrcmp(argrest, "rm") == 0) msg_action = MSG_REMOVE;
0ef732d9
PH
2793 else if (Ustrcmp(argrest, "set") == 0)
2794 {
2795 msg_action = MSG_LOAD;
2796 one_msg_action = TRUE;
2797 }
059ec3d9
PH
2798 else if (Ustrcmp(argrest, "t") == 0) msg_action = MSG_THAW;
2799 else if (Ustrcmp(argrest, "vb") == 0)
2800 {
2801 msg_action = MSG_SHOW_BODY;
2802 one_msg_action = TRUE;
2803 }
a96603a0
PH
2804 else if (Ustrcmp(argrest, "vc") == 0)
2805 {
2806 msg_action = MSG_SHOW_COPY;
2807 one_msg_action = TRUE;
2808 }
059ec3d9
PH
2809 else if (Ustrcmp(argrest, "vh") == 0)
2810 {
2811 msg_action = MSG_SHOW_HEADER;
2812 one_msg_action = TRUE;
2813 }
2814 else if (Ustrcmp(argrest, "vl") == 0)
2815 {
2816 msg_action = MSG_SHOW_LOG;
2817 one_msg_action = TRUE;
2818 }
2819 else { badarg = TRUE; break; }
2820
2821 /* All the -Mxx options require at least one message id. */
2822
2823 msg_action_arg = i + 1;
2824 if (msg_action_arg >= argc)
9af3c549 2825 exim_fail("exim: no message ids given after %s option\n", arg);
059ec3d9
PH
2826
2827 /* Some require only message ids to follow */
2828
2829 if (!one_msg_action)
2830 {
d7978c0f 2831 for (int j = msg_action_arg; j < argc; j++) if (!mac_ismsgid(argv[j]))
9af3c549 2832 exim_fail("exim: malformed message id %s after %s option\n",
059ec3d9 2833 argv[j], arg);
059ec3d9
PH
2834 goto END_ARG; /* Remaining args are ids */
2835 }
2836
2837 /* Others require only one message id, possibly followed by addresses,
2838 which will be handled as normal arguments. */
2839
2840 else
2841 {
2842 if (!mac_ismsgid(argv[msg_action_arg]))
9af3c549 2843 exim_fail("exim: malformed message id %s after %s option\n",
059ec3d9 2844 argv[msg_action_arg], arg);
059ec3d9
PH
2845 i++;
2846 }
2847 break;
2848
2849
2850 /* Some programs seem to call the -om option without the leading o;
2851 for sendmail it askes for "me too". Exim always does this. */
2852
2853 case 'm':
2854 if (*argrest != 0) badarg = TRUE;
2855 break;
2856
2857
2858 /* -N: don't do delivery - a debugging option that stops transports doing
2859 their thing. It implies debugging at the D_v level. */
2860
2861 case 'N':
2862 if (*argrest == 0)
2863 {
8768d548 2864 f.dont_deliver = TRUE;
059ec3d9
PH
2865 debug_selector |= D_v;
2866 debug_file = stderr;
2867 }
2868 else badarg = TRUE;
2869 break;
2870
2871
12f69989
PP
2872 /* -n: This means "don't alias" in sendmail, apparently.
2873 For normal invocations, it has no effect.
2874 It may affect some other options. */
059ec3d9
PH
2875
2876 case 'n':
12f69989 2877 flag_n = TRUE;
059ec3d9
PH
2878 break;
2879
2880 /* -O: Just ignore it. In sendmail, apparently -O option=value means set
2881 option to the specified value. This form uses long names. We need to handle
2882 -O option=value and -Ooption=value. */
2883
2884 case 'O':
2885 if (*argrest == 0)
2886 {
2887 if (++i >= argc)
9af3c549 2888 exim_fail("exim: string expected after -O\n");
059ec3d9
PH
2889 }
2890 break;
2891
2892 case 'o':
2893
2894 /* -oA: Set an argument for the bi command (sendmail's "alternate alias
2895 file" option). */
2896
2897 if (*argrest == 'A')
2898 {
2899 alias_arg = argrest + 1;
2900 if (alias_arg[0] == 0)
2901 {
2902 if (i+1 < argc) alias_arg = argv[++i]; else
9af3c549 2903 exim_fail("exim: string expected after -oA\n");
059ec3d9
PH
2904 }
2905 }
2906
2907 /* -oB: Set a connection message max value for remote deliveries */
2908
2909 else if (*argrest == 'B')
2910 {
2911 uschar *p = argrest + 1;
2912 if (p[0] == 0)
2913 {
2914 if (i+1 < argc && isdigit((argv[i+1][0]))) p = argv[++i]; else
2915 {
2916 connection_max_messages = 1;
2917 p = NULL;
2918 }
2919 }
2920
2921 if (p != NULL)
2922 {
2923 if (!isdigit(*p))
9af3c549 2924 exim_fail("exim: number expected after -oB\n");
059ec3d9
PH
2925 connection_max_messages = Uatoi(p);
2926 }
2927 }
2928
2929 /* -odb: background delivery */
2930
2931 else if (Ustrcmp(argrest, "db") == 0)
2932 {
8768d548 2933 f.synchronous_delivery = FALSE;
059ec3d9
PH
2934 arg_queue_only = FALSE;
2935 queue_only_set = TRUE;
2936 }
2937
2938 /* -odf: foreground delivery (smail-compatible option); same effect as
2939 -odi: interactive (synchronous) delivery (sendmail-compatible option)
2940 */
2941
2942 else if (Ustrcmp(argrest, "df") == 0 || Ustrcmp(argrest, "di") == 0)
2943 {
8768d548 2944 f.synchronous_delivery = TRUE;
059ec3d9
PH
2945 arg_queue_only = FALSE;
2946 queue_only_set = TRUE;
2947 }
2948
2949 /* -odq: queue only */
2950
2951 else if (Ustrcmp(argrest, "dq") == 0)
2952 {
8768d548 2953 f.synchronous_delivery = FALSE;
059ec3d9
PH
2954 arg_queue_only = TRUE;
2955 queue_only_set = TRUE;
2956 }
2957
2958 /* -odqs: queue SMTP only - do local deliveries and remote routing,
2959 but no remote delivery */
2960
2961 else if (Ustrcmp(argrest, "dqs") == 0)
2962 {
8768d548 2963 f.queue_smtp = TRUE;
059ec3d9
PH
2964 arg_queue_only = FALSE;
2965 queue_only_set = TRUE;
2966 }
2967
2968 /* -oex: Sendmail error flags. As these are also accepted without the
2969 leading -o prefix, for compatibility with vacation and other callers,
2970 they are handled with -e above. */
2971
2972 /* -oi: Set flag so dot doesn't end non-SMTP input (same as -i)
2973 -oitrue: Another sendmail syntax for the same */
2974
2975 else if (Ustrcmp(argrest, "i") == 0 ||
2976 Ustrcmp(argrest, "itrue") == 0)
8768d548 2977 f.dot_ends = FALSE;
059ec3d9
PH
2978
2979 /* -oM*: Set various characteristics for an incoming message; actually
2980 acted on for trusted callers only. */
2981
2982 else if (*argrest == 'M')
2983 {
2984 if (i+1 >= argc)
9af3c549 2985 exim_fail("exim: data expected after -o%s\n", argrest);
059ec3d9
PH
2986
2987 /* -oMa: Set sender host address */
2988
2989 if (Ustrcmp(argrest, "Ma") == 0) sender_host_address = argv[++i];
2990
2991 /* -oMaa: Set authenticator name */
2992
2993 else if (Ustrcmp(argrest, "Maa") == 0)
2994 sender_host_authenticated = argv[++i];
2995
2996 /* -oMas: setting authenticated sender */
2997
2998 else if (Ustrcmp(argrest, "Mas") == 0) authenticated_sender = argv[++i];
2999
3000 /* -oMai: setting authenticated id */
3001
3002 else if (Ustrcmp(argrest, "Mai") == 0) authenticated_id = argv[++i];
3003
3004 /* -oMi: Set incoming interface address */
3005
3006 else if (Ustrcmp(argrest, "Mi") == 0) interface_address = argv[++i];
3007
d2af03f4
HS
3008 /* -oMm: Message reference */
3009
3010 else if (Ustrcmp(argrest, "Mm") == 0)
3011 {
3012 if (!mac_ismsgid(argv[i+1]))
9af3c549 3013 exim_fail("-oMm must be a valid message ID\n");
8768d548 3014 if (!f.trusted_config)
9af3c549 3015 exim_fail("-oMm must be called by a trusted user/config\n");
d2af03f4
HS
3016 message_reference = argv[++i];
3017 }
3018
059ec3d9
PH
3019 /* -oMr: Received protocol */
3020
65e061b7
HSHR
3021 else if (Ustrcmp(argrest, "Mr") == 0)
3022
3023 if (received_protocol)
9af3c549
JH
3024 exim_fail("received_protocol is set already\n");
3025 else
3026 received_protocol = argv[++i];
059ec3d9
PH
3027
3028 /* -oMs: Set sender host name */
3029
3030 else if (Ustrcmp(argrest, "Ms") == 0) sender_host_name = argv[++i];
3031
3032 /* -oMt: Set sender ident */
3033
33d73e3b
PH
3034 else if (Ustrcmp(argrest, "Mt") == 0)
3035 {
3036 sender_ident_set = TRUE;
3037 sender_ident = argv[++i];
3038 }
059ec3d9
PH
3039
3040 /* Else a bad argument */
3041
3042 else
3043 {
3044 badarg = TRUE;
3045 break;
3046 }
3047 }
3048
3049 /* -om: Me-too flag for aliases. Exim always does this. Some programs
3050 seem to call this as -m (undocumented), so that is also accepted (see
3051 above). */
3052
3053 else if (Ustrcmp(argrest, "m") == 0) {}
3054
3055 /* -oo: An ancient flag for old-style addresses which still seems to
3056 crop up in some calls (see in SCO). */
3057
3058 else if (Ustrcmp(argrest, "o") == 0) {}
3059
3060 /* -oP <name>: set pid file path for daemon */
3061
3062 else if (Ustrcmp(argrest, "P") == 0)
3063 override_pid_file_path = argv[++i];
3064
3065 /* -or <n>: set timeout for non-SMTP acceptance
3066 -os <n>: set timeout for SMTP acceptance */
3067
3068 else if (*argrest == 'r' || *argrest == 's')
3069 {
3070 int *tp = (*argrest == 'r')?
3071 &arg_receive_timeout : &arg_smtp_receive_timeout;
3072 if (argrest[1] == 0)
3073 {
3074 if (i+1 < argc) *tp= readconf_readtime(argv[++i], 0, FALSE);
3075 }
3076 else *tp = readconf_readtime(argrest + 1, 0, FALSE);
3077 if (*tp < 0)
9af3c549 3078 exim_fail("exim: bad time value %s: abandoned\n", argv[i]);
059ec3d9
PH
3079 }
3080
3081 /* -oX <list>: Override local_interfaces and/or default daemon ports */
3082
3083 else if (Ustrcmp(argrest, "X") == 0)
3084 override_local_interfaces = argv[++i];
3085
3086 /* Unknown -o argument */
3087
3088 else badarg = TRUE;
3089 break;
3090
3091
3092 /* -ps: force Perl startup; -pd force delayed Perl startup */
3093
3094 case 'p':
3095 #ifdef EXIM_PERL
3096 if (*argrest == 's' && argrest[1] == 0)
3097 {
3098 perl_start_option = 1;
3099 break;
3100 }
3101 if (*argrest == 'd' && argrest[1] == 0)
3102 {
3103 perl_start_option = -1;
3104 break;
3105 }
3106 #endif
3107
3108 /* -panythingelse is taken as the Sendmail-compatible argument -prval:sval,
3109 which sets the host protocol and host name */
3110
3111 if (*argrest == 0)
5bfe3b35
JH
3112 if (i+1 < argc)
3113 argrest = argv[++i];
3114 else
059ec3d9 3115 { badarg = TRUE; break; }
059ec3d9
PH
3116
3117 if (*argrest != 0)
3118 {
65e061b7
HSHR
3119 uschar *hn;
3120
3121 if (received_protocol)
9af3c549 3122 exim_fail("received_protocol is set already\n");
65e061b7
HSHR
3123
3124 hn = Ustrchr(argrest, ':');
059ec3d9 3125 if (hn == NULL)
059ec3d9 3126 received_protocol = argrest;
059ec3d9
PH
3127 else
3128 {
90341c71
JH
3129 int old_pool = store_pool;
3130 store_pool = POOL_PERM;
059ec3d9 3131 received_protocol = string_copyn(argrest, hn - argrest);
90341c71 3132 store_pool = old_pool;
059ec3d9
PH
3133 sender_host_name = hn + 1;
3134 }
3135 }
3136 break;
3137
3138
3139 case 'q':
3140 receiving_message = FALSE;
3cc66b45 3141 if (queue_interval >= 0)
9af3c549 3142 exim_fail("exim: -q specified more than once\n");
059ec3d9
PH
3143
3144 /* -qq...: Do queue runs in a 2-stage manner */
3145
3146 if (*argrest == 'q')
3147 {
8768d548 3148 f.queue_2stage = TRUE;
059ec3d9
PH
3149 argrest++;
3150 }
3151
3152 /* -qi...: Do only first (initial) deliveries */
3153
3154 if (*argrest == 'i')
3155 {
8768d548 3156 f.queue_run_first_delivery = TRUE;
059ec3d9
PH
3157 argrest++;
3158 }
3159
3160 /* -qf...: Run the queue, forcing deliveries
3161 -qff..: Ditto, forcing thawing as well */
3162
3163 if (*argrest == 'f')
3164 {
8768d548 3165 f.queue_run_force = TRUE;
55e70e76 3166 if (*++argrest == 'f')
059ec3d9 3167 {
8768d548 3168 f.deliver_force_thaw = TRUE;
059ec3d9
PH
3169 argrest++;
3170 }
3171 }
3172
3173 /* -q[f][f]l...: Run the queue only on local deliveries */
3174
3175 if (*argrest == 'l')
3176 {
8768d548 3177 f.queue_run_local = TRUE;
059ec3d9
PH
3178 argrest++;
3179 }
3180
55e70e76 3181 /* -q[f][f][l][G<name>]... Work on the named queue */
28b3821f
JH
3182
3183 if (*argrest == 'G')
3184 {
fa665e0b
JH
3185 int i;
3186 for (argrest++, i = 0; argrest[i] && argrest[i] != '/'; ) i++;
3187 queue_name = string_copyn(argrest, i);
3188 argrest += i;
3189 if (*argrest == '/') argrest++;
28b3821f
JH
3190 }
3191
3192 /* -q[f][f][l][G<name>]: Run the queue, optionally forced, optionally local
3193 only, optionally named, optionally starting from a given message id. */
059ec3d9 3194
e5903596
JH
3195 if (!(list_queue || count_queue))
3196 if (*argrest == 0
3197 && (i + 1 >= argc || argv[i+1][0] == '-' || mac_ismsgid(argv[i+1])))
3198 {
3199 queue_interval = 0;
3200 if (i+1 < argc && mac_ismsgid(argv[i+1]))
3201 start_queue_run_id = argv[++i];
3202 if (i+1 < argc && mac_ismsgid(argv[i+1]))
3203 stop_queue_run_id = argv[++i];
3204 }
059ec3d9 3205
fa665e0b
JH
3206 /* -q[f][f][l][G<name>/]<n>: Run the queue at regular intervals, optionally
3207 forced, optionally local only, optionally named. */
059ec3d9 3208
e5903596
JH
3209 else if ((queue_interval = readconf_readtime(*argrest ? argrest : argv[++i],
3210 0, FALSE)) <= 0)
3211 exim_fail("exim: bad time value %s: abandoned\n", argv[i]);
059ec3d9
PH
3212 break;
3213
3214
3215 case 'R': /* Synonymous with -qR... */
3216 receiving_message = FALSE;
3217
3218 /* -Rf: As -R (below) but force all deliveries,
3219 -Rff: Ditto, but also thaw all frozen messages,
3220 -Rr: String is regex
3221 -Rrf: Regex and force
3222 -Rrff: Regex and force and thaw
3223
3224 in all cases provided there are no further characters in this
3225 argument. */
3226
3227 if (*argrest != 0)
d7978c0f 3228 for (int i = 0; i < nelem(rsopts); i++)
059ec3d9
PH
3229 if (Ustrcmp(argrest, rsopts[i]) == 0)
3230 {
8768d548
JH
3231 if (i != 2) f.queue_run_force = TRUE;
3232 if (i >= 2) f.deliver_selectstring_regex = TRUE;
3233 if (i == 1 || i == 4) f.deliver_force_thaw = TRUE;
059ec3d9
PH
3234 argrest += Ustrlen(rsopts[i]);
3235 }
059ec3d9
PH
3236
3237 /* -R: Set string to match in addresses for forced queue run to
3238 pick out particular messages. */
3239
55e70e76
JH
3240 if (*argrest)
3241 deliver_selectstring = argrest;
3242 else if (i+1 < argc)
3243 deliver_selectstring = argv[++i];
3244 else
9af3c549 3245 exim_fail("exim: string expected after -R\n");
059ec3d9
PH
3246 break;
3247
3248
3249 /* -r: an obsolete synonym for -f (see above) */
3250
3251
3252 /* -S: Like -R but works on sender. */
3253
3254 case 'S': /* Synonymous with -qS... */
3255 receiving_message = FALSE;
3256
3257 /* -Sf: As -S (below) but force all deliveries,
3258 -Sff: Ditto, but also thaw all frozen messages,
3259 -Sr: String is regex
3260 -Srf: Regex and force
3261 -Srff: Regex and force and thaw
3262
3263 in all cases provided there are no further characters in this
3264 argument. */
3265
55e70e76 3266 if (*argrest)
d7978c0f 3267 for (int i = 0; i < nelem(rsopts); i++)
059ec3d9
PH
3268 if (Ustrcmp(argrest, rsopts[i]) == 0)
3269 {
8768d548
JH
3270 if (i != 2) f.queue_run_force = TRUE;
3271 if (i >= 2) f.deliver_selectstring_sender_regex = TRUE;
3272 if (i == 1 || i == 4) f.deliver_force_thaw = TRUE;
059ec3d9
PH
3273 argrest += Ustrlen(rsopts[i]);
3274 }
059ec3d9
PH
3275
3276 /* -S: Set string to match in addresses for forced queue run to
3277 pick out particular messages. */
3278
55e70e76
JH
3279 if (*argrest)
3280 deliver_selectstring_sender = argrest;
3281 else if (i+1 < argc)
3282 deliver_selectstring_sender = argv[++i];
3283 else
9af3c549 3284 exim_fail("exim: string expected after -S\n");
059ec3d9
PH
3285 break;
3286
3287 /* -Tqt is an option that is exclusively for use by the testing suite.
3288 It is not recognized in other circumstances. It allows for the setting up
3289 of explicit "queue times" so that various warning/retry things can be
3290 tested. Otherwise variability of clock ticks etc. cause problems. */
3291
3292 case 'T':
8768d548 3293 if (f.running_in_test_harness && Ustrcmp(argrest, "qt") == 0)
059ec3d9
PH
3294 fudged_queue_times = argv[++i];
3295 else badarg = TRUE;
3296 break;
3297
3298
3299 /* -t: Set flag to extract recipients from body of message. */
3300
3301 case 't':
3302 if (*argrest == 0) extract_recipients = TRUE;
3303
3304 /* -ti: Set flag to extract recipients from body of message, and also
3305 specify that dot does not end the message. */
3306
3307 else if (Ustrcmp(argrest, "i") == 0)
3308 {
3309 extract_recipients = TRUE;
8768d548 3310 f.dot_ends = FALSE;
059ec3d9
PH
3311 }
3312
3313 /* -tls-on-connect: don't wait for STARTTLS (for old clients) */
3314
01603eec 3315 #ifndef DISABLE_TLS
817d9f57 3316 else if (Ustrcmp(argrest, "ls-on-connect") == 0) tls_in.on_connect = TRUE;
059ec3d9
PH
3317 #endif
3318
3319 else badarg = TRUE;
3320 break;
3321
3322
3323 /* -U: This means "initial user submission" in sendmail, apparently. The
3324 doc claims that in future sendmail may refuse syntactically invalid
3325 messages instead of fixing them. For the moment, we just ignore it. */
3326
3327 case 'U':
3328 break;
3329
3330
3331 /* -v: verify things - this is a very low-level debugging */
3332
3333 case 'v':
3334 if (*argrest == 0)
3335 {
3336 debug_selector |= D_v;
3337 debug_file = stderr;
3338 }
3339 else badarg = TRUE;
3340 break;
3341
3342
3343 /* -x: AIX uses this to indicate some fancy 8-bit character stuff:
3344
3345 The -x flag tells the sendmail command that mail from a local
3346 mail program has National Language Support (NLS) extended characters
3347 in the body of the mail item. The sendmail command can send mail with
3348 extended NLS characters across networks that normally corrupts these
3349 8-bit characters.
3350
3351 As Exim is 8-bit clean, it just ignores this flag. */
3352
3353 case 'x':
3354 if (*argrest != 0) badarg = TRUE;
3355 break;
3356
a3fb9793
PP
3357 /* -X: in sendmail: takes one parameter, logfile, and sends debugging
3358 logs to that file. We swallow the parameter and otherwise ignore it. */
3359
3360 case 'X':
3361 if (*argrest == '\0')
a3fb9793 3362 if (++i >= argc)
9af3c549 3363 exim_fail("exim: string expected after -X\n");
0ad2e0fc
JH
3364 break;
3365
3366 case 'z':
3367 if (*argrest == '\0')
9af3c549
JH
3368 if (++i < argc)
3369 log_oneline = argv[i];
3370 else
3371 exim_fail("exim: file name expected after %s\n", argv[i-1]);
a3fb9793
PP
3372 break;
3373
059ec3d9
PH
3374 /* All other initial characters are errors */
3375
3376 default:
3377 badarg = TRUE;
3378 break;
3379 } /* End of high-level switch statement */
3380
3381 /* Failed to recognize the option, or syntax error */
3382
3383 if (badarg)
9af3c549 3384 exim_fail("exim abandoned: unknown, malformed, or incomplete "
059ec3d9 3385 "option %s\n", arg);
059ec3d9
PH
3386 }
3387
3388
3cc66b45
PH
3389/* If -R or -S have been specified without -q, assume a single queue run. */
3390
55e70e76
JH
3391if ( (deliver_selectstring || deliver_selectstring_sender)
3392 && queue_interval < 0)
3393 queue_interval = 0;
3cc66b45
PH
3394
3395
059ec3d9 3396END_ARG:
81ea09ca
NM
3397/* If usage_wanted is set we call the usage function - which never returns */
3398if (usage_wanted) exim_usage(called_as);
3399
3400/* Arguments have been processed. Check for incompatibilities. */
059ec3d9
PH
3401if ((
3402 (smtp_input || extract_recipients || recipients_arg < argc) &&
8768d548 3403 (f.daemon_listen || queue_interval >= 0 || bi_option ||
059ec3d9 3404 test_retry_arg >= 0 || test_rewrite_arg >= 0 ||
f05da2e8 3405 filter_test != FTEST_NONE || (msg_action_arg > 0 && !one_msg_action))
059ec3d9
PH
3406 ) ||
3407 (
3408 msg_action_arg > 0 &&
8768d548 3409 (f.daemon_listen || queue_interval > 0 || list_options ||
0ef732d9
PH
3410 (checking && msg_action != MSG_LOAD) ||
3411 bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0)
059ec3d9
PH
3412 ) ||
3413 (
8768d548 3414 (f.daemon_listen || queue_interval > 0) &&
059ec3d9 3415 (sender_address != NULL || list_options || list_queue || checking ||
0ef732d9 3416 bi_option)
059ec3d9
PH
3417 ) ||
3418 (
8768d548 3419 f.daemon_listen && queue_interval == 0
059ec3d9
PH
3420 ) ||
3421 (
8768d548 3422 f.inetd_wait_mode && queue_interval >= 0
9ee44efb
PP
3423 ) ||
3424 (
059ec3d9
PH
3425 list_options &&
3426 (checking || smtp_input || extract_recipients ||
f05da2e8 3427 filter_test != FTEST_NONE || bi_option)
059ec3d9
PH
3428 ) ||
3429 (
3430 verify_address_mode &&
8768d548 3431 (f.address_test_mode || smtp_input || extract_recipients ||
f05da2e8 3432 filter_test != FTEST_NONE || bi_option)
059ec3d9
PH
3433 ) ||
3434 (
8768d548 3435 f.address_test_mode && (smtp_input || extract_recipients ||
f05da2e8 3436 filter_test != FTEST_NONE || bi_option)
059ec3d9
PH
3437 ) ||
3438 (
f05da2e8 3439 smtp_input && (sender_address != NULL || filter_test != FTEST_NONE ||
059ec3d9
PH
3440 extract_recipients)
3441 ) ||
3442 (
3443 deliver_selectstring != NULL && queue_interval < 0
328895cc
PH
3444 ) ||
3445 (
3446 msg_action == MSG_LOAD &&
3447 (!expansion_test || expansion_test_message != NULL)
059ec3d9
PH
3448 )
3449 )
9af3c549 3450 exim_fail("exim: incompatible command-line options or arguments\n");
059ec3d9
PH
3451
3452/* If debugging is set up, set the file and the file descriptor to pass on to
3453child processes. It should, of course, be 2 for stderr. Also, force the daemon
3454to run in the foreground. */
3455
3456if (debug_selector != 0)
3457 {
3458 debug_file = stderr;
3459 debug_fd = fileno(debug_file);
8768d548
JH
3460 f.background_daemon = FALSE;
3461 if (f.running_in_test_harness) millisleep(100); /* lets caller finish */
059ec3d9
PH
3462 if (debug_selector != D_v) /* -v only doesn't show this */
3463 {
3464 debug_printf("Exim version %s uid=%ld gid=%ld pid=%d D=%x\n",
3465 version_string, (long int)real_uid, (long int)real_gid, (int)getpid(),
3466 debug_selector);
6545de78
PP
3467 if (!version_printed)
3468 show_whats_supported(stderr);
059ec3d9
PH
3469 }
3470 }
3471
3472/* When started with root privilege, ensure that the limits on the number of
3473open files and the number of processes (where that is accessible) are
3474sufficiently large, or are unset, in case Exim has been called from an
3475environment where the limits are screwed down. Not all OS have the ability to
3476change some of these limits. */
3477
3478if (unprivileged)
3479 {
3480 DEBUG(D_any) debug_print_ids(US"Exim has no root privilege:");
3481 }
3482else
3483 {
3484 struct rlimit rlp;
3485
3486 #ifdef RLIMIT_NOFILE
3487 if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
3488 {
3489 log_write(0, LOG_MAIN|LOG_PANIC, "getrlimit(RLIMIT_NOFILE) failed: %s",
3490 strerror(errno));
3491 rlp.rlim_cur = rlp.rlim_max = 0;
3492 }
eb2c0248
PH
3493
3494 /* I originally chose 1000 as a nice big number that was unlikely to
a494b1e1
PH
3495 be exceeded. It turns out that some older OS have a fixed upper limit of
3496 256. */
eb2c0248 3497
059ec3d9
PH
3498 if (rlp.rlim_cur < 1000)
3499 {
3500 rlp.rlim_cur = rlp.rlim_max = 1000;
3501 if (setrlimit(RLIMIT_NOFILE, &rlp) < 0)
eb2c0248 3502 {
a494b1e1
PH
3503 rlp.rlim_cur = rlp.rlim_max = 256;
3504 if (setrlimit(RLIMIT_NOFILE, &rlp) < 0)
3505 log_write(0, LOG_MAIN|LOG_PANIC, "setrlimit(RLIMIT_NOFILE) failed: %s",
3506 strerror(errno));
eb2c0248 3507 }
059ec3d9
PH
3508 }
3509 #endif
3510
3511 #ifdef RLIMIT_NPROC
3512 if (getrlimit(RLIMIT_NPROC, &rlp) < 0)
3513 {
3514 log_write(0, LOG_MAIN|LOG_PANIC, "getrlimit(RLIMIT_NPROC) failed: %s",
3515 strerror(errno));
3516 rlp.rlim_cur = rlp.rlim_max = 0;
3517 }
3518
3519 #ifdef RLIM_INFINITY
3520 if (rlp.rlim_cur != RLIM_INFINITY && rlp.rlim_cur < 1000)
3521 {
3522 rlp.rlim_cur = rlp.rlim_max = RLIM_INFINITY;
3523 #else
3524 if (rlp.rlim_cur < 1000)
3525 {
3526 rlp.rlim_cur = rlp.rlim_max = 1000;
3527 #endif
3528 if (setrlimit(RLIMIT_NPROC, &rlp) < 0)
3529 log_write(0, LOG_MAIN|LOG_PANIC, "setrlimit(RLIMIT_NPROC) failed: %s",
3530 strerror(errno));
3531 }
3532 #endif
3533 }
3534
3535/* Exim is normally entered as root (but some special configurations are
3536possible that don't do this). However, it always spins off sub-processes that
3537set their uid and gid as required for local delivery. We don't want to pass on
3538any extra groups that root may belong to, so we want to get rid of them all at
3539this point.
3540
3541We need to obey setgroups() at this stage, before possibly giving up root
3542privilege for a changed configuration file, but later on we might need to
3543check on the additional groups for the admin user privilege - can't do that
3544till after reading the config, which might specify the exim gid. Therefore,
3545save the group list here first. */
3546
157d73b5 3547if ((group_count = getgroups(nelem(group_list), group_list)) < 0)
9af3c549 3548 exim_fail("exim: getgroups() failed: %s\n", strerror(errno));
059ec3d9
PH
3549
3550/* There is a fundamental difference in some BSD systems in the matter of
3551groups. FreeBSD and BSDI are known to be different; NetBSD and OpenBSD are
3552known not to be different. On the "different" systems there is a single group
3553list, and the first entry in it is the current group. On all other versions of
3554Unix there is a supplementary group list, which is in *addition* to the current
3555group. Consequently, to get rid of all extraneous groups on a "standard" system
3556you pass over 0 groups to setgroups(), while on a "different" system you pass
3557over a single group - the current group, which is always the first group in the
3558list. Calling setgroups() with zero groups on a "different" system results in
3559an error return. The following code should cope with both types of system.
3560
3b7ac02c
JH
3561 Unfortunately, recent MacOS, which should be a FreeBSD, "helpfully" succeeds
3562 the "setgroups() with zero groups" - and changes the egid.
3563 Thanks to that we had to stash the original_egid above, for use below
3564 in the call to exim_setugid().
3565
059ec3d9
PH
3566However, if this process isn't running as root, setgroups() can't be used
3567since you have to be root to run it, even if throwing away groups. Not being
3568root here happens only in some unusual configurations. We just ignore the
3569error. */
3570
9af3c549
JH
3571if (setgroups(0, NULL) != 0 && setgroups(1, group_list) != 0 && !unprivileged)
3572 exim_fail("exim: setgroups() failed: %s\n", strerror(errno));
059ec3d9
PH
3573
3574/* If the configuration file name has been altered by an argument on the
3575command line (either a new file name or a macro definition) and the caller is
cd25e41d
DW
3576not root, or if this is a filter testing run, remove any setuid privilege the
3577program has and run as the underlying user.
059ec3d9 3578
cd25e41d
DW
3579The exim user is locked out of this, which severely restricts the use of -C
3580for some purposes.
059ec3d9
PH
3581
3582Otherwise, set the real ids to the effective values (should be root unless run
3583from inetd, which it can either be root or the exim uid, if one is configured).
3584
3585There is a private mechanism for bypassing some of this, in order to make it
3586possible to test lots of configurations automatically, without having either to
3587recompile each time, or to patch in an actual configuration file name and other
3588values (such as the path name). If running in the test harness, pretend that
3589configuration file changes and macro definitions haven't happened. */
3590
3591if (( /* EITHER */
8768d548 3592 (!f.trusted_config || /* Config changed, or */
a4034eb8 3593 !macros_trusted(opt_D_used)) && /* impermissible macros and */
059ec3d9 3594 real_uid != root_uid && /* Not root, and */
8768d548 3595 !f.running_in_test_harness /* Not fudged */
059ec3d9
PH
3596 ) || /* OR */
3597 expansion_test /* expansion testing */
3598 || /* OR */
f05da2e8 3599 filter_test != FTEST_NONE) /* Filter testing */
059ec3d9
PH
3600 {
3601 setgroups(group_count, group_list);
3602 exim_setugid(real_uid, real_gid, FALSE,
3603 US"-C, -D, -be or -bf forces real uid");
3604 removed_privilege = TRUE;
3605
3606 /* In the normal case when Exim is called like this, stderr is available
3607 and should be used for any logging information because attempts to write
3608 to the log will usually fail. To arrange this, we unset really_exim. However,
3609 if no stderr is available there is no point - we might as well have a go
b7487bce 3610 at the log (if it fails, syslog will be written).
059ec3d9 3611
b7487bce
PP
3612 Note that if the invoker is Exim, the logs remain available. Messing with
3613 this causes unlogged successful deliveries. */
3614
9af3c549 3615 if (log_stderr && real_uid != exim_uid)
8768d548 3616 f.really_exim = FALSE;
059ec3d9
PH
3617 }
3618
3619/* Privilege is to be retained for the moment. It may be dropped later,
3620depending on the job that this Exim process has been asked to do. For now, set
3621the real uid to the effective so that subsequent re-execs of Exim are done by a
3622privileged user. */
3623
9af3c549 3624else
3b7ac02c 3625 exim_setugid(geteuid(), original_egid, FALSE, US"forcing real = effective");
059ec3d9 3626
f05da2e8 3627/* If testing a filter, open the file(s) now, before wasting time doing other
059ec3d9
PH
3628setups and reading the message. */
3629<