From 1f9e8612be6409a4e1d49381849e426ac2153ae8 Mon Sep 17 00:00:00 2001 From: Kirill A. Korinskiy Date: Thu, 18 Feb 2010 19:49:13 +0300 Subject: [PATCH] Implement support {x,y} syntax for take random number from range {x,y} Cc: catap@catap.ru --- man/crontab.5 | 7 +++++++ src/cron.c | 1 + src/entry.c | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletions(-) diff --git a/man/crontab.5 b/man/crontab.5 index 5942ef3..e6cf05e 100644 --- a/man/crontab.5 +++ b/man/crontab.5 @@ -186,6 +186,13 @@ field matches the current time. For example, "30 4 1,15 * 5" would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday. +.PP +You can use a random number from the range instead of any number. For +example, +.br +"*/{4,6} * * *" +run command every 4, 5 or 6 minutes. An integer random number is +chosen from a range every time of loading file. .SH EXAMPLE CRON FILE .nf # use /bin/sh to run commands, no matter what /etc/passwd says diff --git a/src/cron.c b/src/cron.c index 7b57932..bcc9c9b 100644 --- a/src/cron.c +++ b/src/cron.c @@ -221,6 +221,7 @@ int main(int argc, char *argv[]) { } pid = getpid(); + srandom(pid); acquire_daemonlock(0); database.head = NULL; database.tail = NULL; diff --git a/src/entry.c b/src/entry.c index 97cafc8..2b1adf2 100644 --- a/src/entry.c +++ b/src/entry.c @@ -49,6 +49,7 @@ static const char *ecodes[] = { static int get_list(bitstr_t *, int, int, const char *[], int, FILE *), get_range(bitstr_t *, int, int, const char *[], int, FILE *), +get_num(int *, int, const char *[], int, FILE *, const char *), get_number(int *, int, const char *[], int, FILE *, const char *), set_element(bitstr_t *, int, int, int); @@ -520,7 +521,7 @@ get_range(bitstr_t * bits, int low, int high, const char *names[], } static int -get_number(int *numptr, int low, const char *names[], int ch, FILE * file, +get_num(int *numptr, int low, const char *names[], int ch, FILE * file, const char *terms) { char temp[MAX_TEMPSTR], *pc; int len, i; @@ -570,6 +571,40 @@ get_number(int *numptr, int low, const char *names[], int ch, FILE * file, return (EOF); } +static int +get_number(int *numptr, int low, const char *names[], int ch, FILE * file, + const char *terms) { + int num1, num2, rnd; + + /* first look a start of random number */ + if ((unsigned char) ch != '{') { + return get_num(numptr, low, names, ch, file, terms); + } + + ch = get_char(file); + + ch = get_number(&num1, 0, PPC_NULL, ch, file, ","); + if (ch == EOF) + return (EOF); + + ch = get_char(file); + + ch = get_number(&num2, 0, PPC_NULL, ch, file, "}"); + if (ch == EOF) + return (EOF); + + /* skip '}' */ + ch = get_char(file); + + rnd = random(); + + *numptr = num1 + (rnd / (RAND_MAX/(num2 - num1))); + + Debug(DPARS | DEXT, ("get_number, {%d, %d} = %d\n", num1, num2, *numptr)) + + return ch; +} + static int set_element(bitstr_t * bits, int low, int high, int number) { Debug(DPARS | DEXT, ("set_element(?,%d,%d,%d)\n", low, high, number)) -- 1.6.6