X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/650edc6fbfceeb90635fbe3019c419387ba9542b..789f8a4f4046120b7ae2aafa45f7f45c3ae4c8f5:/src/src/queue.c diff --git a/src/src/queue.c b/src/src/queue.c index c3e81a09d..cc8d36b23 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/queue.c,v 1.2 2004/11/05 14:59:12 ph10 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2004 */ +/* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions that operate on the input queue. */ @@ -453,7 +451,8 @@ for (i = (queue_run_in_order? -1 : 0); load_average = os_getloadavg(); if (load_average > deliver_queue_load_max) { - log_write(0, LOG_MAIN, "abandon queue run (load %.2f, max %.2f)", + log_write(L_queue_run, LOG_MAIN, "Abandon queue run: %s (load %.2f, max %.2f)", + log_detail, (double)load_average/1000.0, (double)deliver_queue_load_max/1000.0); i = subcount; /* Don't process other directories */ @@ -594,7 +593,7 @@ for (i = (queue_run_in_order? -1 : 0); if (queue_run_pipe == 0) { queue_run_pipe = dup(queue_run_pipe); - close(0); + (void)close(0); } /* Before forking to deliver the message, ensure any open and cached @@ -615,6 +614,7 @@ for (i = (queue_run_in_order? -1 : 0); if ((pid = fork()) == 0) { int rc; + if (running_in_test_harness) millisleep(100); (void)close(pfd[pipe_read]); rc = deliver_message(f->text, force_delivery, FALSE); _exit(rc == DELIVER_NOT_ATTEMPTED); @@ -626,7 +626,7 @@ for (i = (queue_run_in_order? -1 : 0); /* Close the writing end of the synchronizing pipe in this process, then wait for the first level process to terminate. */ - close(pfd[pipe_write]); + (void)close(pfd[pipe_write]); set_process_info("running queue: waiting for %s (%d)", f->text, pid); while (wait(&status) != pid); @@ -650,7 +650,8 @@ for (i = (queue_run_in_order? -1 : 0); the mere fact that read() unblocks is enough. */ set_process_info("running queue: waiting for children of %d", pid); - (void)read(pfd[pipe_read], buffer, sizeof(buffer)); + if (read(pfd[pipe_read], buffer, sizeof(buffer)) > 0) + log_write(0, LOG_MAIN|LOG_PANIC, "queue run: unexpected data on pipe"); (void)close(pfd[pipe_read]); set_process_info("running queue"); @@ -872,7 +873,7 @@ for (; f != NULL; f = f->next) big_buffer[n-1] = 0; tree_add_nonrecipient(big_buffer); } - fclose(jread); + (void)fclose(jread); } } @@ -894,10 +895,8 @@ for (; f != NULL; f = f->next) sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir, f->text); if (Ustat(big_buffer, &statbuf) == 0) - { - int size = statbuf.st_size; /* Because might be a long */ - printf("*** spool format error: size=%d ***", size); - } + printf("*** spool format error: size=" OFF_T_FMT " ***", + statbuf.st_size); else printf("*** spool format error ***"); } else printf("*** spool read error: %s ***", strerror(save_errno)); @@ -936,9 +935,9 @@ for (; f != NULL; f = f->next) * Act on a specific message * *************************************************/ -/* Actions that require a list of addresses make use of -argv/argc/recipients_arg. Other actions do not. This function does its -own authority checking. +/* Actions that require a list of addresses make use of argv/argc/ +recipients_arg. Other actions do not. This function does its own +authority checking. Arguments: id id of the message to work on @@ -1020,9 +1019,9 @@ if (action >= MSG_SHOW_BODY) } while((rc = read(fd, big_buffer, big_buffer_size)) > 0) - write(fileno(stdout), big_buffer, rc); + rc = write(fileno(stdout), big_buffer, rc); - close(fd); + (void)close(fd); return TRUE; } @@ -1031,7 +1030,7 @@ other process is working on this message. If the file does not exist, continue only if the action is remove and the user is an admin user, to allow for tidying up broken states. */ -if (!spool_open_datafile(id)) +if ((deliver_datafile = spool_open_datafile(id)) < 0) { if (errno == ENOENT) { @@ -1065,7 +1064,7 @@ if (spool_read_header(spoolname, TRUE, FALSE) != spool_read_OK) printf("Spool format error for %s\n", spoolname); if (action != MSG_REMOVE || !admin_user) { - close(deliver_datafile); + (void)close(deliver_datafile); deliver_datafile = -1; return FALSE; } @@ -1080,7 +1079,7 @@ why we leave this check until after the headers are read. */ if (!admin_user && (action != MSG_REMOVE || real_uid != originator_uid)) { printf("Permission denied\n"); - close(deliver_datafile); + (void)close(deliver_datafile); deliver_datafile = -1; return FALSE; } @@ -1093,10 +1092,17 @@ username = (pw != NULL)? /* Take the necessary action. */ -printf("Message %s ", id); +if (action != MSG_SHOW_COPY) printf("Message %s ", id); switch(action) { + case MSG_SHOW_COPY: + deliver_in_buffer = store_malloc(DELIVER_IN_BUFFER_SIZE); + deliver_out_buffer = store_malloc(DELIVER_OUT_BUFFER_SIZE); + transport_write_message(NULL, 1, 0, 0, NULL, NULL, NULL, NULL, NULL, 0); + break; + + case MSG_FREEZE: if (deliver_freeze) { @@ -1190,11 +1196,11 @@ switch(action) if (deliver_datafile >= 0) printf("has been removed\n"); else printf("has been removed or did not exist\n"); - if (removed) + if (removed) { log_write(0, LOG_MAIN, "removed by %s", username); - log_write(0, LOG_MAIN, "Completed"); - } + log_write(0, LOG_MAIN, "Completed"); + } break; @@ -1268,6 +1274,9 @@ switch(action) { if (action == MSG_ADD_RECIPIENT) { +#ifdef SUPPORT_I18N + if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE; +#endif receive_add_recipient(recipient, -1); log_write(0, LOG_MAIN, "recipient <%s> added by %s", recipient, username); @@ -1291,6 +1300,9 @@ switch(action) } else /* MSG_EDIT_SENDER */ { +#ifdef SUPPORT_I18N + if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE; +#endif sender_address = recipient; log_write(0, LOG_MAIN, "sender address changed to <%s> by %s", recipient, username); @@ -1315,7 +1327,7 @@ switch(action) /* Closing the datafile releases the lock and permits other processes to operate on the message (if it still exists). */ -close(deliver_datafile); +(void)close(deliver_datafile); deliver_datafile = -1; return yield; } @@ -1339,7 +1351,8 @@ queue_check_only(void) BOOL *set; int sep = 0; struct stat statbuf; -uschar *s, *ss, *name; +const uschar *s; +uschar *ss, *name; uschar buffer[1024]; if (queue_only_file == NULL) return;