X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/9094b84b4cce2eb862394b752eda93124d96d655..584e96c65f12aca9414450b656504af6e3f7a399:/src/src/exim.c diff --git a/src/src/exim.c b/src/src/exim.c index 81db2c2c8..01770df73 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) @@ -814,9 +818,6 @@ fprintf(f, "Support for:"); #ifdef WITH_CONTENT_SCAN fprintf(f, " Content_Scanning"); #endif -#ifdef WITH_OLD_DEMIME - fprintf(f, " Old_Demime"); -#endif #ifndef DISABLE_DKIM fprintf(f, " DKIM"); #endif @@ -1028,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 @@ -1043,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) @@ -1139,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; } @@ -1269,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; @@ -2049,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, @@ -2228,6 +2239,7 @@ for (i = 1; i < argc; i++) printf("%s\n", CS version_copyright); version_printed = TRUE; show_whats_supported(stdout); + log_testing_mode = TRUE; } /* -bw: inetd wait mode, accept a listening socket as stdin */ @@ -2717,12 +2729,22 @@ for (i = 1; i < argc; i++) /* -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; } + /* -MCG: set the queue name, to a non-default value */ + + else if (Ustrcmp(argrest, "CG") == 0) + { + if (++i < argc) queue_name = string_copy(argv[i]); + else badarg = TRUE; + break; + } + /* -MCP: set the smtp_use_pipelining flag; this is useful only when it preceded -MC (see above) */ @@ -2738,9 +2760,9 @@ for (i = 1; i < argc; i++) else if (Ustrcmp(argrest, "CQ") == 0) { - if(++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); + if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); else badarg = TRUE; - if(++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); + if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); else badarg = TRUE; break; } @@ -3215,7 +3237,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++; @@ -3230,8 +3252,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]))) @@ -3243,20 +3276,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; @@ -3276,8 +3303,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; @@ -3285,21 +3311,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; @@ -3320,11 +3345,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; @@ -3332,21 +3356,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. @@ -3460,8 +3483,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: @@ -3477,12 +3501,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) ) || @@ -4658,7 +4682,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); } @@ -4942,6 +4969,7 @@ Otherwise, if -bem was used, read a message from stdin. */ if (expansion_test) { + dns_init(FALSE, FALSE, FALSE); if (msg_action_arg > 0 && msg_action == MSG_LOAD) { uschar spoolname[256]; /* Not big_buffer; used in spool_read_header() */ @@ -4952,7 +4980,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); @@ -5701,8 +5729,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. */ }