X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/03f68c52bd7d014304b03ad6394343350ea71b2c..e983e85a314998aed1d586990969fea128a8b4c7:/src/src/exim.c diff --git a/src/src/exim.c b/src/src/exim.c index ddb35982d..14e0b9d67 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -12,6 +12,10 @@ Also a few functions that don't naturally fit elsewhere. */ #include "exim.h" +#ifdef __GLIBC__ +# include +#endif + #ifdef USE_GNUTLS # include # if GNUTLS_VERSION_NUMBER < 0x030103 && !defined(DISABLE_OCSP) @@ -1025,6 +1029,14 @@ DEBUG(D_any) do { fprintf(f, "Compiler: \n"); #endif +#ifdef __GLIBC__ + fprintf(f, "Library version: Glibc: Compile: %d.%d\n", + __GLIBC__, __GLIBC_MINOR__); + if (__GLIBC_PREREQ(2, 1)) + fprintf(f, " Runtime: %s\n", + gnu_get_libc_version()); +#endif + #ifdef SUPPORT_TLS tls_version_report(f); #endif @@ -1040,7 +1052,7 @@ DEBUG(D_any) do { characters; unless it's an ancient version of PCRE in which case it is not defined. */ #ifndef PCRE_PRERELEASE -#define PCRE_PRERELEASE +# define PCRE_PRERELEASE #endif #define QUOTE(X) #X #define EXPAND_AND_QUOTE(X) QUOTE(X) @@ -1136,23 +1148,23 @@ for (t = lpart; !needs_quote && *t != 0; t++) if (!needs_quote) return lpart; size = ptr = 0; -yield = string_cat(NULL, &size, &ptr, US"\"", 1); +yield = string_catn(NULL, &size, &ptr, US"\"", 1); for (;;) { uschar *nq = US Ustrpbrk(lpart, "\\\""); if (nq == NULL) { - yield = string_cat(yield, &size, &ptr, lpart, Ustrlen(lpart)); + yield = string_cat(yield, &size, &ptr, lpart); break; } - yield = string_cat(yield, &size, &ptr, lpart, nq - lpart); - yield = string_cat(yield, &size, &ptr, US"\\", 1); - yield = string_cat(yield, &size, &ptr, nq, 1); + yield = string_catn(yield, &size, &ptr, lpart, nq - lpart); + yield = string_catn(yield, &size, &ptr, US"\\", 1); + yield = string_catn(yield, &size, &ptr, nq, 1); lpart = nq + 1; } -yield = string_cat(yield, &size, &ptr, US"\"", 1); +yield = string_catn(yield, &size, &ptr, US"\"", 1); yield[ptr] = 0; return yield; } @@ -1266,15 +1278,16 @@ for (i = 0;; i++) while (p < ss && isspace(*p)) p++; /* leading space after cont */ } - yield = string_cat(yield, &size, &ptr, p, ss - p); + yield = string_catn(yield, &size, &ptr, p, ss - p); #ifdef USE_READLINE if (fn_readline != NULL) free(readline_line); #endif + /* yield can only be NULL if ss==p */ if (ss == p || yield[ptr-1] != '\\') { - yield[ptr] = 0; + if (yield) yield[ptr] = 0; break; } yield[--ptr] = 0; @@ -2046,6 +2059,7 @@ for (i = 1; i < argc; i++) sender_host_address = argv[i]; host_checking = checking = log_testing_mode = TRUE; host_checking_callout = argrest[1] == 'c'; + message_logs = FALSE; } /* -bi: This option is used by sendmail to initialize *the* alias file, @@ -2703,66 +2717,63 @@ for (i = 1; i < argc; i++) break; } + else if (*argrest == 'C' && argrest[1] && !argrest[2]) + { + switch(argrest[1]) + { /* -MCA: set the smtp_authenticated flag; this is useful only when it precedes -MC (see above). The flag indicates that the host to which Exim is connected has accepted an AUTH sequence. */ - else if (Ustrcmp(argrest, "CA") == 0) - { - smtp_authenticated = TRUE; - break; - } + case 'A': smtp_authenticated = TRUE; break; /* -MCD: set the smtp_use_dsn flag; this indicates that the host that exim is connected to supports the esmtp extension DSN */ - else if (Ustrcmp(argrest, "CD") == 0) - { - smtp_use_dsn = TRUE; - break; - } + + case 'D': smtp_peer_options |= PEER_OFFERED_DSN; break; + + /* -MCG: set the queue name, to a non-default value */ + + case 'G': if (++i < argc) queue_name = string_copy(argv[i]); + else badarg = TRUE; + break; + + /* -MCK: the peer offered CHUNKING. Must precede -MC */ + + case 'K': smtp_peer_options |= PEER_OFFERED_CHUNKING; break; /* -MCP: set the smtp_use_pipelining flag; this is useful only when it preceded -MC (see above) */ - else if (Ustrcmp(argrest, "CP") == 0) - { - smtp_use_pipelining = TRUE; - break; - } + case 'P': smtp_peer_options |= PEER_OFFERED_PIPE; break; /* -MCQ: pass on the pid of the queue-running process that started this chain of deliveries and the fd of its synchronizing pipe; this is useful only when it precedes -MC (see above) */ - else if (Ustrcmp(argrest, "CQ") == 0) - { - if(++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); - else badarg = TRUE; - if(++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); - else badarg = TRUE; - break; - } + case 'Q': if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); + else badarg = TRUE; + if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); + else badarg = TRUE; + break; /* -MCS: set the smtp_use_size flag; this is useful only when it precedes -MC (see above) */ - else if (Ustrcmp(argrest, "CS") == 0) - { - smtp_use_size = TRUE; - break; - } + case 'S': smtp_peer_options |= PEER_OFFERED_SIZE; break; +#ifdef SUPPORT_TLS /* -MCT: set the tls_offered flag; this is useful only when it precedes -MC (see above). The flag indicates that the host to which Exim is connected has offered TLS support. */ - #ifdef SUPPORT_TLS - else if (Ustrcmp(argrest, "CT") == 0) - { - tls_offered = TRUE; - break; + case 'T': smtp_peer_options |= PEER_OFFERED_TLS; break; +#endif + + default: badarg = TRUE; break; + } + break; } - #endif /* -M[x]: various operations on the following list of message ids: -M deliver the messages, ignoring next retry times and thawing @@ -3213,7 +3224,7 @@ for (i = 1; i < argc; i++) if (*argrest == 'f') { queue_run_force = TRUE; - if (*(++argrest) == 'f') + if (*++argrest == 'f') { deliver_force_thaw = TRUE; argrest++; @@ -3228,8 +3239,19 @@ for (i = 1; i < argc; i++) argrest++; } - /* -q[f][f][l]: Run the queue, optionally forced, optionally local only, - optionally starting from a given message id. */ + /* -q[f][f][l][G]... Work on the named queue */ + + if (*argrest == 'G') + { + int i; + for (argrest++, i = 0; argrest[i] && argrest[i] != '/'; ) i++; + queue_name = string_copyn(argrest, i); + argrest += i; + if (*argrest == '/') argrest++; + } + + /* -q[f][f][l][G]: Run the queue, optionally forced, optionally local + only, optionally named, optionally starting from a given message id. */ if (*argrest == 0 && (i + 1 >= argc || argv[i+1][0] == '-' || mac_ismsgid(argv[i+1]))) @@ -3241,20 +3263,14 @@ for (i = 1; i < argc; i++) stop_queue_run_id = argv[++i]; } - /* -q[f][f][l]: Run the queue at regular intervals, optionally forced, - optionally local only. */ + /* -q[f][f][l][G/]: Run the queue at regular intervals, optionally + forced, optionally local only, optionally named. */ - else + else if ((queue_interval = readconf_readtime(*argrest ? argrest : argv[++i], + 0, FALSE)) <= 0) { - if (*argrest != 0) - queue_interval = readconf_readtime(argrest, 0, FALSE); - else - queue_interval = readconf_readtime(argv[++i], 0, FALSE); - if (queue_interval <= 0) - { - fprintf(stderr, "exim: bad time value %s: abandoned\n", argv[i]); - exit(EXIT_FAILURE); - } + fprintf(stderr, "exim: bad time value %s: abandoned\n", argv[i]); + exit(EXIT_FAILURE); } break; @@ -3274,8 +3290,7 @@ for (i = 1; i < argc; i++) if (*argrest != 0) { int i; - for (i = 0; i < sizeof(rsopts)/sizeof(uschar *); i++) - { + for (i = 0; i < nelem(rsopts); i++) if (Ustrcmp(argrest, rsopts[i]) == 0) { if (i != 2) queue_run_force = TRUE; @@ -3283,21 +3298,20 @@ for (i = 1; i < argc; i++) if (i == 1 || i == 4) deliver_force_thaw = TRUE; argrest += Ustrlen(rsopts[i]); } - } } /* -R: Set string to match in addresses for forced queue run to pick out particular messages. */ - if (*argrest == 0) + if (*argrest) + deliver_selectstring = argrest; + else if (i+1 < argc) + deliver_selectstring = argv[++i]; + else { - if (i+1 < argc) deliver_selectstring = argv[++i]; else - { - fprintf(stderr, "exim: string expected after -R\n"); - exit(EXIT_FAILURE); - } + fprintf(stderr, "exim: string expected after -R\n"); + exit(EXIT_FAILURE); } - else deliver_selectstring = argrest; break; @@ -3318,11 +3332,10 @@ for (i = 1; i < argc; i++) in all cases provided there are no further characters in this argument. */ - if (*argrest != 0) + if (*argrest) { int i; - for (i = 0; i < sizeof(rsopts)/sizeof(uschar *); i++) - { + for (i = 0; i < nelem(rsopts); i++) if (Ustrcmp(argrest, rsopts[i]) == 0) { if (i != 2) queue_run_force = TRUE; @@ -3330,21 +3343,20 @@ for (i = 1; i < argc; i++) if (i == 1 || i == 4) deliver_force_thaw = TRUE; argrest += Ustrlen(rsopts[i]); } - } } /* -S: Set string to match in addresses for forced queue run to pick out particular messages. */ - if (*argrest == 0) + if (*argrest) + deliver_selectstring_sender = argrest; + else if (i+1 < argc) + deliver_selectstring_sender = argv[++i]; + else { - if (i+1 < argc) deliver_selectstring_sender = argv[++i]; else - { - fprintf(stderr, "exim: string expected after -S\n"); - exit(EXIT_FAILURE); - } + fprintf(stderr, "exim: string expected after -S\n"); + exit(EXIT_FAILURE); } - else deliver_selectstring_sender = argrest; break; /* -Tqt is an option that is exclusively for use by the testing suite. @@ -3458,8 +3470,9 @@ for (i = 1; i < argc; i++) /* If -R or -S have been specified without -q, assume a single queue run. */ -if ((deliver_selectstring != NULL || deliver_selectstring_sender != NULL) && - queue_interval < 0) queue_interval = 0; +if ( (deliver_selectstring || deliver_selectstring_sender) + && queue_interval < 0) + queue_interval = 0; END_ARG: @@ -3475,12 +3488,12 @@ if (( ) || ( msg_action_arg > 0 && - (daemon_listen || queue_interval >= 0 || list_options || + (daemon_listen || queue_interval > 0 || list_options || (checking && msg_action != MSG_LOAD) || bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0) ) || ( - (daemon_listen || queue_interval >= 0) && + (daemon_listen || queue_interval > 0) && (sender_address != NULL || list_options || list_queue || checking || bi_option) ) || @@ -4656,7 +4669,10 @@ if (queue_interval == 0 && !daemon_listen) (start_queue_run_id == NULL)? US"" : start_queue_run_id, (stop_queue_run_id == NULL)? US"" : US" stopping at ", (stop_queue_run_id == NULL)? US"" : stop_queue_run_id); - set_process_info("running the queue (single queue run)"); + if (*queue_name) + set_process_info("running the '%s' queue (single queue run)", queue_name); + else + set_process_info("running the queue (single queue run)"); queue_run(start_queue_run_id, stop_queue_run_id, FALSE); exim_exit(EXIT_SUCCESS); } @@ -4951,7 +4967,7 @@ if (expansion_test) } message_id = argv[msg_action_arg]; (void)string_format(spoolname, sizeof(spoolname), "%s-H", message_id); - if (!spool_open_datafile(message_id)) + if ((deliver_datafile = spool_open_datafile(message_id)) < 0) printf ("Failed to load message datafile %s\n", message_id); if (spool_read_header(spoolname, TRUE, FALSE) != spool_read_OK) printf ("Failed to load message %s\n", message_id); @@ -5700,8 +5716,8 @@ while (more) if (geteuid() != root_uid && !deliver_drop_privilege && !unprivileged) { - (void)child_exec_exim(CEE_EXEC_EXIT, FALSE, NULL, FALSE, 2, US"-Mc", - message_id); + (void)child_exec_exim(CEE_EXEC_EXIT, FALSE, NULL, FALSE, + 2, US"-Mc", message_id); /* Control does not return here. */ }