diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-07 21:02:35 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-07 21:02:35 +0000 |
| commit | 6fa1ba3972ddba2216c216236dbc878b9fa8752a (patch) | |
| tree | 3217321efa202b860229408b60c57d47bc0cdb8f | |
| parent | 90c31b3d4b58512ec2e1ed00670668dd52236415 (diff) | |
| download | busybox-w32-6fa1ba3972ddba2216c216236dbc878b9fa8752a.tar.gz busybox-w32-6fa1ba3972ddba2216c216236dbc878b9fa8752a.tar.bz2 busybox-w32-6fa1ba3972ddba2216c216236dbc878b9fa8752a.zip | |
crond: add handling of "MAILTO=user" lines
sendmail: handle a case when the whole mail comes from stdin
(and no separate sender/subj is provided)
both by dronnikov AT gmail.com
function old new delta
sendgetmail_main 1509 1674 +165
SynchronizeFile 671 767 +96
packed_usage 24054 24088 +34
crond_main 1404 1420 +16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 311/0) Total: 311 bytes
| -rw-r--r-- | miscutils/crond.c | 59 | ||||
| -rw-r--r-- | networking/sendmail.c | 28 |
2 files changed, 67 insertions, 20 deletions
diff --git a/miscutils/crond.c b/miscutils/crond.c index ba9cf3581..98dd22d9d 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
| @@ -33,7 +33,11 @@ | |||
| 33 | #define SENDMAIL "sendmail" | 33 | #define SENDMAIL "sendmail" |
| 34 | #endif | 34 | #endif |
| 35 | #ifndef SENDMAIL_ARGS | 35 | #ifndef SENDMAIL_ARGS |
| 36 | #define SENDMAIL_ARGS "-ti", "oem" | 36 | # if ENABLE_SENDMAIL |
| 37 | # define SENDMAIL_ARGS "localhost", line->cl_MailTo | ||
| 38 | # else | ||
| 39 | # define SENDMAIL_ARGS "-ti", "oem" | ||
| 40 | # endif | ||
| 37 | #endif | 41 | #endif |
| 38 | #ifndef CRONUPDATE | 42 | #ifndef CRONUPDATE |
| 39 | #define CRONUPDATE "cron.update" | 43 | #define CRONUPDATE "cron.update" |
| @@ -59,6 +63,7 @@ typedef struct CronLine { | |||
| 59 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL | 63 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL |
| 60 | int cl_MailPos; /* 'empty file' size */ | 64 | int cl_MailPos; /* 'empty file' size */ |
| 61 | smallint cl_MailFlag; /* running pid is for mail */ | 65 | smallint cl_MailFlag; /* running pid is for mail */ |
| 66 | char *cl_MailTo; /* whom to mail results */ | ||
| 62 | #endif | 67 | #endif |
| 63 | /* ordered by size, not in natural order. makes code smaller: */ | 68 | /* ordered by size, not in natural order. makes code smaller: */ |
| 64 | char cl_Dow[7]; /* 0-6, beginning sunday */ | 69 | char cl_Dow[7]; /* 0-6, beginning sunday */ |
| @@ -449,6 +454,9 @@ static void SynchronizeFile(const char *fileName) | |||
| 449 | int maxEntries; | 454 | int maxEntries; |
| 450 | int maxLines; | 455 | int maxLines; |
| 451 | char buf[1024]; | 456 | char buf[1024]; |
| 457 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL | ||
| 458 | char *mailTo = NULL; | ||
| 459 | #endif | ||
| 452 | 460 | ||
| 453 | if (!fileName) | 461 | if (!fileName) |
| 454 | return; | 462 | return; |
| @@ -485,6 +493,14 @@ static void SynchronizeFile(const char *fileName) | |||
| 485 | if (DebugOpt) { | 493 | if (DebugOpt) { |
| 486 | crondlog(LVL5 "user:%s entry:%s", fileName, buf); | 494 | crondlog(LVL5 "user:%s entry:%s", fileName, buf); |
| 487 | } | 495 | } |
| 496 | /* check if line is setting MAILTO= */ | ||
| 497 | if (0 == strncmp("MAILTO=", buf, 7)) { | ||
| 498 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL | ||
| 499 | free(mailTo); | ||
| 500 | mailTo = (buf[7]) ? xstrdup(buf+7) : NULL; | ||
| 501 | #endif /* otherwise just ignore such lines */ | ||
| 502 | continue; | ||
| 503 | } | ||
| 488 | *pline = line = xzalloc(sizeof(CronLine)); | 504 | *pline = line = xzalloc(sizeof(CronLine)); |
| 489 | /* parse date ranges */ | 505 | /* parse date ranges */ |
| 490 | ptr = ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, buf); | 506 | ptr = ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, buf); |
| @@ -498,10 +514,14 @@ static void SynchronizeFile(const char *fileName) | |||
| 498 | continue; | 514 | continue; |
| 499 | } | 515 | } |
| 500 | /* | 516 | /* |
| 501 | * fix days and dow - if one is not * and the other | 517 | * fix days and dow - if one is not "*" and the other |
| 502 | * is *, the other is set to 0, and vise-versa | 518 | * is "*", the other is set to 0, and vise-versa |
| 503 | */ | 519 | */ |
| 504 | FixDayDow(line); | 520 | FixDayDow(line); |
| 521 | #if ENABLE_FEATURE_CROND_CALL_SENDMAIL | ||
| 522 | /* copy mailto (can be NULL) */ | ||
| 523 | line->cl_MailTo = xstrdup(mailTo); | ||
| 524 | #endif | ||
| 505 | /* copy command */ | 525 | /* copy command */ |
| 506 | line->cl_Shell = xstrdup(ptr); | 526 | line->cl_Shell = xstrdup(ptr); |
| 507 | if (DebugOpt) { | 527 | if (DebugOpt) { |
| @@ -515,7 +535,7 @@ static void SynchronizeFile(const char *fileName) | |||
| 515 | FileBase = file; | 535 | FileBase = file; |
| 516 | 536 | ||
| 517 | if (maxLines == 0 || maxEntries == 0) { | 537 | if (maxLines == 0 || maxEntries == 0) { |
| 518 | crondlog(WARN9 "maximum number of lines reached for user %s", fileName); | 538 | crondlog(WARN9 "user %s: too many lines", fileName); |
| 519 | } | 539 | } |
| 520 | } | 540 | } |
| 521 | fclose(fi); | 541 | fclose(fi); |
| @@ -567,7 +587,7 @@ static void SynchronizeDir(void) | |||
| 567 | 587 | ||
| 568 | if (!dir) | 588 | if (!dir) |
| 569 | crondlog(DIE9 "can't chdir(%s)", "."); /* exits */ | 589 | crondlog(DIE9 "can't chdir(%s)", "."); /* exits */ |
| 570 | while ((den = readdir(dir))) { | 590 | while ((den = readdir(dir)) != NULL) { |
| 571 | if (strchr(den->d_name, '.') != NULL) { | 591 | if (strchr(den->d_name, '.') != NULL) { |
| 572 | continue; | 592 | continue; |
| 573 | } | 593 | } |
| @@ -811,23 +831,25 @@ ForkJob(const char *user, CronLine *line, int mailFd, | |||
| 811 | static void RunJob(const char *user, CronLine *line) | 831 | static void RunJob(const char *user, CronLine *line) |
| 812 | { | 832 | { |
| 813 | char mailFile[128]; | 833 | char mailFile[128]; |
| 814 | int mailFd; | 834 | int mailFd = -1; |
| 815 | 835 | ||
| 816 | line->cl_Pid = 0; | 836 | line->cl_Pid = 0; |
| 817 | line->cl_MailFlag = 0; | 837 | line->cl_MailFlag = 0; |
| 818 | 838 | ||
| 819 | /* open mail file - owner root so nobody can screw with it. */ | 839 | if (line->cl_MailTo) { |
| 820 | snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, getpid()); | 840 | /* open mail file - owner root so nobody can screw with it. */ |
| 821 | mailFd = open(mailFile, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL | O_APPEND, 0600); | 841 | snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, getpid()); |
| 842 | mailFd = open(mailFile, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL | O_APPEND, 0600); | ||
| 822 | 843 | ||
| 823 | if (mailFd >= 0) { | 844 | if (mailFd >= 0) { |
| 824 | line->cl_MailFlag = 1; | 845 | line->cl_MailFlag = 1; |
| 825 | fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user, | 846 | fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user, |
| 826 | line->cl_Shell); | 847 | line->cl_Shell); |
| 827 | line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR); | 848 | line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR); |
| 828 | } else { | 849 | } else { |
| 829 | crondlog(ERR20 "cannot create mail file %s for user %s, " | 850 | crondlog(ERR20 "cannot create mail file %s for user %s, " |
| 830 | "discarding output", mailFile, user); | 851 | "discarding output", mailFile, user); |
| 852 | } | ||
| 831 | } | 853 | } |
| 832 | 854 | ||
| 833 | ForkJob(user, line, mailFd, DEFAULT_SHELL, "-c", line->cl_Shell, mailFile); | 855 | ForkJob(user, line, mailFd, DEFAULT_SHELL, "-c", line->cl_Shell, mailFile); |
| @@ -877,7 +899,8 @@ static void EndJob(const char *user, CronLine *line) | |||
| 877 | close(mailFd); | 899 | close(mailFd); |
| 878 | return; | 900 | return; |
| 879 | } | 901 | } |
| 880 | ForkJob(user, line, mailFd, SENDMAIL, SENDMAIL_ARGS, NULL); | 902 | if (line->cl_MailTo) |
| 903 | ForkJob(user, line, mailFd, SENDMAIL, SENDMAIL_ARGS, NULL); | ||
| 881 | } | 904 | } |
| 882 | 905 | ||
| 883 | #else /* crond without sendmail */ | 906 | #else /* crond without sendmail */ |
diff --git a/networking/sendmail.c b/networking/sendmail.c index 973d712b9..242bb0eaf 100644 --- a/networking/sendmail.c +++ b/networking/sendmail.c | |||
| @@ -273,6 +273,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 273 | 273 | ||
| 274 | OPTS_c = 1 << 6, // sendmail: assumed charset | 274 | OPTS_c = 1 << 6, // sendmail: assumed charset |
| 275 | OPTS_t = 1 << 7, // sendmail: recipient(s) | 275 | OPTS_t = 1 << 7, // sendmail: recipient(s) |
| 276 | OPTS_i = 1 << 8, // sendmail: ignore lone dots in message body (implied) | ||
| 276 | }; | 277 | }; |
| 277 | 278 | ||
| 278 | const char *options; | 279 | const char *options; |
| @@ -288,8 +289,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 288 | // SENDMAIL | 289 | // SENDMAIL |
| 289 | // save initial stdin (body or attachements can be piped!) | 290 | // save initial stdin (body or attachements can be piped!) |
| 290 | xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); | 291 | xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); |
| 291 | opt_complementary = "-2:w+:t:t::"; // count(-t) > 0 | 292 | opt_complementary = "-2:w+:t::"; |
| 292 | options = "w:U:P:X" "ns:c:t:"; | 293 | options = "w:U:P:X" "ns:c:t:i"; |
| 293 | } else { | 294 | } else { |
| 294 | // FETCHMAIL | 295 | // FETCHMAIL |
| 295 | opt_after_connect = NULL; | 296 | opt_after_connect = NULL; |
| @@ -346,6 +347,29 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 346 | // get the sender | 347 | // get the sender |
| 347 | opt_from = sane(*argv++); | 348 | opt_from = sane(*argv++); |
| 348 | 349 | ||
| 350 | // if no recipients _and_ no body files specified -> enter all-included mode | ||
| 351 | // i.e. scan stdin for To: and Subject: lines ... | ||
| 352 | // ... and then use the rest of stdin as message body | ||
| 353 | if (!opt_recipients && !*argv) { | ||
| 354 | // fetch recipients and (optionally) subject | ||
| 355 | char *s; | ||
| 356 | while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) { | ||
| 357 | if (0 == strncmp("To: ", s, 4)) { | ||
| 358 | llist_add_to_end(&opt_recipients, s+4); | ||
| 359 | } else if (0 == strncmp("Subject: ", s, 9)) { | ||
| 360 | opt_subject = s+9; | ||
| 361 | opts |= OPTS_s; | ||
| 362 | } else { | ||
| 363 | char first = s[0]; | ||
| 364 | free(s); | ||
| 365 | if (!first) | ||
| 366 | break; // empty line | ||
| 367 | } | ||
| 368 | } | ||
| 369 | // order to read body from stdin | ||
| 370 | *--argv = (char *)"-"; | ||
| 371 | } | ||
| 372 | |||
| 349 | // introduce to server | 373 | // introduce to server |
| 350 | // we should start with modern EHLO | 374 | // we should start with modern EHLO |
| 351 | if (250 != smtp_checkp("EHLO %s", opt_from, -1)) { | 375 | if (250 != smtp_checkp("EHLO %s", opt_from, -1)) { |
