X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=snooze.c;h=ed929c77e8c38789a0a6ea11a316b7eb0b73e1e4;hb=refs%2Fheads%2Ffix-incorrect-mtime-usage;hp=9a3381a06144667379d2ab2c208fa478ff16dcfb;hpb=1b13bb82c9a732cd9d7216e74dab45e782c4f207;p=user%2Fhenk%2Fcode%2Fsnooze.git diff --git a/snooze.c b/snooze.c index 9a3381a..ed929c7 100644 --- a/snooze.c +++ b/snooze.c @@ -28,6 +28,7 @@ static int nflag, vflag; static int timewait = -1; static int randdelay = 0; +static int jitter = 0; static char *timefile; static sig_atomic_t alarm_rang = 0; @@ -99,7 +100,7 @@ parse(char *expr, char *buf, long bufsiz, int offset) while (*s) { switch (*s) { case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': + case '5': case '6': case '7': case '8': case '9': n = parse_int(&s, -offset, bufsiz); buf[n+offset] = '*'; break; @@ -120,7 +121,7 @@ parse(char *expr, char *buf, long bufsiz, int offset) for (i = n0; i < bufsiz; i += n) buf[i+offset] = '*'; break; - case ',': + case ',': s++; n = 0; break; @@ -140,9 +141,9 @@ parse(char *expr, char *buf, long bufsiz, int offset) } char weekday[8] = {0}; -char dayofmonth[31] = {0}; -char month[12] = {0}; -char dayofyear[366] = {0}; +char dayofmonth[32] = {0}; +char month[13] = {0}; +char dayofyear[367] = {0}; char weekofyear[54] = {0}; char hour[24] = {0}; char minute[60] = {0}; @@ -168,11 +169,12 @@ find_next(time_t from) tm = localtime(&t); next_day: - while (!(weekday[tm->tm_wday] == '*' - && dayofmonth[tm->tm_mday-1] == '*' - && month[tm->tm_mon] == '*' - && weekofyear[isoweek(tm)] == '*' - && dayofyear[tm->tm_yday] == '*')) { + while (!( + weekday[tm->tm_wday] == '*' && + dayofmonth[tm->tm_mday-1] == '*' && + month[tm->tm_mon] == '*' && + weekofyear[isoweek(tm)-1] == '*' && + dayofyear[tm->tm_yday] == '*')) { if (month[tm->tm_mon] != '*') { // if month is not good, step month tm->tm_mon++; @@ -181,20 +183,24 @@ next_day: tm->tm_mday++; } + tm->tm_isdst = -1; tm->tm_sec = 0; tm->tm_min = 0; tm->tm_hour = 0; t = mktime(tm); + tm->tm_isdst = -1; + if (t > from+(366*24*60*60)) // no result within a year return -1; } int y = tm->tm_yday; // save yday - while (!(hour[tm->tm_hour] == '*' - && minute[tm->tm_min] == '*' - && second[tm->tm_sec] == '*')) { + while (!( + hour[tm->tm_hour] == '*' && + minute[tm->tm_min] == '*' && + second[tm->tm_sec] == '*')) { if (hour[tm->tm_hour] != '*') { tm->tm_hour++; tm->tm_min = 0; @@ -209,7 +215,15 @@ next_day: if (tm->tm_yday != y) // hit a different day, retry... goto next_day; } - + + if (jitter && !nflag) { + long delay; + delay = lrand48() % jitter; + if (vflag) + printf("adding %lds for jitter.\n", delay); + t += delay; + } + return t; } @@ -221,7 +235,8 @@ isotime(const struct tm *tm) return isobuf; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { int c; time_t t; @@ -238,8 +253,10 @@ int main(int argc, char *argv[]) minute[0] = '*'; second[0] = '*'; - while ((c = getopt(argc, argv, "+D:W:H:M:S:T:R:d:m:ns:t:vw:")) != -1) - switch(c) { + setvbuf(stdout, 0, _IOLBF, 0); + + while ((c = getopt(argc, argv, "+D:W:H:M:S:T:R:J:d:m:ns:t:vw:")) != -1) + switch (c) { case 'D': parse(optarg, dayofyear, sizeof dayofyear, -1); break; case 'W': parse(optarg, weekofyear, sizeof weekofyear, -1); break; case 'H': parse(optarg, hour, sizeof hour, 0); break; @@ -249,7 +266,7 @@ int main(int argc, char *argv[]) case 'm': parse(optarg, month, sizeof month, -1); break; case 'w': parse(optarg, weekday, sizeof weekday, 0); // special case: sunday is both 0 and 7. - if (weekday[7] == '*') + if (weekday[7] == '*') weekday[0] = '*'; break; case 'n': nflag++; break; @@ -258,14 +275,15 @@ int main(int argc, char *argv[]) case 'T': timewait = parse_dur(optarg); break; case 't': timefile = optarg; break; case 'R': randdelay = parse_dur(optarg); break; + case 'J': jitter = parse_dur(optarg); break; default: - fprintf(stderr, "Usage: %s [-nv] [-t timefile] [-T timewait] [-R randdelay] [-s slack]\n" + fprintf(stderr, "Usage: %s [-nv] [-t timefile] [-T timewait] [-R randdelay] [-J jitter] [-s slack]\n" " [-d mday] [-m mon] [-w wday] [-D yday] [-W yweek] [-H hour] [-M min] [-S sec] COMMAND...\n" "Timespec: exact: 1,3,5\n" " range: 1-7\n" " every n-th: /10\n", argv[0]); - exit(2); - } + exit(2); + } time_t start = now + 1; @@ -283,23 +301,16 @@ int main(int argc, char *argv[]) t = find_next(t + 1); start = t; } else { - if (t + timewait > start) - start = st.st_mtime + timewait; + if (t + timewait > start - slack) + start = t + timewait; } } + srand48(getpid() ^ start); + if (randdelay) { long delay; -#ifdef __linux__ - long rnd = getauxval(AT_RANDOM); - if (rnd > 0) - delay = rnd % randdelay; - else -#endif - { - srand48(getpid() ^ start); - delay = lrand48() % randdelay; - } + delay = lrand48() % randdelay; if (vflag) printf("randomly delaying by %lds.\n", delay); start += delay; @@ -318,13 +329,18 @@ int main(int argc, char *argv[]) char weekstr[4]; struct tm *tm = localtime(&t); strftime(weekstr, sizeof weekstr, "%a", tm); - printf("%s %s %2ldd%3ldh%3ldm%3lds\n", + printf("%s %s %2ldd%3ldh%3ldm%3lds ", isotime(tm), weekstr, ((t - now) / (60*60*24)), ((t - now) / (60*60)) % 24, ((t - now) / 60) % 60, (t - now) % 60); + if(jitter) { + printf("(plus up to %ds for jitter)\n", jitter); + } else { + printf("\n"); + } t = find_next(t + 1); if (t < 0) { fprintf(stderr, @@ -376,16 +392,16 @@ int main(int argc, char *argv[]) } } - // no command to run, the outside script can go on - if (argc == optind) - return 0; - if (vflag) { now = time(0); tm = localtime(&now); printf("Starting execution at %s\n", isotime(tm)); } + // no command to run, the outside script can go on + if (argc == optind) + return 0; + execvp(argv[optind], argv+optind); perror("execvp"); return 255;