File: bcron.html

package info (click to toggle)
bcron 0.10-3
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 504 kB
  • ctags: 353
  • sloc: ansic: 2,161; sh: 611; makefile: 108
file content (750 lines) | stat: -rw-r--r-- 30,766 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
<html lang="en">
<head>
<title>bcron documentation</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="bcron documentation">
<meta name="generator" content="makeinfo 4.13">
<link title="Top" rel="top" href="#Top">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
  pre.display { font-family:inherit }
  pre.format  { font-family:inherit }
  pre.smalldisplay { font-family:inherit; font-size:smaller }
  pre.smallformat  { font-family:inherit; font-size:smaller }
  pre.smallexample { font-size:smaller }
  pre.smalllisp    { font-size:smaller }
  span.sc    { font-variant:small-caps }
  span.roman { font-family:serif; font-weight:normal; } 
  span.sansserif { font-family:sans-serif; font-weight:normal; } 
--></style>
</head>
<body>
<h1 class="settitle">bcron documentation</h1>
<div class="node">
<a name="Top"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Introduction">Introduction</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>

</div>

<ul class="menu">
<li><a accesskey="1" href="#Introduction">Introduction</a>
<li><a accesskey="2" href="#Design-Notes">Design Notes</a>
<li><a accesskey="3" href="#Configuration">Configuration</a>
<li><a accesskey="4" href="#Implementation-Notes">Implementation Notes</a>
</ul>

<!-- **************************************************************************** -->
<div class="node">
<a name="Introduction"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Design-Notes">Design Notes</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Top">Top</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>

</div>

<h2 class="chapter">1 Introduction</h2>

<p>Name comes from: Bruce's / Better / Busy cron.

<ul class="menu">
<li><a accesskey="1" href="#Problems">Problems</a>
<li><a accesskey="2" href="#Requirements">Requirements</a>
<li><a accesskey="3" href="#Design-Choices">Design Choices</a>
<li><a accesskey="4" href="#vixie_002dcron-Patches">vixie-cron Patches</a>
</ul>

<div class="node">
<a name="Problems"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Requirements">Requirements</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Introduction">Introduction</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Introduction">Introduction</a>

</div>

<h3 class="section">1.1 Problems With Other cron Systems</h3>

<ul class="menu">
<li><a accesskey="1" href="#Problems-with-vixie_002dcron">Problems with vixie-cron</a>
<li><a accesskey="2" href="#Problems-with-fcron">Problems with fcron</a>
<li><a accesskey="3" href="#Problems-with-anacron">Problems with anacron</a>
<li><a accesskey="4" href="#Problems-with-dcron">Problems with dcron</a>
</ul>

<div class="node">
<a name="Problems-with-vixie-cron"></a>
<a name="Problems-with-vixie_002dcron"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Problems-with-fcron">Problems with fcron</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Problems">Problems</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Problems">Problems</a>

</div>

<h4 class="subsection">1.1.1 vixie-cron</h4>

     <ul>
<li>Too many bugs
The last official release of vixie-cron was in December of 1993. 
Since then, many security holes and other bugs have been found,
requiring every vendor to distribute a multiply-patched version of
this system.  Most vendors have a different set of patches, making
this a bit of a moving target.

     <li>Can't handle DST changes
vixie-cron's mode of operations is to wake up every minute and
determine, with no history, what jobs to run.  When DST changes, this
causes some jobs to be either skipped or run twice.

</ul>

<div class="node">
<a name="Problems-with-fcron"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Problems-with-anacron">Problems with anacron</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Problems-with-vixie_002dcron">Problems with vixie-cron</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Problems">Problems</a>

</div>

<h4 class="subsection">1.1.2 fcron</h4>

     <ul>
<li>Parsing issues
If a job starts with a word (terminated by any non-word character,
like <code>/</code>) that happens to also be a username, fcron interprets
this word as the userid to run the job under, even for non-root users. 
This causes problems for jobs like <code>bin/something</code> when user
<code>bin</code> exists.

     <li>No support for <samp><span class="file">/etc/cron.d</span></samp>

     <li>No support for <samp><span class="file">/etc/crontab</span></samp>

     <li>Gratuitious incompatibilities with vixie-cron
Jobs are run with the login shell for the user instead of
<samp><span class="file">/bin/sh</span></samp>.  The default mode of execution prevents the same job
from running multiple times (a good option, but bad default). 
<code>MAILTO</code> can only contain a username, not a full email address.

</ul>

<div class="node">
<a name="Problems-with-anacron"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Problems-with-dcron">Problems with dcron</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Problems-with-fcron">Problems with fcron</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Problems">Problems</a>

</div>

<h4 class="subsection">1.1.3 anacron</h4>

<p>Anacron is only really useful for running jobs once a day or less
frequently.  From what I've seen, it's good at what it does, just not
useful at much else.

<div class="node">
<a name="Problems-with-dcron"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Problems-with-anacron">Problems with anacron</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Problems">Problems</a>

</div>

<h4 class="subsection">1.1.4 dcron</h4>

     <ul>
<li>No support for <samp><span class="file">/etc/cron.d</span></samp>

     <li>No support for <samp><span class="file">/etc/crontab</span></samp>

     <li>No easy way of emulating support for system crontabs
dcron's crontab format does not include a &ldquo;username&rdquo; column, and as
such makes it nearly impossible to even emulate system crontabs.

     <li>Unusual or broken handling of DST changes
From reading the source, dcron only handles cases where the linear
time jumps.  When DST changes, linear time does not change, and so
dcron effectively does not handle this situation.

</ul>

<div class="node">
<a name="Requirements"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Design-Choices">Design Choices</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Problems">Problems</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Introduction">Introduction</a>

</div>

<h3 class="section">1.2 Requirements</h3>

     <ul>
<li>Security

     <p>I am choosing to make a number of relatively unorthodox choices in
order to avoid many of the security issues that have plagued
vixie-cron and other related systems.

     <li>External compatability with vixie-cron

     <p>In particular, the system must support:
          <ul>
<li>crontabs in the same file format as vixie-cron
<li>crontabs submitted via a command-line compatable <samp><span class="file">crontab</span></samp>
program
<li>mail is sent to <code>$MAILTO</code> if the job produces any output
(and possibly if the job exits non-zero)
</ul>

     <li>Support for system crontabs

     <p>This means that the system MUST support:
          <ul>
<li>System crontab entries in <samp><span class="file">/etc/crontab</span></samp>
<li>System crontab entries in <samp><span class="file">/etc/cron.d/*</span></samp>
</ul>
     System crontab entries are additionally differentiated from normal
ones by having a &ldquo;username&rdquo; column immediately preceding the
command.

     <li>Intelligent handling of DST time changes

     <p>One of the biggest frustrations I have had with dealing with
vixie-cron is its complete inability to deal with time jumps in an
intelligent manner.  In particular, when DST changes happen, jobs will
either get skipped (when time jumps forward) or executed twice (when
time jumps backwards).  This is unacceptable.

     <li>Allow setting ulimits before executing commands

     <p>In one of the target installations, we need to set up ulimits
(limiting CPU time and memory) before executing commands.  It would be
easy enough to ulimit the entire daemon, but then the daemon itself
would be vulnerable to getting killed when it has run for long enough. 
Our current setup is to run jobs through a global wrapper script,
which can set any necessary limits (or anything else) and then execute
the job.

</ul>

<div class="node">
<a name="Design-Choices"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#vixie_002dcron-Patches">vixie-cron Patches</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Requirements">Requirements</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Introduction">Introduction</a>

</div>

<h3 class="section">1.3 Design Choices</h3>

     <dl>
<dt>Use local socket to submit files.<dd>
There are two basic methods of submitting crontab files:
          <ol type=1 start=1>
<li>Use a setuid program to write directly into spool files. 
<li>Set up a local socket to submit jobs to a daemon.
          </ol>
<a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a> Using a setuid submission
agent was discarded to prevent the possibility of all the bugs that
have plagued other setuid submission agents.  The socket protocol is
deliberately very simple, to make the submission agent foolproof.

     <br><dt>Multiple process daemon.<dd>
By seperating job submission from job execution, exploiting the system
to run arbitrary jobs as privileged users is made even harder.  It
also makes the design of those individual programs much simpler.

</dl>

<div class="node">
<a name="vixie-cron-Patches"></a>
<a name="vixie_002dcron-Patches"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Design-Choices">Design Choices</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Introduction">Introduction</a>

</div>

<h3 class="section">1.4 vixie-cron Patches</h3>

<p>This section lists all the non-trivial patches found for vixie-cron,
what problem they appear to address, and (if appropriate) how bcron
will avoid the same problem.  The patches listed come from multiple
sources, including the latest RPM (Fedora Core IIRC).

     <dl>
<dt>0days.patch<dd>
This patch modifies the <samp><span class="file">crontab.5</span></samp> man page to remove allowing
&lsquo;<samp><span class="samp">0</span></samp>&rsquo; for day of month or month numbers.

     <br><dt>badsig.patch<dd>
On some systems, signal handlers are single-shot.  This patch modifies
the SIGHUP handler to reactivate itself before it returns.  bcron will
use the bglibs signal functions, which use sigaction to create
suitable handlers, where appropriate.  bcron doesn't use signals for
any purpose.

     <!-- uses named pipe triggers -->
     <!-- instead of signals to deliver notifications, removing the need for -->
     <!-- most signal handlers. -->
     <br><dt>buffer.patch<dd>
This patch increases the maximum username length from 20 to 32, and
modifies calls to strcpy to use strncpy to ensure all string copies
are length bounded.  bcron uses dynamically allocated strings to
eliminate the possibility of buffer overflows.

     <br><dt>close_stdin.diff<dd>
This patch modifies the cron daemon to close stdin, stdout, and stderr
on startup, and to reopen them as <samp><span class="file">/dev/null</span></samp>.  The bcron daemons
run under supervise, and have no need of such handling.

     <br><dt>crond.patch<dd>
Adds support for <samp><span class="file">/etc/cron.d</span></samp>

     <br><dt>cront_stdin.patch<dd>
Appears to modify <samp><span class="file">crontab</span></samp>'s command-line handling such that no
argument is interpreted as to read the crontab from standard input.

     <br><dt>crontab.5.diff<dd>
Documents several builtin macros to replace the first 5 fields.  This
macros consist of: &lsquo;<samp><span class="samp">@reboot</span></samp>&rsquo;, &lsquo;<samp><span class="samp">@yearly</span></samp>&rsquo;,
&lsquo;<samp><span class="samp">@annually</span></samp>&rsquo;, &lsquo;<samp><span class="samp">@monthly</span></samp>&rsquo;, &lsquo;<samp><span class="samp">@weekly</span></samp>&rsquo;, &lsquo;<samp><span class="samp">@daily</span></samp>&rsquo;,
&lsquo;<samp><span class="samp">@midnight</span></samp>&rsquo;, and &lsquo;<samp><span class="samp">@hourly</span></samp>&rsquo;.  bcron will not, at least
initially, support these macros.

     <br><dt>crontab.patch<dd>
Modifies crontab to use strncpy and snprintf when writing into
length-bounded strings.

     <br><dt>crontabloc.patch<dd>
Patches the crontab man page to reference <samp><span class="file">/etc/crontab</span></samp>.

     <br><dt>dst.patch<dd>
Patches the crontab man page to point out that DST may cause jobs to
be skipped or repeated.

     <br><dt>name.patch<dd>
Appears to modify how the cron daemon handles sending messages to
syslog.  bcron will log messages to stderr, avoiding syslog entirely.

     <br><dt>nodot.patch<dd>
Adds &lsquo;<samp><span class="samp">-i</span></samp>&rsquo; to the list of arguments sent to sendmail (result is
&lsquo;<samp><span class="samp">-FCronDaemon -i -odi -oem</span></samp>&rsquo;).  Only useful for sendmail, but
still needed.

     <br><dt>root_-u-85879.patch<dd>
Sanity checks the use of &lsquo;<samp><span class="samp">-u</span></samp>&rsquo; against UID and/or root.

     <br><dt>security2.patch<dd>
Does some sanity checking on mailto, and does a setuid before sending
mail.  bcron plays safe with mailto by putting it into a message
header, and always drops root privileges before executing commands.

     <br><dt>sigchld.patch<dd>
Return the SIGCHLD handler to its default state before executing
commands.

     <br><dt>sprintf.patch<dd>
More sprintf -&gt; snprintf conversions.

     <br><dt>time.patch<dd>
Sync all the crontabs before sleeping to handle changes in the system
time.

     <br><dt>timeaftertime.patch<dd>
The previous patch created double execution issues with small
backwards adjustments in the clock time.

     </dl>

<!-- **************************************************************************** -->
<div class="node">
<a name="Design-Notes"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Configuration">Configuration</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Introduction">Introduction</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>

</div>

<h2 class="chapter">2 Design Notes</h2>

<ul class="menu">
<li><a accesskey="1" href="#Fundamental-Operations">Fundamental Operations</a>
<li><a accesskey="2" href="#Programs">Programs</a>
<li><a accesskey="3" href="#Files">Files</a>
<li><a accesskey="4" href="#Inter_002dProcess-Communication">Inter-Process Communication</a>
</ul>

<div class="node">
<a name="Fundamental-Operations"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Programs">Programs</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Design-Notes">Design Notes</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Design-Notes">Design Notes</a>

</div>

<h3 class="section">2.1 Fundamental Operations</h3>

<p>The following is a list of all the &ldquo;core&rdquo; operations that must be
provided based on the requirements.

     <dl>
<dt>Execute jobs<dd>Strictly speaking, this is the only role that requires superuser
privileges.  Every other job should run as non-root.

     <br><dt>Schedule jobs<dd>Scan all the known jobs, determine which one needs to be executed
next, and sleep until that time arrives.

     <br><dt>Accept new user crontabs<dd>Listen for connections on a socket and accept job data.

     <br><dt>Parse crontabs into internal job format<dd>Read the submitted files and parse their contents into a structured
format.

     <br><dt>Check for new system crontabs<dd>Check <samp><span class="file">/etc/crontab</span></samp> and <samp><span class="file">/etc/cron.d/*</span></samp> every minute for
modifications.  If any files are changed, added, or deleted, add the
listed jobs.  On systems with tightened security, these files may only
be readable by &lsquo;<samp><span class="samp">root</span></samp>&rsquo;.

     <br><dt>Manage saved state<dd>All jobs need to be saved to disk along with when they were last
executed, in order to determine when they should be next executed.

     </dl>

<div class="node">
<a name="Programs"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Files">Files</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Fundamental-Operations">Fundamental Operations</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Design-Notes">Design Notes</a>

</div>

<h3 class="section">2.2 Programs</h3>

     <dl>
<dt><samp><span class="file">bcron-sched</span></samp><dd>Top-level scheduler agent.  Starts up as root, runs <samp><span class="file">bcron-exec</span></samp>,
and then drops root permanently.

     <br><dt><samp><span class="file">bcron-exec</span></samp><dd>Accepts jobs to run from <samp><span class="file">bcron-sched</span></samp> on stdin, writes exit
status back to stdout.

     <br><dt><samp><span class="file">bcron-spool</span></samp><dd>Manages the cron spool: receives jobs submitted from users, writes
them to files in <samp><span class="file">/var/spool/cron/crontabs</span></samp>, and notifies
<samp><span class="file">bcron-sched</span></samp>.  This needs to be run from <samp><span class="file">unixserver</span></samp> in
order to securely determine the invoking UID.  This program will
optionally run the file through an external filter, specified on the
command line, before installing the job.

     <br><dt><samp><span class="file">bcron-update</span></samp><dd>Watches for changes to the system crontabs and notifies
<samp><span class="file">bcron-sched</span></samp>.

</dl>

<div class="node">
<a name="Files"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Inter_002dProcess-Communication">Inter-Process Communication</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Programs">Programs</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Design-Notes">Design Notes</a>

</div>

<h3 class="section">2.3 Files</h3>

<ul class="menu">
<li><a accesskey="1" href="#File-Hierarchy">File Hierarchy</a>
</ul>

<div class="node">
<a name="File-Hierarchy"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Files">Files</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Files">Files</a>

</div>

<h4 class="subsection">2.3.1 File Hierarchy</h4>

     <dl>
<dt><samp><span class="file">/etc/cron.d/</span></samp>
<br><dt><samp><span class="file">/etc/cron.d/*</span></samp>
<br><dt><samp><span class="file">/etc/crontab</span></samp><dd>The above three items are read

     <br><dt><samp><span class="file">/var/spool/cron/</span></samp>
<br><dt><samp><span class="file">/var/spool/cron/crontabs/</span></samp><dd>Directory containing raw (text) crontab files.

     <br><dt><samp><span class="file">/var/spool/cron/crontabs/:etc:cron.d:*</span></samp><dd>Colon is chosen as a seperator because usernames cannot contain
colons due to the format of <samp><span class="file">/etc/passwd</span></samp>.

     <br><dt><samp><span class="file">/var/spool/cron/crontabs/:etc:crontab</span></samp>
<br><dt><samp><span class="file">/var/spool/cron/bcrontabs/</span></samp><dd>Directory containing pre-parsed (aka compiled) crontab files (Not yet
implemented).

     <br><dt><samp><span class="file">/var/spool/cron/tmp/</span></samp><dd>Temporary directory for files as they are written.

     <br><dt><samp><span class="file">/var/spool/cron/trigger</span></samp><dd>Named pipe used to tell <samp><span class="file">bcron-sched</span></samp> to rescan the crontabs.

</dl>

<div class="node">
<a name="Inter-Process-Communication"></a>
<a name="Inter_002dProcess-Communication"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Files">Files</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Design-Notes">Design Notes</a>

</div>

<h3 class="section">2.4 Inter-Process Communication</h3>

<p>All communication between programs is done in terms of either
&ldquo;packets&rdquo; or &ldquo;lines&rdquo;.  A packet is formatted as a
<a href="http://cr.yp.to/proto/netstrings.txt">netstring</a>.  That is, a
packet of length <var>N</var> is encoded as the ASCII decimal value of
<var>N</var>, &lsquo;<samp><span class="samp">:</span></samp>&rsquo;, N bytes of data, terminated by &lsquo;<samp><span class="samp">,</span></samp>&rsquo;.  A line is
simply a series of non-NUL bytes terminated by a NUL byte.

<ul class="menu">
<li><a accesskey="1" href="#Job-Submission-Protocol">Job Submission Protocol</a>
<li><a accesskey="2" href="#bcron_002dexec-Protocol">bcron-exec Protocol</a>
</ul>

<div class="node">
<a name="Job-Submission-Protocol"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#bcron_002dexec-Protocol">bcron-exec Protocol</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Inter_002dProcess-Communication">Inter-Process Communication</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Inter_002dProcess-Communication">Inter-Process Communication</a>

</div>

<h4 class="subsection">2.4.1 Job Submission Protocol</h4>

<p>Client sends a packet containing a single byte command followed by the
username.  If the command requires additional data, it is seperated
from the username by a NUL byte.  Server responds with a packet
containing a response byte followed by a text message.

     <p>Client command codes are:
     <dl>
<dt><code>S</code><dd>Submit a user crontab file.  The content string contains the entire
crontab file. 
<br><dt><code>L</code><dd>List the current crontab file.  No content string. 
<br><dt><code>R</code><dd>Remove any previously submitted crontab file.  No content string. 
<br><dt><code>Y</code><dd>List all system crontabs.  No content string.  This command is only
available to users &lsquo;<samp><span class="samp">root</span></samp>&rsquo; and &lsquo;<samp><span class="samp">cron</span></samp>&rsquo;. 
</dl>

     <p>Server response codes are:
     <dl>
<dt><code>K</code><dd>Command was successful; file was parsed and accepted. 
<br><dt><code>D</code><dd>File could not be parsed. 
<br><dt><code>Z</code><dd>Temporary internal error. 
</dl>

<div class="node">
<a name="bcron-exec-Protocol"></a>
<a name="bcron_002dexec-Protocol"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Job-Submission-Protocol">Job Submission Protocol</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Inter_002dProcess-Communication">Inter-Process Communication</a>

</div>

<h4 class="subsection">2.4.2 bcron-exec Protocol</h4>

<p>Input packets contain a series of four or more NUL-terminated lines:
     <dl>
<dt><code>ID</code><br><dt><code>username</code><br><dt><code>command</code><br><dt><code>environment</code><dd>The environment is optional.  If the environment contains
<code>SHELL</code>, it replaces the default shell (&lsquo;<samp><span class="samp">/bin/sh</span></samp>&rsquo;).  If the
environment contains <code>MAILTO</code>, it overrides the default mailing
address derived from the username. 
</dl>

     <p>Output packet:
     <dl>
<dt><code>ID</code><br><dt><code>NUL</code><br><dt><code>response code</code><br><dt><code>text message</code><dd></dl>
     Output packets are sent asynchronously with respect to input packets.

<!-- **************************************************************************** -->
<div class="node">
<a name="Configuration"></a>
<p><hr>
Next:&nbsp;<a rel="next" accesskey="n" href="#Implementation-Notes">Implementation Notes</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Design-Notes">Design Notes</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>

</div>

<h2 class="chapter">3 Configuration</h2>

<ul class="menu">
<li><a accesskey="1" href="#Environment-Variables">Environment Variables</a>
</ul>

<div class="node">
<a name="Environment-Variables"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Configuration">Configuration</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Configuration">Configuration</a>

</div>

<h3 class="section">3.1 Environment Variables</h3>

     <dl>
<dt><code>BCRON_SPOOL</code><dd>The base directory for bcron's files.  Defaults to
<samp><span class="file">/var/spool/cron</span></samp>.

     <br><dt><code>BCRON_USER</code><dd>The non-root user name to switch to for all processes that don't
require root privileges.  Defaults to &lsquo;<samp><span class="samp">cron</span></samp>&rsquo;.

     <br><dt><code>BCRON_MAXSIZE</code><dd>The maximum size (in bytes) of a single user crontab.  Defaults to
unlimited.

     <br><dt><code>BCRON_MAXJOBS</code><dd>The maximum number of jobs in a single user crontab.  Defaults to
unlimited.

     <br><dt><code>BCRON_SOCKET</code><dd>The full path to the UNIX-domain socket used to submit crontabs. 
Defaults to <samp><span class="file">/var/run/bcron-spool</span></samp>.

</dl>

<!-- **************************************************************************** -->
<div class="node">
<a name="Implementation-Notes"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Configuration">Configuration</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>

</div>

<h2 class="chapter">4 Implementation Notes</h2>

<ul class="menu">
<li><a accesskey="1" href="#Job-Scheduler">Job Scheduler</a>
</ul>

<div class="node">
<a name="Job-Scheduler"></a>
<p><hr>
Previous:&nbsp;<a rel="previous" accesskey="p" href="#Implementation-Notes">Implementation Notes</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="#Implementation-Notes">Implementation Notes</a>

</div>

<h3 class="section">4.1 Job Scheduler</h3>

<p>Getting the job scheduler to work correctly for all possible cases
consumed more time than all the other parts of the program put
together, and this is <strong>all</strong> because of the problems that
daylight savings causes.

     <p>The ultimate goal is this: given a linear timestamp, determine the
<strong>next</strong> linear timestamp after which a job must be run. 
&ldquo;Linear time&rdquo; means the number of seconds since an epoch, in this
case the UNIX epoch, midnight GMT January 1st, 1970.  To contrast,
&ldquo;local time&rdquo; means the time in terms of years, months, days, hours,
minutes, and seconds in the current locale.

     <p>The time specification for jobs is composed of a set of local time
bitmaps quantifying under what time conditions the job should run,
assuming the conditions are evaluated every minute.  The maximum
scheduling resolution is one minute.

     <p>The effective algorithm is to step through every possible minute until
the local time matches all the conditions in the time specification. 
This would result in an algorithm that could take up to 527,040-1
steps to complete, which is far too big a number to evaluate on every
job.  So, the algorithm optimizes away all impossible cases to make
much larger time jumps.  For example, if the job cannot be scheduled
on the current day, skip over the entire day instead of just the
current minute.

     <p>There are two ways I approached this task.  First, do all calculations
in terms of local time, and return the linear time at the last step. 
Second, do as many calculations as possible in terms of linear time,
which can be returned directly.  Both methods start with the same
input data: The current linear time, and a set of bitmasks
representing under what time conditions the job should run.

     <p>The first method was the most straightforward to get mostly working,
until I started to consider the implications of DST.  During the
transition from normal time to DST, an hour is skipped.  This is no
big deal, as <code>mktime</code> will (or can be made to) compensate by
picking the next valid hour when presented with a &ldquo;missing&rdquo; hour. 
On the other hand, there are many gotchas when dealing with the
duplicated hour.  For example, hourly jobs need to get scheduled on
both, but daily jobs on only one.

     <p>The second method was harder to get working initially, as the math is
more complicated.  Despite doing many calculations in terms of linear
time, this method still needs to keep track of the local time, in
order to check against the bitmaps as well as to determine things like
when the next day or month should start.  This approach proved to be
much easier to work with, once the initial math was done, and easier
to make work correctly with regards to DST transitions.

<!-- **************************************************************************** -->
     <div class="contents">
<h2>Table of Contents</h2>
<ul>
<li><a name="toc_Introduction" href="#Introduction">1 Introduction</a>
<ul>
<li><a href="#Problems">1.1 Problems With Other cron Systems</a>
<ul>
<li><a href="#Problems-with-vixie_002dcron">1.1.1 vixie-cron</a>
<li><a href="#Problems-with-fcron">1.1.2 fcron</a>
<li><a href="#Problems-with-anacron">1.1.3 anacron</a>
<li><a href="#Problems-with-dcron">1.1.4 dcron</a>
</li></ul>
<li><a href="#Requirements">1.2 Requirements</a>
<li><a href="#Design-Choices">1.3 Design Choices</a>
<li><a href="#vixie_002dcron-Patches">1.4 vixie-cron Patches</a>
</li></ul>
<li><a name="toc_Design-Notes" href="#Design-Notes">2 Design Notes</a>
<ul>
<li><a href="#Fundamental-Operations">2.1 Fundamental Operations</a>
<li><a href="#Programs">2.2 Programs</a>
<li><a href="#Files">2.3 Files</a>
<ul>
<li><a href="#File-Hierarchy">2.3.1 File Hierarchy</a>
</li></ul>
<li><a href="#Inter_002dProcess-Communication">2.4 Inter-Process Communication</a>
<ul>
<li><a href="#Job-Submission-Protocol">2.4.1 Job Submission Protocol</a>
<li><a href="#bcron_002dexec-Protocol">2.4.2 bcron-exec Protocol</a>
</li></ul>
</li></ul>
<li><a name="toc_Configuration" href="#Configuration">3 Configuration</a>
<ul>
<li><a href="#Environment-Variables">3.1 Environment Variables</a>
</li></ul>
<li><a name="toc_Implementation-Notes" href="#Implementation-Notes">4 Implementation Notes</a>
<ul>
<li><a href="#Job-Scheduler">4.1 Job Scheduler</a>
</li></ul>
</li></ul>
</div>

     <div class="footnote">
<hr>
<a name="texinfo-footnotes-in-document"></a><h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> There are actually others, but these two are the most simple
and portable of the choices.  See also
<a href="http://cr.yp.to/docs/secureipc.html">http://cr.yp.to/docs/secureipc.html</a></p>

     <hr></div>

</body></html>