1 /*
2  * FCRON - periodic command scheduler
3  *
4  *  Copyright 2000-2016 Thibault Godouet <fcron@free.fr>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  The GNU General Public License can also be found in the file
21  *  `LICENSE' that comes with the fcron source distribution.
22  */
23 
24 
25 /* This has been inspired from bitstring(3) : here is the original copyright :
26  */
27 
28 /*
29  * Copyright (c) 1989 The Regents of the University of California.
30  * All rights reserved.
31  *
32  * This code is derived from software contributed to Berkeley by
33  * Paul Vixie.
34  *
35  * Redistribution and use in source and binary forms are permitted
36  * provided that the above copyright notice and this paragraph are
37  * duplicated in all such forms and that any documentation,
38  * advertising materials, and other materials related to such
39  * distribution and use acknowledge that the software was developed
40  * by the University of California, Berkeley.  The name of the
41  * University may not be used to endorse or promote products derived
42  * from this software without specific prior written permission.
43  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
44  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
45  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
46  *
47  */
48 
49 
50 /* read and set options of a line */
51 
52 /* WARNING : do not change any option number, nor remove any option, nor change
53  *           the meaning of a value (i.e. bit set to 1 -> true).
54  *           It can lead to errors with fcrontabs already saved to disk
55  *           or loaded in memory.
56  */
57 
58 /* WARNING : if you add some options, make sure that OPTION_SIZE is big
59  *           enough in global.h */
60 
61 /*
62 
63   The options are :
64 
65   bit:   option:
66   0      is this job based on time and date or system up time ?
67   1      is this job based on system load average ?
68   2      perform a logic OR or a logic AND between load averages ?
69   3      perform a logic OR or a logic AND between week day and month day ?
70   4      should we run this job at fcron startup if it should have been
71            executed during system down?
72   5      should this job be run serially ?
73   6      should this job be run serially only once (for bootrun) ?
74   7      does the output have to be mailed to user ?
75   8      does the output (even if zero-length) must be mailed to user ?
76   9      if time of execution is exceeded, exec the lavg job or not ?
77   10     can this job be executed several times simultaneously
78   11     can this job be put several times in the serial queue simultaneously
79   12     can this job be put several times in the lavg queue simultaneously
80   13     should mins field be ignored in goto_non_matching() ?
81   14     should hrs field be ignored in goto_non_matching() ?
82   15     should days field be ignored in goto_non_matching() ?
83   16     should mons field be ignored in goto_non_matching() ?
84   17     should dow field be ignored in goto_non_matching() ?
85   18     First freq is the freq (*ly) or the first field to take into account ?
86   19     Freq (ie daily) is from middle to middle of period (ie nightly) ?
87   20     Should we remove a %-job from lavg queue if the interval is exceeded ?
88   21     Should user be mailed if a %-job has not run during a period ?
89   22     Should fcron log everything about this job or just errors ?
90   23     Should this job be run asap, or randomly in its allowed interval of execution ?
91   24     Should first value be applied at each fcron startup, or before line first exe ?
92   25     if fcron is running in foreground, print jobs output to stderr/stdout or mail ?
93   26     should the output of the job be emailed to the user only non-zero exit status ?
94   27     rebootreset: if set then apply option first at each system startup
95   28     runatreboot: if set then run the job at each system startup
96   29     runonce: if set then run the job only once
97   30     hasrun: set if the job has been run at least once
98 
99 */
100 
101 #ifndef __OPTIONH__
102 #define __OPTIONH__
103 
104 /* we need to include this to get some default values */
105 #include "config.h"
106 
107 /* internal macros */
108 
109 #define	_bit_byte(bit) \
110 	((bit) >> 3)
111 
112 #define	_bit_set(opt, bit) \
113 	((opt)[_bit_byte(bit)] |= (1 << ((bit)&0x7)))
114 
115 #define	_bit_test(opt, bit) \
116 	((opt)[_bit_byte(bit)] & (1 << ((bit)&0x7)))
117 
118 #define	_bit_clear(opt, bit) \
119 	((opt)[_bit_byte(bit)] &= ~(1 << ((bit)&0x7)))
120 
121 
122 /* external macros */
123 
124 /* default value generally corresponds to a bit value of 0 : if you want to
125  * change the default value of an option, do it by modifying the following
126  * macro (set to 1 the needed bits) */
127 #define set_default_opt(opt)  \
128        { \
129           if ( SERIAL_ONCE >= 1 ) clear_serial_sev(opt); \
130           if ( LAVG_ONCE == 0 ) set_lavg_sev(opt); \
131        }
132 
133 
134 /*
135   bit 0 : set to 1 : line is based on system up time
136           set to 0 : line is based on time and date
137 */
138 #define	is_freq(opt) \
139 	(_bit_test(opt, 0))
140 #define is_td(opt) \
141         ( ! _bit_test(opt, 0))
142 #define	set_freq(opt) \
143 	(_bit_set(opt, 0))
144 #define set_td(opt) \
145 	(_bit_clear(opt, 0))
146 
147 
148 /*
149   bit 1 : set to 1 : line based on system load average
150           set to 0 : line doesn't take care of load average
151 */
152 #define	is_lavg(opt) \
153 	(_bit_test(opt, 1))
154 #define	set_lavg(opt) \
155 	(_bit_set(opt, 1))
156 #define clear_lavg(opt) \
157 	(_bit_clear(opt, 1))
158 
159 
160 /*
161   bit 2 : set to 1 : perform a logic OR between load averages
162           set to 0 : perform a logic AND between load averages
163 */
164 #define	is_lor(opt) \
165 	(_bit_test(opt, 2))
166 #define	is_land(opt) \
167 	( ! _bit_test(opt, 2))
168 #define	set_lor(opt) \
169 	(_bit_set(opt, 2))
170 #define	set_land(opt) \
171 	(_bit_clear(opt, 2))
172 
173 /*
174   bit 3 : set to 1 : perform a logic OR between week day and month day
175           set to 0 : perform a logic AND between week day and month day
176 */
177 #define	is_dayor(opt) \
178 	(_bit_test(opt, 3))
179 #define	is_dayand(opt) \
180 	( ! _bit_test(opt, 3))
181 #define	set_dayor(opt) \
182 	(_bit_set(opt, 3))
183 #define set_dayand(opt) \
184 	(_bit_clear(opt, 3))
185 
186 
187 /*
188   bit 4 : set to 1 : run this line at fcron's startup if it should have been
189                      executed during system down
190           set to 0 : do not run it at fcron's startup
191 */
192 #define	is_bootrun(opt) \
193 	(_bit_test(opt, 4))
194 #define	set_bootrun(opt) \
195 	(_bit_set(opt, 4))
196 #define clear_bootrun(opt) \
197 	(_bit_clear(opt, 4))
198 
199 
200 /*
201   bit 5 : set to 1 : run this line serially
202           set to 0 : do not run it serially
203 */
204 #define	is_serial(opt) \
205 	(_bit_test(opt, 5))
206 #define	set_serial(opt) \
207 	(_bit_set(opt, 5))
208 #define clear_serial(opt) \
209 	(_bit_clear(opt, 5))
210 
211 
212 /*
213   bit 6 : set to 1 : job is being serialized once
214           set to 0 : job is not being serialized once
215 */
216 #define	is_serial_once(opt) \
217 	(_bit_test(opt, 6))
218 #define	set_serial_once(opt) \
219 	(_bit_set(opt, 6))
220 #define clear_serial_once(opt) \
221 	(_bit_clear(opt, 6))
222 
223 
224 /*
225   bit 7 : set to 1 : do not mail output
226           set to 0 : mail output to user
227 */
228 #define	is_mail(opt) \
229 	( ! _bit_test(opt, 7))
230 #define	set_mail(opt) \
231 	(_bit_clear(opt, 7))
232 #define clear_mail(opt) \
233 	(_bit_set(opt, 7))
234 
235 
236 /*
237   bit 8 : set to 1 : mail output even if it is zero-length to user
238           set to 0 : mail output only if it is non-zero length
239 */
240 #define	is_mailzerolength(opt) \
241 	(_bit_test(opt, 8))
242 #define	set_mailzerolength(opt) \
243 	(_bit_set(opt, 8))
244 #define clear_mailzerolength(opt) \
245 	(_bit_clear(opt, 8))
246 
247 
248 /*
249   bit 9 : set to 1 : exec the job now if time of execution is exceeded
250           set to 0 : do not exec the job if time of execution is exceeded
251 */
252 #define	is_run_if_late(opt) \
253 	(_bit_test(opt, 9))
254 #define	set_run_if_late(opt) \
255 	(_bit_set(opt, 9))
256 #define clear_run_if_late(opt) \
257 	(_bit_clear(opt, 9))
258 
259 
260 /*
261   bit 10 : set to 1 : line can be executed several times simultaneously
262            set to 0 : line can only be executed once simultaneously
263 */
264 #define	is_exe_sev(opt) \
265 	(_bit_test(opt, 10))
266 #define	set_exe_sev(opt) \
267 	(_bit_set(opt, 10))
268 #define clear_exe_sev(opt) \
269 	(_bit_clear(opt, 10))
270 
271 
272 /*
273   bit 11 : set to 1 : can only be put once in serial queue simultaneously
274            set to 0 : can be put several times in serial queue simultaneously
275 */
276 #define	is_serial_sev(opt) \
277 	( ! _bit_test(opt, 11))
278 #define	set_serial_sev(opt) \
279 	(_bit_clear(opt, 11))
280 #define clear_serial_sev(opt) \
281 	(_bit_set(opt, 11))
282 
283 
284 /*
285   bit 12 : set to 1 : can only be put once in lavg queue simultaneously
286            set to 0 : can be put several times in lavg queue simultaneously
287 */
288 #define	is_lavg_sev(opt) \
289 	(_bit_test(opt, 12))
290 #define	set_lavg_sev(opt) \
291 	(_bit_set(opt, 12))
292 #define clear_lavg_sev(opt) \
293 	(_bit_clear(opt, 12))
294 
295 
296 /*
297   bit 13 : set to 1 : mins field is the limit
298            set to 0 : mins field is not the limit
299 */
300 #define	is_freq_mins(opt) \
301 	(_bit_test(opt, 13))
302 #define	set_freq_mins(opt) \
303 	(_bit_set(opt, 13))
304 #define clear_freq_mins(opt) \
305 	(_bit_clear(opt, 13))
306 
307 
308 /*
309   bit 14 : set to 1 : hrs field is the limit
310            set to 0 : hrs field is not the limit
311 */
312 #define	is_freq_hrs(opt) \
313 	(_bit_test(opt, 14))
314 #define	set_freq_hrs(opt) \
315 	(_bit_set(opt, 14))
316 #define clear_freq_hrs(opt) \
317 	(_bit_clear(opt, 14))
318 
319 
320 /*
321   bit 15 : set to 1 : days field is the limit
322            set to 0 : days field is not the limit
323 */
324 #define	is_freq_days(opt) \
325 	(_bit_test(opt, 15))
326 #define	set_freq_days(opt) \
327 	(_bit_set(opt, 15))
328 #define clear_freq_days(opt) \
329 	(_bit_clear(opt, 15))
330 
331 
332 /*
333   bit 16 : set to 1 : mons field is the limit
334            set to 0 : mons field is not the limit
335 */
336 #define	is_freq_mons(opt) \
337 	(_bit_test(opt, 16))
338 #define	set_freq_mons(opt) \
339 	(_bit_set(opt, 16))
340 #define clear_freq_mons(opt) \
341 	(_bit_clear(opt, 16))
342 
343 
344 /*
345   bit 17 : set to 1 : dow field is the limit
346            set to 0 : dow field is not the limit
347 */
348 #define	is_freq_dow(opt) \
349 	(_bit_test(opt, 17))
350 #define	set_freq_dow(opt) \
351 	(_bit_set(opt, 17))
352 #define clear_freq_dow(opt) \
353 	(_bit_clear(opt, 17))
354 
355 
356 /*
357   bit 18 : set to 1 : limit field is freq to run the line (once a hour, etc)
358            set to 0 : run once per interval of the limit field
359 */
360 #define	is_freq_periodically(opt) \
361 	(_bit_test(opt, 18))
362 #define	set_freq_periodically(opt) \
363 	(_bit_set(opt, 18))
364 #define clear_freq_periodically(opt) \
365 	(_bit_clear(opt, 18))
366 
367 
368 /*
369   bit 19 : set to 1 : run once from mid-period to mid-period (i.e. nightly)
370            set to 0 : run once from begin to the end of period (i.e. daily)
371 */
372 #define	is_freq_mid(opt) \
373 	(_bit_test(opt, 19))
374 #define	set_freq_mid(opt) \
375 	(_bit_set(opt, 19))
376 #define clear_freq_mid(opt) \
377 	(_bit_clear(opt, 19))
378 
379 
380 /*
381   bit 20 : set to 1 : let the job in the %-queue if interval is exceeded
382            set to 0 : remove %-job from lavg queue if interval is exceeded
383 */
384 #define	is_strict(opt) \
385 	( ! _bit_test(opt, 20))
386 #define	set_strict(opt) \
387 	(_bit_clear(opt, 20))
388 #define clear_strict(opt) \
389 	(_bit_set(opt, 20))
390 
391 
392 /*
393   bit 21 : set to 1 : mail user if a job has not run during a period
394            set to 0 : do not mail user if a job has not run during a period
395 */
396 #define	is_notice_notrun(opt) \
397 	(_bit_test(opt, 21))
398 #define	set_notice_notrun(opt) \
399 	(_bit_set(opt, 21))
400 #define clear_notice_notrun(opt) \
401 	(_bit_clear(opt, 21))
402 
403 
404 /*
405   bit 22 : set to 1 : do not log normal activity of this job (only errors)
406            set to 0 : log everything
407 */
408 #define	is_nolog(opt) \
409 	(_bit_test(opt, 22))
410 #define	set_nolog(opt) \
411 	(_bit_set(opt, 22))
412 #define clear_nolog(opt) \
413 	(_bit_clear(opt, 22))
414 
415 
416 /*
417   bit 23 : set to 1 : run this job at a random time in its allowed interval of execution.
418            set to 0 : run this job asap (safer)
419 */
420 #define	is_random(opt) \
421 	(_bit_test(opt, 23))
422 #define	set_random(opt) \
423 	(_bit_set(opt, 23))
424 #define clear_random(opt) \
425 	(_bit_clear(opt, 23))
426 
427 
428 /*
429   bit 24 : set to 1 : "volatile" system up time, i.e. restart counting each time fcron
430                       is started
431            set to 0 : continue counting uptime where last fcron instance left of
432 */
433 #define	is_volatile(opt) \
434 	(_bit_test(opt, 24))
435 #define	set_volatile(opt) \
436 	(_bit_set(opt, 24))
437 #define clear_volatile(opt) \
438 	(_bit_clear(opt, 24))
439 
440 /*
441   bit 25 : set to 1 : if fcron is running in the forground, then also let jobs print
442                       to stderr/stdout instead of mailing or discarding it
443            set to 0 : if fcron is not running in the foreground or this bit is not
444 	              set, then treat it as specified with the other options
445 */
446 #define	is_stdout(opt) \
447 	(_bit_test(opt, 25))
448 #define	set_stdout(opt) \
449 	(_bit_set(opt, 25))
450 #define clear_stdout(opt) \
451 	(_bit_clear(opt, 25))
452 
453 /*
454   bit 26 : set to 1 : The ouput of a job will only be emailed to the user if the job
455                       exited with a non-zero status.
456            set to 0 : The exit-status of the job won't be taken into account to decide
457                       if the output should be emailed to the user.
458 */
459 #define	is_erroronlymail(opt) \
460 	(_bit_test(opt, 26))
461 #define	set_erroronlymail(opt) \
462 	(_bit_set(opt, 26))
463 #define clear_erroronlymail(opt) \
464 	(_bit_clear(opt, 26))
465 
466 /*
467   bit 27 : set to 1 : at each system startup, run the job after the delay set
468                       in the option first
469            set to 0 : leave the nextexe time as it
470 */
471 #define	is_rebootreset(opt) \
472 	(_bit_test(opt, 27))
473 #define	set_rebootreset(opt) \
474 	(_bit_set(opt, 27))
475 #define clear_rebootreset(opt) \
476 	(_bit_clear(opt, 27))
477 
478 /*
479   bit 28 : set to 1 : run the job immediately after the system startup
480            set to 0 : leave the nextexe time as it
481 */
482 #define	is_runatreboot(opt) \
483 	(_bit_test(opt, 28))
484 #define	set_runatreboot(opt) \
485 	(_bit_set(opt, 28))
486 #define clear_runatreboot(opt) \
487 	(_bit_clear(opt, 28))
488 
489 /*
490   bit 29 : set to 1 : run the job only once until next system reboot
491                       (or next fcron restart if volatile is set)
492            set to 0 : don't limit the number of times the job is run
493 */
494 #define	is_runonce(opt) \
495 	(_bit_test(opt, 29))
496 #define	set_runonce(opt) \
497 	(_bit_set(opt, 29))
498 #define clear_runonce(opt) \
499 	(_bit_clear(opt, 29))
500 
501 /*
502   bit 30 : set to 1 : the job has run at least once since system reboot
503                       (or since fcron restart if volatile is set)
504            set to 0 : job hasn't run yet
505 */
506 #define	is_hasrun(opt) \
507 	(_bit_test(opt, 30))
508 #define	set_hasrun(opt) \
509 	(_bit_set(opt, 30))
510 #define clear_hasrun(opt) \
511 	(_bit_clear(opt, 30))
512 
513 #endif                          /* __OPTIONH__ */
514