diff options
Diffstat (limited to 'source/a/dcron/patches')
8 files changed, 729 insertions, 0 deletions
diff --git a/source/a/dcron/patches/0002-README-var-spool-cron-crontabs-root.patch b/source/a/dcron/patches/0002-README-var-spool-cron-crontabs-root.patch new file mode 100644 index 00000000..57b8966d --- /dev/null +++ b/source/a/dcron/patches/0002-README-var-spool-cron-crontabs-root.patch @@ -0,0 +1,26 @@ +From 500f3d402a94c6950946515d76ebd72872a6d0e2 Mon Sep 17 00:00:00 2001 +From: Jim Pryor <profjim@jimpryor.net> +Date: Sun, 1 May 2011 18:56:17 -0400 +Subject: [PATCH 2/9] README: /var/spool/cron/crontabs/root + +Signed-off-by: Jim Pryor <profjim@jimpryor.net> +--- + README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/README b/README +index de02958..e33b1aa 100644 +--- a/README ++++ b/README +@@ -115,7 +115,7 @@ are normally in /var/spool/cron/cronstamps. These directories normally have perm + + Here is the superuser's crontab, created using `sudo crontab -e`: + +- -rw------- 0 root root 513 Jan 6 18:58 /var/spool/cron/root ++ -rw------- 0 root root 513 Jan 6 18:58 /var/spool/cron/crontabs/root + + TESTING + ------- +-- +2.13.2 + diff --git a/source/a/dcron/patches/0003-CHANGELOG-tweak.patch b/source/a/dcron/patches/0003-CHANGELOG-tweak.patch new file mode 100644 index 00000000..56f3c750 --- /dev/null +++ b/source/a/dcron/patches/0003-CHANGELOG-tweak.patch @@ -0,0 +1,34 @@ +From 2e3717c48ead5a962e2c29bc818672fff36f73f6 Mon Sep 17 00:00:00 2001 +From: Jim Pryor <profjim@jimpryor.net> +Date: Sun, 1 May 2011 19:21:21 -0400 +Subject: [PATCH 3/9] CHANGELOG tweak + +Signed-off-by: Jim Pryor <profjim@jimpryor.net> +--- + CHANGELOG | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index a1ea4a7..0710c3b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -19,12 +19,12 @@ git + + * Documentation and error message updates. + +-v4.5 30-Apr-2011 ++v4.5 1-May-2011 + * Some cron jobs were running multiple times. Now we make sure not to + ArmJobs that are already running; and not to resynchronize while jobs are +- running; and to poll the DST setting. (Fixes Arch FS#18681; thanks to Paul +- Gideon Dann for identifying the second issue; and Tilman Sauerbeck for +- identifying the third.) ++ running; and to poll the DST setting. (Fixes Arch FS#18681; thanks to Vincent ++ Cappe and Paul Gideon Dann for identifying the second issue; and Tilman ++ Sauerbeck for identifying the third.) + + * @monthly was wrongly being parsed the same as @yearly (fixes Arch + FS#19123). Thanks to Peter Johnson, Paul Gideon Dann, and Tilman Sauerbeck. +-- +2.13.2 + diff --git a/source/a/dcron/patches/0006-Fixed-a-bug-whereby-syncs-killed-all-waiting-jobs.patch b/source/a/dcron/patches/0006-Fixed-a-bug-whereby-syncs-killed-all-waiting-jobs.patch new file mode 100644 index 00000000..090e2e5f --- /dev/null +++ b/source/a/dcron/patches/0006-Fixed-a-bug-whereby-syncs-killed-all-waiting-jobs.patch @@ -0,0 +1,35 @@ +From 65d2649a7c8b72561eefcec239f97e7fd386114e Mon Sep 17 00:00:00 2001 +From: Corey Theiss <corey.theiss@maclaren.com> +Date: Mon, 24 Mar 2014 16:25:31 -0400 +Subject: [PATCH 6/9] Fixed a bug whereby syncs killed all waiting jobs. + +--- + database.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/database.c b/database.c +index dd971ce..02c5c92 100644 +--- a/database.c ++++ b/database.c +@@ -1232,8 +1232,17 @@ CheckJobs(void) + } + } + } ++ nStillRunning += file->cf_Running; ++ } ++ /* For the purposes of this check, increase the "still running" counter if a file has lines that are waiting */ ++ if (file->cf_Running == 0) { ++ for (line = file->cf_LineBase; line; line = line->cl_Next) { ++ if (line->cl_Pid == -2) { ++ nStillRunning += 1; ++ break; ++ } ++ } + } +- nStillRunning += file->cf_Running; + } + return(nStillRunning); + } +-- +2.13.2 + diff --git a/source/a/dcron/patches/0007-Update-main.c.patch b/source/a/dcron/patches/0007-Update-main.c.patch new file mode 100644 index 00000000..d120f37c --- /dev/null +++ b/source/a/dcron/patches/0007-Update-main.c.patch @@ -0,0 +1,27 @@ +From abf8c4bf53a84ef3de530519a3bbb6b599595f2c Mon Sep 17 00:00:00 2001 +From: robdewit <rdewit@wise-guys.nl> +Date: Tue, 31 Mar 2015 14:24:15 +0200 +Subject: [PATCH 7/9] Update main.c + +Removed bug where cron.update is not picked up while jobs are still running. (We have long running cronjobs and experienced long overdue cron.update files) +--- + main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/main.c b/main.c +index 595f07a..0eba280 100644 +--- a/main.c ++++ b/main.c +@@ -338,7 +338,8 @@ main(int ac, char **av) + SynchronizeDir(SCDir, "root", 0); + ReadTimestamps(NULL); + } +- } else { ++ } ++ if (rescan < 60) { + CheckUpdates(CDir, NULL, t1, t2); + CheckUpdates(SCDir, "root", t1, t2); + } +-- +2.13.2 + diff --git a/source/a/dcron/patches/0008-Fix-3-every-Nth-day-of-week-syntax-not-working.patch b/source/a/dcron/patches/0008-Fix-3-every-Nth-day-of-week-syntax-not-working.patch new file mode 100644 index 00000000..e50158f0 --- /dev/null +++ b/source/a/dcron/patches/0008-Fix-3-every-Nth-day-of-week-syntax-not-working.patch @@ -0,0 +1,538 @@ +From f048a83da348c1d62204fcbdf407b7abf33e3db0 Mon Sep 17 00:00:00 2001 +From: Erik on RPi <ewfalor@gmail.com> +Date: Tue, 17 Nov 2015 11:28:42 -0700 +Subject: [PATCH 8/9] Fix #3 '"every Nth [day of week]" syntax not working' + +--- + database.c | 237 ++++++++++++++++++++++++++++++++++++++++++------------------- + defs.h | 24 ++++--- + 2 files changed, 180 insertions(+), 81 deletions(-) + +diff --git a/database.c b/database.c +index 02c5c92..c0cdc11 100644 +--- a/database.c ++++ b/database.c +@@ -9,6 +9,14 @@ + + #include "defs.h" + ++#define FIRST_DOW (1 << 0) ++#define SECOND_DOW (1 << 1) ++#define THIRD_DOW (1 << 2) ++#define FOURTH_DOW (1 << 3) ++#define FIFTH_DOW (1 << 4) ++#define LAST_DOW (1 << 5) ++#define ALL_DOW (FIRST_DOW|SECOND_DOW|THIRD_DOW|FOURTH_DOW|FIFTH_DOW|LAST_DOW) ++ + Prototype void CheckUpdates(const char *dpath, const char *user_override, time_t t1, time_t t2); + Prototype void SynchronizeDir(const char *dpath, const char *user_override, int initial_scan); + Prototype void ReadTimestamps(const char *user); +@@ -21,8 +29,10 @@ Prototype int CheckJobs(void); + void SynchronizeFile(const char *dpath, const char *fname, const char *uname); + void DeleteFile(CronFile **pfile); + char *ParseInterval(int *interval, char *ptr); +-char *ParseField(char *userName, char *ary, int modvalue, int off, int onvalue, const char **names, char *ptr); ++char *ParseField(char *userName, char *ary, int modvalue, int offset, int onvalue, const char **names, char *ptr); + void FixDayDow(CronLine *line); ++void PrintLine(CronLine *line); ++void PrintFile(CronFile *file, char* loc, char* fname, int line); + + CronFile *FileBase = NULL; + +@@ -454,15 +464,15 @@ SynchronizeFile(const char *dpath, const char *fileName, const char *userName) + * parse date ranges + */ + +- ptr = ParseField(file->cf_UserName, line.cl_Mins, 60, 0, 1, ++ ptr = ParseField(file->cf_UserName, line.cl_Mins, FIELD_MINUTES, 0, 1, + NULL, ptr); +- ptr = ParseField(file->cf_UserName, line.cl_Hrs, 24, 0, 1, ++ ptr = ParseField(file->cf_UserName, line.cl_Hrs, FIELD_HOURS, 0, 1, + NULL, ptr); +- ptr = ParseField(file->cf_UserName, line.cl_Days, 32, 0, 1, ++ ptr = ParseField(file->cf_UserName, line.cl_Days, FIELD_M_DAYS, 0, 1, + NULL, ptr); +- ptr = ParseField(file->cf_UserName, line.cl_Mons, 12, -1, 1, ++ ptr = ParseField(file->cf_UserName, line.cl_Mons, FIELD_MONTHS, -1, 1, + MonAry, ptr); +- ptr = ParseField(file->cf_UserName, line.cl_Dow, 7, 0, 31, ++ ptr = ParseField(file->cf_UserName, line.cl_Dow, FIELD_W_DAYS, 0, ALL_DOW, + DowAry, ptr); + /* + * check failure +@@ -634,12 +644,12 @@ SynchronizeFile(const char *dpath, const char *fileName, const char *userName) + + if (line.cl_JobName) { + if (DebugOpt) +- printlogf(LOG_DEBUG, " Command %s Job %s\n", line.cl_Shell, line.cl_JobName); ++ printlogf(LOG_DEBUG, " Command %s Job %s\n\n", line.cl_Shell, line.cl_JobName); + } else { + /* when cl_JobName is NULL, we point cl_Description to cl_Shell */ + line.cl_Description = line.cl_Shell; + if (DebugOpt) +- printlogf(LOG_DEBUG, " Command %s\n", line.cl_Shell); ++ printlogf(LOG_DEBUG, " Command %s\n\n", line.cl_Shell); + } + + *pline = calloc(1, sizeof(CronLine)); +@@ -691,7 +701,7 @@ ParseInterval(int *interval, char *ptr) + } + + char * +-ParseField(char *user, char *ary, int modvalue, int off, int onvalue, const char **names, char *ptr) ++ParseField(char *user, char *ary, int modvalue, int offset, int onvalue, const char **names, char *ptr) + { + char *base = ptr; + int n1 = -1; +@@ -714,9 +724,9 @@ ParseField(char *user, char *ary, int modvalue, int off, int onvalue, const char + ++ptr; + } else if (*ptr >= '0' && *ptr <= '9') { + if (n1 < 0) +- n1 = strtol(ptr, &ptr, 10) + off; ++ n1 = strtol(ptr, &ptr, 10) + offset; + else +- n2 = strtol(ptr, &ptr, 10) + off; ++ n2 = strtol(ptr, &ptr, 10) + offset; + skip = 1; + } else if (names) { + int i; +@@ -805,7 +815,7 @@ ParseField(char *user, char *ary, int modvalue, int off, int onvalue, const char + int i; + + for (i = 0; i < modvalue; ++i) +- if (modvalue == 7) ++ if (modvalue == FIELD_W_DAYS) + printlogf(LOG_DEBUG, "%2x ", ary[i]); + else + printlogf(LOG_DEBUG, "%d", ary[i]); +@@ -815,50 +825,66 @@ ParseField(char *user, char *ary, int modvalue, int off, int onvalue, const char + return(ptr); + } + ++/* Reconcile Days of Month with Days of Week. ++ * There are four cases to cover: ++ * 1) DoM and DoW are both specified as *; the task may run on any day ++ * 2) DoM is * and DoW is specific; the task runs weekly on the specified DoW(s) ++ * 3) DoM is specific and DoW is *; the task runs on the specified DoM, regardless ++ * of which day of the week they fall ++ * 4) DoM is in the range [1..5] and DoW is specific; the task runs on the Nth ++ * specified DoW. DoM > 5 means the last such DoW in that month ++ */ + void + FixDayDow(CronLine *line) + { +- unsigned short i,j; +- short weekUsed = 0; +- short daysUsed = 0; ++ unsigned short i; ++ short DowStar = 1; ++ short DomStar = 1; ++ char mask = 0; + + for (i = 0; i < arysize(line->cl_Dow); ++i) { + if (line->cl_Dow[i] == 0) { +- weekUsed = 1; ++ /* '*' was NOT specified in the DoW field on this CronLine */ ++ DowStar = 0; + break; + } + } ++ + for (i = 0; i < arysize(line->cl_Days); ++i) { + if (line->cl_Days[i] == 0) { +- if (weekUsed) { +- if (!daysUsed) { +- daysUsed = 1; +- /* change from "every Mon" to "ith Mon" +- * 6th,7th... Dow are treated as 1st,2nd... */ +- for (j = 0; j < arysize(line->cl_Dow); ++j) { +- line->cl_Dow[j] &= 1 << (i-1)%5; +- } +- } else { +- /* change from "nth Mon" to "nth or ith Mon" */ +- for (j = 0; j < arysize(line->cl_Dow); ++j) { +- if (line->cl_Dow[j]) +- line->cl_Dow[j] |= 1 << (i-1)%5; +- } +- } +- /* continue cycling through cl_Days */ +- } +- else { +- daysUsed = 1; +- break; +- } ++ /* '*' was NOT specified in the Date field on this CronLine */ ++ DomStar = 0; ++ break; + } + } +- if (weekUsed) { +- memset(line->cl_Days, 0, sizeof(line->cl_Days)); ++ ++ /* When cases 1, 2 or 3 there is nothing left to do */ ++ if (DowStar || DomStar) ++ return; ++ ++ /* Set individual bits within the DoW mask... */ ++ for (i = 0; i < arysize(line->cl_Days); ++i) { ++ if (line->cl_Days[i]) { ++ if (i < 6) ++ mask |= 1 << (i - 1); ++ else ++ mask |= LAST_DOW; ++ } + } +- if (daysUsed && !weekUsed) { +- memset(line->cl_Dow, 0, sizeof(line->cl_Dow)); ++ ++ /* and apply the mask to each DoW element */ ++ for (i = 0; i < arysize(line->cl_Dow); ++i) { ++ if (line->cl_Dow[i]) ++ line->cl_Dow[i] = mask; ++ else ++ line->cl_Dow[i] = 0; + } ++ ++ /* case 4 relies on the DoW value to guard the date instead of using the ++ * cl_Days field for this purpose; so we must set each element of cl_Days ++ * to 1 to allow the DoW bitmask test to be made ++ */ ++ memset(line->cl_Days, 1, sizeof(line->cl_Days)); + } + + /* +@@ -881,7 +907,7 @@ DeleteFile(CronFile **pfile) + file->cf_Deleted = 1; + + while ((line = *pline) != NULL) { +- if (line->cl_Pid > 0) { ++ if (line->cl_Pid > JOB_NONE) { + file->cf_Running = 1; + pline = &line->cl_Next; + } else { +@@ -942,13 +968,14 @@ TestJobs(time_t t1, time_t t2) + CronFile *file; + CronLine *line; + ++ PrintFile(FileBase, "TestJobs()", __FILE__, __LINE__); + for (file = FileBase; file; file = file->cf_Next) { + if (file->cf_Deleted) + continue; + for (line = file->cf_LineBase; line; line = line->cl_Next) { + struct CronWaiter *waiter; + +- if (line->cl_Pid == -2) { ++ if (line->cl_Pid == JOB_WAITING) { + /* can job stop waiting? */ + int ready = 1; + waiter = line->cl_Waiters; +@@ -965,7 +992,7 @@ TestJobs(time_t t1, time_t t2) + if (ready == 2) { + if (DebugOpt) + printlogf(LOG_DEBUG, "cancelled waiting: user %s %s\n", file->cf_UserName, line->cl_Description); +- line->cl_Pid = 0; ++ line->cl_Pid = JOB_NONE; + } else if (ready) { + if (DebugOpt) + printlogf(LOG_DEBUG, "finished waiting: user %s %s\n", file->cf_UserName, line->cl_Description); +@@ -987,24 +1014,23 @@ TestJobs(time_t t1, time_t t2) + if (t > t1) { + struct tm *tp = localtime(&t); + +- unsigned short n_wday = (tp->tm_mday - 1)%7 + 1; +- if (n_wday >= 4) { ++ char n_wday = 1 << ((tp->tm_mday - 1) / 7); ++ if (n_wday >= FOURTH_DOW) { + struct tm tnext = *tp; + tnext.tm_mday += 7; + if (mktime(&tnext) != (time_t)-1 && tnext.tm_mon != tp->tm_mon) +- n_wday |= 16; /* last dow in month is always recognized as 5th */ ++ n_wday |= LAST_DOW; /* last dow in month is always recognized as 6th bit */ + } + + for (file = FileBase; file; file = file->cf_Next) { + if (file->cf_Deleted) + continue; + for (line = file->cf_LineBase; line; line = line->cl_Next) { +- if ((line->cl_Pid == -2 || line->cl_Pid == 0) && (line->cl_Freq == 0 || (line->cl_Freq > 0 && t2 >= line->cl_NotUntil))) { ++ if ((line->cl_Pid == JOB_WAITING || line->cl_Pid == JOB_NONE) && (line->cl_Freq == 0 || (line->cl_Freq > 0 && t2 >= line->cl_NotUntil))) { + /* (re)schedule job? */ + if (line->cl_Mins[tp->tm_min] && + line->cl_Hrs[tp->tm_hour] && +- (line->cl_Days[tp->tm_mday] || (n_wday && line->cl_Dow[tp->tm_wday]) ) && +- line->cl_Mons[tp->tm_mon] ++ (line->cl_Days[tp->tm_mday] && n_wday & line->cl_Dow[tp->tm_wday]) + ) { + if (line->cl_NotUntil) + line->cl_NotUntil = t2 - t2 % 60 + line->cl_Delay; /* save what minute this job was scheduled/started waiting, plus cl_Delay */ +@@ -1027,19 +1053,19 @@ int + ArmJob(CronFile *file, CronLine *line, time_t t1, time_t t2) + { + struct CronWaiter *waiter; +- if (line->cl_Pid > 0) { ++ if (line->cl_Pid > JOB_NONE) { + printlogf(LOG_NOTICE, "process already running (%d): user %s %s\n", + line->cl_Pid, + file->cf_UserName, + line->cl_Description + ); +- } else if (t2 == -1 && line->cl_Pid != -1) { +- line->cl_Pid = -1; ++ } else if (t2 == -1 && line->cl_Pid != JOB_ARMED) { ++ line->cl_Pid = JOB_ARMED; + file->cf_Ready = 1; + return 1; +- } else if (line->cl_Pid == 0) { ++ } else if (line->cl_Pid == JOB_NONE) { + /* arming a waiting job (cl_Pid == -2) without forcing has no effect */ +- line->cl_Pid = -1; ++ line->cl_Pid = JOB_ARMED; + /* if we have any waiters, zero them and arm cl_Pid=-2 */ + waiter = line->cl_Waiters; + while (waiter != NULL) { +@@ -1047,15 +1073,15 @@ ArmJob(CronFile *file, CronLine *line, time_t t1, time_t t2) + if (!waiter->cw_NotifLine) + /* notifier deleted */ + waiter->cw_Flag = 0; +- else if (waiter->cw_NotifLine->cl_Pid != 0) { ++ else if (waiter->cw_NotifLine->cl_Pid != JOB_NONE) { + /* if notifier is armed, or waiting, or running, we wait for it */ + waiter->cw_Flag = -1; +- line->cl_Pid = -2; ++ line->cl_Pid = JOB_WAITING; + } else if (waiter->cw_NotifLine->cl_Freq < 0) { + /* arm any @noauto or @reboot jobs we're waiting on */ + ArmJob(file, waiter->cw_NotifLine, t1, t2); + waiter->cw_Flag = -1; +- line->cl_Pid = -2; ++ line->cl_Pid = JOB_WAITING; + } else { + time_t t; + if (waiter->cw_MaxWait == 0) +@@ -1068,21 +1094,20 @@ ArmJob(CronFile *file, CronLine *line, time_t t1, time_t t2) + if (t > t1) { + struct tm *tp = localtime(&t); + +- unsigned short n_wday = (tp->tm_mday - 1)%7 + 1; +- if (n_wday >= 4) { ++ char n_wday = 1 << ((tp->tm_mday - 1) / 7); ++ if (n_wday >= FOURTH_DOW) { + struct tm tnext = *tp; + tnext.tm_mday += 7; + if (mktime(&tnext) != (time_t)-1 && tnext.tm_mon != tp->tm_mon) +- n_wday |= 16; /* last dow in month is always recognized as 5th */ ++ n_wday |= LAST_DOW; /* last dow in month is always recognized as 6th */ + } + if (line->cl_Mins[tp->tm_min] && + line->cl_Hrs[tp->tm_hour] && +- (line->cl_Days[tp->tm_mday] || (n_wday && line->cl_Dow[tp->tm_wday]) ) && +- line->cl_Mons[tp->tm_mon] ++ (line->cl_Days[tp->tm_mday] && n_wday & line->cl_Dow[tp->tm_wday]) + ) { + /* notifier will run soon enough, we wait for it */ + waiter->cw_Flag = -1; +- line->cl_Pid = -2; ++ line->cl_Pid = JOB_WAITING; + break; + } + } +@@ -1091,7 +1116,7 @@ ArmJob(CronFile *file, CronLine *line, time_t t1, time_t t2) + } + waiter = waiter->cw_Next; + } +- if (line->cl_Pid == -1) { ++ if (line->cl_Pid == JOB_ARMED) { + /* job is ready to run */ + file->cf_Ready = 1; + if (DebugOpt) +@@ -1135,18 +1160,18 @@ TestStartupJobs(void) + if (line->cl_Freq == -1) { + /* freq is @reboot */ + +- line->cl_Pid = -1; ++ line->cl_Pid = JOB_ARMED; + /* if we have any waiters, reset them and arm Pid = -2 */ + waiter = line->cl_Waiters; + while (waiter != NULL) { + waiter->cw_Flag = -1; +- line->cl_Pid = -2; ++ line->cl_Pid = JOB_WAITING; + /* we only arm @noauto jobs we're waiting on, not other @reboot jobs */ + if (waiter->cw_NotifLine && waiter->cw_NotifLine->cl_Freq == -2) + ArmJob(file, waiter->cw_NotifLine, t1, t1+60); + waiter = waiter->cw_Next; + } +- if (line->cl_Pid == -1) { ++ if (line->cl_Pid == JOB_ARMED) { + /* job is ready to run */ + file->cf_Ready = 1; + ++nJobs; +@@ -1173,7 +1198,7 @@ RunJobs(void) + file->cf_Ready = 0; + + for (line = file->cf_LineBase; line; line = line->cl_Next) { +- if (line->cl_Pid == -1) { ++ if (line->cl_Pid == JOB_ARMED) { + + RunJob(file, line); + +@@ -1184,10 +1209,10 @@ RunJobs(void) + line->cl_Pid, + line->cl_Description + ); +- if (line->cl_Pid < 0) ++ if (line->cl_Pid < JOB_NONE) + /* QUESTION how could this happen? RunJob will leave cl_Pid set to 0 or the actual pid */ + file->cf_Ready = 1; +- else if (line->cl_Pid > 0) ++ else if (line->cl_Pid > JOB_NONE) + file->cf_Running = 1; + } + } +@@ -1214,7 +1239,7 @@ CheckJobs(void) + file->cf_Running = 0; + + for (line = file->cf_LineBase; line; line = line->cl_Next) { +- if (line->cl_Pid > 0) { ++ if (line->cl_Pid > JOB_NONE) { + int status; + int r = waitpid(line->cl_Pid, &status, WNOHANG); + +@@ -1237,7 +1262,7 @@ CheckJobs(void) + /* For the purposes of this check, increase the "still running" counter if a file has lines that are waiting */ + if (file->cf_Running == 0) { + for (line = file->cf_LineBase; line; line = line->cl_Next) { +- if (line->cl_Pid == -2) { ++ if (line->cl_Pid == JOB_WAITING) { + nStillRunning += 1; + break; + } +@@ -1247,3 +1272,69 @@ CheckJobs(void) + return(nStillRunning); + } + ++void ++PrintLine(CronLine *line) ++{ ++ int i; ++ if (!line) ++ return; ++ ++ printlogf(LOG_DEBUG, "CronLine:\n------------\n"); ++ printlogf(LOG_DEBUG, " Command: %s\n", line->cl_Shell); ++ //printlogf(LOG_DEBUG, " Desc: %s\n", line->cl_Description); ++ printlogf(LOG_DEBUG, " Freq: %s\n", (line->cl_Freq ? ++ (line->cl_Freq == -1 ? "(noauto)" : "(startup") : "(use arrays)")); ++ printlogf(LOG_DEBUG, " PID: %d\n", line->cl_Pid); ++ ++ printlogf(LOG_DEBUG, " Mins: "); ++ for (i = 0; i < 60; ++i) ++ printlogf(LOG_DEBUG, "%d", line->cl_Mins[i]); ++ ++ printlogf(LOG_DEBUG, "\n Hrs: "); ++ for (i = 0; i < 24; ++i) ++ printlogf(LOG_DEBUG, "%d", line->cl_Hrs[i]); ++ ++ printlogf(LOG_DEBUG, "\n Days: "); ++ for (i = 0; i < 32; ++i) ++ printlogf(LOG_DEBUG, "%d", line->cl_Days[i]); ++ ++ printlogf(LOG_DEBUG, "\n Mons: "); ++ for (i = 0; i < 12; ++i) ++ printlogf(LOG_DEBUG, "%d", line->cl_Mons[i]); ++ ++ printlogf(LOG_DEBUG, "\n Dow: "); ++ for (i = 0; i < 7; ++i) ++ printlogf(LOG_DEBUG, "%02x ", line->cl_Dow[i]); ++ printlogf(LOG_DEBUG, "\n\n"); ++} ++ ++void ++PrintFile(CronFile *file, char* loc, char* fname, int line) ++{ ++ CronFile *f; ++ CronLine *l; ++ ++ printlogf(LOG_DEBUG, "%s %s:%d\n", loc, fname, line); ++ ++ if (!file) ++ return; ++ ++ f = file; ++ while (f) { ++ ++ if (strncmp(file->cf_UserName, "root", 4)) { ++ printlogf(LOG_DEBUG, "FILE %s/%s USER %s\n=============================\n", ++ file->cf_DPath, ++ file->cf_FileName, ++ file->cf_UserName); ++ l = f->cf_LineBase; ++ ++ while (l) { ++ PrintLine(l); ++ l = l->cl_Next; ++ } ++ } ++ f = f->cf_Next; ++ } ++ ++} +diff --git a/defs.h b/defs.h +index b221636..cf77b5f 100644 +--- a/defs.h ++++ b/defs.h +@@ -17,6 +17,7 @@ + */ + + #define _XOPEN_SOURCE 1 ++#define _DEFAULT_SOURCE 1 + #define _BSD_SOURCE 1 + + #include <sys/types.h> +@@ -102,6 +103,16 @@ + #define MONTHLY_FREQ 30 * DAILY_FREQ + #define YEARLY_FREQ 365 * DAILY_FREQ + ++#define FIELD_MINUTES 60 ++#define FIELD_HOURS 24 ++#define FIELD_M_DAYS 32 ++#define FIELD_MONTHS 12 ++#define FIELD_W_DAYS 7 ++ ++#define JOB_NONE 0 ++#define JOB_ARMED -1 ++#define JOB_WAITING -2 ++ + #define LOGHEADER TIMESTAMP_FMT " %%s " LOG_IDENT ": " + #define LOCALE_LOGHEADER "%c %%s " LOG_IDENT ": " + +@@ -112,9 +123,6 @@ + #define RW_BUFFER 1024 + #define LOG_BUFFER 2048 /* max size of log line */ + +- +- +- + typedef struct CronFile { + struct CronFile *cf_Next; + struct CronLine *cf_LineBase; +@@ -141,11 +149,11 @@ typedef struct CronLine { + int cl_Pid; /* running pid, 0, or armed (-1), or waiting (-2) */ + int cl_MailFlag; /* running pid is for mail */ + int cl_MailPos; /* 'empty file' size */ +- char cl_Mins[60]; /* 0-59 */ +- char cl_Hrs[24]; /* 0-23 */ +- char cl_Days[32]; /* 1-31 */ +- char cl_Mons[12]; /* 0-11 */ +- char cl_Dow[7]; /* 0-6, beginning sunday */ ++ char cl_Mins[FIELD_MINUTES]; /* 0-59 */ ++ char cl_Hrs[FIELD_HOURS]; /* 0-23 */ ++ char cl_Days[FIELD_M_DAYS]; /* 1-31 */ ++ char cl_Mons[FIELD_MONTHS]; /* 0-11 */ ++ char cl_Dow[FIELD_W_DAYS]; /* 0-6, beginning sunday */ + } CronLine; + + typedef struct CronWaiter { +-- +2.13.2 + diff --git a/source/a/dcron/patches/0009-Updated-manpage.patch b/source/a/dcron/patches/0009-Updated-manpage.patch new file mode 100644 index 00000000..5db2550c --- /dev/null +++ b/source/a/dcron/patches/0009-Updated-manpage.patch @@ -0,0 +1,45 @@ +From 496027f566df6968939c45ad1a0069af495a2d40 Mon Sep 17 00:00:00 2001 +From: "Erik Falor (fadein)" <ewfalor@gmail.com> +Date: Tue, 24 Nov 2015 22:19:30 -0700 +Subject: [PATCH 9/9] Updated manpage + +--- + crontab.1 | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/crontab.1 b/crontab.1 +index 36043a9..1e2f59f 100644 +--- a/crontab.1 ++++ b/crontab.1 +@@ -92,20 +92,23 @@ Some examples: + .fi + .PP + To request the last Monday, etc. +-in a month, ask for the \[lq]5th\[rq] one. ++in a month, ask for the \[lq]6th\[rq] one. + This will always match the last Monday, etc., even if there are + only four Mondays in the month: + .IP + .nf + \f[C] + #\ run\ at\ 11\ am\ on\ the\ first\ and\ last\ Mon,\ Tue,\ Wed\ of\ each\ month +-0\ 11\ 1,5\ *\ mon-wed\ date ++0\ 11\ 1,6\ *\ mon-wed\ date ++ ++#\ run\ at\ noon\ on\ the\ fourth\ and\ last\ Friday\ of\ each\ month ++0\ 12\ 4,6\ *\ fri\ date + \f[] + .fi + .PP +-When the fourth Monday in a month is the last, it will match +-against both the \[lq]4th\[rq] and the \[lq]5th\[rq] (it will only +-run once if both are specified). ++When the fourth Monday in a month is also the last, this will match against ++both the \[lq]4th\[rq] and the \[lq]6th\[rq] but the job is scheduled only ++once. + .PP + The following formats are also recognized: + .IP +-- +2.13.2 + diff --git a/source/a/dcron/patches/crontab.c.O_EXCL.diff b/source/a/dcron/patches/crontab.c.O_EXCL.diff new file mode 100644 index 00000000..f705487e --- /dev/null +++ b/source/a/dcron/patches/crontab.c.O_EXCL.diff @@ -0,0 +1,12 @@ +diff -Nur dcron-4.5.orig//crontab.c dcron-4.5/crontab.c +--- dcron-4.5.orig//crontab.c 2011-05-01 07:22:09.000000000 -0500 ++++ dcron-4.5/crontab.c 2011-08-22 16:26:46.778225447 -0500 +@@ -199,7 +199,7 @@ + * Read from repFd, write to fd for "$CDir/$USER.new" + */ + snprintf(path, sizeof(path), "%s.new", pas->pw_name); +- if ((fd = open(path, O_CREAT|O_TRUNC|O_EXCL|O_APPEND|O_WRONLY, 0600)) >= 0) { ++ if ((fd = open(path, O_CREAT|O_TRUNC|O_APPEND|O_WRONLY, 0600)) >= 0) { + while ((n = read(repFd, buf, sizeof(buf))) > 0) { + write(fd, buf, n); + } diff --git a/source/a/dcron/patches/defs.h.TMPDIR.diff b/source/a/dcron/patches/defs.h.TMPDIR.diff new file mode 100644 index 00000000..0210c55c --- /dev/null +++ b/source/a/dcron/patches/defs.h.TMPDIR.diff @@ -0,0 +1,12 @@ +diff -Nur dcron-4.5.orig//defs.h dcron-4.5/defs.h +--- dcron-4.5.orig//defs.h 2011-05-01 07:22:09.000000000 -0500 ++++ dcron-4.5/defs.h 2011-08-22 16:28:35.343956248 -0500 +@@ -73,7 +73,7 @@ + #define CRONUPDATE "cron.update" + #endif + #ifndef TMPDIR +-#define TMPDIR "/tmp" ++#define TMPDIR "/run/cron" + #endif + + #ifndef SENDMAIL |