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

@@ -19,10 +19,12 @@
  * CDDL HEADER END
  */
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2013 Joshua M. Clulow <josh@sysmgr.org>
  */
 
 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
 /*        All Rights Reserved   */
 

@@ -143,11 +145,10 @@
 error for each of your commands."
 
 #define CLOCK_DRIFT     "clock time drifted backwards after event!\n"
 #define PIDERR          "unexpected pid returned %d (ignored)"
 #define CRONTABERR      "Subject: Your crontab file has an error in it\n\n"
-#define CRONOUT         "Subject: Output from \"cron\" command\n\n"
 #define MALLOCERR       "out of space, cannot create new string\n"
 
 #define DIDFORK didfork
 #define NOFORK !didfork
 

@@ -2709,10 +2710,11 @@
         FILE    *st;
         struct utsname  name;
         int     nbytes;
         char    iobuf[BUFSIZ];
         char    *cmd;
+        char    *lowname = (pr->jobtype == CRONEVENT ? "cron" : "at");
 
         (void) uname(&name);
         if ((ruser_ids = getpwnam(p->name)) == NULL)
                 exit(0);
         (void) setuid(ruser_ids->pw_uid);

@@ -2722,35 +2724,44 @@
         mailpipe = popen(cmd, "w");
         free(cmd);
         if (mailpipe == NULL)
                 exit(127);
         (void) fprintf(mailpipe, "To: %s\n", p->name);
-        if (pr->jobtype == CRONEVENT) {
-                (void) fprintf(mailpipe, CRONOUT);
-                (void) fprintf(mailpipe, "Your \"cron\" job on %s\n",
-                    name.nodename);
-                if (pr->jobname != NULL) {
-                        (void) fprintf(mailpipe, "%s\n\n", pr->jobname);
-                }
-        } else {
-                (void) fprintf(mailpipe, "Subject: Output from \"at\" job\n\n");
-                (void) fprintf(mailpipe, "Your \"at\" job on %s\n",
-                    name.nodename);
-                if (pr->jobname != NULL) {
-                        (void) fprintf(mailpipe, "\"%s\"\n\n", pr->jobname);
-                }
-        }
-        /* Tmp. file is fopen'ed w/ "r",  secure open */
+        (void) fprintf(mailpipe, "Subject: %s <%s@%s> %s\n",
+            (pr->jobtype == CRONEVENT ? "Cron" : "At"),
+            p->name, name.nodename, pr->jobname);
+
+        /*
+         * RFC3834 (Section 5) defines the Auto-Submitted header to prevent
+         * vacation replies, et al, from being sent in response to
+         * machine-generated mail.
+         */
+        (void) fprintf(mailpipe, "Auto-Submitted: auto-generated\n");
+
+        /*
+         * Additional headers for mail filtering and diagnostics:
+         */
+        (void) fprintf(mailpipe, "X-Mailer: cron (%s %s)\n", name.sysname,
+            name.release);
+        (void) fprintf(mailpipe, "X-Cron-User: %s\n", p->name);
+        (void) fprintf(mailpipe, "X-Cron-Host: %s\n", name.nodename);
+        (void) fprintf(mailpipe, "X-Cron-Job-Name: %s\n", pr->jobname);
+        (void) fprintf(mailpipe, "X-Cron-Job-Type: %s\n", lowname);
+
+        /*
+         * Message Body:
+         *
+         * (Temporary file is fopen'ed with "r", secure open.)
+         */
+        (void) fprintf(mailpipe, "\n");
         if (filesize > 0 &&
             (st = fopen(pr->outfile, "r")) != NULL) {
-                (void) fprintf(mailpipe,
-                    "produced the following output:\n\n");
                 while ((nbytes = fread(iobuf, sizeof (char), BUFSIZ, st)) != 0)
                         (void) fwrite(iobuf, sizeof (char), nbytes, mailpipe);
                 (void) fclose(st);
         } else {
-                (void) fprintf(mailpipe, "completed.\n");
+                (void) fprintf(mailpipe, "Job completed with no output.\n");
         }
         (void) pclose(mailpipe);
         exit(0);
 }