X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/8768d5483a5894400ae1f70cda1beb44ed9b087c..727a5d2511acd513514b52a72f8db294e54f3ae9:/src/src/queue.c diff --git a/src/src/queue.c b/src/src/queue.c index 9f9e409ed..f65c65262 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,7 +345,6 @@ const pcre *selectstring_regex = NULL; const pcre *selectstring_regex_sender = NULL; uschar *log_detail = NULL; int subcount = 0; -int i; uschar subdirs[64]; /* Cancel any specific queue domains. Turn off the flag that causes SMTP @@ -455,12 +420,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 +436,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 +488,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 @@ -650,7 +614,7 @@ for (i = queue_run_in_order ? -1 : 0; if (f.running_in_test_harness) millisleep(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 " @@ -704,9 +668,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 +678,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 +718,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 +745,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 +781,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 +792,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 +818,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 +838,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 +876,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 +911,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 +950,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 +968,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 +999,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; @@ -1135,7 +1098,7 @@ switch(action) deliver_in_buffer = store_malloc(DELIVER_IN_BUFFER_SIZE); deliver_out_buffer = store_malloc(DELIVER_OUT_BUFFER_SIZE); tctx.u.fd = 1; - transport_write_message(&tctx, 0); + (void) transport_write_message(&tctx, 0); break; } @@ -1203,7 +1166,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 +1186,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; @@ -1255,6 +1218,38 @@ switch(action) else printf("has been removed or did not exist\n"); if (removed) { +#ifndef DISABLE_EVENT + if (event_action) for (int i = 0; i < recipients_count; i++) + { + tree_node *delivered = + tree_search(tree_nonrecipients, recipients_list[i].address); + if (!delivered) + { + uschar * save_local = deliver_localpart; + const uschar * save_domain = deliver_domain; + uschar * addr = recipients_list[i].address, * errmsg = NULL; + int start, end, dom; + + if (!parse_extract_address(addr, &errmsg, &start, &end, &dom, TRUE)) + log_write(0, LOG_MAIN|LOG_PANIC, + "failed to parse address '%.100s'\n: %s", addr, errmsg); + else + { + deliver_localpart = + string_copyn(addr+start, dom ? (dom-1) - start : end - start); + deliver_domain = dom + ? CUS string_copyn(addr+dom, end - dom) : CUS""; + + event_raise(event_action, US"msg:fail:internal", + string_sprintf("message removed by %s", username)); + + deliver_localpart = save_local; + deliver_domain = save_domain; + } + } + } + (void) event_raise(event_action, US"msg:complete", NULL); +#endif log_write(0, LOG_MAIN, "removed by %s", username); log_write(0, LOG_MAIN, "Completed"); } @@ -1263,14 +1258,13 @@ switch(action) 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); } @@ -1341,6 +1335,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)