On 23-05-04 05:40PM, Todd C. Miller wrote:
> On Thu, 04 May 2023 21:41:26 -0000, Klemens Nanni wrote:
> 
> > On Thu, May 04, 2023 at 03:30:30PM -0600, Todd C. Miller wrote:
> > > This fixes two issues with the parsing of random values:
> > > 
> > > 1) A random value with a step is now rejected.  For example:
> > > 
> > >     ~/10    * * * * echo invalid
> >
> > I've ben using ~/10 to randomly distribute four similar tasks so that
> > they don't start at the same time.
> >
> > Is that wrong?
> 
> I'm fairly certain that doesn't do what you think it does.  When I
> tested it "~/10" behaved the same as "~".  The step value is not
> even parsed.

todd is correct in that the step value is not parsed with "~/10". We
recently discovered this when setting up Got mirrors to sync every 15
minutes. IIRC, Lucas (or op?) asked about syncing each mirror at
a different 15 minute interval by using the same syntax kn is using.

I found kn's attempted syntax intuitive though; it feels like a natural
extension of the existing random and step syntax. I also assumed ~/15
would run every 15 minutes starting with a random minute, and since
discovering it didn't work like that, I've been carrying a simple patch
that allows kn's syntax:

  ~/15          random 15 minute intervals in [0, 59]
  1~9/10        random 10 minute intervals in [1,59]

----8<--------
diff refs/remotes/origin/master refs/heads/master
commit - e253a7cc21de530da6fcf49c1279258fecade8f4
commit + 761b09ae46431344766330cc14c958ffca5a3a0a
blob - ab683b8476a8c862aabc53101b4080959820835a
blob + 030ab599dcf07eb3e94efe90c118e4e9bea8f6c4
--- usr.sbin/cron/entry.c
+++ usr.sbin/cron/entry.c
@@ -456,10 +456,11 @@ get_range(bitstr_t *bits, int low, int high, const cha
        /* range = number | number* "~" number* | number "-" number ["/" number]
         */
 
-       int i, num1, num2, num3;
+       int i, num1, num2, num3, rndstep;
 
        num1 = low;
        num2 = high;
+       rndstep = 0;
 
        if (ch == '*') {
                /* '*' means [low, high] but can still be modified by /step
@@ -497,7 +498,7 @@ get_range(bitstr_t *bits, int low, int high, const cha
 
                        /* get the (optional) number following the tilde
                         */
-                       ch = get_number(&num2, low, names, ch, file, ", \t\n");
+                       ch = get_number(&num2, low, names, ch, file, "/, \t\n");
                        if (ch == EOF)
                                ch = get_char(file);
                        if (ch == EOF || num1 > num2) {
@@ -509,6 +510,10 @@ get_range(bitstr_t *bits, int low, int high, const cha
                         */
                        num3 = num1;
                        num1 = arc4random_uniform(num2 - num3 + 1) + num3;
+                       if (ch == '/') {
+                               rndstep = 1;
+                               break;
+                       }
                        /* FALLTHROUGH */
                default:
                        /* not a range, it's a single number.
@@ -538,6 +543,10 @@ get_range(bitstr_t *bits, int low, int high, const cha
                ch = get_number(&num3, 0, NULL, ch, file, ", \t\n");
                if (ch == EOF || num3 == 0)
                        return (EOF);
+               if (rndstep) {
+                       num1 %= num3;
+                       num2 = high;
+               }
        } else {
                /* no step.  default==1.
                 */
-------->8----

> It sounds like what you want is the proposed syntax "*/~10"
> to use a random offset.

But this would be nice too! Anything that enables regular intervals from
a random offset would satisfy a common enough use case.

-- 
Mark Jamsek <fnc.bsdbox.org|got.bsdbox.org>
GPG: F2FF 13DE 6A06 C471 CA80  E6E2 2930 DC66 86EE CF68

Reply via email to