X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fqueue.c;h=a578014262863091eb123a08bdaab249e2b6c567;hb=5031095fd4553935c70e1c24a9936dfc609cdc67;hp=92109ef927c5e845665d151dd4ac814e77c3638a;hpb=ee8b809061baea861fc87c41bcb72a62d76b0047;p=exim.git diff --git a/src/src/queue.c b/src/src/queue.c index 92109ef92..a57801426 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -12,39 +12,6 @@ -/* Routines with knowledge of spool layout */ - -#ifndef COMPILE_UTILITY -static void -spool_pname_buf(uschar * buf, int len) -{ -snprintf(CS buf, len, "%s/%s/input", spool_directory, queue_name); -} - -uschar * -spool_dname(const uschar * purpose, uschar * subdir) -{ -return string_sprintf("%s/%s/%s/%s", - spool_directory, queue_name, purpose, subdir); -} -#endif - -uschar * -spool_sname(const uschar * purpose, uschar * subdir) -{ -return string_sprintf("%s%s%s%s%s", - queue_name, *queue_name ? "/" : "", - purpose, - *subdir ? "/" : "", subdir); -} - -uschar * -spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname, - const uschar * suffix) -{ -return string_sprintf("%s/%s/%s/%s/%s%s", - spool_directory, queue_name, purpose, subdir, fname, suffix); -} @@ -239,7 +206,7 @@ for (; i <= *subcount; i++) Ustrcmp(name + SPOOL_NAME_LENGTH - 2, "-H") == 0) { queue_filename *next = - store_get(sizeof(queue_filename) + Ustrlen(name)); + store_get(sizeof(queue_filename) + Ustrlen(name), is_tainted(name)); Ustrcpy(next->text, name); next->dir_uschar = subdirchar; @@ -277,9 +244,8 @@ for (; i <= *subcount; i++) else { - int j; next->next = NULL; - for (j = 0; j < LOG2_MAXNODES; j++) + for (int j = 0; j < LOG2_MAXNODES; j++) if (root[j]) { next = merge_queue_lists(next, root[j]); @@ -379,9 +345,12 @@ const pcre *selectstring_regex = NULL; const pcre *selectstring_regex_sender = NULL; uschar *log_detail = NULL; int subcount = 0; -int i; uschar subdirs[64]; +#ifdef MEASURE_TIMING +report_time_since(×tamp_startup, US"queue_run start"); +#endif + /* Cancel any specific queue domains. Turn off the flag that causes SMTP deliveries not to happen, unless doing a 2-stage queue run, when the SMTP flag gets set. Save the queue_runner's pid and the flag that indicates any @@ -455,12 +424,11 @@ subsequent iterations. When the first argument of queue_get_spool_list() is -1 (for queue_run_in_ order), it scans all directories and makes a single message list. */ -for (i = queue_run_in_order ? -1 : 0; +for (int i = queue_run_in_order ? -1 : 0; i <= (queue_run_in_order ? -1 : subcount); i++) { - queue_filename * fq; - void *reset_point1 = store_get(0); + rmark reset_point1 = store_mark(); DEBUG(D_queue_run) { @@ -472,9 +440,9 @@ for (i = queue_run_in_order ? -1 : 0; debug_printf("queue running subdirectory '%c'\n", subdirs[i]); } - for (fq = queue_get_spool_list(i, subdirs, &subcount, !queue_run_in_order); - fq; - fq = fq->next) + for (queue_filename * fq = queue_get_spool_list(i, subdirs, &subcount, + !queue_run_in_order); + fq; fq = fq->next) { pid_t pid; int status; @@ -524,7 +492,7 @@ for (i = queue_run_in_order ? -1 : 0; { BOOL wanted = TRUE; BOOL orig_dont_deliver = f.dont_deliver; - void *reset_point2 = store_get(0); + rmark reset_point2 = store_mark(); /* Restore the original setting of dont_deliver after reading the header, so that a setting for a particular message doesn't force it for any that @@ -644,13 +612,17 @@ for (i = queue_run_in_order ? -1 : 0; set_process_info("running queue: %s", fq->text); fq->text[SPOOL_NAME_LENGTH-2] = 0; +#ifdef MEASURE_TIMING + report_time_since(×tamp_startup, US"queue msg selected"); +#endif + if ((pid = fork()) == 0) { int rc; - if (f.running_in_test_harness) millisleep(100); + testharness_pause_ms(100); (void)close(pfd[pipe_read]); rc = deliver_message(fq->text, force_delivery, FALSE); - _exit(rc == DELIVER_NOT_ATTEMPTED); + exim_underbar_exit(rc == DELIVER_NOT_ATTEMPTED); } if (pid < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork of delivery process from " @@ -666,11 +638,11 @@ for (i = queue_run_in_order ? -1 : 0; /* A zero return means a delivery was attempted; turn off the force flag for any subsequent calls unless queue_force is set. */ - if ((status & 0xffff) == 0) force_delivery = f.queue_run_force; + if (!(status & 0xffff)) force_delivery = f.queue_run_force; /* If the process crashed, tell somebody */ - else if ((status & 0x00ff) != 0) + else if (status & 0x00ff) log_write(0, LOG_MAIN|LOG_PANIC, "queue run: process %d crashed with signal %d while delivering %s", (int)pid, status & 0x00ff, fq->text); @@ -682,8 +654,9 @@ for (i = queue_run_in_order ? -1 : 0; set_process_info("running queue: waiting for children of %d", pid); if ((status = read(pfd[pipe_read], buffer, sizeof(buffer))) != 0) - log_write(0, LOG_MAIN|LOG_PANIC, "queue run: %s on pipe", - status > 0 ? "unexpected data" : "error"); + log_write(0, LOG_MAIN|LOG_PANIC, status > 0 ? + "queue run: unexpected data on pipe" : "queue run: error on pipe: %s", + strerror(errno)); (void)close(pfd[pipe_read]); set_process_info("running queue"); @@ -692,8 +665,8 @@ for (i = queue_run_in_order ? -1 : 0; if (f.running_in_test_harness && !f.queue_2stage) { - uschar *fqtnext = Ustrchr(fudged_queue_times, '/'); - if (fqtnext != NULL) fudged_queue_times = fqtnext + 1; + uschar * fqtnext = Ustrchr(fudged_queue_times, '/'); + if (fqtnext) fudged_queue_times = fqtnext + 1; } } /* End loop for list of messages */ @@ -704,9 +677,9 @@ for (i = queue_run_in_order ? -1 : 0; sub-directories have been found, randomize their order if necessary. */ if (i == 0 && subcount > 1 && !queue_run_in_order) - { - int j, r; - for (j = 1; j <= subcount; j++) + for (int j = 1; j <= subcount; j++) + { + int r; if ((r = random_number(100)) >= 50) { int k = (r % subcount) + 1; @@ -714,7 +687,7 @@ for (i = queue_run_in_order ? -1 : 0; subdirs[j] = subdirs[k]; subdirs[k] = x; } - } + } } /* End loop for multiple directories */ /* If queue_2stage is true, we do it all again, with the 2stage flag @@ -754,14 +727,14 @@ queue_count(void) { int subcount; int count = 0; -queue_filename *f = NULL; uschar subdirs[64]; -f = queue_get_spool_list( - -1, /* entire queue */ - subdirs, /* for holding sub list */ - &subcount, /* for subcount */ - FALSE); /* not random */ -for (; f != NULL; f = f->next) count++; + +for (queue_filename *f = queue_get_spool_list( + -1, /* entire queue */ + subdirs, /* for holding sub list */ + &subcount, /* for subcount */ + FALSE); /* not random */ + f; f = f->next) count++; fprintf(stdout, "%d\n", count); } @@ -781,11 +754,12 @@ Argument: points to the tree node Returns: nothing */ -static void queue_list_extras(tree_node *p) +static void +queue_list_extras(tree_node *p) { -if (p->left != NULL) queue_list_extras(p->left); +if (p->left) queue_list_extras(p->left); if (!p->data.val) printf(" +D %s\n", p->name); -if (p->right != NULL) queue_list_extras(p->right); +if (p->right) queue_list_extras(p->right); } @@ -816,10 +790,9 @@ Returns: nothing void queue_list(int option, uschar **list, int count) { -int i; int subcount; int now = (int)time(NULL); -void *reset_point; +rmark reset_point; queue_filename * qf = NULL; uschar subdirs[64]; @@ -828,10 +801,10 @@ uschar subdirs[64]; if (count > 0) { queue_filename *last = NULL; - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) { queue_filename *next = - store_get(sizeof(queue_filename) + Ustrlen(list[i]) + 2); + store_get(sizeof(queue_filename) + Ustrlen(list[i]) + 2, is_tainted(list[i])); sprintf(CS next->text, "%s-H", list[i]); next->dir_uschar = '*'; next->next = NULL; @@ -854,8 +827,8 @@ if (option >= 8) option -= 8; /* Now scan the chain and print information, resetting store used each time. */ -for (reset_point = store_get(0); - qf; +for (; + qf && (reset_point = store_mark()); spool_clear_header_globals(), store_reset(reset_point), qf = qf->next ) { @@ -874,7 +847,7 @@ for (reset_point = store_get(0); if (env_read) { - int ptr; + int i, ptr; FILE *jread; struct stat statbuf; uschar * fname = spool_fname(US"input", message_subdir, qf->text, US""); @@ -912,7 +885,7 @@ for (reset_point = store_get(0); } fprintf(stdout, "%s ", string_format_size(size, big_buffer)); - for (i = 0; i < 16; i++) fputc(qf->text[i], stdout); + for (int i = 0; i < 16; i++) fputc(qf->text[i], stdout); if (env_read && sender_address) { @@ -947,7 +920,7 @@ for (reset_point = store_get(0); if (recipients_list) { - for (i = 0; i < recipients_count; i++) + for (int i = 0; i < recipients_count; i++) { tree_node *delivered = tree_search(tree_nonrecipients, recipients_list[i].address); @@ -986,7 +959,6 @@ Returns: FALSE if there was any problem BOOL queue_action(uschar *id, int action, uschar **argv, int argc, int recipients_arg) { -int i, j; BOOL yield = TRUE; BOOL removed = FALSE; struct passwd *pw; @@ -1005,7 +977,7 @@ done. Only admin users may read the spool files. */ if (action >= MSG_SHOW_BODY) { - int fd, i, rc; + int fd, rc; uschar *subdirectory, *suffix; if (!f.admin_user) @@ -1036,9 +1008,9 @@ if (action >= MSG_SHOW_BODY) suffix = US""; } - for (i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { - message_subdir[0] = split_spool_directory == (i == 0) ? id[5] : 0; + set_subdir_str(message_subdir, id, i); if ((fd = Uopen(spool_fname(subdirectory, message_subdir, id, suffix), O_RDONLY, 0)) >= 0) break; @@ -1203,7 +1175,7 @@ switch(action) suffix[2] = 0; message_subdir[0] = id[5]; - for (j = 0; j < 2; message_subdir[0] = 0, j++) + for (int j = 0; j < 2; message_subdir[0] = 0, j++) { uschar * fname = spool_fname(US"msglog", message_subdir, id, US""); @@ -1223,7 +1195,7 @@ switch(action) DEBUG(D_any) debug_printf(" (ok)\n"); } - for (i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { uschar * fname; @@ -1256,7 +1228,7 @@ switch(action) if (removed) { #ifndef DISABLE_EVENT - for (i = 0; i < recipients_count; i++) + if (event_action) for (int i = 0; i < recipients_count; i++) { tree_node *delivered = tree_search(tree_nonrecipients, recipients_list[i].address); @@ -1294,14 +1266,22 @@ switch(action) } + case MSG_SETQUEUE: + /* The global "queue_name_dest" is used as destination, "queue_name" + as source */ + + spool_move_message(id, message_subdir, US"", US""); + break; + + case MSG_MARK_ALL_DELIVERED: - for (i = 0; i < recipients_count; i++) + for (int i = 0; i < recipients_count; i++) tree_add_nonrecipient(recipients_list[i].address); if (spool_write_header(id, SW_MODIFYING, &errmsg) >= 0) { printf("has been modified\n"); - for (i = 0; i < recipients_count; i++) + for (int i = 0; i < recipients_count; i++) log_write(0, LOG_MAIN, "address <%s> marked delivered by %s", recipients_list[i].address, username); } @@ -1372,6 +1352,7 @@ switch(action) } else if (action == MSG_MARK_DELIVERED) { + int i; for (i = 0; i < recipients_count; i++) if (Ustrcmp(recipients_list[i].address, recipient) == 0) break; if (i >= recipients_count)