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