static char *sccsid
= "@(#)cron.c 4.15 (Berkeley) %G%";
#include <sys/resource.h>
char crontab
[] = _PATH_CRON
;
char loc_crontab
[] = _PATH_LCRON
;
#define dprintf if (debug) fprintf
fprintf(stderr
, "cron: NOT super-user\n");
openlog("cron", LOG_PID
| LOG_CONS
| LOG_NOWAIT
, LOG_DAEMON
);
syslog(LOG_ERR
, "fork: %m");
c
= getopt(argc
, argv
, "d:");
debug
= fopen(optarg
, "w");
(void) fcntl(fileno(debug
), F_SETFL
, FAPPEND
);
(void) freopen("/", "r", stdout
);
(void) freopen("/", "r", stderr
);
(void) signal(SIGHUP
, SIG_IGN
);
(void) signal(SIGINT
, SIG_IGN
);
(void) signal(SIGQUIT
, SIG_IGN
);
(void) signal(SIGCHLD
, reapchild
);
itime
-= localtime(&itime
)->tm_sec
;
for (;; itime
+=60, slp()) {
struct stat cstat
, lcstat
;
if (stat(crontab
, &cstat
) < 0)
if (cstat
.st_mtime
!= filetime
) {
filetime
= cstat
.st_mtime
;
if (stat(loc_crontab
, &lcstat
) < 0)
if (lcstat
.st_mtime
!= lfiletime
) {
lfiletime
= lcstat
.st_mtime
;
loct
= localtime(&itime
);
loct
->tm_mon
++; /* 1-12 for month */
loct
->tm_wday
= 7; /* sunday is 7, not 0 */
for(cp
= list
; *cp
!= EOS
;) {
cp
= cmp(cp
, loct
->tm_min
);
cp
= cmp(cp
, loct
->tm_hour
);
cp
= cmp(cp
, loct
->tm_mday
);
cp
= cmp(cp
, loct
->tm_mon
);
cp
= cmp(cp
, loct
->tm_wday
);
if(i
< -60 * 60 || i
> 60 * 60) {
i
= 60 - localtime(&itime
)->tm_sec
;
register struct passwd
*pwd
;
syslog(LOG_ERR
, "cannot fork: %m (running %.40s%s)",
s
, strlen(s
) > 40 ? "..." : "");
while(*s
!= ' ' && *s
!= '\t')
if ((pwd
= getpwnam(user
)) == NULL
) {
syslog(LOG_ERR
, "invalid user name \"%s\"", user
);
dprintf(debug
, "%d: cannot find %s\n", pid
, user
),
(void) setgid(pwd
->pw_gid
);
(void) initgroups(pwd
->pw_name
, pwd
->pw_gid
);
(void) setuid(pwd
->pw_uid
);
(void) freopen("/", "r", stdin
);
dprintf(debug
, "%d: executing %s", pid
, s
), fflush (debug
);
execl(_PATH_BSHELL
, "sh", "-c", s
, 0);
syslog(LOG_ERR
, "cannot exec %s: %m");
dprintf(debug
, "%d: cannot execute sh\n", pid
), fflush (debug
);
* Don't free in case was longer than LISTS. Trades off
* the rare case of crontab shrinking vs. the common case of
* extra realloc's needed in append() for a large crontab.
if (freopen(fn
, "r", stdin
) == NULL
)
if(cp
> list
+listsize
-MAXLIN
) {
list
= realloc(list
, listsize
);
while(c
== ' ' || c
== '\t')
if(c
== EOF
|| c
== '\n')
if(c
!= '\t' && c
!= ' ')
if ((n
= number(getchar())) < 0)
if(c
!= '\t' && c
!= ' ')
if ((n
= number(getchar())) < 0)
if(c
!= '\t' && c
!= ' ')
while ((pid
= wait3(&status
, WNOHANG
, (struct rusage
*)0)) > 0)
dprintf(debug
, "%d: child exits with signal %d status %d\n",
pid
, status
.w_termsig
, status
.w_retcode
),
i
= open(_PATH_TTY
, O_RDWR
);
(void) ioctl(i
, TIOCNOTTY
, (char *)0);