X-Git-Url: https://git.exim.org/users/jgh/exim.git/blobdiff_plain/059ec3d9952740285fb1ebf47961b8aca2eb1b4a..c09b95966e16e092453cdb797c8048579b3585bd:/src/src/exim.c diff --git a/src/src/exim.c b/src/src/exim.c index 6d227c33e..189d5ef31 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.9.2.2 2004/12/02 16:33:30 tom Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -196,7 +196,10 @@ os_non_restarting_signal(SIGALRM, sigalrm_handler); /* This function is called by millisleep() and exim_wait_tick() to wait for a period of time that may include a fraction of a second. The coding is somewhat -tedious... +tedious. We do not expect setitimer() ever to fail, but if it does, the process +will wait for ever, so we panic in this instance. (There was a case of this +when a bug in a function that calls milliwait() caused it to pass invalid data. +That's when I added the check. :-) Argument: an itimerval structure containing the interval Returns: nothing @@ -210,7 +213,9 @@ sigset_t old_sigmask; (void)sigemptyset(&sigmask); /* Empty mask */ (void)sigaddset(&sigmask, SIGALRM); /* Add SIGALRM */ (void)sigprocmask(SIG_BLOCK, &sigmask, &old_sigmask); /* Block SIGALRM */ -(void)setitimer(ITIMER_REAL, itval, NULL); /* Start timer */ +if (setitimer(ITIMER_REAL, itval, NULL) < 0) /* Start timer */ + log_write(0, LOG_MAIN|LOG_PANIC_DIE, + "setitimer() failed: %s", strerror(errno)); (void)sigfillset(&sigmask); /* All signals */ (void)sigdelset(&sigmask, SIGALRM); /* Remove SIGALRM */ (void)sigsuspend(&sigmask); /* Until SIGALRM */ @@ -635,7 +640,7 @@ if (address == NULL) else { int rc = verify_address(deliver_make_addr(address,TRUE), stdout, flags, -1, - -1, NULL, NULL, NULL); + -1, -1, NULL, NULL, NULL); if (rc == FAIL) *exit_value = 2; else if (rc == DEFER && *exit_value == 0) *exit_value = 1; } @@ -834,6 +839,12 @@ fprintf(f, "Support for:"); fprintf(f, " OpenSSL"); #endif #endif +#ifdef WITH_CONTENT_SCAN + fprintf(f, " Content_Scanning"); +#endif +#ifdef WITH_OLD_DEMIME + fprintf(f, " Old_Demime"); +#endif fprintf(f, "\n"); fprintf(f, "Lookups:"); @@ -1229,7 +1240,7 @@ because some OS define it in /usr/include/unistd.h. */ extern char **environ; -/* If the Exim user and/or group and/or the configuration file owner were +/* If the Exim user and/or group and/or the configuration file owner/group were defined by ref:name at build time, we must now find the actual uid/gid values. This is a feature to make the lives of binary distributors easier. */ @@ -1264,6 +1275,15 @@ if (!route_finduser(US CONFIGURE_OWNERNAME, NULL, &config_uid)) } #endif +#ifdef CONFIGURE_GROUPNAME +if (!route_findgroup(US CONFIGURE_GROUPNAME, &config_gid)) + { + fprintf(stderr, "exim: failed to find gid for group name \"%s\"\n", + CONFIGURE_GROUPNAME); + exit(EXIT_FAILURE); + } +#endif + /* In the Cygwin environment, some initialization needs doing. It is fudged in by means of this macro. */ @@ -1849,7 +1869,8 @@ for (i = 1; i < argc; i++) break; /* -d: Set debug level (see also -v below) or set the drop_cr option. - The latter is now a no-opt, retained for compatibility only. */ + The latter is now a no-op, retained for compatibility only. If -dd is used, + debugging subprocesses of the daemon is disabled. */ case 'd': if (Ustrcmp(argrest, "ropcr") == 0) @@ -1865,6 +1886,11 @@ for (i = 1; i < argc; i++) unsigned int selector = D_default; debug_selector = 0; debug_file = NULL; + if (*argrest == 'd') + { + debug_daemon = TRUE; + argrest++; + } if (*argrest != 0) decode_bits(&selector, NULL, argrest, debug_options, debug_options_count, US"debug"); @@ -2823,12 +2849,21 @@ else strerror(errno)); rlp.rlim_cur = rlp.rlim_max = 0; } + + /* I originally chose 1000 as a nice big number that was unlikely to + be exceeded. It turns out that some older OS have a fixed upper limit of + 256. */ + if (rlp.rlim_cur < 1000) { rlp.rlim_cur = rlp.rlim_max = 1000; if (setrlimit(RLIMIT_NOFILE, &rlp) < 0) - log_write(0, LOG_MAIN|LOG_PANIC, "setrlimit(RLIMIT_NOFILE) failed: %s", - strerror(errno)); + { + rlp.rlim_cur = rlp.rlim_max = 256; + if (setrlimit(RLIMIT_NOFILE, &rlp) < 0) + log_write(0, LOG_MAIN|LOG_PANIC, "setrlimit(RLIMIT_NOFILE) failed: %s", + strerror(errno)); + } } #endif @@ -4065,10 +4100,22 @@ call to find the ident for. */ if (host_checking) { + int x[4]; + int size; + sender_ident = NULL; if (running_in_test_harness && sender_host_port != 0 && interface_address != NULL && interface_port != 0) verify_get_ident(1413); + + /* In case the given address is a non-canonical IPv6 address, canonicize + it. The code works for both IPv4 and IPv6, as it happens. */ + + size = host_aton(sender_host_address, x); + sender_host_address = store_get(48); /* large enough for full IPv6 */ + (void)host_nmtoa(size, x, -1, sender_host_address, ':'); + + /* Now set up for testing */ host_build_sender_fullhost(); smtp_input = TRUE; @@ -4371,6 +4418,11 @@ while (more) int count = argc - recipients_arg; uschar **list = argv + recipients_arg; + /* These options cannot be changed dynamically for non-SMTP messages */ + + active_local_sender_retain = local_sender_retain; + active_local_from_check = local_from_check; + /* Save before any rewriting */ raw_sender = string_copy(sender_address); @@ -4574,11 +4626,16 @@ while (more) /* Else do the delivery unless the ACL or local_scan() called for queue only or froze the message. Always deliver in a separate process. A fork failure is not a disaster, as the delivery will eventually happen on a subsequent queue - run. */ + run. The search cache must be tidied before the fork, as the parent will + do it before exiting. The child will trigger a lookup failure and + thereby defer the delivery if it tries to use (for example) a cached ldap + connection that the parent has called unbind on. */ else if (!queue_only_policy && !deliver_freeze) { pid_t pid; + search_tidyup(); + if ((pid = fork()) == 0) { int rc;