aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/crond.c59
-rw-r--r--networking/sendmail.c28
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,
811static void RunJob(const char *user, CronLine *line) 831static 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)) {