diff --git a/.gitignore b/.gitignore index 28488ef..4079eb0 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /cronie-1.5.7.tar.gz /cronie-1.6.0.tar.gz /cronie-1.6.1.tar.gz +/cronie-1.7.0.tar.gz diff --git a/add_-n_option_for_crontab_entries.patch b/add_-n_option_for_crontab_entries.patch deleted file mode 100644 index 441c214..0000000 --- a/add_-n_option_for_crontab_entries.patch +++ /dev/null @@ -1,205 +0,0 @@ -From ce7d5bf0a43d147f8502e6424cd523b56adf5599 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20Poho=C5=99elsk=C3=BD?= -Date: Mon, 26 Sep 2022 16:51:41 +0200 -Subject: [PATCH] Add -n option for crontab entries - -The -n option causes no mail to be sent -when the command finishes successfully. - -These kind of options are already supported in *BSD; -in fact, this is a port of a patch from NetBSD [1]. - -This was requested in [2]. - -[1]: NetBSD/src@666eac5 -[2]: https://bugzilla.redhat.com/show_bug.cgi?id=1591763 ---- - src/do_command.c | 32 +++++++++++++++++++++++++++++--- - src/entry.c | 31 +++++++++++++++++++++++++++++++ - src/funcs.h | 1 + - src/popen.c | 33 ++++++++++++++++++++++++++++++--- - src/structs.h | 1 + - 5 files changed, 92 insertions(+), 6 deletions(-) - -diff --git a/src/do_command.c b/src/do_command.c -index 87f996f..6a3886a 100644 ---- a/src/do_command.c -+++ b/src/do_command.c -@@ -94,6 +94,7 @@ static int child_process(entry * e, char **jobenv) { - char mailfrom_expanded[MAX_EMAILSTR]; - int children = 0; - pid_t pid = getpid(); -+ pid_t jobpid = -1; - struct sigaction sa; - - /* Ignore SIGPIPE as we will be writing to pipes and do not want to terminate -@@ -199,7 +200,7 @@ static int child_process(entry * e, char **jobenv) { - - /* fork again, this time so we can exec the user's command. - */ -- switch (fork()) { -+ switch (jobpid = fork()) { - case -1: - log_it("CRON", pid, "CAN'T FORK", "child_process", errno); - return ERROR_EXIT; -@@ -552,10 +553,35 @@ static int child_process(entry * e, char **jobenv) { - } - #endif - } -- /* only close pipe if we opened it -- i.e., we're -- * mailing... -+ /* if -n option was specified, abort the sending -+ * now when we read all of the command output -+ * and thus can wait for it's exit status - */ -+ if (mail && e->flags & MAIL_WHEN_ERR) { -+ int jobstatus = -1; -+ if (jobpid > 0) { -+ while (waitpid(jobpid, &jobstatus, WNOHANG) == -1) { -+ if (errno == EINTR) continue; -+ log_it("CRON", getpid(), "error", "invalid job pid", errno); -+ break; -+ } -+ } else { -+ log_it("CRON", getpid(), "error", "invalid job pid", 0); -+ } - -+ /* if everything went well, -n is set, and we have mail, -+ * we won't be mailing – so shoot the messenger! -+ */ -+ if (WIFEXITED(jobstatus) && WEXITSTATUS(jobstatus) == EXIT_SUCCESS) { -+ Debug(DPROC, ("[%ld] aborting pipe to mail\n", (long)getpid())); -+ status = cron_pabort(mail); -+ mail = NULL; -+ } -+ } -+ -+ /* only close pipe if we opened it -- i.e., we're (still) -+ * mailing... -+ */ - if (mail) { - Debug(DPROC, ("[%ld] closing pipe to mail\n", (long) getpid())); - /* Note: the pclose will probably see -diff --git a/src/entry.c b/src/entry.c -index bb7cb62..9e199fe 100644 ---- a/src/entry.c -+++ b/src/entry.c -@@ -417,6 +417,37 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw, - - Debug(DPARS, ("load_entry()...about to parse command\n")); - -+ /* If the first character of the command is '-', it is a cron option. */ -+ ch = get_char(file); -+ while (ch == '-') { -+ switch (ch = get_char(file)) { -+ case 'n': -+ /* only allow user to set the option once */ -+ if ((e->flags & MAIL_WHEN_ERR) == MAIL_WHEN_ERR) { -+ ecode = e_option; -+ goto eof; -+ } -+ e->flags |= MAIL_WHEN_ERR; -+ break; -+ -+ default: -+ ecode = e_option; -+ goto eof; -+ } -+ -+ ch = get_char(file); -+ if (ch != '\t' && ch != ' ') { -+ ecode = e_option; -+ goto eof; -+ } -+ Skip_Blanks(ch, file); -+ if (ch == EOF || ch == '\n') { -+ ecode = e_cmd; -+ goto eof; -+ } -+ } -+ unget_char(ch, file); -+ - /* Everything up to the next \n or EOF is part of the command... - * too bad we don't know in advance how long it will be, since we - * need to malloc a string for it... so, we limit it to MAX_COMMAND. -diff --git a/src/funcs.h b/src/funcs.h -index dea737e..427e027 100644 ---- a/src/funcs.h -+++ b/src/funcs.h -@@ -67,6 +67,7 @@ int load_database(cron_db *), - swap_uids_back(void), - load_env(char *, FILE *), - env_set_from_environ(char ***envpp), -+ cron_pabort(FILE *), - cron_pclose(FILE *), - glue_strings(char *, size_t, const char *, const char *, char), - strcmp_until(const char *, const char *, char), -diff --git a/src/popen.c b/src/popen.c -index 4397264..3043eb6 100644 ---- a/src/popen.c -+++ b/src/popen.c -@@ -167,7 +167,7 @@ FILE *cron_popen(char *program, const char *type, struct passwd *pw, char **jobe - return (iop); - } - --int cron_pclose(FILE * iop) { -+static int cron_finalize(FILE * iop, int sig) { - int fdes; - sigset_t oset, nset; - WAIT_T stat_loc; -@@ -180,7 +180,12 @@ int cron_pclose(FILE * iop) { - fdes = fileno(iop); - if (pids == NULL || fdes >= fds || pids[fdes] == 0L) - return (-1); -- (void) fclose(iop); -+ -+ if (!sig) { -+ (void) fclose(iop); -+ } else if (kill(pids[fdes], sig) == -1) { -+ return -1; -+ } - - sigemptyset(&nset); - sigaddset(&nset, SIGINT); -@@ -189,6 +194,28 @@ int cron_pclose(FILE * iop) { - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1) ; - (void) sigprocmask(SIG_SETMASK, &oset, NULL); -+ -+ if (sig) { -+ (void) fclose(iop); -+ } - pids[fdes] = 0; -- return (pid == -1 ? -1 : WEXITSTATUS(stat_loc)); -+ -+ if (pid < 0) { -+ return pid; -+ } -+ -+ if (WIFEXITED(stat_loc)) { -+ return WEXITSTATUS(stat_loc); -+ } else { -+ return WTERMSIG(stat_loc); -+ } -+} -+ -+int cron_pclose(FILE * iop) { -+ return cron_finalize(iop, 0); -+} -+ -+int cron_pabort(FILE * iop) { -+ int esig = cron_finalize(iop, SIGKILL); -+ return esig == SIGKILL ? 0 : esig; - } -diff --git a/src/structs.h b/src/structs.h -index 6d3c15b..d930da5 100644 ---- a/src/structs.h -+++ b/src/structs.h -@@ -48,6 +48,7 @@ typedef struct _entry { - #define DOW_STAR 0x08 - #define WHEN_REBOOT 0x10 - #define DONT_LOG 0x20 -+#define MAIL_WHEN_ERR 0x40 - } entry; - - /* the crontab database will be a list of the diff --git a/cronie.spec b/cronie.spec index 49a6672..e422e1b 100644 --- a/cronie.spec +++ b/cronie.spec @@ -5,15 +5,12 @@ Summary: Cron daemon for executing programs at set times Name: cronie -Version: 1.6.1 +Version: 1.7.0 Release: %autorelease License: GPL-2.0-or-later AND BSD-3-Clause AND BSD-2-Clause AND ISC AND LGPL-2.1-or-later URL: https://github.com/cronie-crond/cronie Source0: https://github.com/cronie-crond/cronie/releases/download/cronie-%{version}/cronie-%{version}.tar.gz -# https://github.com/cronie-crond/cronie/commit/ce7d5bf0a43d147f8502e6424cd523b56adf5599 -Patch: add_-n_option_for_crontab_entries.patch - Requires: dailyjobs %if %{with selinux} diff --git a/sources b/sources index a34176c..22b8e68 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (cronie-1.6.1.tar.gz) = 610fb21077fde08f2cf302e26c9b71aa711b8f4ac1e8a4e9f9f70d616d916965673e836f48b79c4b75de4a93ab893f62887263dce214d6e064fc41fcf0f4093d +SHA512 (cronie-1.7.0.tar.gz) = a8e6688a164540e2cd3741c58813b6684c4c22a04806bcc8ba028a9ff72f986f165715ac3663bd34133af6566bdbd272a3e7be893f139e315aef35b2dbeb622f