Print this page
374 cron should send more useful mail
Reviewed by: Richard Lowe <richlowe@richlowe.net>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/cron/cron.c
          +++ new/usr/src/cmd/cron/cron.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + *
       25 + * Copyright 2013 Joshua M. Clulow <josh@sysmgr.org>
  24   26   */
  25   27  
  26   28  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  27   29  /*        All Rights Reserved   */
  28   30  
  29   31  /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  30   32  /*        All Rights Reserved   */
  31   33  
  32   34  #ifdef lint
  33   35  /* make lint happy */
↓ open down ↓ 104 lines elided ↑ open up ↑
 138  140  \nof one of your cron commands.\n"
 139  141  
 140  142  #define STDOUTERR       "one of your commands generated output or errors, \
 141  143  but cron was unable to mail you this output.\
 142  144  \nRemember to redirect standard output and standard \
 143  145  error for each of your commands."
 144  146  
 145  147  #define CLOCK_DRIFT     "clock time drifted backwards after event!\n"
 146  148  #define PIDERR          "unexpected pid returned %d (ignored)"
 147  149  #define CRONTABERR      "Subject: Your crontab file has an error in it\n\n"
 148      -#define CRONOUT         "Subject: Output from \"cron\" command\n\n"
 149  150  #define MALLOCERR       "out of space, cannot create new string\n"
 150  151  
 151  152  #define DIDFORK didfork
 152  153  #define NOFORK !didfork
 153  154  
 154  155  #define MAILBUFLEN      (8*1024)
 155  156  #define LINELIMIT       80
 156  157  #define MAILBINITFREE   (MAILBUFLEN - (sizeof (cte_intro) - 1) \
 157  158              - (sizeof (cte_trail1) - 1) - (sizeof (cte_trail2) - 1) - 1)
 158  159  
↓ open down ↓ 2545 lines elided ↑ open up ↑
2704 2705  static void
2705 2706  mail_result(struct usr *p, struct runinfo *pr, size_t filesize)
2706 2707  {
2707 2708          struct  passwd  *ruser_ids;
2708 2709          FILE    *mailpipe;
2709 2710          FILE    *st;
2710 2711          struct utsname  name;
2711 2712          int     nbytes;
2712 2713          char    iobuf[BUFSIZ];
2713 2714          char    *cmd;
     2715 +        char    *lowname = (pr->jobtype == CRONEVENT ? "cron" : "at");
2714 2716  
2715 2717          (void) uname(&name);
2716 2718          if ((ruser_ids = getpwnam(p->name)) == NULL)
2717 2719                  exit(0);
2718 2720          (void) setuid(ruser_ids->pw_uid);
2719 2721  
2720 2722          cmd = xmalloc(strlen(MAIL) + strlen(p->name)+2);
2721 2723          (void) sprintf(cmd, "%s %s", MAIL, p->name);
2722 2724          mailpipe = popen(cmd, "w");
2723 2725          free(cmd);
2724 2726          if (mailpipe == NULL)
2725 2727                  exit(127);
2726 2728          (void) fprintf(mailpipe, "To: %s\n", p->name);
2727      -        if (pr->jobtype == CRONEVENT) {
2728      -                (void) fprintf(mailpipe, CRONOUT);
2729      -                (void) fprintf(mailpipe, "Your \"cron\" job on %s\n",
2730      -                    name.nodename);
2731      -                if (pr->jobname != NULL) {
2732      -                        (void) fprintf(mailpipe, "%s\n\n", pr->jobname);
2733      -                }
2734      -        } else {
2735      -                (void) fprintf(mailpipe, "Subject: Output from \"at\" job\n\n");
2736      -                (void) fprintf(mailpipe, "Your \"at\" job on %s\n",
2737      -                    name.nodename);
2738      -                if (pr->jobname != NULL) {
2739      -                        (void) fprintf(mailpipe, "\"%s\"\n\n", pr->jobname);
2740      -                }
2741      -        }
2742      -        /* Tmp. file is fopen'ed w/ "r",  secure open */
     2729 +        (void) fprintf(mailpipe, "Subject: %s <%s@%s> %s\n",
     2730 +            (pr->jobtype == CRONEVENT ? "Cron" : "At"),
     2731 +            p->name, name.nodename, pr->jobname);
     2732 +
     2733 +        /*
     2734 +         * RFC3834 (Section 5) defines the Auto-Submitted header to prevent
     2735 +         * vacation replies, et al, from being sent in response to
     2736 +         * machine-generated mail.
     2737 +         */
     2738 +        (void) fprintf(mailpipe, "Auto-Submitted: auto-generated\n");
     2739 +
     2740 +        /*
     2741 +         * Additional headers for mail filtering and diagnostics:
     2742 +         */
     2743 +        (void) fprintf(mailpipe, "X-Mailer: cron (%s %s)\n", name.sysname,
     2744 +            name.release);
     2745 +        (void) fprintf(mailpipe, "X-Cron-User: %s\n", p->name);
     2746 +        (void) fprintf(mailpipe, "X-Cron-Host: %s\n", name.nodename);
     2747 +        (void) fprintf(mailpipe, "X-Cron-Job-Name: %s\n", pr->jobname);
     2748 +        (void) fprintf(mailpipe, "X-Cron-Job-Type: %s\n", lowname);
     2749 +
     2750 +        /*
     2751 +         * Message Body:
     2752 +         *
     2753 +         * (Temporary file is fopen'ed with "r", secure open.)
     2754 +         */
     2755 +        (void) fprintf(mailpipe, "\n");
2743 2756          if (filesize > 0 &&
2744 2757              (st = fopen(pr->outfile, "r")) != NULL) {
2745      -                (void) fprintf(mailpipe,
2746      -                    "produced the following output:\n\n");
2747 2758                  while ((nbytes = fread(iobuf, sizeof (char), BUFSIZ, st)) != 0)
2748 2759                          (void) fwrite(iobuf, sizeof (char), nbytes, mailpipe);
2749 2760                  (void) fclose(st);
2750 2761          } else {
2751      -                (void) fprintf(mailpipe, "completed.\n");
     2762 +                (void) fprintf(mailpipe, "Job completed with no output.\n");
2752 2763          }
2753 2764          (void) pclose(mailpipe);
2754 2765          exit(0);
2755 2766  }
2756 2767  
2757 2768  static int
2758 2769  msg_wait(long tim)
2759 2770  {
2760 2771          struct  message msg;
2761 2772          int     cnt;
↓ open down ↓ 889 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX