sendmail: update from maintainer
No binary (build failed)
—
(log yok)
| @@ -1026,17 +1026,19 @@ USE_FEATURE_BRCTL_FANCY("\n" \ | |
| " -v Give fdisk version" | |
| #define fetchmail_trivial_usage \ | |
| - | "[-C dir] [-w timeout] [-U user] -P password [-X] [-t] [-z] server[:port]" |
| + | "[-w timeout] [-U user] -P password [-X] [-t] [-z] server[:port] maildir [prog]" |
| #define fetchmail_full_usage \ | |
| "Fetch content of remote mailbox to local Maildir." \ | |
| "\n\nOptions:\n" \ | |
| - | " -C dir Set Maildir location\n" \ |
| " -w timeout Set timeout on network operations\n" \ | |
| " -U username Authenticate with specified username\n" \ | |
| " -P password Authenticate with specified password\n" \ | |
| " -X Use openssl connection helper for secured servers\n" \ | |
| " -t Get only headers\n" \ | |
| - | " -z Delete messages on server" |
| + | " -z Delete messages on server" \ |
| + | USE_FEATURE_FETCHMAIL_FILTER("\n" \ |
| + | " prog Run prog <message file> on message delivery" \ |
| + | ) |
| #define findfs_trivial_usage \ | |
| "LABEL=label or UUID=uuid" | |
| @@ -3258,18 +3260,16 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when | |
| #define selinuxenabled_full_usage | |
| #define sendmail_trivial_usage \ | |
| - | "[-C dir] [-w timeout] [-U user] [-P password] [-X]\n" \ |
| - | "-t to [-t to] -f from [-n] [-s subject] [-c charset] server[:port] [body] [attachment ...]" |
| + | "[-w timeout] [-U user] [-P password] [-X]\n" \ |
| + | "-t to [-t to]... [-n] [-s subject] [-c charset] server[:port] from [body] [attachment ...]" |
| #define sendmail_full_usage \ | |
| "Send an email with optional attachments." \ | |
| "\n\nOptions:\n" \ | |
| - | " -C dir Change current directory to dir\n" \ |
| " -w timeout Set timeout on network operations\n" \ | |
| " -U username Authenticate with specified username\n" \ | |
| " -P password Authenticate with specified password\n" \ | |
| + | " -t address Recipient(s). May be multiple\n" \ |
| " -X Use openssl connection helper for secured servers\n" \ | |
| - | " -t to Recipient email. May be multiple\n" \ |
| - | " -f from Sender address\n" \ |
| " -n Request delivery notification to sender\n" \ | |
| " -s subject Subject\n" \ | |
| " -c charset Assumed charset for body and subject [utf-8]" | |
| @@ -27,9 +27,13 @@ static void uuencode(char *fname, const char *text) | |
| if (NOT_LONE_DASH(fname)) | |
| fd = xopen(fname, O_RDONLY); | |
| src_buf = bb_common_bufsiz1; | |
| - | } else { |
| + | // N.B. strlen(NULL) segfaults! |
| + | } else if (text) { |
| + | // though we do not call uuencode(NULL, NULL) explicitly |
| + | // still we do not want to break things suddenly |
| len = strlen(text); | |
| - | } |
| + | } else |
| + | return; |
| fflush(stdout); // sync stdio and unistd output | |
| while (1) { | |
| @@ -59,7 +63,38 @@ static void uuencode(char *fname, const char *text) | |
| close(fd); | |
| } | |
| - | static pid_t helper_pid; |
| + | static const char *const init_xargs[9] = { |
| + | "openssl", "s_client", "-quiet", "-connect", |
| + | NULL, "-tls1", "-starttls", "smtp" |
| + | }; |
| + | |
| + | struct globals { |
| + | pid_t helper_pid; |
| + | unsigned timeout; |
| + | // arguments for SSL connection helper |
| + | const char *xargs[9]; |
| + | #if ENABLE_FEATURE_FETCHMAIL_FILTER |
| + | // arguments for postprocess helper |
| + | const char *fargs[3]; |
| + | #endif |
| + | }; |
| + | #define G (*ptr_to_globals) |
| + | #define helper_pid (G.helper_pid) |
| + | #define timeout (G.timeout ) |
| + | #define xargs (G.xargs ) |
| + | #define fargs (G.fargs ) |
| + | #define INIT_G() do { \ |
| + | PTR_TO_GLOBALS = xzalloc(sizeof(G)); \ |
| + | memcpy(xargs, init_xargs, sizeof(init_xargs)); \ |
| + | fargs[0] = "utf-8"; \ |
| + | } while (0) |
| + | |
| + | #define opt_connect (xargs[4]) |
| + | #define opt_after_connect (xargs[5]) |
| + | #if ENABLE_FEATURE_FETCHMAIL_FILTER |
| + | #define opt_charset (fargs[0]) |
| + | #define opt_subject (fargs[1]) |
| + | #endif |
| static void kill_helper(void) | |
| { | |
| @@ -71,7 +106,7 @@ static void kill_helper(void) | |
| // generic signal handler | |
| static void signal_handler(int signo) | |
| { | |
| - | int err; |
| + | #define err signo |
| if (SIGALRM == signo) { | |
| kill_helper(); | |
| @@ -107,20 +142,19 @@ static void launch_helper(const char **argv) | |
| close(pipes[i]); | |
| if (!helper_pid) { | |
| // child - try to execute connection helper | |
| - | BB_EXECVP(argv[0], (char **)argv); |
| + | // close(STDERR_FILENO); |
| + | BB_EXECVP(*argv, (char **)argv); |
| _exit(127); | |
| } | |
| // parent - check whether child is alive | |
| - | bb_signals_recursive(0 |
| - | + (1 << SIGCHLD) |
| - | + (1 << SIGALRM) |
| - | , signal_handler); |
| + | bb_signals(0 |
| + | + (1 << SIGCHLD) |
| + | + (1 << SIGALRM) |
| + | , signal_handler); |
| signal_handler(SIGCHLD); | |
| // child seems OK -> parent goes on | |
| } | |
| - | static unsigned timeout; |
| - | |
| static char *command(const char *fmt, const char *param) | |
| { | |
| char *msg = (char *)fmt; | |
| @@ -145,7 +179,9 @@ static int smtp_checkp(const char *fmt, const char *param, int code) | |
| // if code != -1 then checks whether the number equals the code | |
| // if not equal -> die saying msg | |
| #if ENABLE_FEATURE_SENDMAIL_EHLO | |
| - | while ((answer = xmalloc_getline(stdin)) && '-' == answer[3]) ; |
| + | while ((answer = xmalloc_getline(stdin)) != NULL) |
| + | if (strlen(answer) <= 3 || '-' != answer[3]) |
| + | break; |
| #else | |
| answer = xmalloc_getline(stdin); | |
| #endif | |
| @@ -169,15 +205,31 @@ static int smtp_check(const char *fmt, int code) | |
| return smtp_checkp(fmt, NULL, code); | |
| } | |
| + | // strip argument of bad chars |
| + | static char *sane(char *str) |
| + | { |
| + | char *s = str; |
| + | char *p = s; |
| + | while (*s) { |
| + | if (isalnum(*s) || '_' == *s || '-' == *s || '.' == *s || '@' == *s) { |
| + | *p++ = *s; |
| + | } |
| + | s++; |
| + | } |
| + | *p = '\0'; |
| + | return str; |
| + | } |
| + | |
| + | #if ENABLE_FETCHMAIL |
| static void pop3_checkr(const char *fmt, const char *param, char **ret) | |
| { | |
| char *msg = command(fmt, param); | |
| char *answer = xmalloc_getline(stdin); | |
| - | if (answer && '+' == answer[0]) { |
| + | if (answer && '+' == *answer) { |
| alarm(0); | |
| if (ret) | |
| - | *ret = answer; |
| - | else |
| + | *ret = answer+4; // skip "+OK " |
| + | else if (ENABLE_FEATURE_CLEAN_UP) |
| free(answer); | |
| return; | |
| } | |
| @@ -190,28 +242,16 @@ static void pop3_check(const char *fmt, const char *param) | |
| pop3_checkr(fmt, param, NULL); | |
| } | |
| - | // strip argument of bad chars |
| - | static char *sane(char *str) |
| - | { |
| - | char *s = str; |
| - | char *p = s; |
| - | while (*s) { |
| - | if (isalnum(*s) || '_' == *s || '-' == *s || '.' == *s || '@' == *s) { |
| - | *p++ = *s; |
| - | } |
| - | s++; |
| - | } |
| - | *p = '\0'; |
| - | return str; |
| - | } |
| - | |
| - | static void pop3_message(int fd) |
| + | static void pop3_message(const char *filename) |
| { | |
| + | int fd; |
| char *answer; | |
| - | // read stdin, copy to file fd |
| + | // create and open file filename |
| + | // read stdin, copy to created file |
| + | fd = xopen(filename, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL); |
| while ((answer = xmalloc_fgets_str(stdin, "\r\n"))) { | |
| char *s = answer; | |
| - | if ('.' == answer[0]) { |
| + | if ('.' == *answer) { |
| if ('.' == answer[1]) | |
| s++; | |
| else if ('\r' == answer[1] && '\n' == answer[2] && '\0' == answer[3]) | |
| @@ -222,64 +262,56 @@ static void pop3_message(int fd) | |
| } | |
| close(fd); | |
| } | |
| - | |
| - | static const char *args[] = { |
| - | "openssl", "s_client", "-quiet", "-connect", NULL, "-tls1", "-starttls", "smtp", NULL |
| - | }; |
| - | #define opt_connect args[4] |
| - | #define opt_after_connect args[5] |
| + | #endif |
| int sendgetmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int sendgetmail_main(int argc, char **argv) | |
| { | |
| - | llist_t *recipients = NULL; |
| - | char *from; |
| - | const char *subject; |
| - | char *charset = (char *)"utf-8"; |
| + | llist_t *opt_recipients = NULL; |
| + | #if !ENABLE_FEATURE_FETCHMAIL_FILTER |
| + | char *opt_subject; |
| + | char *opt_charset = (char *)"utf-8"; |
| + | #endif |
| const char *opt_user; | |
| const char *opt_pass; | |
| - | const char *opt_timeout; |
| - | const char *opt_chdir; |
| enum { | |
| - | OPT_C = 1 << 0, // chdir |
| - | OPT_w = 1 << 1, // network timeout |
| - | OPT_U = 1 << 2, // user |
| - | OPT_P = 1 << 3, // password |
| - | OPT_X = 1 << 4, // use openssl connection helper |
| + | OPT_w = 1 << 0, // network timeout |
| + | OPT_U = 1 << 1, // user |
| + | OPT_P = 1 << 2, // password |
| + | OPT_X = 1 << 3, // connect using openssl s_client helper |
| - | OPTS_t = 1 << 5, // sendmail "to" |
| - | OPTF_t = 1 << 5, // fetchmail "TOP" |
| + | OPTS_n = 1 << 4, // sendmail: request notification |
| + | OPTF_t = 1 << 4, // fetchmail: use "TOP" not "RETR" |
| - | OPTS_f = 1 << 6, // sendmail "from" |
| - | OPTF_z = 1 << 6, // fetchmail "delete" |
| + | OPTS_s = 1 << 5, // sendmail: subject |
| + | OPTF_z = 1 << 5, // fetchmail: delete from server |
| - | OPTS_n = 1 << 7, // notification |
| - | OPTS_s = 1 << 8, // subject given |
| - | OPTS_c = 1 << 9, // charset for subject and body |
| + | OPTS_c = 1 << 6, // sendmail: assumed charset |
| + | OPTS_t = 1 << 7, // sendmail: recipient(s) |
| }; | |
| const char *options; | |
| unsigned opts; | |
| - | // SENDMAIL |
| - | if ('s' == applet_name[0]) { |
| - | // save initial stdin |
| + | INIT_G(); |
| + | |
| + | if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) { |
| + | // SENDMAIL |
| + | // save initial stdin (body or attachements can be piped!) |
| xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); | |
| - | // -f must be specified |
| - | // -t may be multiple |
| - | opt_complementary = "-1:f:t::"; |
| - | options = "C:w:U:P:X" "t:f:ns:c:"; |
| - | // FETCHMAIL |
| + | opt_complementary = "-2:w+:t:t::"; // count(-t) > 0 |
| + | options = "w:U:P:X" "ns:c:t:"; |
| } else { | |
| + | // FETCHMAIL |
| opt_after_connect = NULL; | |
| - | opt_complementary = "=1:P"; |
| - | options = "C:w:U:P:X" "tz"; |
| + | opt_complementary = "-2:w+:P"; |
| + | options = "w:U:P:X" "tz"; |
| } | |
| opts = getopt32(argv, options, | |
| - | &opt_chdir, &opt_timeout, &opt_user, &opt_pass, |
| - | &recipients, &from, &subject, &charset |
| + | &timeout, &opt_user, &opt_pass, |
| + | &opt_subject, &opt_charset, &opt_recipients |
| ); | |
| //argc -= optind; | |
| @@ -288,16 +320,9 @@ int sendgetmail_main(int argc, char **argv) | |
| // first argument is remote server[:port] | |
| opt_connect = *argv++; | |
| - | if (opts & OPT_w) |
| - | timeout = xatou(opt_timeout); |
| - | |
| - | // chdir |
| - | if (opts & OPT_C) |
| - | xchdir(opt_chdir); |
| - | |
| // connect to server | |
| if (opts & OPT_X) { | |
| - | launch_helper(args); |
| + | launch_helper(xargs); |
| } else { | |
| // no connection helper provided -> make plain connect | |
| int fd = create_and_connect_stream_or_die(opt_connect, 0); | |
| @@ -305,24 +330,30 @@ int sendgetmail_main(int argc, char **argv) | |
| xdup2(STDIN_FILENO, STDOUT_FILENO); | |
| } | |
| - | // randomize |
| - | srand(time(NULL)); |
| - | |
| - | // SENDMAIL |
| - | if (recipients) { |
| + | #if ENABLE_FETCHMAIL |
| + | if (opt_after_connect) |
| + | #endif |
| + | { |
| + | // SENDMAIL |
| + | char *opt_from; |
| int code; | |
| char *boundary; | |
| + | const char *fmt; |
| + | const char *p; |
| + | char *q; |
| // wait for initial OK on plain connect | |
| if (!(opts & OPT_X)) | |
| smtp_check(NULL, 220); | |
| - | sane(from); |
| + | // get specified sender |
| + | opt_from = sane(*argv++); |
| + | |
| // introduce to server | |
| // should we respect modern (but useless here) EHLO? | |
| // or should they respect we wanna be tiny?! | |
| - | if (!ENABLE_FEATURE_SENDMAIL_EHLO || 250 != smtp_checkp("EHLO %s", from, -1)) { |
| - | smtp_checkp("HELO %s", from, 250); |
| + | if (!ENABLE_FEATURE_SENDMAIL_EHLO || 250 != smtp_checkp("EHLO %s", opt_from, -1)) { |
| + | smtp_checkp("HELO %s", opt_from, 250); |
| } | |
| // set sender | |
| @@ -330,13 +361,13 @@ int sendgetmail_main(int argc, char **argv) | |
| // no authentication is possible | |
| code = (opts & OPT_P) ? -1 : 250; | |
| // first try softly without authentication | |
| - | while (250 != smtp_checkp("MAIL FROM:<%s>", from, code)) { |
| + | while (250 != smtp_checkp("MAIL FROM:<%s>", opt_from, code)) { |
| // MAIL FROM failed -> authentication needed | |
| // do we have username? | |
| if (!(opts & OPT_U)) { | |
| // no! fetch it from "from" option | |
| //opts |= OPT_U; | |
| - | opt_user = xstrdup(from); |
| + | opt_user = xstrdup(opt_from); |
| *strchrnul(opt_user, '@') = '\0'; | |
| } | |
| // now it seems we have username | |
| @@ -351,30 +382,35 @@ int sendgetmail_main(int argc, char **argv) | |
| // but now die on failure | |
| code = 250; | |
| } | |
| + | |
| // set recipients | |
| - | for (llist_t *to = recipients; to; to = to->link) { |
| + | for (llist_t *to = opt_recipients; to; to = to->link) { |
| smtp_checkp("RCPT TO:<%s>", sane(to->data), 250); | |
| } | |
| // now put message | |
| smtp_check("DATA", 354); | |
| // put address headers | |
| - | printf("From: %s\r\n", from); |
| - | for (llist_t *to = recipients; to; to = to->link) { |
| + | printf("From: %s\r\n", opt_from); |
| + | for (llist_t *to = opt_recipients; to; to = to->link) { |
| printf("To: %s\r\n", to->data); | |
| } | |
| // put encoded subject | |
| if (opts & OPTS_c) | |
| - | sane(charset); |
| + | sane((char *)opt_charset); |
| if (opts & OPTS_s) { | |
| - | printf("Subject: =?%s?B?", charset); |
| - | uuencode(NULL, subject); |
| + | printf("Subject: =?%s?B?", opt_charset); |
| + | uuencode(NULL, opt_subject); |
| printf("?=\r\n"); | |
| } | |
| // put notification | |
| if (opts & OPTS_n) | |
| - | printf("Disposition-Notification-To: %s\r\n", from); |
| + | printf("Disposition-Notification-To: %s\r\n", opt_from); |
| // put common headers and body start | |
| + | // randomize |
| + | #if ENABLE_FEATURE_SENDMAIL_BLOATY |
| + | srand(time(NULL)); |
| + | #endif |
| boundary = xasprintf("%d-%d-%d", rand(), rand(), rand()); | |
| printf( | |
| USE_FEATURE_SENDMAIL_BLOATY("X-Mailer: busybox " BB_VER " sendmail\r\n") | |
| @@ -386,16 +422,16 @@ int sendgetmail_main(int argc, char **argv) | |
| , boundary | |
| ); | |
| // put body + attachment(s) | |
| - | { |
| - | const char *fmt = |
| + | |
| + | fmt = |
| "\r\n--%s\r\n" | |
| "%stext/plain; charset=%s\r\n" | |
| "%s%s\r\n" | |
| "%s" | |
| ; | |
| - | const char *p = charset; |
| - | char *q = (char *)""; |
| - | while (argv[0]) { |
| + | p = opt_charset; |
| + | q = (char *)""; |
| + | while (*argv) { |
| printf( | |
| fmt | |
| , boundary | |
| @@ -414,9 +450,9 @@ int sendgetmail_main(int argc, char **argv) | |
| ; | |
| uuencode(*argv, NULL); | |
| if (*(++argv)) | |
| - | q = bb_get_last_path_component_strip(argv[0]); |
| + | q = bb_get_last_path_component_strip(*argv); |
| } | |
| - | } |
| + | |
| // put terminator | |
| printf("\r\n--%s--\r\n" "\r\n", boundary); | |
| if (ENABLE_FEATURE_CLEAN_UP) | |
| @@ -426,11 +462,25 @@ int sendgetmail_main(int argc, char **argv) | |
| smtp_check(".", 250); | |
| smtp_check("QUIT", 221); | |
| - | // FETCHMAIL |
| + | #if ENABLE_FETCHMAIL |
| } else { | |
| - | // authenticate |
| + | // FETCHMAIL |
| char *buf; | |
| unsigned nmsg; | |
| + | char *hostname; |
| + | pid_t pid; |
| + | // cache fetch command |
| + | const char *retr = (opts & OPTF_t) ? "TOP %u 0" : "RETR %u"; |
| + | |
| + | // goto maildir |
| + | xchdir(*argv++); |
| + | |
| + | #if ENABLE_FEATURE_FETCHMAIL_FILTER |
| + | // cache postprocess program |
| + | *fargs = *argv; |
| + | #endif |
| + | |
| + | // authenticate |
| if (!(opts & OPT_U)) { | |
| //opts |= OPT_U; | |
| opt_user = getenv("USER"); | |
| @@ -438,25 +488,29 @@ int sendgetmail_main(int argc, char **argv) | |
| #if ENABLE_FEATURE_FETCHMAIL_APOP | |
| pop3_checkr(NULL, NULL, &buf); | |
| // server supports APOP? | |
| - | if ('<' == buf[4]) { |
| + | if ('<' == *buf) { |
| md5_ctx_t md5; | |
| - | uint8_t hex[16*2 + 1]; |
| // yes. compose <stamp><password> | |
| char *s = strchr(buf, '>'); | |
| if (s) | |
| strcpy(s+1, opt_pass); | |
| - | s = buf+4; |
| + | s = buf; |
| // get md5 sum of <stamp><password> | |
| md5_begin(&md5); | |
| md5_hash(s, strlen(s), &md5); | |
| md5_end(s, &md5); | |
| - | bin2hex(hex, s, 16); |
| + | // NOTE: md5 struct contains enough space |
| + | // so we reuse md5 space instead of xzalloc(16*2+1) |
| + | #define md5_hex ((uint8_t *)&md5) |
| + | // uint8_t *md5_hex = (uint8_t *)&md5; |
| + | *bin2hex(md5_hex, s, 16) = '\0'; |
| // APOP | |
| - | s = xasprintf("%s %s", opt_user, hex); |
| + | s = xasprintf("%s %s", opt_user, md5_hex); |
| + | #undef md5_hex |
| pop3_check("APOP %s", s); | |
| if (ENABLE_FEATURE_CLEAN_UP) { | |
| free(s); | |
| - | free(buf); |
| + | free(buf-4); // buf is "+OK " away from malloc'ed string |
| } | |
| } else { | |
| #else | |
| @@ -472,60 +526,64 @@ int sendgetmail_main(int argc, char **argv) | |
| // get statistics | |
| pop3_checkr("STAT", NULL, &buf); | |
| + | // prepare message filename suffix |
| + | hostname = xzalloc(MAXHOSTNAMELEN+1); |
| + | gethostname(hostname, MAXHOSTNAMELEN); |
| + | pid = getpid(); |
| + | |
| // get number of messages | |
| - | nmsg = atoi(buf+4); |
| + | // NOTE: we don't use xatou(buf) since buf is "nmsg nbytes" |
| + | // we only need nmsg and atoi is just exactly what we need |
| + | // if atoi fails to convert buf into number it returns 0 |
| + | // in this case the following loop simply will not be executed |
| + | nmsg = atoi(buf); |
| if (ENABLE_FEATURE_CLEAN_UP) | |
| - | free(buf); |
| - | |
| - | // lock maildir |
| - | ////USE_FEATURE_CLEAN_UP(close)(xopen(".lock", O_CREAT | O_WRONLY | O_TRUNC | O_EXCL)); |
| - | |
| - | // make tempnam(dir, salt) respect dir argument |
| - | unsetenv("TMPDIR"); |
| - | |
| - | // TODO: piping through external filter argv... if *argv |
| + | free(buf-4); // buf is "+OK " away from malloc'ed string |
| - | // cache fetch command |
| - | { |
| - | const char *retr = (opts & OPTF_t) ? "TOP %u 0" : "RETR %u"; |
| // loop through messages | |
| for (; nmsg; nmsg--) { | |
| - | int fd; |
| - | char tmp_name[sizeof("tmp/XXXXXX")]; |
| - | char new_name[sizeof("new/XXXXXX")]; |
| - | |
| + | char *filename = xasprintf("tmp/%llu.%u.%s", monotonic_us(), pid, hostname); |
| + | char *target; |
| + | #if ENABLE_FEATURE_FETCHMAIL_FILTER |
| + | int rc; |
| + | #endif |
| // retrieve message in ./tmp | |
| - | strcpy(tmp_name, "tmp/XXXXXX"); |
| - | fd = mkstemp(tmp_name); |
| - | if (fd < 0) |
| - | bb_perror_msg_and_die("cannot create unique file"); |
| pop3_check(retr, (const char *)nmsg); | |
| - | pop3_message(fd); // NB: closes fd |
| - | |
| - | // move file to ./new atomically |
| - | strncpy(new_name, "new", 3); |
| - | strcpy(new_name + 3, tmp_name + 3); |
| - | if (rename(tmp_name, new_name) < 0) { |
| - | // rats! such file exists! try to make unique name |
| - | strcpy(new_name + 3, "tmp/XXXXXX" + 3); |
| - | fd = mkstemp(new_name); |
| - | if (fd < 0) |
| - | bb_perror_msg_and_die("cannot create unique file"); |
| - | close(fd); |
| - | xrename(tmp_name, new_name); |
| - | } |
| - | |
| + | pop3_message(filename); |
| // delete message from server | |
| if (opts & OPTF_z) | |
| pop3_check("DELE %u", (const char*)nmsg); | |
| + | |
| + | #if ENABLE_FEATURE_FETCHMAIL_FILTER |
| + | // run postprocessing program |
| + | if (*fargs) { |
| + | fargs[1] = filename; |
| + | rc = wait4pid(spawn((char **)fargs)); |
| + | if (99 == rc) |
| + | break; |
| + | if (1 == rc) |
| + | goto skip; |
| + | } |
| + | #endif |
| + | // atomically move message to ./new |
| + | target = xstrdup(filename); |
| + | strncpy(target, "new", 3); |
| + | // ... or just stop receiving on error |
| + | if (rename_or_warn(filename, target)) |
| + | break; |
| + | free(target); |
| + | #if ENABLE_FEATURE_FETCHMAIL_FILTER |
| + | skip: |
| + | #endif |
| + | free(filename); |
| } | |
| - | } |
| + | |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| + | free(hostname); |
| // Bye | |
| pop3_check("QUIT", NULL); | |
| - | |
| - | // unlock maildir |
| - | ////unlink(".lock"); |
| + | #endif // ENABLE_FETCHMAIL |
| } | |
| return 0; | |