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
This commit is contained in:
parent
90c31b3d4b
commit
6fa1ba3972
@ -33,7 +33,11 @@
|
|||||||
#define SENDMAIL "sendmail"
|
#define SENDMAIL "sendmail"
|
||||||
#endif
|
#endif
|
||||||
#ifndef SENDMAIL_ARGS
|
#ifndef SENDMAIL_ARGS
|
||||||
#define SENDMAIL_ARGS "-ti", "oem"
|
# if ENABLE_SENDMAIL
|
||||||
|
# define SENDMAIL_ARGS "localhost", line->cl_MailTo
|
||||||
|
# else
|
||||||
|
# define SENDMAIL_ARGS "-ti", "oem"
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef CRONUPDATE
|
#ifndef CRONUPDATE
|
||||||
#define CRONUPDATE "cron.update"
|
#define CRONUPDATE "cron.update"
|
||||||
@ -59,6 +63,7 @@ typedef struct CronLine {
|
|||||||
#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
|
#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
|
||||||
int cl_MailPos; /* 'empty file' size */
|
int cl_MailPos; /* 'empty file' size */
|
||||||
smallint cl_MailFlag; /* running pid is for mail */
|
smallint cl_MailFlag; /* running pid is for mail */
|
||||||
|
char *cl_MailTo; /* whom to mail results */
|
||||||
#endif
|
#endif
|
||||||
/* ordered by size, not in natural order. makes code smaller: */
|
/* ordered by size, not in natural order. makes code smaller: */
|
||||||
char cl_Dow[7]; /* 0-6, beginning sunday */
|
char cl_Dow[7]; /* 0-6, beginning sunday */
|
||||||
@ -449,6 +454,9 @@ static void SynchronizeFile(const char *fileName)
|
|||||||
int maxEntries;
|
int maxEntries;
|
||||||
int maxLines;
|
int maxLines;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
|
||||||
|
char *mailTo = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!fileName)
|
if (!fileName)
|
||||||
return;
|
return;
|
||||||
@ -485,6 +493,14 @@ static void SynchronizeFile(const char *fileName)
|
|||||||
if (DebugOpt) {
|
if (DebugOpt) {
|
||||||
crondlog(LVL5 "user:%s entry:%s", fileName, buf);
|
crondlog(LVL5 "user:%s entry:%s", fileName, buf);
|
||||||
}
|
}
|
||||||
|
/* check if line is setting MAILTO= */
|
||||||
|
if (0 == strncmp("MAILTO=", buf, 7)) {
|
||||||
|
#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
|
||||||
|
free(mailTo);
|
||||||
|
mailTo = (buf[7]) ? xstrdup(buf+7) : NULL;
|
||||||
|
#endif /* otherwise just ignore such lines */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
*pline = line = xzalloc(sizeof(CronLine));
|
*pline = line = xzalloc(sizeof(CronLine));
|
||||||
/* parse date ranges */
|
/* parse date ranges */
|
||||||
ptr = ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, buf);
|
ptr = ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, buf);
|
||||||
@ -498,10 +514,14 @@ static void SynchronizeFile(const char *fileName)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* fix days and dow - if one is not * and the other
|
* fix days and dow - if one is not "*" and the other
|
||||||
* is *, the other is set to 0, and vise-versa
|
* is "*", the other is set to 0, and vise-versa
|
||||||
*/
|
*/
|
||||||
FixDayDow(line);
|
FixDayDow(line);
|
||||||
|
#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
|
||||||
|
/* copy mailto (can be NULL) */
|
||||||
|
line->cl_MailTo = xstrdup(mailTo);
|
||||||
|
#endif
|
||||||
/* copy command */
|
/* copy command */
|
||||||
line->cl_Shell = xstrdup(ptr);
|
line->cl_Shell = xstrdup(ptr);
|
||||||
if (DebugOpt) {
|
if (DebugOpt) {
|
||||||
@ -515,7 +535,7 @@ static void SynchronizeFile(const char *fileName)
|
|||||||
FileBase = file;
|
FileBase = file;
|
||||||
|
|
||||||
if (maxLines == 0 || maxEntries == 0) {
|
if (maxLines == 0 || maxEntries == 0) {
|
||||||
crondlog(WARN9 "maximum number of lines reached for user %s", fileName);
|
crondlog(WARN9 "user %s: too many lines", fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fi);
|
fclose(fi);
|
||||||
@ -567,7 +587,7 @@ static void SynchronizeDir(void)
|
|||||||
|
|
||||||
if (!dir)
|
if (!dir)
|
||||||
crondlog(DIE9 "can't chdir(%s)", "."); /* exits */
|
crondlog(DIE9 "can't chdir(%s)", "."); /* exits */
|
||||||
while ((den = readdir(dir))) {
|
while ((den = readdir(dir)) != NULL) {
|
||||||
if (strchr(den->d_name, '.') != NULL) {
|
if (strchr(den->d_name, '.') != NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -811,23 +831,25 @@ ForkJob(const char *user, CronLine *line, int mailFd,
|
|||||||
static void RunJob(const char *user, CronLine *line)
|
static void RunJob(const char *user, CronLine *line)
|
||||||
{
|
{
|
||||||
char mailFile[128];
|
char mailFile[128];
|
||||||
int mailFd;
|
int mailFd = -1;
|
||||||
|
|
||||||
line->cl_Pid = 0;
|
line->cl_Pid = 0;
|
||||||
line->cl_MailFlag = 0;
|
line->cl_MailFlag = 0;
|
||||||
|
|
||||||
/* open mail file - owner root so nobody can screw with it. */
|
if (line->cl_MailTo) {
|
||||||
snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, getpid());
|
/* open mail file - owner root so nobody can screw with it. */
|
||||||
mailFd = open(mailFile, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL | O_APPEND, 0600);
|
snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, getpid());
|
||||||
|
mailFd = open(mailFile, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL | O_APPEND, 0600);
|
||||||
|
|
||||||
if (mailFd >= 0) {
|
if (mailFd >= 0) {
|
||||||
line->cl_MailFlag = 1;
|
line->cl_MailFlag = 1;
|
||||||
fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user,
|
fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user,
|
||||||
line->cl_Shell);
|
line->cl_Shell);
|
||||||
line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR);
|
line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR);
|
||||||
} else {
|
} else {
|
||||||
crondlog(ERR20 "cannot create mail file %s for user %s, "
|
crondlog(ERR20 "cannot create mail file %s for user %s, "
|
||||||
"discarding output", mailFile, user);
|
"discarding output", mailFile, user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ForkJob(user, line, mailFd, DEFAULT_SHELL, "-c", line->cl_Shell, mailFile);
|
ForkJob(user, line, mailFd, DEFAULT_SHELL, "-c", line->cl_Shell, mailFile);
|
||||||
@ -877,7 +899,8 @@ static void EndJob(const char *user, CronLine *line)
|
|||||||
close(mailFd);
|
close(mailFd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ForkJob(user, line, mailFd, SENDMAIL, SENDMAIL_ARGS, NULL);
|
if (line->cl_MailTo)
|
||||||
|
ForkJob(user, line, mailFd, SENDMAIL, SENDMAIL_ARGS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* crond without sendmail */
|
#else /* crond without sendmail */
|
||||||
|
@ -273,6 +273,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
|
|
||||||
OPTS_c = 1 << 6, // sendmail: assumed charset
|
OPTS_c = 1 << 6, // sendmail: assumed charset
|
||||||
OPTS_t = 1 << 7, // sendmail: recipient(s)
|
OPTS_t = 1 << 7, // sendmail: recipient(s)
|
||||||
|
OPTS_i = 1 << 8, // sendmail: ignore lone dots in message body (implied)
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *options;
|
const char *options;
|
||||||
@ -288,8 +289,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
// SENDMAIL
|
// SENDMAIL
|
||||||
// save initial stdin (body or attachements can be piped!)
|
// save initial stdin (body or attachements can be piped!)
|
||||||
xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO);
|
xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO);
|
||||||
opt_complementary = "-2:w+:t:t::"; // count(-t) > 0
|
opt_complementary = "-2:w+:t::";
|
||||||
options = "w:U:P:X" "ns:c:t:";
|
options = "w:U:P:X" "ns:c:t:i";
|
||||||
} else {
|
} else {
|
||||||
// FETCHMAIL
|
// FETCHMAIL
|
||||||
opt_after_connect = NULL;
|
opt_after_connect = NULL;
|
||||||
@ -346,6 +347,29 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
// get the sender
|
// get the sender
|
||||||
opt_from = sane(*argv++);
|
opt_from = sane(*argv++);
|
||||||
|
|
||||||
|
// if no recipients _and_ no body files specified -> enter all-included mode
|
||||||
|
// i.e. scan stdin for To: and Subject: lines ...
|
||||||
|
// ... and then use the rest of stdin as message body
|
||||||
|
if (!opt_recipients && !*argv) {
|
||||||
|
// fetch recipients and (optionally) subject
|
||||||
|
char *s;
|
||||||
|
while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) {
|
||||||
|
if (0 == strncmp("To: ", s, 4)) {
|
||||||
|
llist_add_to_end(&opt_recipients, s+4);
|
||||||
|
} else if (0 == strncmp("Subject: ", s, 9)) {
|
||||||
|
opt_subject = s+9;
|
||||||
|
opts |= OPTS_s;
|
||||||
|
} else {
|
||||||
|
char first = s[0];
|
||||||
|
free(s);
|
||||||
|
if (!first)
|
||||||
|
break; // empty line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// order to read body from stdin
|
||||||
|
*--argv = (char *)"-";
|
||||||
|
}
|
||||||
|
|
||||||
// introduce to server
|
// introduce to server
|
||||||
// we should start with modern EHLO
|
// we should start with modern EHLO
|
||||||
if (250 != smtp_checkp("EHLO %s", opt_from, -1)) {
|
if (250 != smtp_checkp("EHLO %s", opt_from, -1)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user