vixie-cron small patch
Hello everybody!
I've added new environment support to vixie-cron which is used by default cron in Debian. This environment is adding oppotunity to set mail subject for cron's report. It looks like this:
MAILSUBJECT="CRON at the %hostname% (fqdn: %fqdn%): User %user% ran command %cmd% which was executed with status %status%. Cron fork status: %forkstatus%"
* * * * * root echo test
It can be useful for many users. I've attached the patch for vixie cron. Could the patch be included to Debian release?
Thanks!
---
Site Reliability Engineer
Stan E. Putrya
/"\
\ / ASCII Ribbon Campaign
X against HTML email & vCards
/ \
--- a/compat.c
+++ b/compat.c
@@ -236,3 +236,18 @@ setenv(name, value, overwrite)
return putenv(tmp); /* intentionally orphan 'tmp' storage */
}
#endif
+
+void
+replace_str(char *str, int len, char *origin, char *replace) {
+ char *p;
+ char buf[len];
+ memset(buf, 0, len);
+ if (strnlen(str, len+1) > len)
+ return;
+ if (!(p=strstr(str, origin)))
+ return;
+ strncpy(buf, str, p-str);
+ sprintf(buf+(p-str), "%s%s", replace, p+strlen(origin));
+ strncpy(str, buf, strlen(buf));
+ memset(str+strlen(buf), 0, len-strlen(buf));
+}
--- a/compat.h
+++ b/compat.h
@@ -135,3 +135,5 @@
#if !defined(UNICOS) && !defined(UNIXPC)
# define HAS_FCHMOD
#endif
+
+#define MAXREPLACEBUF 4028 /* max length for string origin replace */
--- a/cron.h
+++ b/cron.h
@@ -98,6 +98,14 @@
#define DTEST 0x0040 /* test mode: don't execute any commands */
#define DBIT 0x0080 /* bit twiddling shown (long) */
+// Templates
+#define CRONUSER "%user%" /* tag for cron's user */
+#define HOSTNAME "%hostname%" /* tag for cron's hostname*/
+#define FQDN "%fqdn%" /* tag for cron's fqdn*/
+#define CMD "%cmd%" /* extend flag for other debug masks */
+#define STATUS "%status%" /* extend flag for other debug masks */
+#define FORKSTATUS "%forkstatus%" /* extend flag for other debug masks */
+
#define CRON_TAB(u) "%s/%s", SPOOL_DIR, u
#define REG register
#define PPC_NULL ((char **)NULL)
--- a/do_command.c
+++ b/do_command.c
@@ -129,7 +129,7 @@ child_process(e, u)
int stdin_pipe[2];
FILE *tmpout;
register char *input_data;
- char *usernm, *mailto;
+ char *usernm, *mailto, *mailsubject, *p;
int children = 0;
pid_t job_pid;
@@ -153,6 +153,7 @@ child_process(e, u)
*/
usernm = env_get("LOGNAME", e->envp);
mailto = env_get("MAILTO", e->envp);
+ mailsubject = env_get("MAILSUBJECT", e->envp);
/* Check for arguments */
if (mailto) {
@@ -474,6 +475,7 @@ child_process(e, u)
/* wait for children to die.
*/
int status = 0;
+ int execstatus = 0;
for (; children > 0; children--)
{
char msg[256];
@@ -489,6 +491,7 @@ child_process(e, u)
}
Debug(DPROC, ("[%d] grandchild #%d finished, status=%04x\n",
getpid(), pid, WEXITSTATUS(waiter)))
+ execstatus = WEXITSTATUS(waiter);
if (log_level & CRON_LOG_JOBFAILED) {
if (WIFEXITED(waiter) && WEXITSTATUS(waiter)) {
@@ -560,9 +563,37 @@ child_process(e, u)
}
fprintf(mail, "From: root (Cron Daemon)\n");
fprintf(mail, "To: %s\n", mailto);
- fprintf(mail, "Subject: Cron <%s@%s> %s%s\n",
+
+ // Generate subject
+ if (mailsubject == NULL) {
+ fprintf(mail, "Subject: Cron <%s@%s> %s%s\n",
usernm, first_word(hostname, "."),
e->cmd, status?" (failed)":"");
+ } else {
+ char buffer[MAXREPLACEBUF];
+ memset(buffer, 0, MAXREPLACEBUF);
+ if (strnlen(mailsubject, MAXREPLACEBUF+1) > MAXREPLACEBUF) {
+ fprintf(mail, "Subject: Cron <%s@%s> %s%s\n",
+ usernm, first_word(hostname, "."),
+ e->cmd, status?" (failed)":"");
+ } else {
+ strncpy(buffer, mailsubject, strlen(mailsubject));
+ if (strstr(buffer, CRONUSER))
+ replace_str(buffer, MAXREPLACEBUF, CRONUSER, usernm);
+ if (strstr(buffer, HOSTNAME))
+ replace_str(buffer, MAXREPLACEBUF, HOSTNAME, first_word(hostname, "."));
+ if (strstr(buffer, CMD))
+ replace_str(buffer, MAXREPLACEBUF, CMD, e->cmd);
+ if (strstr(buffer, STATUS))
+ replace_str(buffer, MAXREPLACEBUF, STATUS, execstatus?"failed":"success");
+ if (strstr(buffer, FORKSTATUS))
+ replace_str(buffer, MAXREPLACEBUF, FORKSTATUS, status?"failed":"success");
+ if (strstr(buffer, FQDN))
+ replace_str(buffer, MAXREPLACEBUF, FQDN, hostname);
+ fprintf(mail, "Subject: %s\n", buffer);
+ }
+ }
+ //
# if defined(MAIL_DATE)
fprintf(mail, "Date: %s\n",
arpadate(&StartTime));
Reply to: