home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
TOP
/
USR
/
SRC
/
vcron.t.Z
/
vcron.t
/
VCRON
/
vcron.c
< prev
Wrap
C/C++ Source or Header
|
1988-11-15
|
8KB
|
312 lines
/* $Source: /h0/usr/src/local/src/crond/crond.c,v $
* $Revision: 1.7 $
* $Log: crond.c,v $
* Revision 1.7 88/04/20 20:00:00 ram
* adapted paul's UN*X version for OSK
* got around the UN*X fork() by executing vcron with special
* argv[0]. Also moved crontab-owner recognition to group-entry.
* Mailing of output with '-' as first character of command instead of
* empty MAILTO. Usage of Sysinfo. Vcron now forks commands at the beginning
* of a minute.
*
* Revision 1.6 87/05/02 17:33:16 paul
* baseline for mod.sources release
*
* Revision 1.5 87/03/31 00:23:08 paul
* another GREAT idea from rs@mirror...
* do all time calculations in int instead of double -- the double
* stuff was for a previous kludge that turned out to be unneeded.
* time.c went away as of this change, also.
*
* Revision 1.4 87/02/12 18:20:29 paul
* fixed target_time scope misdesign, lots of fixes to sigchld stuff
*
* Revision 1.3 87/02/10 18:26:38 paul
* POKECRON, time_d(), target_time, other massive changes
*
* Revision 1.2 87/02/02 19:25:43 paul
* various
*
* Revision 1.1 87/01/26 23:48:55 paul
* Initial revision
*/
/* Copyright 1987 by Vixie Enterprises
* All rights reserved
*
* Distribute freely, except: don't sell it, don't remove my name from the
* source or documentation (don't take credit for my work), mark your changes
* (don't get me blamed for your possible bugs), don't alter or remove this
* notice. Commercial redistribution is negotiable; contact me for details.
*
* Send bug reports, bug fixes, enhancements, requests, flames, etc., and
* I'll try to keep a version up to date. I can be reached as follows:
* Paul Vixie, Vixie Enterprises, 329 Noe Street, San Francisco, CA, 94114,
* (415) 864-7013, {ucbvax!dual,ames,ucsfmis,lll-crg,sun}!ptsfa!vixie!paul.
*/
#define MAIN_PROGRAM
#include "cron.h"
#include <time.h>
#include <signal.h>
#include <types.h>
# include <modes.h>
# include <info.h>
extern int fprintf(), exit(), sleep();
extern time_t time();
static int dummy;
static int PokeCron;
static int Ticks_sec;
char *console = NULL;
char spooldir[MAX_FNAME];
void
usage()
{
exit (_errmsg (ERROR_EXIT, "usage: %s [-x<=>debugflag[,...]] \n", PROGNAME));
}
void
main(argc, argv)
int argc;
char *argv[];
{
extern char *_prgname(),*getenv(),**environ;
extern void set_cron_uid(), parse_args(),
free_database(),
do_1th_child(),do_2nd_child();
extern user *load_database();
extern long cron(),getuid(),os9exec(),os9forkc(),_memmins;
REG user *database;
REG long target_time;
int i,handler ();
_memmins = BUFSIZ; /* make vcron smaller */
PROGNAME = _prgname(); /* get name of Modul */
/*
* After getting the modulename, we are checking for argv[0][0],
* because of 'sub'crons. If we are a 'normal' Vcron we fork our-
* self again with argv[0][0] == '-'. That one is the real cron,
* parent == sysgo etc...
*/
switch( argv[0][0] ) {
case '*' :do_1th_child(argc,argv); exit(0);
case '?' :do_2nd_child(argc,argv); exit(0);
case '-' :break;
default: {
argv[0][0] = '-';
os9exec(os9forkc,PROGNAME,argv,environ,0,0,3);
sleep(1);
exit(0);
}
}
if( (long) getuid() )
exit (_errmsg (1,"YOU are NOT allowed to start Vcron !\n"));
intercept (handler);
Ticks_sec = CLK_TCK; /* how many ticks per second ? */
/*
* get the spooldir. there are 2 ways to guess it:
* 1. entry 'CRONDIR' in Sysinfo
* 2. hardcoded to SPOOLDIR
*/
if(!( info_str("CRONDIR",spooldir, MAX_FNAME)))
strcpy( spooldir, SPOOLDIR);
strcat(spooldir, "/");
/* if there is only one argument, it's the program name. this means
* that debugging can't be on (it would require '-x'), thus test-mode
* can't be on, thus we should fork and exit, to be compatible with
* the real cron. Not so in OSK-Version.
*/
(void) fprintf(stderr, "[%d] vcron started\n", getpid());
parse_args(argc, argv);
if (!console) console = CONSOLE;
if ( info_is_locked(POKECRON) )
exit (_errmsg (1,"Already locked: %s!\n",POKECRON));
if ( info_lock( POKECRON, 99) <0)
exit (_errmsg (1,"Cant't lock: %s!\n",POKECRON));
close (STDOUT);
close (STDERR);
if (access (console,02)) close (create (console,02,03));
open (console,S_IWRITE | S_IREAD);
dup (1);
/*open (console,S_IWRITE);*/
close (STDIN);
if (!strcmp (console,"/nil")) dup (1);
else open ("/nil",S_IREAD);
set_cron_uid();
_sysdate(0, &i, &dummy, &dummy, &dummy);
sleep( 60 - ( i & 0xff)); /* synch to begining of minute */
target_time = (long) time((time_t*)0);
PokeCron = 0;
while (TRUE)
{
database = load_database();
target_time = cron(database, target_time);
free_database(database);
}
}
static long
cron(db, target_time)
REG user *db;
REG long target_time;
{
extern int unlink();
extern void cron_tick(), cron_sleep();
/*
* The Variable PokeCron contains the last signal received (if any)
* if we got one, exit the loop to reload the database.
*/
while (! PokeCron)
{
/* do this iteration
*/
cron_tick(db, target_time);
/* sleep 1 minute
*/
target_time += 60;
cron_sleep(target_time);
}
PokeCron = 0;
#if DEBUGGING
Debug(DSCH, "POKECRON Signal detected\n");
#endif
return target_time;
}
static void
cron_tick(db, target_time)
user *db;
long target_time;
{
extern void do_command();
extern struct tm *localtime();
REG struct tm *tm = localtime((time_t*) &target_time);
REG user *u;
REG entry *e;
REG int minute, hour, dom, month, dow;
minute = tm->tm_min -FIRST_MINUTE;
hour = tm->tm_hour -FIRST_HOUR;
dom = tm->tm_mday -FIRST_DOM;
month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
dow = tm->tm_wday -FIRST_DOW;
#if DEBUGGING
Debug(DSCH, "tick(%d,%d,%d,%d,%d)\n", minute, hour, dom, month, dow);
#endif
/* the dom/dow situation is odd. '* * 1,15 * Sun' will run on the
* first and fifteenth AND every Sunday; '* * * * Sun' will run *only*
* on Sundays; '* * 1,15 * *' will run *only* the 1st and 15th. this
* is why we keep 'e->dow_star' and 'e->dom_star'.
*/
for (u = db; u != NULL; u = u->next)
for (e = u->crontab; e != NULL; e = e->next)
if (bit_test(e->minute, minute)
&& bit_test(e->hour, hour)
&& bit_test(e->month, month)
&& ( (e->dom_star || e->dow_star)
? (bit_test(e->dow,dow) && bit_test(e->dom,dom))
: (bit_test(e->dow,dow) || bit_test(e->dom,dom))
)
)
do_command(e->cmd, u);
}
static void
cron_sleep(target_time)
long target_time;
{
REG int seconds_to_wait;
seconds_to_wait = (int) (target_time - (long) time((time_t*)0));
#if DEBUGGING
Debug(DSCH, "target_time=%ld, sec-to-wait=%d\n",
target_time, seconds_to_wait);
#endif
if (seconds_to_wait > 0)
{
#if DEBUGGING
Debug(DSCH, "sleeping for %d seconds\n", seconds_to_wait);
#endif
/* sleep for x seconds, signal-proof :-) */
seconds_to_wait *= Ticks_sec;
while( seconds_to_wait = tsleep( (unsigned int) seconds_to_wait)) ;
}
}
static void
parse_args(argc, argv)
int argc;
char *argv[];
{
char *x;
int t;
for (t=1;t<argc;++t)
if (*(x = argv[t]) == '-') {
++x;
while (*x) {
switch (*x) {
case 'x':
if (*(x+1) == '=') ++x;
if (*x) ++x;
if (!*x) x = "ext,sch,proc,pars,misc";
if (!set_debug_flags(x))
usage();
else while (*x) ++x;
break;
case 'c':
if (*(x+1) == '=') ++x;
if (*x) ++x;
console = x;
while (*x) ++x;
break;
default:
usage ();
}
}
}
else usage ();
}
handler (sig)
REG int sig;
{
if (sig == SIGINT || sig == SIGQUIT) {
info_unlock(POKECRON);
exit (1);
}
PokeCron = sig;
#if DEBUGGING
Debug(DMISC, "Signal #%d received\n",sig);
#endif
}