X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fexim.c;h=01770df7338354f74b628d96b310e4ec0a234629;hb=4d146046d9a82339d26c6be230fe1480a72b8bee;hp=d6f2d4aac601c3fde28b0167461785bad131543e;hpb=d1af83598f7d6b32516a11bb28e569d592a05c48;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/exim.c b/src/src/exim.c index d6f2d4aac..01770df73 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -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; @@ -1999,7 +2009,7 @@ for (i = 1; i < argc; i++) else if (*argrest == 'F') { - filter_test |= FTEST_SYSTEM; + filter_test |= checking = FTEST_SYSTEM; if (*(++argrest) != 0) { badarg = TRUE; break; } if (++i < argc) filter_test_sfile = argv[i]; else { @@ -2019,7 +2029,7 @@ for (i = 1; i < argc; i++) { if (*(++argrest) == 0) { - filter_test |= FTEST_USER; + filter_test |= checking = FTEST_USER; if (++i < argc) filter_test_ufile = argv[i]; else { fprintf(stderr, "exim: file name expected after %s\n", argv[i-1]); @@ -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, @@ -2094,6 +2105,7 @@ for (i = 1; i < argc; i++) else if (Ustrcmp(argrest, "malware") == 0) { if (++i >= argc) { badarg = TRUE; break; } + checking = TRUE; malware_test_file = argv[i]; } @@ -2175,6 +2187,7 @@ for (i = 1; i < argc; i++) else if (Ustrcmp(argrest, "rt") == 0) { + checking = TRUE; test_retry_arg = i + 1; goto END_ARG; } @@ -2183,6 +2196,7 @@ for (i = 1; i < argc; i++) else if (Ustrcmp(argrest, "rw") == 0) { + checking = TRUE; test_rewrite_arg = i + 1; goto END_ARG; } @@ -2225,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 */ @@ -2714,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) */ @@ -2735,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; } @@ -3212,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++; @@ -3227,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]))) @@ -3240,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; @@ -3273,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; @@ -3282,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; @@ -3317,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; @@ -3329,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. @@ -3457,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: @@ -3474,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) ) || @@ -3741,16 +3768,38 @@ if (running_in_test_harness) smtputf8_advertise_hosts = NULL; /* Read the main runtime configuration data; this gives up if there is a failure. It leaves the configuration file open so that the subsequent -configuration data for delivery can be read if needed. */ +configuration data for delivery can be read if needed. -/* To be safe: change the working directory to /. */ -if (Uchdir("/") < 0) +NOTE: immediatly after opening the configuration file we change the working +directory to "/"! Later we change to $spool_directory. We do it there, because +during readconf_main() some expansion takes place already. */ + +/* Store the initial cwd before we change directories */ +if ((initial_cwd = os_getcwd(NULL, 0)) == NULL) { - perror("exim: chdir `/': "); - exit(EXIT_FAILURE); + perror("exim: can't get the current working directory"); + exit(EXIT_FAILURE); } -readconf_main(); +/* checking: + -be[m] expansion test - + -b[fF] filter test new + -bh[c] host test - + -bmalware malware_test_file new + -brt retry test new + -brw rewrite test new + -bt address test - + -bv[s] address verify - + list_options: + -bP