summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/cron/compat.c238
-rw-r--r--usr.sbin/cron/compat.h137
-rw-r--r--usr.sbin/cron/config.h62
-rw-r--r--usr.sbin/cron/cron.843
-rw-r--r--usr.sbin/cron/cron.c296
-rw-r--r--usr.sbin/cron/cron.h298
-rw-r--r--usr.sbin/cron/crontab.128
-rw-r--r--usr.sbin/cron/crontab.530
-rw-r--r--usr.sbin/cron/crontab.c367
-rw-r--r--usr.sbin/cron/database.c118
-rw-r--r--usr.sbin/cron/do_command.c291
-rw-r--r--usr.sbin/cron/entry.c156
-rw-r--r--usr.sbin/cron/env.c104
-rw-r--r--usr.sbin/cron/externs.h207
-rw-r--r--usr.sbin/cron/funcs.h70
-rw-r--r--usr.sbin/cron/globals.h77
-rw-r--r--usr.sbin/cron/job.c54
-rw-r--r--usr.sbin/cron/macros.h125
-rw-r--r--usr.sbin/cron/misc.c218
-rw-r--r--usr.sbin/cron/pathnames.h51
-rw-r--r--usr.sbin/cron/popen.c56
-rw-r--r--usr.sbin/cron/structs.h64
-rw-r--r--usr.sbin/cron/user.c83
23 files changed, 1435 insertions, 1738 deletions
diff --git a/usr.sbin/cron/compat.c b/usr.sbin/cron/compat.c
deleted file mode 100644
index 141f120cc7b..00000000000
--- a/usr.sbin/cron/compat.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* Copyright 1988,1990,1993,1994 by Paul Vixie
- * All rights reserved
- *
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
- *
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
- */
-
-#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: compat.c,v 1.3 2000/08/21 21:08:55 deraadt Exp $";
-#endif
-
-/* vix 30dec93 [broke this out of misc.c - see RCS log for history]
- * vix 15jan87 [added TIOCNOTTY, thanks csg@pyramid]
- */
-
-
-#include "cron.h"
-#ifdef NEED_GETDTABLESIZE
-# include <limits.h>
-#endif
-#if defined(NEED_SETSID) && defined(BSD)
-# include <sys/ioctl.h>
-#endif
-#include <errno.h>
-
-
-/* the code does not depend on any of vfork's
- * side-effects; it just uses it as a quick
- * fork-and-exec.
- */
-#ifdef NEED_VFORK
-PID_T
-vfork() {
- return (fork());
-}
-#endif
-
-
-#ifdef NEED_STRDUP
-char *
-strdup(str)
- char *str;
-{
- char *temp;
-
- if ((temp = malloc(strlen(str) + 1)) == NULL) {
- errno = ENOMEM;
- return NULL;
- }
- (void) strcpy(temp, str);
- return temp;
-}
-#endif
-
-
-#ifdef NEED_STRERROR
-char *
-strerror(error)
- int error;
-{
- extern char *sys_errlist[];
- extern int sys_nerr;
- static char buf[32];
-
- if ((error <= sys_nerr) && (error > 0)) {
- return sys_errlist[error];
- }
-
- snprintf(buf, sizeof buf, "Unknown error: %d", error);
- return buf;
-}
-#endif
-
-
-#ifdef NEED_STRCASECMP
-int
-strcasecmp(left, right)
- char *left;
- char *right;
-{
- while (*left && (MkLower(*left) == MkLower(*right))) {
- left++;
- right++;
- }
- return MkLower(*left) - MkLower(*right);
-}
-#endif
-
-
-#ifdef NEED_SETSID
-int
-setsid()
-{
- int newpgrp;
-# if defined(BSD)
- int fd;
-# if defined(POSIX)
- newpgrp = setpgid((pid_t)0, getpid());
-# else
- newpgrp = setpgrp(0, getpid());
-# endif
- if ((fd = open("/dev/tty", 2)) >= 0)
- {
- (void) ioctl(fd, TIOCNOTTY, (char*)0);
- (void) close(fd);
- }
-# else /*BSD*/
- newpgrp = setpgrp();
-
- (void) close(STDIN); (void) open("/dev/null", 0);
- (void) close(STDOUT); (void) open("/dev/null", 1);
- (void) close(STDERR); (void) open("/dev/null", 2);
-# endif /*BSD*/
- return newpgrp;
-}
-#endif /*NEED_SETSID*/
-
-
-#ifdef NEED_GETDTABLESIZE
-int
-getdtablesize() {
-#ifdef _SC_OPEN_MAX
- return sysconf(_SC_OPEN_MAX);
-#else
- return _POSIX_OPEN_MAX;
-#endif
-}
-#endif
-
-
-#ifdef NEED_FLOCK
-/* The following flock() emulation snarfed intact *) from the HP-UX
- * "BSD to HP-UX porting tricks" maintained by
- * system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson))
- * from the version "last updated: 11-Jan-1993"
- * Snarfage done by Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi>
- * *) well, almost, had to K&R the function entry, HPUX "cc"
- * does not grok ANSI function prototypes */
-
-/*
- * flock (fd, operation)
- *
- * This routine performs some file locking like the BSD 'flock'
- * on the object described by the int file descriptor 'fd',
- * which must already be open.
- *
- * The operations that are available are:
- *
- * LOCK_SH - get a shared lock.
- * LOCK_EX - get an exclusive lock.
- * LOCK_NB - don't block (must be ORed with LOCK_SH or LOCK_EX).
- * LOCK_UN - release a lock.
- *
- * Return value: 0 if lock successful, -1 if failed.
- *
- * Note that whether the locks are enforced or advisory is
- * controlled by the presence or absence of the SETGID bit on
- * the executable.
- *
- * Note that there is no difference between shared and exclusive
- * locks, since the 'lockf' system call in SYSV doesn't make any
- * distinction.
- *
- * The file "<sys/file.h>" should be modified to contain the definitions
- * of the available operations, which must be added manually (see below
- * for the values).
- */
-
-/* this code has been reformatted by vixie */
-
-int
-flock(fd, operation)
- int fd;
- int operation;
-{
- int i;
-
- switch (operation) {
- case LOCK_SH: /* get a shared lock */
- case LOCK_EX: /* get an exclusive lock */
- i = lockf (fd, F_LOCK, 0);
- break;
-
- case LOCK_SH|LOCK_NB: /* get a non-blocking shared lock */
- case LOCK_EX|LOCK_NB: /* get a non-blocking exclusive lock */
- i = lockf (fd, F_TLOCK, 0);
- if (i == -1)
- if ((errno == EAGAIN) || (errno == EACCES))
- errno = EWOULDBLOCK;
- break;
-
- case LOCK_UN: /* unlock */
- i = lockf (fd, F_ULOCK, 0);
- break;
-
- default: /* can't decipher operation */
- i = -1;
- errno = EINVAL;
- break;
- }
-
- return (i);
-}
-#endif /*NEED_FLOCK*/
-
-
-#ifdef NEED_SETENV
-int
-setenv(name, value, overwrite)
- char *name, *value;
- int overwrite;
-{
- char *tmp;
- int len;
-
- if (overwrite && getenv(name))
- return -1;
-
- len = strlen(name) + strlen(value) + 2;
- if (!(tmp = malloc(len))) {
- errno = ENOMEM;
- return -1;
- }
-
- snprintf(tmp, len, "%s=%s", name, value);
- return putenv(tmp); /* intentionally orphan 'tmp' storage */
-}
-#endif
diff --git a/usr.sbin/cron/compat.h b/usr.sbin/cron/compat.h
deleted file mode 100644
index 552ee0ffb4b..00000000000
--- a/usr.sbin/cron/compat.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Copyright 1993,1994 by Paul Vixie
- * All rights reserved
- *
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
- *
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
- */
-
-/*
- * $Id: compat.h,v 1.1 1995/10/18 08:47:30 deraadt Exp $
- */
-
-#ifndef __P
-# ifdef __STDC__
-# define __P(x) x
-# else
-# define __P(x) ()
-# define const
-# endif
-#endif
-
-#if defined(UNIXPC) || defined(unixpc)
-# define UNIXPC 1
-# define ATT 1
-#endif
-
-#if defined(hpux) || defined(_hpux) || defined(__hpux)
-# define HPUX 1
-# define seteuid(e) setresuid(-1,e,-1)
-# define setreuid(r,e) setresuid(r,e,-1)
-#endif
-
-#if defined(_IBMR2)
-# define AIX 1
-#endif
-
-#if defined(__convex__)
-# define CONVEX 1
-#endif
-
-#if defined(sgi) || defined(_sgi) || defined(__sgi)
-# define IRIX 1
-/* IRIX 4 hdrs are broken: one cannot #include both <stdio.h>
- * and <stdlib.h> because they disagree on system(), perror().
- * Therefore we must zap the "const" keyword BEFORE including
- * either of them.
- */
-# define const
-#endif
-
-#if defined(_UNICOS)
-# define UNICOS 1
-#endif
-
-#ifndef POSIX
-# if (BSD >= 199103) || defined(__linux) || defined(ultrix) || defined(AIX) ||\
- defined(HPUX) || defined(CONVEX) || defined(IRIX)
-# define POSIX
-# endif
-#endif
-
-#ifndef BSD
-# if defined(ultrix)
-# define BSD 198902
-# endif
-#endif
-
-/*****************************************************************/
-
-#if !defined(BSD) && !defined(HPUX) && !defined(CONVEX) && !defined(__linux)
-# define NEED_VFORK
-#endif
-
-#if (!defined(BSD) || (BSD < 198902)) && !defined(__linux) && \
- !defined(IRIX) && !defined(NeXT) && !defined(HPUX)
-# define NEED_STRCASECMP
-#endif
-
-#if (!defined(BSD) || (BSD < 198911)) && !defined(__linux) &&\
- !defined(IRIX) && !defined(UNICOS) && !defined(HPUX)
-# define NEED_STRDUP
-#endif
-
-#if (!defined(BSD) || (BSD < 198911)) && !defined(POSIX) && !defined(NeXT)
-# define NEED_STRERROR
-#endif
-
-#if defined(HPUX) || defined(AIX) || defined(UNIXPC)
-# define NEED_FLOCK
-#endif
-
-#ifndef POSIX
-# define NEED_SETSID
-#endif
-
-#if (defined(POSIX) && !defined(BSD)) && !defined(__linux)
-# define NEED_GETDTABLESIZE
-#endif
-
-#if (BSD >= 199103)
-# define HAVE_SAVED_UIDS
-#endif
-
-#if !defined(ATT) && !defined(__linux) && !defined(IRIX) && !defined(UNICOS)
-# define USE_SIGCHLD
-#endif
-
-#if !defined(AIX) && !defined(UNICOS)
-# define SYS_TIME_H 1
-#else
-# define SYS_TIME_H 0
-#endif
-
-#if defined(BSD) && !defined(POSIX)
-# define USE_UTIMES
-#endif
-
-#if defined(AIX) || defined(HPUX) || defined(IRIX)
-# define NEED_SETENV
-#endif
-
-#if !defined(UNICOS) && !defined(UNIXPC)
-# define HAS_FCHOWN
-#endif
-
-#if !defined(UNICOS) && !defined(UNIXPC)
-# define HAS_FCHMOD
-#endif
diff --git a/usr.sbin/cron/config.h b/usr.sbin/cron/config.h
index 91120609b74..4f7d67f4ab7 100644
--- a/usr.sbin/cron/config.h
+++ b/usr.sbin/cron/config.h
@@ -1,29 +1,28 @@
+/* $OpenBSD: config.h,v 1.6 2001/02/18 19:48:31 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
/* config.h - configurables for Vixie Cron
- *
- * $Id: config.h,v 1.5 2000/08/20 18:42:42 millert Exp $
*/
-#if !defined(_PATH_SENDMAIL)
-# define _PATH_SENDMAIL "/usr/lib/sendmail"
-#endif /*SENDMAIL*/
-
/*
* these are site-dependent
*/
@@ -33,37 +32,35 @@
#endif
/*
- * choose one of these MAILCMD commands. I use
+ * choose one of these mailer commands. some use
* /bin/mail for speed; it makes biff bark but doesn't
- * do aliasing. /usr/lib/sendmail does aliasing but is
+ * do aliasing. sendmail does do aliasing but is
* a hog for short messages. aliasing is not needed
* if you make use of the MAILTO= feature in crontabs.
* (hint: MAILTO= was added for this reason).
*/
-#define MAILCMD _PATH_SENDMAIL /*-*/
-#define MAILARGS "%s -FCronDaemon -odi -oem -oi -t" /*-*/
+#define MAILFMT "%s -FCronDaemon -odi -oem -or0s -t" /*-*/
/* -Fx = set full-name of sender
* -odi = Option Deliverymode Interactive
* -oem = Option Errors Mailedtosender
- * -t = read recipient from header of message
- * NOTE: since this runs as the user, not root you must
- * not specify any args that will cause sendmail
- * to drop its suidness (see op.me for a list).
+ * -or0s = Option Readtimeout -- don't time out
+ * -t = Get recipient from headers
*/
+#define MAILARG _PATH_SENDMAIL /*-*/
-/* #define MAILCMD "/bin/mail" -*/
-/* #define MAILARGS "%s -d %s" -*/
+/* #define MAILFMT "%s -d %s" -*/
/* -d = undocumented but common flag: deliver locally?
*/
+/* #define MAILARG "/bin/mail",mailto -*/
-/* #define MAILCMD "/usr/mmdf/bin/submit" -*/
-/* #define MAILARGS "%s -mlrxto %s" -*/
+/* #define MAILFMT "%s -mlrxto %s" -*/
+/* #define MAILARG "/usr/mmdf/bin/submit",mailto -*/
/* #define MAIL_DATE -*/
/* should we include an ersatz Date: header in
* generated mail? if you are using sendmail
- * for MAILCMD, it is better to let sendmail
+ * as the mailer, it is better to let sendmail
* generate the Date: header.
*/
@@ -89,4 +86,7 @@
#define SYSLOG /*-*/
/* if your OS supports a BSD-style login.conf file */
-#define LOGIN_CAP /*-*/
+#define LOGIN_CAP /*-*/
+
+ /* if your OS supports BSD authentication */
+/*#define BSD_AUTH -*/
diff --git a/usr.sbin/cron/cron.8 b/usr.sbin/cron/cron.8
index 8cb0cbe7a0f..59845209488 100644
--- a/usr.sbin/cron/cron.8
+++ b/usr.sbin/cron/cron.8
@@ -1,21 +1,23 @@
-.\"/* Copyright 1988,1990,1993 by Paul Vixie
+.\"/* Copyright 1988,1990,1993,1996 by Paul Vixie
.\" * All rights reserved
-.\" *
-.\" * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
-.\" * warrantee of any kind, express or implied, is included with this
-.\" * software; use at your own risk, responsibility for damages (if any) to
-.\" * anyone resulting from the use of this software rests entirely with the
-.\" * user.
-.\" *
-.\" * 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 <paul@vix.com> uunet!decwrl!vixie!paul
.\" */
.\"
-.\" $Id: cron.8,v 1.8 2000/03/19 17:57:03 aaron Exp $
+.\" Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+.\" ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+.\" CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\"
+.\" $OpenBSD: cron.8,v 1.9 2001/02/18 19:48:31 millert Exp $
.\"
.Dd June 6, 1999
.Dt CRON 8
@@ -90,6 +92,17 @@ new time immediately.
.Pp
Clock changes of more than 3 hours are considered to be corrections to
the clock, and the new time is used immediately.
+.Sh SIGNALS
+On receipt of a
+.Tn SIGHUP ,
+the cron daemon will close and reopen its log file.
+This is useful in scripts which rotate and age log files.
+Naturally this is not relevant if cron was built to use
+.Xr syslog 3 .
+Sh BUGS
+.Nm
+will behave mysteriously if a system clock is reset backward by more than
+59 seconds. Smaller steps, or steps forward, are handled correctly.
.Sh SEE ALSO
.Xr crontab 1 ,
.Xr crontab 5
diff --git a/usr.sbin/cron/cron.c b/usr.sbin/cron/cron.c
index 59ab8b33b07..b9086c8c2c0 100644
--- a/usr.sbin/cron/cron.c
+++ b/usr.sbin/cron/cron.c
@@ -1,70 +1,65 @@
+/* $OpenBSD: cron.c,v 1.10 2001/02/18 19:48:31 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: cron.c,v 1.9 2001/01/19 17:53:12 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: cron.c,v 1.10 2001/02/18 19:48:31 millert Exp $";
#endif
-
#define MAIN_PROGRAM
-
#include "cron.h"
-#include <sys/signal.h>
-#if SYS_TIME_H
-# include <sys/time.h>
-#else
-# include <time.h>
-#endif
-
-static void usage __P((void)),
- run_reboot_jobs __P((cron_db *)),
+static void usage(void),
+ run_reboot_jobs(cron_db *),
find_jobs __P((time_min, cron_db *, int, int)),
set_time __P((void)),
cron_sleep __P((time_min)),
-#ifdef USE_SIGCHLD
- sigchld_handler __P((int)),
-#endif
- sighup_handler __P((int)),
- parse_args __P((int c, char *v[]));
+ sigchld_handler(int),
+ sighup_handler(int),
+ sigchld_reaper(void),
+ parse_args(int c, char *v[]);
+static int got_sighup, got_sigchld;
static void
-usage() {
- char **dflags;
+usage(void) {
+ const char **dflags;
fprintf(stderr, "usage: %s [-x [", ProgramName);
- for(dflags = DebugFlagNames; *dflags; dflags++)
+ for (dflags = DebugFlagNames; *dflags; dflags++)
fprintf(stderr, "%s%s", *dflags, dflags[1] ? "," : "]");
fprintf(stderr, "]\n");
exit(ERROR_EXIT);
}
-
int
-main(argc, argv)
- int argc;
- char *argv[];
-{
+main(int argc, char *argv[]) {
cron_db database;
+ struct sigaction sact;
ProgramName = argv[0];
+ setlocale(LC_ALL, "");
+
#if defined(BSD)
setlinebuf(stdout);
setlinebuf(stderr);
@@ -72,30 +67,31 @@ main(argc, argv)
parse_args(argc, argv);
-#ifdef USE_SIGCHLD
- (void) signal(SIGCHLD, sigchld_handler);
-#else
- (void) signal(SIGCLD, SIG_IGN);
+ bzero((char *)&sact, sizeof sact);
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = 0;
+#ifdef SA_RESTART
+ sact.sa_flags |= SA_RESTART;
#endif
- (void) signal(SIGHUP, sighup_handler);
+ sact.sa_handler = sigchld_handler;
+ (void) sigaction(SIGCHLD, &sact, NULL);
+ sact.sa_handler = sighup_handler;
+ (void) sigaction(SIGHUP, &sact, NULL);
acquire_daemonlock(0);
set_cron_uid();
set_cron_cwd();
-#if defined(POSIX)
- if (setenv("PATH", _PATH_DEFPATH, 1) == -1) {
+ if (putenv("PATH="_PATH_DEFPATH) == -1) {
log_it("CRON",getpid(),"DEATH","can't malloc");
exit(1);
}
-#endif
/* if there are no debug flags turned on, fork as a daemon should.
*/
-
if (DebugFlags) {
#if DEBUGGING
- (void) fprintf(stderr, "[%d] cron started\n", getpid());
+ (void) fprintf(stderr, "[%ld] cron started\n", (long)getpid());
#endif
} else {
switch (fork()) {
@@ -119,13 +115,12 @@ main(argc, argv)
database.tail = NULL;
database.mtime = (time_t) 0;
load_database(&database);
-
set_time();
run_reboot_jobs(&database);
timeRunning = virtualTime = clockTime;
/*
- * too many clocks, not enough time (Al. Einstein)
+ * Too many clocks, not enough time (Al. Einstein)
* These clocks are in minutes since the epoch (time()/60).
* virtualTime: is the time it *would* be if we woke up
* promptly and nobody ever changed the clock. It is
@@ -138,8 +133,16 @@ main(argc, argv)
time_min timeDiff;
int wakeupKind;
- load_database(&database);
+ if (got_sighup) {
+ got_sighup = 0;
+ log_close();
+ }
+ if (got_sigchld) {
+ got_sigchld = 0;
+ sigchld_reaper();
+ }
+ load_database(&database);
/* ... wait for the time (in minutes) to change ... */
do {
cron_sleep(timeRunning + 1);
@@ -148,9 +151,8 @@ main(argc, argv)
timeRunning = clockTime;
/*
- * ... calculate how the current time differs from
- * our virtual clock. Classify the change into one
- * of 4 cases
+ * Calculate how the current time differs from our virtual
+ * clock. Classify the change into one of 4 cases.
*/
timeDiff = timeRunning - virtualTime;
@@ -173,8 +175,8 @@ main(argc, argv)
case 1:
/*
* case 1: timeDiff is a small positive number
- * (wokeup late) run jobs for each virtual minute
- * until caught up.
+ * (wokeup late) run jobs for each virtual
+ * minute until caught up.
*/
Debug(DSCH, ("[%d], normal case %d minutes to go\n",
getpid(), timeRunning - virtualTime))
@@ -182,31 +184,35 @@ main(argc, argv)
if (job_runqueue())
sleep(10);
virtualTime++;
- find_jobs(virtualTime, &database, TRUE, TRUE);
+ find_jobs(virtualTime, &database,
+ TRUE, TRUE);
} while (virtualTime< timeRunning);
break;
case 2:
/*
- * case 2: timeDiff is a medium-sized positive number,
- * for example because we went to DST run wildcard
- * jobs once, then run any fixed-time jobs that would
- * otherwise be skipped if we use up our minute
- * (possible, if there are a lot of jobs to run) go
- * around the loop again so that wildcard jobs have
- * a chance to run, and we do our housekeeping
+ * case 2: timeDiff is a medium-sized positive
+ * number, for example because we went to DST
+ * run wildcard jobs once, then run any
+ * fixed-time jobs that would otherwise be
+ * skipped if we use up our minute (possible,
+ * if there are a lot of jobs to run) go
+ * around the loop again so that wildcard jobs
+ * have a chance to run, and we do our
+ * housekeeping.
*/
Debug(DSCH, ("[%d], DST begins %d minutes to go\n",
getpid(), timeRunning - virtualTime))
/* run wildcard jobs for current minute */
find_jobs(timeRunning, &database, TRUE, FALSE);
- /* run fixed-time jobs for each minute missed */
+ /* run fixed-time jobs for each minute missed */
do {
if (job_runqueue())
sleep(10);
virtualTime++;
- find_jobs(virtualTime, &database, FALSE, TRUE);
+ find_jobs(virtualTime, &database,
+ FALSE, TRUE);
set_time();
} while (virtualTime< timeRunning &&
clockTime == timeRunning);
@@ -215,10 +221,11 @@ main(argc, argv)
case 0:
/*
* case 3: timeDiff is a small or medium-sized
- * negative num, eg. because of DST ending just run
- * the wildcard jobs. The fixed-time jobs probably
- * have already run, and should not be repeated
- * virtual time does not change until we are caught up
+ * negative num, eg. because of DST ending just
+ * run the wildcard jobs. The fixed-time jobs
+ * probably have already run, and should not be
+ * repeated. Virtual time does not change until
+ * we are caught up.
*/
Debug(DSCH, ("[%d], DST ends %d minutes to go\n",
getpid(), virtualTime - timeRunning))
@@ -234,42 +241,33 @@ main(argc, argv)
find_jobs(timeRunning, &database, TRUE, TRUE);
}
}
- /* jobs to be run (if any) are loaded. clear the queue */
+
+ /* Jobs to be run (if any) are loaded; clear the queue. */
job_runqueue();
}
}
-
static void
-run_reboot_jobs(db)
- cron_db *db;
-{
- register user *u;
- register entry *e;
-
- for (u = db->head; u != NULL; u = u->next) {
- for (e = u->crontab; e != NULL; e = e->next) {
- if (e->flags & WHEN_REBOOT) {
+run_reboot_jobs(cron_db *db) {
+ user *u;
+ entry *e;
+
+ for (u = db->head; u != NULL; u = u->next) {
+ for (e = u->crontab; e != NULL; e = e->next) {
+ if (e->flags & WHEN_REBOOT)
job_add(e, u);
- }
}
}
(void) job_runqueue();
}
-
static void
-find_jobs(vtime, db, doWild, doNonWild)
- time_min vtime;
- cron_db *db;
- int doWild;
- int doNonWild;
-{
- time_t virtualSecond = vtime * SECONDS_PER_MINUTE;
- register struct tm *tm = localtime(&virtualSecond);
- register int minute, hour, dom, month, dow;
- register user *u;
- register entry *e;
+find_jobs(time_min vtime, cron_db *db, int doWild, int doNonWild) {
+ time_t virtualSecond = vtime * SECONDS_PER_MINUTE;
+ struct tm *tm = localtime(&virtualSecond);
+ int minute, hour, dom, month, dow;
+ user *u;
+ entry *e;
/* make 0-based values out of these so we can use them as indicies
*/
@@ -279,9 +277,9 @@ find_jobs(vtime, db, doWild, doNonWild)
month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
dow = tm->tm_wday -FIRST_DOW;
- Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d) %s %s\n",
- getpid(), minute, hour, dom, month, dow,
- doWild?" ":"No wildcard",doNonWild?" ":"Wildcard only"))
+ Debug(DSCH, ("[%ld] tick(%d,%d,%d,%d,%d) %s %s\n",
+ (long)getpid(), minute, hour, dom, month, dow,
+ doWild?" ":"No wildcard",doNonWild?" ":"Wildcard only"))
/* the dom/dow situation is odd. '* * 1,15 * Sun' will run on the
* first and fifteenth AND every Sunday; '* * * * Sun' will run *only*
@@ -289,108 +287,90 @@ find_jobs(vtime, db, doWild, doNonWild)
* is why we keep 'e->dow_star' and 'e->dom_star'. yes, it's bizarre.
* like many bizarre things, it's the standard.
*/
- for (u = db->head; u != NULL; u = u->next) {
- for (e = u->crontab; e != NULL; e = e->next) {
- Debug(DSCH|DEXT, ("user [%s:%d:%d:...] cmd=\"%s\"\n",
- env_get("LOGNAME", e->envp),
- e->uid, e->gid, e->cmd))
+ for (u = db->head; u != NULL; u = u->next) {
+ for (e = u->crontab; e != NULL; e = e->next) {
+ Debug(DSCH|DEXT, ("user [%s:%ld:%ld:...] cmd=\"%s\"\n",
+ env_get("LOGNAME", e->envp),
+ (long)e->uid, (long)e->gid, e->cmd))
if (bit_test(e->minute, minute) &&
bit_test(e->hour, hour) &&
bit_test(e->month, month) &&
( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
? (bit_test(e->dow,dow) && bit_test(e->dom,dom))
- : (bit_test(e->dow,dow) || bit_test(e->dom,dom)))) {
- if ((doNonWild && !(e->flags & (MIN_STAR|HR_STAR)))
- || (doWild && (e->flags & (MIN_STAR|HR_STAR))))
- job_add(e, u);
- }
+ : (bit_test(e->dow,dow) || bit_test(e->dom,dom))
+ )
+ )
+ job_add(e, u);
}
}
}
-
/*
- * set StartTime and clockTime to the current time.
- * these are used for computing what time it really is right now.
- * note that clockTime is a unix wallclock time converted to minutes
+ * Set StartTime and clockTime to the current time.
+ * These are used for computing what time it really is right now.
+ * Note that clockTime is a unix wallclock time converted to minutes.
*/
static void
-set_time()
-{
+set_time(void) {
+
StartTime = time((time_t *)0);
clockTime = StartTime / (unsigned long)SECONDS_PER_MINUTE;
}
/*
- * try to just hit the next minute
+ * Try to just hit the next minute.
*/
static void
-cron_sleep(target)
- time_min target;
-{
- register int seconds_to_wait;
+cron_sleep(time_min target) {
+ int seconds_to_wait;
- seconds_to_wait = (int)(target*SECONDS_PER_MINUTE - time((time_t*)0)) + 1;
- Debug(DSCH, ("[%d] TargetTime=%ld, sec-to-wait=%d\n",
- getpid(), (long)target*SECONDS_PER_MINUTE, seconds_to_wait))
+ seconds_to_wait = (int)(target * SECONDS_PER_MINUTE - time(NULL)) + 1;
+ Debug(DSCH, ("[%ld] Target time=%ld, sec-to-wait=%d\n",
+ (long)getpid(), (long)target*SECONDS_PER_MINUTE, seconds_to_wait))
- if (seconds_to_wait > 0 && seconds_to_wait< 65)
+ if (seconds_to_wait > 0 && seconds_to_wait < 65)
sleep((unsigned int) seconds_to_wait);
}
+static void
+sighup_handler(int x) {
+ got_sighup = 1;
+}
+
+static void
+sigchld_handler(int x) {
+ got_sigchld = 1;
+}
-#ifdef USE_SIGCHLD
static void
-sigchld_handler(x) {
- int save_errno = errno;
- WAIT_T waiter;
- PID_T pid;
+sigchld_reaper() {
+ WAIT_T waiter;
+ PID_T pid;
- for (;;) {
-#ifdef POSIX
+ do {
pid = waitpid(-1, &waiter, WNOHANG);
-#else
- pid = wait3(&waiter, WNOHANG, (struct rusage *)0);
-#endif
- /* XXX unsafe */
switch (pid) {
case -1:
Debug(DPROC,
- ("[%d] sigchld...no children\n", getpid()))
- errno = save_errno;
- return;
+ ("[%ld] sigchld...no children\n",
+ (long)getpid()))
+ break;
case 0:
Debug(DPROC,
- ("[%d] sigchld...no dead kids\n", getpid()))
- errno = save_errno;
- return;
+ ("[%ld] sigchld...no dead kids\n",
+ (long)getpid()))
+ break;
default:
Debug(DPROC,
- ("[%d] sigchld...pid #%d died, stat=%d\n",
- getpid(), pid, WEXITSTATUS(waiter)))
+ ("[%ld] sigchld...pid #%ld died, stat=%d\n",
+ (long)getpid(), (long)pid, WEXITSTATUS(waiter)))
}
- }
- errno = save_errno;
-}
-#endif /*USE_SIGCHLD*/
-
-
-static void
-sighup_handler(x) {
- int save_errno = errno;
-
- /* XXX unsafe */
- log_close();
- errno = save_errno;
+ } while (pid > 0);
}
-
static void
-parse_args(argc, argv)
- int argc;
- char *argv[];
-{
- int argch;
+parse_args(int argc, char *argv[]) {
+ int argch;
while (-1 != (argch = getopt(argc, argv, "x:"))) {
switch (argch) {
diff --git a/usr.sbin/cron/cron.h b/usr.sbin/cron/cron.h
index 144c33328e2..bc7b5659bf1 100644
--- a/usr.sbin/cron/cron.h
+++ b/usr.sbin/cron/cron.h
@@ -1,292 +1,36 @@
+/* $OpenBSD: cron.h,v 1.6 2001/02/18 19:48:31 millert Exp $ */
+
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
/* cron.h - header for vixie's cron
*
- * $Id: cron.h,v 1.5 2001/02/12 18:46:54 millert Exp $
- *
* vix 14nov88 [rest of log is in RCS]
* vix 14jan87 [0 or 7 can be sunday; thanks, mwm@berkeley]
* vix 30dec86 [written]
*/
-/* reorder these #include's at your peril */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include "compat.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <bitstring.h>
-#include <pwd.h>
-#include <sys/wait.h>
-
-#include "pathnames.h"
#include "config.h"
#include "externs.h"
-
- /* these are really immutable, and are
- * defined for symbolic convenience only
- * TRUE, FALSE, and ERR must be distinct
- * ERR must be < OK.
- */
-#define TRUE 1
-#define FALSE 0
- /* system calls return this on success */
-#define OK 0
- /* or this on error */
-#define ERR (-1)
-
- /* turn this on to get '-x' code */
-#ifndef DEBUGGING
-#define DEBUGGING FALSE
-#endif
-
-#define READ_PIPE 0 /* which end of a pipe pair do you read? */
-#define WRITE_PIPE 1 /* or write to? */
-#define STDIN 0 /* what is stdin's file descriptor? */
-#define STDOUT 1 /* stdout's? */
-#define STDERR 2 /* stderr's? */
-#define ERROR_EXIT 1 /* exit() with this will scare the shell */
-#define OK_EXIT 0 /* exit() with this is considered 'normal' */
-#define MAX_FNAME 100 /* max length of internally generated fn */
-#define MAX_COMMAND 1000 /* max length of internally generated cmd */
-#define MAX_ENVSTR 1000 /* max length of envvar=value\0 strings */
-#define MAX_TEMPSTR 100 /* obvious */
-#define MAX_UNAME (_PW_NAME_LEN+1) /* max length of username */
-#define ROOT_UID 0 /* don't change this, it really must be root */
-#define ROOT_USER "root" /* ditto */
-
- /* NOTE: these correspond to DebugFlagNames,
- * defined below.
- */
-#define DEXT 0x0001 /* extend flag for other debug masks */
-#define DSCH 0x0002 /* scheduling debug mask */
-#define DPROC 0x0004 /* process control debug mask */
-#define DPARS 0x0008 /* parsing debug mask */
-#define DLOAD 0x0010 /* database loading debug mask */
-#define DMISC 0x0020 /* misc debug mask */
-#define DTEST 0x0040 /* test mode: don't execute any commands */
-#define DBIT 0x0080 /* bit twiddling shown (long) */
-
-#define CRON_TAB(u) "%s/%s", SPOOL_DIR, u
-#define REG register
-#define PPC_NULL ((char **)NULL)
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#define Skip_Blanks(c, f) \
- while (c == '\t' || c == ' ') \
- c = get_char(f);
-
-#define Skip_Nonblanks(c, f) \
- while (c!='\t' && c!=' ' && c!='\n' && c != EOF) \
- c = get_char(f);
-
-#define Skip_Line(c, f) \
- do {c = get_char(f);} while (c != '\n' && c != EOF);
-
-#if DEBUGGING
-# define Debug(mask, message) \
- if ( (DebugFlags & (mask) ) == (mask) ) \
- printf message;
-#else /* !DEBUGGING */
-# define Debug(mask, message) \
- ;
-#endif /* DEBUGGING */
-
-#define MkLower(ch) (isupper(ch) ? tolower(ch) : ch)
-#define MkUpper(ch) (islower(ch) ? toupper(ch) : ch)
-#define Set_LineNum(ln) {Debug(DPARS|DEXT,("linenum=%d\n",ln)); \
- LineNumber = ln; \
- }
-
-typedef int time_min;
-
-#define SECONDS_PER_MINUTE 60
-
-#define FIRST_MINUTE 0
-#define LAST_MINUTE 59
-#define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1)
-
-#define FIRST_HOUR 0
-#define LAST_HOUR 23
-#define HOUR_COUNT (LAST_HOUR - FIRST_HOUR + 1)
-
-#define FIRST_DOM 1
-#define LAST_DOM 31
-#define DOM_COUNT (LAST_DOM - FIRST_DOM + 1)
-
-#define FIRST_MONTH 1
-#define LAST_MONTH 12
-#define MONTH_COUNT (LAST_MONTH - FIRST_MONTH + 1)
-
-/* note on DOW: 0 and 7 are both Sunday, for compatibility reasons. */
-#define FIRST_DOW 0
-#define LAST_DOW 7
-#define DOW_COUNT (LAST_DOW - FIRST_DOW + 1)
-
- /* each user's crontab will be held as a list of
- * the following structure.
- *
- * These are the cron commands.
- */
-
-typedef struct _entry {
- struct _entry *next;
- uid_t uid;
- gid_t gid;
- char **envp;
- char *cmd;
- bitstr_t bit_decl(minute, MINUTE_COUNT);
- bitstr_t bit_decl(hour, HOUR_COUNT);
- bitstr_t bit_decl(dom, DOM_COUNT);
- bitstr_t bit_decl(month, MONTH_COUNT);
- bitstr_t bit_decl(dow, DOW_COUNT);
- int flags;
-#define DOM_STAR 0x01
-#define DOW_STAR 0x02
-#define WHEN_REBOOT 0x04
-#define MIN_STAR 0x08
-#define HR_STAR 0x10
-} entry;
-
- /* the crontab database will be a list of the
- * following structure, one element per user
- * plus one for the system.
- *
- * These are the crontabs.
- */
-
-typedef struct _user {
- struct _user *next, *prev; /* links */
- char *name;
- time_t mtime; /* last modtime of crontab */
- entry *crontab; /* this person's crontab */
-} user;
-
-typedef struct _cron_db {
- user *head, *tail; /* links */
- time_t mtime; /* last modtime on spooldir */
-} cron_db;
-
-
-void set_cron_uid __P((void)),
- set_cron_cwd __P((void)),
- load_database __P((cron_db *)),
- open_logfile __P((void)),
- sigpipe_func __P((void)),
- job_add __P((entry *, user *)),
- do_command __P((entry *, user *)),
- link_user __P((cron_db *, user *)),
- unlink_user __P((cron_db *, user *)),
- free_user __P((user *)),
- env_free __P((char **)),
- unget_char __P((int, FILE *)),
- free_entry __P((entry *)),
- acquire_daemonlock __P((int)),
- skip_comments __P((FILE *)),
- log_it __P((char *, int, char *, char *)),
- log_close __P((void));
-
-int job_runqueue __P((void)),
- set_debug_flags __P((char *)),
- get_char __P((FILE *)),
- get_string __P((char *, int, FILE *, char *)),
- swap_uids __P((void)),
- swap_uids_back __P((void)),
- load_env __P((char *, FILE *)),
- cron_pclose __P((FILE *)),
- strcmp_until __P((char *, char *, int)),
- allowed __P((char *)),
- strdtb __P((char *));
-
-char *env_get __P((char *, char **)),
- *arpadate __P((time_t *)),
- *mkprints __P((unsigned char *, unsigned int)),
- *first_word __P((char *, char *)),
- **env_init __P((void)),
- **env_copy __P((char **)),
- **env_set __P((char **, char *));
-
-user *load_user __P((int, struct passwd *, char *)),
- *find_user __P((cron_db *, char *));
-
-entry *load_entry __P((FILE *, void (*)(),
- struct passwd *, char **));
-
-FILE *cron_popen __P((char *, char *, entry *));
-
-
- /* in the C tradition, we only create
- * variables for the main program, just
- * extern them elsewhere.
- */
-
-#ifdef MAIN_PROGRAM
-# if !defined(LINT) && !defined(lint)
-char *copyright[] = {
- "@(#) Copyright 1988,1989,1990,1993,1994 by Paul Vixie",
- "@(#) All rights reserved"
- };
-# endif
-
-char *MonthNames[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- NULL
- };
-
-char *DowNames[] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
- NULL
- };
-
-char *ProgramName;
-int LineNumber;
-time_t StartTime;
-time_min timeRunning;
-time_min virtualTime;
-time_min clockTime;
-
-# if DEBUGGING
-int DebugFlags;
-char *DebugFlagNames[] = { /* sync with #defines */
- "ext", "sch", "proc", "pars", "load", "misc", "test", "bit",
- NULL /* NULL must be last element */
- };
-# else
-#define DebugFlags 0
-# endif /* DEBUGGING */
-#else /*MAIN_PROGRAM*/
-extern char *copyright[],
- *MonthNames[],
- *DowNames[],
- *ProgramName;
-extern int LineNumber;
-extern time_t StartTime;
-extern time_min timeRunning;
-extern time_min virtualTime;
-extern time_min clockTime;
-# if DEBUGGING
-extern int DebugFlags;
-extern char *DebugFlagNames[];
-# endif /* DEBUGGING */
-#endif /*MAIN_PROGRAM*/
+#include "pathnames.h"
+#include "macros.h"
+#include "structs.h"
+#include "funcs.h"
+#include "globals.h"
diff --git a/usr.sbin/cron/crontab.1 b/usr.sbin/cron/crontab.1
index a838ac7e426..9ab9b5d1b4b 100644
--- a/usr.sbin/cron/crontab.1
+++ b/usr.sbin/cron/crontab.1
@@ -1,21 +1,21 @@
.\"/* Copyright 1988,1990,1993 by Paul Vixie
.\" * All rights reserved
-.\" *
-.\" * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
-.\" * warrantee of any kind, express or implied, is included with this
-.\" * software; use at your own risk, responsibility for damages (if any) to
-.\" * anyone resulting from the use of this software rests entirely with the
-.\" * user.
-.\" *
-.\" * 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 <paul@vix.com> uunet!decwrl!vixie!paul
.\" */
.\"
-.\" $Id: crontab.1,v 1.7 2000/03/23 21:39:57 aaron Exp $
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+.\" ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+.\" CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\"
+.\" $OpenBSD: crontab.1,v 1.8 2001/02/18 19:48:32 millert Exp $
.\"
.Dd June 8, 1999
.Dt CRONTAB 1
diff --git a/usr.sbin/cron/crontab.5 b/usr.sbin/cron/crontab.5
index 94ddaf40bbe..27f7b05ff39 100644
--- a/usr.sbin/cron/crontab.5
+++ b/usr.sbin/cron/crontab.5
@@ -1,21 +1,21 @@
-.\" $NetBSD: crontab.5,v 1.5 1997/07/13 11:01:16 mouse Exp $
+.\"/* Copyright 1988,1990,1993,1994 by Paul Vixie
.\" * All rights reserved
-.\" *
-.\" * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
-.\" * warrantee of any kind, express or implied, is included with this
-.\" * software; use at your own risk, responsibility for damages (if any) to
-.\" * anyone resulting from the use of this software rests entirely with the
-.\" * user.
-.\" *
-.\" * 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 <paul@vix.com> uunet!decwrl!vixie!paul
.\" */
.\"
-.\" $Id: crontab.5,v 1.11 2000/04/15 11:53:29 aaron Exp $
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+.\" ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+.\" CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\"
+.\" $OpenBSD: crontab.5,v 1.12 2001/02/18 19:48:32 millert Exp $
.\"
.Dd June 8, 1999
.Dt CRONTAB 5
diff --git a/usr.sbin/cron/crontab.c b/usr.sbin/cron/crontab.c
index 407cfa1eb6e..2846971c657 100644
--- a/usr.sbin/cron/crontab.c
+++ b/usr.sbin/cron/crontab.c
@@ -1,22 +1,27 @@
+/* $OpenBSD: crontab.c,v 1.19 2001/02/18 19:48:32 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: crontab.c,v 1.18 2000/08/21 21:08:55 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: crontab.c,v 1.19 2001/02/18 19:48:32 millert Exp $";
#endif
/* crontab - install and manage per-user crontab files
@@ -24,58 +29,39 @@ static char rcsid[] = "$Id: crontab.c,v 1.18 2000/08/21 21:08:55 deraadt Exp $";
* vix 26jan87 [original]
*/
-
#define MAIN_PROGRAM
-
#include "cron.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#ifdef USE_UTIMES
-# include <sys/time.h>
-#else
-# include <time.h>
-# include <utime.h>
-#endif
-#if defined(POSIX)
-# include <locale.h>
-#endif
-
#define NHEADER_LINES 3
-
enum opt_t { opt_unknown, opt_list, opt_delete, opt_edit, opt_replace };
#if DEBUGGING
static char *Options[] = { "???", "list", "delete", "edit", "replace" };
+static char *getoptargs = "u:lerx:";
+#else
+static char *getoptargs = "u:ler";
#endif
-
static PID_T Pid;
static char User[MAX_UNAME], RealUser[MAX_UNAME];
-static char Filename[MAX_FNAME], *TempFilename;
+static char Filename[MAX_FNAME], TempFilename[MAX_FNAME];
static FILE *NewCrontab;
static int CheckErrorCount;
static enum opt_t Option;
static struct passwd *pw;
-static void list_cmd __P((void)),
- delete_cmd __P((void)),
- edit_cmd __P((void)),
- poke_daemon __P((void)),
- check_error __P((char *)),
- parse_args __P((int c, char *v[]));
-static int replace_cmd __P((void));
+static void list_cmd(void),
+ delete_cmd(void),
+ edit_cmd(void),
+ poke_daemon(void),
+ check_error(const char *),
+ parse_args(int c, char *v[]);
+static int replace_cmd(void);
static void clean_turds __P((int));
-
static void
-usage(msg)
- char *msg;
-{
+usage(const char *msg) {
fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg);
fprintf(stderr, "usage:\t%s [-u user] file\n", ProgramName);
fprintf(stderr, "\t%s [-u user] [ -e | -l | -r ]\n", ProgramName);
@@ -86,20 +72,14 @@ usage(msg)
exit(ERROR_EXIT);
}
-
int
-main(argc, argv)
- int argc;
- char *argv[];
-{
+main(int argc, char *argv[]) {
int exitstatus;
Pid = getpid();
ProgramName = argv[0];
-#if defined(POSIX)
setlocale(LC_ALL, "");
-#endif
#if defined(BSD)
setlinebuf(stderr);
@@ -117,32 +97,29 @@ main(argc, argv)
}
exitstatus = OK_EXIT;
switch (Option) {
- case opt_list: list_cmd();
- break;
- case opt_delete: delete_cmd();
- break;
- case opt_edit: edit_cmd();
- break;
- case opt_replace: if (replace_cmd() < 0)
- exitstatus = ERROR_EXIT;
- break;
+ case opt_list:
+ list_cmd();
+ break;
+ case opt_delete:
+ delete_cmd();
+ break;
+ case opt_edit:
+ edit_cmd();
+ break;
+ case opt_replace:
+ if (replace_cmd() < 0)
+ exitstatus = ERROR_EXIT;
+ break;
+ default:
+ abort();
}
exit(0);
/*NOTREACHED*/
}
-
-#if DEBUGGING
-char *getoptarg = "u:lerx:";
-#else
-char *getoptarg = "u:ler";
-#endif
static void
-parse_args(argc, argv)
- int argc;
- char *argv[];
-{
- int argch;
+parse_args(int argc, char *argv[]) {
+ int argch;
if (!(pw = getpwuid(getuid()))) {
fprintf(stderr, "%s: your UID isn't in the passwd file.\n",
@@ -150,36 +127,34 @@ parse_args(argc, argv)
fprintf(stderr, "bailing out.\n");
exit(ERROR_EXIT);
}
- (void) strncpy(User, pw->pw_name, (sizeof User)-1);
- User[(sizeof User)-1] = '\0';
+ if (strlen(pw->pw_name) >= sizeof User) {
+ fprintf(stderr, "username too long\n");
+ exit(ERROR_EXIT);
+ }
+ strcpy(User, pw->pw_name);
strcpy(RealUser, User);
Filename[0] = '\0';
Option = opt_unknown;
-
- while (-1 != (argch = getopt(argc, argv, getoptarg))) {
+ while (-1 != (argch = getopt(argc, argv, getoptargs))) {
switch (argch) {
-#if DEBUGGING
case 'x':
if (!set_debug_flags(optarg))
usage("bad debug option");
- usage("unrecognized option");
break;
-#endif
case 'u':
- if (getuid() != ROOT_UID)
- {
+ if (MY_UID(pw) != ROOT_UID) {
fprintf(stderr,
"must be privileged to use -u\n");
exit(ERROR_EXIT);
}
- if (!(pw = getpwnam(optarg)))
- {
+ if (!(pw = getpwnam(optarg))) {
fprintf(stderr, "%s: user `%s' unknown\n",
ProgramName, optarg);
exit(ERROR_EXIT);
}
- (void) strncpy(User, pw->pw_name, (sizeof User)-1);
- User[(sizeof User)-1] = '\0';
+ if (strlen(optarg) >= sizeof User)
+ usage("username too long");
+ (void) strcpy(User, optarg);
break;
case 'l':
if (Option != opt_unknown)
@@ -204,18 +179,16 @@ parse_args(argc, argv)
endpwent();
if (Option != opt_unknown) {
- if (argv[optind] != NULL) {
+ if (argv[optind] != NULL)
usage("no arguments permitted after this option");
- }
} else {
if (argv[optind] != NULL) {
Option = opt_replace;
- (void) strncpy (Filename, argv[optind], (sizeof Filename)-1);
- Filename[(sizeof Filename)-1] = '\0';
-
- } else {
+ if (strlen(argv[optind]) >= sizeof Filename)
+ usage("filename too long");
+ (void) strcpy (Filename, argv[optind]);
+ } else
usage("file name must be specified for replace");
- }
}
if (Option == opt_replace) {
@@ -223,9 +196,9 @@ parse_args(argc, argv)
* chdir(2) into /var/cron before we get around to
* reading the file.
*/
- if (!strcmp(Filename, "-")) {
+ if (!strcmp(Filename, "-"))
NewCrontab = stdin;
- } else {
+ else {
/* relinquish the setuid status of the binary during
* the open, lest nonroot users read files they should
* not be able to read. we can't use access() here
@@ -255,13 +228,16 @@ parse_args(argc, argv)
static void
-list_cmd() {
- char n[MAX_FNAME];
- FILE *f;
- int ch;
+list_cmd(void) {
+ char n[MAX_FNAME];
+ FILE *f;
+ int ch;
log_it(RealUser, Pid, "LIST", User);
- (void) snprintf(n, sizeof n, CRON_TAB(User));
+ if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) {
+ fprintf(stderr, "path too long\n");
+ exit(ERROR_EXIT);
+ }
if (!(f = fopen(n, "r"))) {
if (errno == ENOENT)
fprintf(stderr, "no crontab for %s\n", User);
@@ -278,14 +254,16 @@ list_cmd() {
fclose(f);
}
-
static void
-delete_cmd() {
- char n[MAX_FNAME];
+delete_cmd(void) {
+ char n[MAX_FNAME];
log_it(RealUser, Pid, "DELETE", User);
- (void) snprintf(n, sizeof n, CRON_TAB(User));
- if (unlink(n)) {
+ if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) {
+ fprintf(stderr, "path too long\n");
+ exit(ERROR_EXIT);
+ }
+ if (unlink(n) != 0) {
if (errno == ENOENT)
fprintf(stderr, "no crontab for %s\n", User);
else
@@ -295,29 +273,28 @@ delete_cmd() {
poke_daemon();
}
-
static void
-check_error(msg)
- char *msg;
-{
+check_error(const char *msg) {
CheckErrorCount++;
fprintf(stderr, "\"%s\":%d: %s\n", Filename, LineNumber-1, msg);
}
-
static void
-edit_cmd() {
- char n[MAX_FNAME], q[MAX_TEMPSTR], *editor;
- FILE *f;
- int ch, t, x;
- struct stat statbuf;
- time_t mtime;
- off_t size;
- WAIT_T waiter;
- PID_T pid, xpid;
+edit_cmd(void) {
+ char n[MAX_FNAME], q[MAX_TEMPSTR], *editor;
+ FILE *f;
+ int ch, t, x;
+ struct stat statbuf;
+ time_t mtime;
+ off_t size;
+ WAIT_T waiter;
+ PID_T pid, xpid;
log_it(RealUser, Pid, "BEGIN EDIT", User);
- (void) snprintf(n, sizeof n, CRON_TAB(User));
+ if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) {
+ fprintf(stderr, "path too long\n");
+ exit(ERROR_EXIT);
+ }
if (!(f = fopen(n, "r"))) {
if (errno != ENOENT) {
perror(n);
@@ -336,19 +313,26 @@ edit_cmd() {
(void)signal(SIGINT, SIG_IGN);
(void)signal(SIGQUIT, SIG_IGN);
- (void) snprintf(Filename, sizeof Filename, "/tmp/crontab.XXXXXXXXXX");
- if ((t = mkstemp(Filename)) == -1) {
+ if (!glue_strings(Filename, sizeof Filename, _PATH_TMP,
+ "crontab.XXXXXXXXXX", '/')) {
+ fprintf(stderr, "path too long\n");
+ goto fatal;
+ }
+ if (-1 == (t = mkstemp(Filename))) {
perror(Filename);
goto fatal;
}
#ifdef HAS_FCHOWN
- if (fchown(t, getuid(), getgid()) < 0) {
-#else
- if (chown(Filename, getuid(), getgid()) < 0) {
-#endif
+ if (fchown(t, MY_UID(pw), MY_GID(pw)) < 0) {
perror("fchown");
goto fatal;
}
+#else
+ if (chown(Filename, MY_UID(pw), MY_GID(pw)) < 0) {
+ perror("chown");
+ goto fatal;
+ }
+#endif
if (!(NewCrontab = fdopen(t, "r+"))) {
perror("fdopen");
goto fatal;
@@ -388,7 +372,8 @@ edit_cmd() {
if (ferror(NewCrontab)) {
fprintf(stderr, "%s: error while writing new crontab to %s\n",
ProgramName, Filename);
- fatal: unlink(Filename);
+ fatal:
+ unlink(Filename);
exit(ERROR_EXIT);
}
if (fstat(t, &statbuf) < 0) {
@@ -398,9 +383,8 @@ edit_cmd() {
mtime = statbuf.st_mtime;
size = statbuf.st_size;
- if ((!(editor = getenv("VISUAL")))
- && (!(editor = getenv("EDITOR")))
- ) {
+ if (((editor = getenv("VISUAL")) == NULL || *editor == '\0') &&
+ ((editor = getenv("EDITOR")) == NULL || *editor == '\0')) {
editor = EDITOR;
}
@@ -418,20 +402,23 @@ edit_cmd() {
goto fatal;
case 0:
/* child */
- if (setuid(getuid()) < 0) {
+ if (setgid(MY_GID(pw)) < 0) {
+ perror("setgid(getgid())");
+ exit(ERROR_EXIT);
+ }
+ if (setuid(MY_UID(pw)) < 0) {
perror("setuid(getuid())");
exit(ERROR_EXIT);
}
- if (chdir("/tmp") < 0) {
- perror("chdir(\"/tmp\")");
+ if (chdir(_PATH_TMP) < 0) {
+ perror(_PATH_TMP);
exit(ERROR_EXIT);
}
- if (strlen(editor) + strlen(Filename) + 2 >= sizeof(q)) {
- fprintf(stderr, "%s: editor or filename too long\n",
- ProgramName);
+ if (!glue_strings(q, sizeof q, editor, Filename, ' ')) {
+ fprintf(stderr, "%s: editor command line too long\n",
+ ProgramName);
exit(ERROR_EXIT);
}
- snprintf(q, sizeof q, "%s %s", editor, Filename);
execlp(_PATH_BSHELL, _PATH_BSHELL, "-c", q, NULL);
perror(editor);
exit(ERROR_EXIT);
@@ -442,14 +429,14 @@ edit_cmd() {
}
/* parent */
- while (1) {
+ for (;;) {
xpid = waitpid(pid, &waiter, WUNTRACED);
if (xpid == -1) {
- fprintf(stderr, "%s: waitpid() failed waiting for PID %d from \"%s\": %s\n",
- ProgramName, pid, editor, strerror(errno));
+ fprintf(stderr, "%s: waitpid() failed waiting for PID %ld from \"%s\": %s\n",
+ ProgramName, (long)pid, editor, strerror(errno));
} else if (xpid != pid) {
- fprintf(stderr, "%s: wrong PID (%d != %d) from \"%s\"\n",
- ProgramName, xpid, pid, editor);
+ fprintf(stderr, "%s: wrong PID (%ld != %ld) from \"%s\"\n",
+ ProgramName, (long)xpid, (long)pid, editor);
goto fatal;
} else if (WIFSTOPPED(waiter)) {
raise(WSTOPSIG(waiter));
@@ -505,7 +492,7 @@ edit_cmd() {
goto done;
default:
fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n",
- ProgramName);
+ ProgramName);
goto fatal;
}
remove:
@@ -513,40 +500,40 @@ edit_cmd() {
done:
log_it(RealUser, Pid, "END EDIT", User);
}
-
+
/* returns 0 on success
* -1 on syntax error
* -2 on install error
*/
static int
-replace_cmd() {
- char n[MAX_FNAME], envstr[MAX_ENVSTR];
- FILE *tmp;
- int ch, eof, fd;
- int error = 0;
- entry *e;
- time_t now = time(NULL);
- char **envp = env_init();
+replace_cmd(void) {
+ char n[MAX_FNAME], envstr[MAX_ENVSTR];
+ FILE *tmp;
+ int ch, eof, fd;
+ int error = 0;
+ entry *e;
+ time_t now = time(NULL);
+ char **envp = env_init();
+ struct stat sb;
if (envp == NULL) {
fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
return (-2);
}
-
- TempFilename = strdup(__CONCAT(SPOOL_DIR,"/tmp.XXXXXXXXXX"));
- if (TempFilename == NULL) {
- fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
+ if (!glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR,
+ "tmp.XXXXXXXXXX", '/')) {
+ TempFilename[0] = '\0';
+ fprintf(stderr, "path too long\n");
return (-2);
}
if ((fd = mkstemp(TempFilename)) == -1 || !(tmp = fdopen(fd, "w+"))) {
perror(TempFilename);
if (fd != -1) {
- fprintf(stderr, "%s: Cannot allocate memory.\n",
- ProgramName);
close(fd);
unlink(TempFilename);
}
+ TempFilename[0] = '\0';
return (-2);
}
@@ -568,7 +555,7 @@ replace_cmd() {
Set_LineNum(1)
while (EOF != (ch = get_char(NewCrontab)))
putc(ch, tmp);
- ftruncate(fileno(tmp), ftell(tmp));
+ ftruncate(fileno(tmp), ftell(tmp)); /* XXX redundant with "w+"? */
fflush(tmp); rewind(tmp);
if (ferror(tmp)) {
@@ -610,29 +597,40 @@ replace_cmd() {
goto done;
}
+ if (fstat(fileno(tmp), &sb))
+ sb.st_gid = -1;
+
#ifdef HAS_FCHOWN
- if (fchown(fileno(tmp), ROOT_UID, -1) < OK)
+ if (fchown(fileno(tmp), ROOT_UID, sb.st_gid) < OK) {
+ perror("fchown");
+ fclose(tmp);
+ error = -2;
+ goto done;
+ }
#else
- if (chown(TempFilename, ROOT_UID, -1) < OK)
-#endif
- {
+ if (chown(TempFilename, ROOT_UID, sb.st_gid) < OK) {
perror("chown");
fclose(tmp);
error = -2;
goto done;
}
+#endif
#ifdef HAS_FCHMOD
- if (fchmod(fileno(tmp), 0600) < OK)
+ if (fchmod(fileno(tmp), 0600) < OK) {
+ perror("fchmod");
+ fclose(tmp);
+ error = -2;
+ goto done;
+ }
#else
- if (chmod(TempFilename, 0600) < OK)
-#endif
- {
- perror("chown");
+ if (chmod(TempFilename, 0600) < OK) {
+ perror("chmod");
fclose(tmp);
error = -2;
goto done;
}
+#endif
if (fclose(tmp) == EOF) {
perror("fclose");
@@ -640,15 +638,19 @@ replace_cmd() {
goto done;
}
- if (snprintf(n, sizeof n, CRON_TAB(User)) >= sizeof n ||
- rename(TempFilename, n)) {
+ if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) {
+ fprintf(stderr, "path too long\n");
+ error = -2;
+ goto done;
+ }
+ if (rename(TempFilename, n)) {
fprintf(stderr, "%s: error renaming %s to %s\n",
ProgramName, TempFilename, n);
perror("rename");
error = -2;
goto done;
}
- TempFilename = NULL;
+ TempFilename[0] = '\0';
log_it(RealUser, Pid, "REPLACE", User);
poke_daemon();
@@ -657,45 +659,30 @@ done:
(void) signal(SIGHUP, SIG_DFL);
(void) signal(SIGINT, SIG_DFL);
(void) signal(SIGQUIT, SIG_DFL);
- if (TempFilename) {
+ if (TempFilename[0]) {
(void) unlink(TempFilename);
- free(TempFilename);
+ TempFilename[0] = '\0';
}
return (error);
}
-
static void
poke_daemon() {
-#ifdef USE_UTIMES
- struct timeval tvs[2];
- struct timezone tz;
-
- (void) gettimeofday(&tvs[0], &tz);
- tvs[1] = tvs[0];
- if (utimes(SPOOL_DIR, tvs) < OK) {
- fprintf(stderr, "crontab: can't update mtime on spooldir\n");
- perror(SPOOL_DIR);
- return;
- }
-#else
if (utime(SPOOL_DIR, NULL) < OK) {
fprintf(stderr, "crontab: can't update mtime on spooldir\n");
perror(SPOOL_DIR);
return;
}
-#endif /*USE_UTIMES*/
}
-
static void
-clean_turds(sig)
- int sig;
+clean_turds(signo)
+ int signo;
{
if (TempFilename[0])
(void) unlink(TempFilename);
- if (sig) {
- (void) signal(sig, SIG_DFL);
- (void) kill(getpid(), sig);
+ if (signo) {
+ (void) signal(signo, SIG_DFL);
+ (void) raise(signo);
}
}
diff --git a/usr.sbin/cron/database.c b/usr.sbin/cron/database.c
index a60c16b4b9d..7fec60661c5 100644
--- a/usr.sbin/cron/database.c
+++ b/usr.sbin/cron/database.c
@@ -1,54 +1,49 @@
+/* $OpenBSD: database.c,v 1.5 2001/02/18 19:48:33 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: database.c,v 1.4 2000/08/21 21:08:56 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: database.c,v 1.5 2001/02/18 19:48:33 millert Exp $";
#endif
/* vix 26jan87 [RCS has the log]
*/
-
#include "cron.h"
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-
-#define TMAX(a,b) ((a)>(b)?(a):(b))
#define HASH(a,b) ((a)+(b))
-static void process_crontab __P((char *, char *, char *,
- struct stat *,
- cron_db *, cron_db *));
-
+static void process_crontab(const char *, const char *,
+ const char *, struct stat *,
+ cron_db *, cron_db *);
void
-load_database(old_db)
- cron_db *old_db;
-{
- DIR *dir;
- struct stat statbuf;
- struct stat syscron_stat;
- DIR_T *dp;
- cron_db new_db;
- user *u, *nu;
+load_database(cron_db *old_db) {
+ struct stat statbuf, syscron_stat;
+ cron_db new_db;
+ DIR_T *dp;
+ DIR *dir;
+ user *u, *nu;
- Debug(DLOAD, ("[%d] load_database()\n", getpid()))
+ Debug(DLOAD, ("[%ld] load_database()\n", (long)getpid()))
/* before we start loading any data, do a stat on SPOOL_DIR
* so that if anything changes as of this moment (i.e., before we've
@@ -72,8 +67,8 @@ load_database(old_db)
* time this function is called.
*/
if (old_db->mtime == HASH(statbuf.st_mtime, syscron_stat.st_mtime)) {
- Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n",
- getpid()))
+ Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n",
+ (long)getpid()))
return;
}
@@ -101,8 +96,7 @@ load_database(old_db)
}
while (NULL != (dp = readdir(dir))) {
- char fname[MAXNAMLEN+1],
- tabname[MAXPATHLEN];
+ char fname[MAXNAMLEN+1], tabname[MAXNAMLEN];
/* avoid file names beginning with ".". this is good
* because we would otherwise waste two guaranteed calls
@@ -112,8 +106,13 @@ load_database(old_db)
if (dp->d_name[0] == '.')
continue;
+ if (strlen(dp->d_name) >= sizeof fname)
+ continue; /* XXX log? */
(void) strcpy(fname, dp->d_name);
- snprintf(tabname, sizeof tabname, CRON_TAB(fname));
+
+ if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR,
+ fname, '/'))
+ continue; /* XXX log? */
process_crontab(fname, fname, tabname,
&statbuf, &new_db, old_db);
@@ -142,12 +141,8 @@ load_database(old_db)
Debug(DLOAD, ("load_database is done\n"))
}
-
void
-link_user(db, u)
- cron_db *db;
- user *u;
-{
+link_user(cron_db *db, user *u) {
if (db->head == NULL)
db->head = u;
if (db->tail)
@@ -157,12 +152,8 @@ link_user(db, u)
db->tail = u;
}
-
void
-unlink_user(db, u)
- cron_db *db;
- user *u;
-{
+unlink_user(cron_db *db, user *u) {
if (u->prev == NULL)
db->head = u->next;
else
@@ -174,36 +165,25 @@ unlink_user(db, u)
u->next->prev = u->prev;
}
-
user *
-find_user(db, name)
- cron_db *db;
- char *name;
-{
- char *env_get();
- user *u;
+find_user(cron_db *db, const char *name) {
+ user *u;
for (u = db->head; u != NULL; u = u->next)
- if (!strcmp(u->name, name))
+ if (strcmp(u->name, name) == 0)
break;
- return u;
+ return (u);
}
-
static void
-process_crontab(uname, fname, tabname, statbuf, new_db, old_db)
- char *uname;
- char *fname;
- char *tabname;
- struct stat *statbuf;
- cron_db *new_db;
- cron_db *old_db;
+process_crontab(const char *uname, const char *fname, const char *tabname,
+ struct stat *statbuf, cron_db *new_db, cron_db *old_db)
{
- struct passwd *pw = NULL;
- int crontab_fd = OK - 1;
- user *u;
+ struct passwd *pw = NULL;
+ int crontab_fd = OK - 1;
+ user *u;
- if (strcmp(fname, "*system*") && !(pw = getpwnam(uname))) {
+ if (strcmp(fname, "*system*") != 0 && !(pw = getpwnam(uname))) {
/* file doesn't have a user in passwd file.
*/
log_it(fname, getpid(), "ORPHAN", "no passwd entry");
@@ -253,7 +233,7 @@ process_crontab(uname, fname, tabname, statbuf, new_db, old_db)
link_user(new_db, u);
}
-next_crontab:
+ next_crontab:
if (crontab_fd >= OK) {
Debug(DLOAD, (" [done]\n"))
close(crontab_fd);
diff --git a/usr.sbin/cron/do_command.c b/usr.sbin/cron/do_command.c
index 2e3e008e22d..120aaacd905 100644
--- a/usr.sbin/cron/do_command.c
+++ b/usr.sbin/cron/do_command.c
@@ -1,48 +1,39 @@
+/* $OpenBSD: do_command.c,v 1.10 2001/02/18 19:48:33 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: do_command.c,v 1.9 2000/08/21 21:08:56 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: do_command.c,v 1.10 2001/02/18 19:48:33 millert Exp $";
#endif
-
#include "cron.h"
-#include <sys/signal.h>
-#if defined(sequent)
-# include <sys/universe.h>
-#endif
-#if defined(SYSLOG)
-# include <syslog.h>
-#endif
-#if defined(LOGIN_CAP)
-# include <login_cap.h>
-#endif
-
-static void child_process __P((entry *, user *)),
- do_univ __P((user *));
+static void child_process(entry *, user *);
+static int safe_p(const char *, const char *);
void
-do_command(e, u)
- entry *e;
- user *u;
-{
- Debug(DPROC, ("[%d] do_command(%s, (%s,%d,%d))\n",
- getpid(), e->cmd, u->name, e->uid, e->gid))
+do_command(entry *e, user *u) {
+ Debug(DPROC, ("[%ld] do_command(%s, (%s,%ld,%ld))\n",
+ (long)getpid(), e->cmd, u->name,
+ (long)e->uid, (long)e->gid))
/* fork to become asynchronous -- parent process is done immediately,
* and continues to run the normal cron code, which means return to
@@ -53,70 +44,55 @@ do_command(e, u)
*/
switch (fork()) {
case -1:
- log_it("CRON",getpid(),"error","can't fork");
+ log_it("CRON", getpid(), "error", "can't fork");
break;
case 0:
/* child process */
acquire_daemonlock(1);
child_process(e, u);
- Debug(DPROC, ("[%d] child process done, exiting\n", getpid()))
+ Debug(DPROC, ("[%ld] child process done, exiting\n",
+ (long)getpid()))
_exit(OK_EXIT);
break;
default:
/* parent process */
break;
}
- Debug(DPROC, ("[%d] main process returning to work\n", getpid()))
+ Debug(DPROC, ("[%ld] main process returning to work\n",(long)getpid()))
}
-
static void
-child_process(e, u)
- entry *e;
- user *u;
-{
- int stdin_pipe[2], stdout_pipe[2];
- char *input_data;
- char *usernm, *mailto;
- int children = 0;
-
-#ifdef __GNUC__
- (void) &input_data; /* Avoid vfork clobbering */
- (void) &mailto;
- (void) &children;
-#endif
+child_process(entry *e, user *u) {
+ int stdin_pipe[2], stdout_pipe[2];
+ char *usernm;
+ char * volatile input_data, * volatile mailto;
+ volatile int children = 0;
- Debug(DPROC, ("[%d] child_process('%s')\n", getpid(), e->cmd))
+ Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd))
+#ifdef CAPITALIZE_FOR_PS
/* mark ourselves as different to PS command watchers by upshifting
* our program name. This has no effect on some kernels.
*/
/*local*/{
- register char *pch;
+ char *pch;
for (pch = ProgramName; *pch; pch++)
*pch = MkUpper(*pch);
}
+#endif /* CAPITALIZE_FOR_PS */
/* discover some useful and important environment settings
*/
usernm = env_get("LOGNAME", e->envp);
mailto = env_get("MAILTO", e->envp);
-#ifdef USE_SIGCHLD
/* our parent is watching for our death by catching SIGCHLD. we
* do not care to watch for our children's deaths this way -- we
- * use wait() explictly. so we have to disable the signal (which
+ * use wait() explictly. so we have to reset the signal (which
* was inherited from the parent).
*/
(void) signal(SIGCHLD, SIG_DFL);
-#else
- /* on system-V systems, we are ignoring SIGCLD. we have to stop
- * ignoring it now or the wait() in cron_pclose() won't work.
- * because of this, we have to wait() for our children here, as well.
- */
- (void) signal(SIGCLD, SIG_DFL);
-#endif /*BSD*/
/* create some pipes to talk to our future child
*/
@@ -134,12 +110,13 @@ child_process(e, u)
* If there are escaped %'s, remove the escape character.
*/
/*local*/{
- register int escaped = FALSE;
- register int ch;
- register char *p;
+ int escaped = FALSE;
+ int ch;
+ char *p;
- for (input_data = p = e->cmd; (ch = *input_data);
- input_data++, p++) {
+ for (input_data = p = e->cmd;
+ (ch = *input_data) != '\0';
+ input_data++, p++) {
if (p != input_data)
*p = ch;
if (escaped) {
@@ -164,19 +141,19 @@ child_process(e, u)
*/
switch (vfork()) {
case -1:
- log_it("CRON",getpid(),"error","can't vfork");
+ log_it("CRON", getpid(), "error", "can't vfork");
exit(ERROR_EXIT);
/*NOTREACHED*/
case 0:
- Debug(DPROC, ("[%d] grandchild process Vfork()'ed\n",
- getpid()))
+ Debug(DPROC, ("[%ld] grandchild process Vfork()'ed\n",
+ (long)getpid()))
/* write a log message. we've waited this long to do it
* because it was not until now that we knew the PID that
* the actual user command shell was going to get and the
* PID is part of the log message.
*/
- /*local*/{
+ if ((e->flags & DONT_LOG) == 0) {
char *x = mkprints((u_char *)e->cmd, strlen(e->cmd));
log_it(usernm, getpid(), "CMD", x);
@@ -214,16 +191,10 @@ child_process(e, u)
close(stdin_pipe[READ_PIPE]);
close(stdout_pipe[WRITE_PIPE]);
- /* set our login universe. Do this in the grandchild
- * so that the child can invoke /usr/lib/sendmail
- * without surprises.
- */
- do_univ(u);
-
/* set our directory, uid and gid. Set gid first, since once
* we set uid, we've lost root privledges.
*/
-# ifdef LOGIN_CAP
+#ifdef LOGIN_CAP
{
struct passwd *pwd;
char *ep, *np;
@@ -238,32 +209,38 @@ child_process(e, u)
fprintf(stderr, "setusercontext failed for %d\n", e->uid);
_exit(ERROR_EXIT);
}
+#ifdef BSD_AUTH
+ if (auth_approval(0, 0, pwd->pw_name, "cron") <= 0) {
+ fprintf(stderr, "approval failed for %d\n", e->uid);
+ _exit(ERROR_EXIT);
+ }
+#endif /* BSD_AUTH */
/* If no PATH specified in crontab file but
- * we just added on via login.conf, add it to
+ * we just added one via login.conf, add it to
* the crontab environment.
*/
if (env_get("PATH", e->envp) == NULL &&
(ep = getenv("PATH"))) {
np = malloc(strlen(ep) + 6);
if (np) {
- strcpy(np, "PATH=");
- strcat(np, ep);
- e->envp = env_set(e->envp, np);
+ strcpy(np, "PATH=");
+ strcat(np, ep);
+ e->envp = env_set(e->envp, np);
}
}
+
}
-
-# else
+#else
setgid(e->gid);
-# if defined(BSD)
initgroups(env_get("LOGNAME", e->envp), e->gid);
-# endif
setlogin(usernm);
setuid(e->uid); /* we aren't root after this... */
-# endif
+
+#endif /* LOGIN_CAP */
chdir(env_get("HOME", e->envp));
- /* exec the command.
+ /*
+ * Exec the command.
*/
{
char *shell = env_get("SHELL", e->envp);
@@ -294,7 +271,7 @@ child_process(e, u)
* the user's command.
*/
- Debug(DPROC, ("[%d] child continues, closing pipes\n", getpid()))
+ Debug(DPROC, ("[%ld] child continues, closing pipes\n",(long)getpid()))
/* close the ends of the pipe that will only be referenced in the
* grandchild process...
@@ -314,12 +291,13 @@ child_process(e, u)
*/
if (*input_data && fork() == 0) {
- register FILE *out = fdopen(stdin_pipe[WRITE_PIPE], "w");
- register int need_newline = FALSE;
- register int escaped = FALSE;
- register int ch;
+ FILE *out = fdopen(stdin_pipe[WRITE_PIPE], "w");
+ int need_newline = FALSE;
+ int escaped = FALSE;
+ int ch;
- Debug(DPROC, ("[%d] child2 sending data to grandchild\n", getpid()))
+ Debug(DPROC, ("[%ld] child2 sending data to grandchild\n",
+ (long)getpid()))
/* close the pipe we don't use, since we inherited it and
* are part of its reference count now.
@@ -355,7 +333,8 @@ child_process(e, u)
*/
fclose(out);
- Debug(DPROC, ("[%d] child2 done sending to grandchild\n", getpid()))
+ Debug(DPROC, ("[%ld] child2 done sending to grandchild\n",
+ (long)getpid()))
exit(0);
}
@@ -373,28 +352,26 @@ child_process(e, u)
* when the grandchild exits, we'll get EOF.
*/
- Debug(DPROC, ("[%d] child reading output from grandchild\n", getpid()))
+ Debug(DPROC, ("[%ld] child reading output from grandchild\n",
+ (long)getpid()))
/*local*/{
- register FILE *in = fdopen(stdout_pipe[READ_PIPE], "r");
- register int ch = getc(in);
+ FILE *in = fdopen(stdout_pipe[READ_PIPE], "r");
+ int ch = getc(in);
if (ch != EOF) {
- FILE *mail;
- register int bytes = 1;
- int status = 0;
+ FILE * volatile mail;
+ int bytes = 1;
+ int status = 0;
-#ifdef __GNUC__
- (void) &mail;
-#endif
Debug(DPROC|DEXT,
- ("[%d] got data (%x:%c) from grandchild\n",
- getpid(), ch, ch))
+ ("[%ld] got data (%x:%c) from grandchild\n",
+ (long)getpid(), ch, ch))
/* get name of recipient. this is MAILTO if set to a
* valid local username; USER otherwise.
*/
- if (mailto) {
+ if (mailto && safe_p(usernm, mailto)) {
/* MAILTO was present in the environment
*/
if (!*mailto) {
@@ -414,15 +391,18 @@ child_process(e, u)
*/
if (mailto) {
- register char **env;
- auto char mailcmd[MAX_COMMAND];
- auto char hostname[MAXHOSTNAMELEN];
-
- (void) gethostname(hostname, MAXHOSTNAMELEN);
- (void) snprintf(mailcmd, sizeof(mailcmd),
- MAILARGS, MAILCMD);
+ char **env;
+ char mailcmd[MAX_COMMAND];
+ char hostname[MAXHOSTNAMELEN];
+
+ gethostname(hostname, MAXHOSTNAMELEN);
+ if (snprintf(mailcmd, sizeof mailcmd, MAILFMT,
+ MAILARG) >= sizeof mailcmd) {
+ fprintf(stderr, "mailcmd too long\n");
+ (void) _exit(ERROR_EXIT);
+ }
if (!(mail = cron_popen(mailcmd, "w", e))) {
- perror(MAILCMD);
+ perror(mailcmd);
(void) _exit(ERROR_EXIT);
}
fprintf(mail, "From: root (Cron Daemon)\n");
@@ -430,10 +410,10 @@ child_process(e, u)
fprintf(mail, "Subject: Cron <%s@%s> %s\n",
usernm, first_word(hostname, "."),
e->cmd);
-# if defined(MAIL_DATE)
+#ifdef MAIL_DATE
fprintf(mail, "Date: %s\n",
arpadate(&StartTime));
-# endif /* MAIL_DATE */
+#endif /*MAIL_DATE*/
for (env = e->envp; *env; env++)
fprintf(mail, "X-Cron-Env: <%s>\n",
*env);
@@ -441,7 +421,7 @@ child_process(e, u)
/* this was the first char from the pipe
*/
- putc(ch, mail);
+ fputc(ch, mail);
}
/* we have to read the input pipe no matter whether
@@ -452,7 +432,7 @@ child_process(e, u)
while (EOF != (ch = getc(in))) {
bytes++;
if (mailto)
- putc(ch, mail);
+ fputc(ch, mail);
}
/* only close pipe if we opened it -- i.e., we're
@@ -460,8 +440,8 @@ child_process(e, u)
*/
if (mailto) {
- Debug(DPROC, ("[%d] closing pipe to mail\n",
- getpid()))
+ Debug(DPROC, ("[%ld] closing pipe to mail\n",
+ (long)getpid()))
/* Note: the pclose will probably see
* the termination of the grandchild
* in addition to the mail process, since
@@ -487,68 +467,47 @@ child_process(e, u)
} /*if data from grandchild*/
- Debug(DPROC, ("[%d] got EOF from grandchild\n", getpid()))
+ Debug(DPROC, ("[%ld] got EOF from grandchild\n",
+ (long)getpid()))
fclose(in); /* also closes stdout_pipe[READ_PIPE] */
}
/* wait for children to die.
*/
- for (; children > 0; children--)
- {
- WAIT_T waiter;
- PID_T pid;
+ for (; children > 0; children--) {
+ WAIT_T waiter;
+ PID_T pid;
- Debug(DPROC, ("[%d] waiting for grandchild #%d to finish\n",
- getpid(), children))
+ Debug(DPROC, ("[%ld] waiting for grandchild #%d to finish\n",
+ (long)getpid(), children))
pid = wait(&waiter);
if (pid < OK) {
- Debug(DPROC, ("[%d] no more grandchildren--mail written?\n",
- getpid()))
+ Debug(DPROC,
+ ("[%ld] no more grandchildren--mail written?\n",
+ (long)getpid()))
break;
}
- Debug(DPROC, ("[%d] grandchild #%d finished, status=%04x",
- getpid(), pid, WEXITSTATUS(waiter)))
+ Debug(DPROC, ("[%ld] grandchild #%ld finished, status=%04x",
+ (long)getpid(), (long)pid, WEXITSTATUS(waiter)))
if (WIFSIGNALED(waiter) && WCOREDUMP(waiter))
Debug(DPROC, (", dumped core"))
Debug(DPROC, ("\n"))
}
}
-
-static void
-do_univ(u)
- user *u;
-{
-#if defined(sequent)
-/* Dynix (Sequent) hack to put the user associated with
- * the passed user structure into the ATT universe if
- * necessary. We have to dig the gecos info out of
- * the user's password entry to see if the magic
- * "universe(att)" string is present.
- */
-
- struct passwd *p;
- char *s;
- int i;
-
- p = getpwuid(u->uid);
- (void) endpwent();
-
- if (p == NULL)
- return;
-
- s = p->pw_gecos;
-
- for (i = 0; i < 4; i++)
- {
- if ((s = strchr(s, ',')) == NULL)
- return;
- s++;
+static int
+safe_p(const char *usernm, const char *s) {
+ static const char safe_delim[] = "@!:%-.,"; /* conservative! */
+ const char *t;
+ int ch, first;
+
+ for (t = s, first = 1; (ch = *t++) != '\0'; first = 0) {
+ if (isascii(ch) && isprint(ch) &&
+ (isalnum(ch) || (!first && strchr(safe_delim, ch))))
+ continue;
+ log_it(usernm, getpid(), "UNSAFE", s);
+ return (FALSE);
}
- if (strcmp(s, "universe(att)"))
- return;
-
- (void) universe(U_ATT);
-#endif
+ return (TRUE);
}
diff --git a/usr.sbin/cron/entry.c b/usr.sbin/cron/entry.c
index 93a74d58e95..3b1906a84d5 100644
--- a/usr.sbin/cron/entry.c
+++ b/usr.sbin/cron/entry.c
@@ -1,22 +1,28 @@
-/* Copyright 1988,1990,1993,1994 by Paul Vixie
+/* $OpenBSD: entry.c,v 1.8 2001/02/18 19:48:33 millert Exp $ */
+/*
+ * Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: entry.c,v 1.7 2000/08/21 21:08:56 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: entry.c,v 1.8 2001/02/18 19:48:33 millert Exp $";
#endif
/* vix 26jan87 [RCS'd; rest of log is in RCS file]
@@ -31,15 +37,10 @@ static char rcsid[] = "$Id: entry.c,v 1.7 2000/08/21 21:08:56 deraadt Exp $";
typedef enum ecode {
e_none, e_minute, e_hour, e_dom, e_month, e_dow,
- e_cmd, e_timespec, e_username
+ e_cmd, e_timespec, e_username, e_option
} ecode_e;
-static char get_list __P((bitstr_t *, int, int, char *[], int, FILE *)),
- get_range __P((bitstr_t *, int, int, char *[], int, FILE *)),
- get_number __P((int *, int, char *[], int, FILE *));
-static int set_element __P((bitstr_t *, int, int, int));
-
-static char *ecodes[] =
+static const char *ecodes[] =
{
"no error",
"bad minute",
@@ -50,8 +51,13 @@ static char *ecodes[] =
"bad command",
"bad time specifier",
"bad username",
+ "bad option"
};
+static char get_list(bitstr_t *, int, int, const char *[], int, FILE *),
+ get_range(bitstr_t *, int, int, const char *[], int, FILE *),
+ get_number(int *, int, const char *[], int, FILE *);
+static int set_element(bitstr_t *, int, int, int);
void
free_entry(e)
@@ -252,7 +258,8 @@ load_entry(file, error_func, pw, envp)
ecode = e_username;
goto eof;
}
- Debug(DPARS, ("load_entry()...uid %d, gid %d\n",e->uid,e->gid))
+ Debug(DPARS, ("load_entry()...uid %ld, gid %ld\n",
+ (long)e->uid, (long)e->gid))
} else if (ch == '*') {
ecode = e_cmd;
goto eof;
@@ -269,55 +276,87 @@ load_entry(file, error_func, pw, envp)
goto eof;
}
if (!env_get("SHELL", e->envp)) {
- snprintf(envstr, sizeof envstr, "SHELL=%s", _PATH_BSHELL);
- if ((tenvp = env_set(e->envp, envstr))) {
- e->envp = tenvp;
- } else {
- ecode = e_none;
- goto eof;
- }
+ if (glue_strings(envstr, sizeof envstr, "SHELL",
+ _PATH_BSHELL, '=')) {
+ if ((tenvp = env_set(e->envp, envstr))) {
+ e->envp = tenvp;
+ } else {
+ ecode = e_none;
+ goto eof;
+ }
+ } else
+ log_it("CRON", getpid(), "error", "can't set SHELL");
}
if (!env_get("HOME", e->envp)) {
- snprintf(envstr, sizeof envstr, "HOME=%s", pw->pw_dir);
+ if (glue_strings(envstr, sizeof envstr, "HOME",
+ pw->pw_dir, '=')) {
+ if ((tenvp = env_set(e->envp, envstr))) {
+ e->envp = tenvp;
+ } else {
+ ecode = e_none;
+ goto eof;
+ }
+ } else
+ log_it("CRON", getpid(), "error", "can't set HOME");
+ }
+#ifdef LOGIN_CAP
+ if (!env_get("PATH", e->envp)) {
+ if (glue_strings(envstr, sizeof envstr, "PATH",
+ _PATH_DEFPATH, '=')) {
+ if ((tenvp = env_set(e->envp, envstr))) {
+ e->envp = tenvp;
+ } else {
+ ecode = e_none;
+ goto eof;
+ }
+ } else
+ log_it("CRON", getpid(), "error", "can't set PATH");
+ }
+#endif /* LOGIN_CAP */
+ if (glue_strings(envstr, sizeof envstr, "LOGNAME",
+ pw->pw_name, '=')) {
if ((tenvp = env_set(e->envp, envstr))) {
e->envp = tenvp;
} else {
ecode = e_none;
goto eof;
}
- }
- if (!env_get("PATH", e->envp)) {
- snprintf(envstr, sizeof envstr, "PATH=%s", _PATH_DEFPATH);
+ } else
+ log_it("CRON", getpid(), "error", "can't set LOGNAME");
+#if defined(BSD)
+ if (glue_strings(envstr, sizeof envstr, "USER",
+ pw->pw_name, '=')) {
if ((tenvp = env_set(e->envp, envstr))) {
e->envp = tenvp;
} else {
ecode = e_none;
goto eof;
}
- }
- snprintf(envstr, sizeof envstr, "%s=%s", "LOGNAME", pw->pw_name);
- if ((tenvp = env_set(e->envp, envstr))) {
- e->envp = tenvp;
- } else {
- ecode = e_none;
- goto eof;
- }
-#if defined(BSD)
- snprintf(envstr, sizeof envstr, "%s=%s", "USER", pw->pw_name);
- if ((tenvp = env_set(e->envp, envstr))) {
- e->envp = tenvp;
- } else {
- ecode = e_none;
- goto eof;
- }
+ } else
+ log_it("CRON", getpid(), "error", "can't set USER");
#endif
Debug(DPARS, ("load_entry()...about to parse command\n"))
+ /* If the first character of the command is '-' it is a cron option.
+ */
+ while ((ch = get_char(file)) == '-') {
+ switch (ch = get_char(file)) {
+ case 'q':
+ e->flags |= DONT_LOG;
+ Skip_Nonblanks(ch, file)
+ break;
+ default:
+ ecode = e_option;
+ goto eof;
+ }
+ Skip_Blanks(ch, file)
+ }
+ unget_char(ch, file);
+
/* Everything up to the next \n or EOF is part of the command...
* too bad we don't know in advance how long it will be, since we
* need to malloc a string for it... so, we limit it to MAX_COMMAND.
- * XXX - should use realloc().
*/
ch = get_string(cmd, MAX_COMMAND, file, "\n");
@@ -359,11 +398,11 @@ static char
get_list(bits, low, high, names, ch, file)
bitstr_t *bits; /* one bit per flag, default=FALSE */
int low, high; /* bounds, impl. offset for bitstr */
- char *names[]; /* NULL or *[] of names for these elements */
+ const char *names[]; /* NULL or *[] of names for these elements */
int ch; /* current character being processed */
FILE *file; /* file being read */
{
- register int done;
+ int done;
/* we know that we point to a non-blank character here;
* must do a Skip_Blanks before we exit, so that the
@@ -406,15 +445,14 @@ static char
get_range(bits, low, high, names, ch, file)
bitstr_t *bits; /* one bit per flag, default=FALSE */
int low, high; /* bounds, impl. offset for bitstr */
- char *names[]; /* NULL or names of elements */
+ const char *names[]; /* NULL or names of elements */
int ch; /* current character being processed */
FILE *file; /* file being read */
{
/* range = number | number "-" number [ "/" number ]
*/
- register int i;
- auto int num1, num2, num3;
+ int i, num1, num2, num3;
Debug(DPARS|DEXT, ("get_range()...entering, exit won't show\n"))
@@ -489,11 +527,11 @@ get_range(bits, low, high, names, ch, file)
static char
get_number(numptr, low, names, ch, file)
- int *numptr; /* where does the result go? */
- int low; /* offset applied to result if symbolic enum used */
- char *names[]; /* symbolic names, if any, for enums */
- int ch; /* current character */
- FILE *file; /* source */
+ int *numptr; /* where does the result go? */
+ int low; /* offset applied to enum result */
+ const char *names[]; /* symbolic names, if any, for enums */
+ int ch; /* current character */
+ FILE *file; /* source */
{
char temp[MAX_TEMPSTR], *pc;
int len, i, all_digits;
diff --git a/usr.sbin/cron/env.c b/usr.sbin/cron/env.c
index a9fc3252fab..69b59f419d8 100644
--- a/usr.sbin/cron/env.c
+++ b/usr.sbin/cron/env.c
@@ -1,22 +1,27 @@
+/* $OpenBSD: env.c,v 1.8 2001/02/18 19:48:34 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: env.c,v 1.7 2000/08/21 21:08:56 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: env.c,v 1.8 2001/02/18 19:48:34 millert Exp $";
#endif
@@ -26,9 +31,9 @@ static char rcsid[] = "$Id: env.c,v 1.7 2000/08/21 21:08:56 deraadt Exp $";
char **
env_init()
{
- register char **p = (char **) malloc(sizeof(char **));
+ char **p = (char **) malloc(sizeof(char **));
- if (p)
+ if (p != NULL)
p[0] = NULL;
return (p);
}
@@ -48,27 +53,26 @@ env_free(envp)
char **
env_copy(envp)
- register char **envp;
+ char **envp;
{
- register int count, i;
- register char **p;
+ int count, i, save_errno;
+ char **p;
for (count = 0; envp[count] != NULL; count++)
;
p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */
- if (p == NULL) {
- errno = ENOMEM;
- return NULL;
+ if (p != NULL) {
+ for (i = 0; i < count; i++)
+ if ((p[i] = strdup(envp[i])) == NULL) {
+ save_errno = errno;
+ while (--i >= 0)
+ free(p[i]);
+ free(p);
+ errno = save_errno;
+ return (NULL);
+ }
+ p[count] = NULL;
}
- for (i = 0; i < count; i++)
- if ((p[i] = strdup(envp[i])) == NULL) {
- while (--i >= 0)
- (void) free(p[i]);
- free(p);
- errno = ENOMEM;
- return NULL;
- }
- p[count] = NULL;
return (p);
}
@@ -78,8 +82,8 @@ env_set(envp, envstr)
char **envp;
char *envstr;
{
- register int count, found;
- register char **p;
+ int count, found;
+ char **p, *cp;
/*
* count the number of elements, including the null pointer;
@@ -100,8 +104,7 @@ env_set(envp, envstr)
free(envp[found]);
if ((envp[found] = strdup(envstr)) == NULL) {
envp[found] = "";
- errno = ENOMEM;
- return NULL;
+ return (NULL);
}
return (envp);
}
@@ -112,16 +115,14 @@ env_set(envp, envstr)
* array.
*/
p = (char **) realloc((void *) envp,
- (unsigned) ((count+1) * sizeof(char **)));
- if (p == NULL) {
- errno = ENOMEM;
- return NULL;
- }
+ (size_t) ((count+1) * sizeof(char **)));
+ if (p == NULL)
+ return (NULL);
+ cp = strdup(envstr);
+ if (cp == NULL)
+ return(NULL);
p[count] = p[count-1];
- if ((p[count-1] = strdup(envstr)) == NULL) {
- errno = ENOMEM;
- return NULL;
- }
+ p[count-1] = cp;
return (p);
}
@@ -157,7 +158,8 @@ load_env(envstr, f)
return (FALSE);
}
- /* 2 fields from scanf; looks like an env setting
+ /*
+ * 2 fields from scanf; looks like an env setting.
*/
/*
@@ -176,8 +178,10 @@ load_env(envstr, f)
}
}
- if (strlen(name) + 1 + strlen(val) >= MAX_ENVSTR-1)
- return (FALSE);
+ /*
+ * This can't overflow because get_string() limited the size of the
+ * name and val fields. Still, it doesn't hurt...
+ */
(void) snprintf(envstr, MAX_ENVSTR, "%s=%s", name, val);
Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
return (TRUE);
@@ -186,13 +190,13 @@ load_env(envstr, f)
char *
env_get(name, envp)
- register char *name;
- register char **envp;
+ char *name;
+ char **envp;
{
- register int len = strlen(name);
- register char *p, *q;
+ int len = strlen(name);
+ char *p, *q;
- while ((p = *envp++) != NULL) {
+ while ((p = *envp++) != '\0') {
if (!(q = strchr(p, '=')))
continue;
if ((q - p) == len && !strncmp(p, name, len))
diff --git a/usr.sbin/cron/externs.h b/usr.sbin/cron/externs.h
index 5d104302279..11b3e7c6cec 100644
--- a/usr.sbin/cron/externs.h
+++ b/usr.sbin/cron/externs.h
@@ -1,68 +1,99 @@
+/* $OpenBSD: externs.h,v 1.3 2001/02/18 19:48:34 millert Exp $ */
+
/* Copyright 1993,1994 by Paul Vixie
* All rights reserved
+ */
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
-#if defined(POSIX) || defined(ATT)
-# include <stdlib.h>
-# include <unistd.h>
-# include <string.h>
-# include <dirent.h>
-# include <errno.h>
-# define DIR_T struct dirent
-# define WAIT_T int
-# define WAIT_IS_INT 1
+/* reorder these #include's at your peril */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <bitstring.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <locale.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
+
+#if defined(SYSLOG)
+# include <syslog.h>
+#endif
+
+#if (defined(BSD)) && (BSD >= 199103) || defined(__linux) || defined(AIX)
+# include <paths.h>
+#endif /*BSD*/
+
+#if !defined(_PATH_SENDMAIL)
+# define _PATH_SENDMAIL "/usr/lib/sendmail"
+#endif /*SENDMAIL*/
+
+#if defined(LOGIN_CAP)
+#include <login_cap.h>
+#endif /*LOGIN_CAP*/
+
+#if defined(BSD_AUTH)
+#include <bsd_auth.h>
+#endif /*BSD_AUTH*/
+
+#define DIR_T struct dirent
+#define WAIT_T int
+#define SIG_T sig_t
+#define TIME_T time_t
+#define PID_T pid_t
+
+#ifndef TZNAME_ALREADY_DEFINED
extern char *tzname[2];
-# define TZONE(tm) tzname[(tm).tm_isdst]
#endif
+#define TZONE(tm) tzname[(tm).tm_isdst]
-#if defined(UNIXPC)
-# undef WAIT_T
-# undef WAIT_IS_INT
-# define WAIT_T union wait
+#if (BSD >= 198606)
+# define HAVE_FCHOWN
+# define HAVE_FCHMOD
#endif
-#if defined(POSIX)
-# define SIG_T sig_t
-# define TIME_T time_t
-# define PID_T pid_t
+#if (BSD >= 199103)
+# define HAVE_SAVED_UIDS
#endif
-#if defined(ATT)
-# define SIG_T void
-# define TIME_T long
-# define PID_T int
-#endif
+#define MY_UID(pw) getuid()
+#define MY_GID(pw) getgid()
-#if !defined(POSIX) && !defined(ATT)
-/* classic BSD */
-extern time_t time();
-extern unsigned sleep();
-extern struct tm *localtime();
-extern struct passwd *getpwnam();
-extern int errno;
-extern void perror(), exit(), free();
-extern char *getenv(), *strcpy(), *strchr(), *strtok();
-extern void *malloc(), *realloc();
-# define SIG_T void
-# define TIME_T long
-# define PID_T int
-# define WAIT_T union wait
-# define DIR_T struct direct
-# include <sys/dir.h>
-# define TZONE(tm) (tm).tm_zone
+#if !defined(AIX) && !defined(UNICOS)
+# define SYS_TIME_H 1
+#else
+# define SYS_TIME_H 0
#endif
/* getopt() isn't part of POSIX. some systems define it in <stdlib.h> anyway.
@@ -71,8 +102,8 @@ extern void *malloc(), *realloc();
* in ways that we cannot predict or comprehend, yet do not define the adjunct
* external variables needed for the interface.
*/
-#if (!defined(BSD) || (BSD < 198911)) && !defined(ATT) && !defined(UNICOS)
-int getopt __P((int, char * const *, const char *));
+#if (!defined(BSD) || (BSD < 198911))
+int getopt(int, char * const *, const char *);
#endif
#if (!defined(BSD) || (BSD < 199103))
@@ -80,67 +111,21 @@ extern char *optarg;
extern int optind, opterr, optopt;
#endif
-#if WAIT_IS_INT
-# ifndef WEXITSTATUS
-# define WEXITSTATUS(x) (((x) >> 8) & 0xff)
-# endif
-# ifndef WTERMSIG
-# define WTERMSIG(x) ((x) & 0x7f)
-# endif
-# ifndef WCOREDUMP
-# define WCOREDUMP(x) ((x) & 0x80)
-# endif
-#else /*WAIT_IS_INT*/
-# ifndef WEXITSTATUS
-# define WEXITSTATUS(x) ((x).w_retcode)
-# endif
-# ifndef WTERMSIG
-# define WTERMSIG(x) ((x).w_termsig)
-# endif
-# ifndef WCOREDUMP
-# define WCOREDUMP(x) ((x).w_coredump)
-# endif
-#endif /*WAIT_IS_INT*/
-
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(x) (WTERMSIG(x) != 0)
-#endif
-#ifndef WIFEXITED
-#define WIFEXITED(x) (WTERMSIG(x) == 0)
-#endif
-
-#ifdef NEED_STRCASECMP
-extern int strcasecmp __P((char *, char *));
-#endif
-
-#ifdef NEED_STRDUP
-extern char *strdup __P((char *));
-#endif
-
-#ifdef NEED_STRERROR
-extern char *strerror __P((int));
-#endif
+/* digital unix needs this but does not give us a way to identify it.
+ */
+extern int flock(int, int);
-#ifdef NEED_FLOCK
-extern int flock __P((int, int));
+/* not all systems who provice flock() provide these definitions.
+ */
+#ifndef LOCK_SH
# define LOCK_SH 1
-# define LOCK_EX 2
-# define LOCK_NB 4
-# define LOCK_UN 8
-#endif
-
-#ifdef NEED_SETSID
-extern int setsid __P((void));
#endif
-
-#ifdef NEED_GETDTABLESIZE
-extern int getdtablesize __P((void));
+#ifndef LOCK_EX
+# define LOCK_EX 2
#endif
-
-#ifdef NEED_SETENV
-extern int setenv __P((char *, char *, int));
+#ifndef LOCK_NB
+# define LOCK_NB 4
#endif
-
-#ifdef NEED_VFORK
-extern PID_T vfork __P((void));
+#ifndef LOCK_UN
+# define LOCK_UN 8
#endif
diff --git a/usr.sbin/cron/funcs.h b/usr.sbin/cron/funcs.h
new file mode 100644
index 00000000000..4e2e0289b89
--- /dev/null
+++ b/usr.sbin/cron/funcs.h
@@ -0,0 +1,70 @@
+/* $OpenBSD: funcs.h,v 1.1 2001/02/18 19:48:35 millert Exp $ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/* Notes:
+ * This file has to be included by cron.h after data structure defs.
+ * We should reorg this into sections by module.
+ */
+
+void set_cron_uid(void),
+ set_cron_cwd(void),
+ load_database(cron_db *),
+ open_logfile(void),
+ sigpipe_func(void),
+ job_add(entry *, user *),
+ do_command(entry *, user *),
+ link_user(cron_db *, user *),
+ unlink_user(cron_db *, user *),
+ free_user(user *),
+ env_free(char **),
+ unget_char(int, FILE *),
+ free_entry(entry *),
+ acquire_daemonlock(int),
+ skip_comments(FILE *),
+ log_it(const char *, int, const char *, const char *),
+ log_close(void);
+
+int job_runqueue(void),
+ set_debug_flags(char *),
+ get_char(FILE *),
+ get_string(char *, int, FILE *, char *),
+ swap_uids(void),
+ swap_uids_back __P((void)),
+ load_env(char *, FILE *),
+ cron_pclose(FILE *),
+ glue_strings(char *, int, char *, char *, int),
+ strcmp_until(const char *, const char *, int),
+ allowed(char *),
+ strdtb(char *);
+
+char *env_get(char *, char **),
+ *arpadate(time_t *),
+ *mkprints(unsigned char *, unsigned int),
+ *first_word(char *, char *),
+ **env_init(void),
+ **env_copy(char **),
+ **env_set(char **, char *);
+
+user *load_user(int, struct passwd *, const char *),
+ *find_user(cron_db *, const char *);
+
+entry *load_entry(FILE *, void (*)(),
+ struct passwd *, char **);
+
+FILE *cron_popen(char *, char *, entry *);
diff --git a/usr.sbin/cron/globals.h b/usr.sbin/cron/globals.h
new file mode 100644
index 00000000000..a6063785b1f
--- /dev/null
+++ b/usr.sbin/cron/globals.h
@@ -0,0 +1,77 @@
+/* $OpenBSD: globals.h,v 1.1 2001/02/18 19:48:35 millert Exp $ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef MAIN_PROGRAM
+# define XTRN
+# define INIT(x) = x
+#else
+# define XTRN extern
+# define INIT(x)
+#endif
+
+XTRN const char *copyright[]
+#ifdef MAIN_PROGRAM
+ = {
+ "@(#) Copyright 1988,1989,1990,1993,1994 by Paul Vixie",
+ "@(#) Copyright 1997 by Internet Software Consortium, Inc.",
+ "@(#) All rights reserved",
+ NULL
+ }
+#endif
+ ;
+
+XTRN const char *MonthNames[]
+#ifdef MAIN_PROGRAM
+ = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",\
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",\
+ NULL
+ }
+#endif
+ ;
+
+XTRN const char *DowNames[]
+#ifdef MAIN_PROGRAM
+ = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",\
+ NULL
+ }
+#endif
+ ;
+
+XTRN const char *ProgramName INIT("amnesia");
+XTRN int LineNumber INIT(0);
+XTRN time_t StartTime INIT(0);
+XTRN time_min timeRunning INIT(0);
+XTRN time_min virtualTime INIT(0);
+XTRN time_min clockTime INIT(0);
+
+#if DEBUGGING
+XTRN int DebugFlags INIT(0);
+XTRN const char *DebugFlagNames[]
+#ifdef MAIN_PROGRAM
+ = {
+ "ext", "sch", "proc", "pars", "load", "misc", "test", "bit",\
+ NULL
+ }
+#endif
+ ;
+#else
+#define DebugFlags 0
+#endif /* DEBUGGING */
diff --git a/usr.sbin/cron/job.c b/usr.sbin/cron/job.c
index 18e96b6e36b..c85c7270d53 100644
--- a/usr.sbin/cron/job.c
+++ b/usr.sbin/cron/job.c
@@ -1,22 +1,27 @@
+/* $OpenBSD: job.c,v 1.3 2001/02/18 19:48:35 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: job.c,v 1.2 1996/11/01 23:27:36 millert Exp $";
+static char rcsid[] = "$OpenBSD: job.c,v 1.3 2001/02/18 19:48:35 millert Exp $";
#endif
@@ -35,14 +40,15 @@ static job *jhead = NULL, *jtail = NULL;
void
job_add(e, u)
- register entry *e;
- register user *u;
+ entry *e;
+ user *u;
{
- register job *j;
+ job *j;
/* if already on queue, keep going */
- for (j=jhead; j; j=j->next)
- if (j->e == e && j->u == u) { return; }
+ for (j = jhead; j != NULL; j = j->next)
+ if (j->e == e && j->u == u)
+ return;
/* build a job queue element */
if ((j = (job*)malloc(sizeof(job))) == NULL)
@@ -52,8 +58,10 @@ job_add(e, u)
j->u = u;
/* add it to the tail */
- if (!jhead) { jhead=j; }
- else { jtail->next=j; }
+ if (jhead == NULL)
+ jhead = j;
+ else
+ jtail->next = j;
jtail = j;
}
@@ -61,15 +69,15 @@ job_add(e, u)
int
job_runqueue()
{
- register job *j, *jn;
- register int run = 0;
+ job *j, *jn;
+ int run = 0;
- for (j=jhead; j; j=jn) {
+ for (j = jhead; j; j = jn) {
do_command(j->e, j->u);
jn = j->next;
free(j);
run++;
}
jhead = jtail = NULL;
- return run;
+ return (run);
}
diff --git a/usr.sbin/cron/macros.h b/usr.sbin/cron/macros.h
new file mode 100644
index 00000000000..8dfae8772f3
--- /dev/null
+++ b/usr.sbin/cron/macros.h
@@ -0,0 +1,125 @@
+/* $OpenBSD: macros.h,v 1.1 2001/02/18 19:48:35 millert Exp $ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+ /* these are really immutable, and are
+ * defined for symbolic convenience only
+ * TRUE, FALSE, and ERR must be distinct
+ * ERR must be < OK.
+ */
+#define TRUE 1
+#define FALSE 0
+ /* system calls return this on success */
+#define OK 0
+ /* or this on error */
+#define ERR (-1)
+
+ /* turn this on to get '-x' code */
+#ifndef DEBUGGING
+#define DEBUGGING FALSE
+#endif
+
+#define INIT_PID 1 /* parent of orphans */
+#define READ_PIPE 0 /* which end of a pipe pair do you read? */
+#define WRITE_PIPE 1 /* or write to? */
+#define STDIN 0 /* what is stdin's file descriptor? */
+#define STDOUT 1 /* stdout's? */
+#define STDERR 2 /* stderr's? */
+#define ERROR_EXIT 1 /* exit() with this will scare the shell */
+#define OK_EXIT 0 /* exit() with this is considered 'normal' */
+#define MAX_FNAME 100 /* max length of internally generated fn */
+#define MAX_COMMAND 1000 /* max length of internally generated cmd */
+#define MAX_ENVSTR 1000 /* max length of envvar=value\0 strings */
+#define MAX_TEMPSTR 100 /* obvious */
+#define MAX_UNAME (_PW_NAME_LEN+1) /* max length of username, should be overkill */
+#define ROOT_UID 0 /* don't change this, it really must be root */
+#define ROOT_USER "root" /* ditto */
+
+ /* NOTE: these correspond to DebugFlagNames,
+ * defined below.
+ */
+#define DEXT 0x0001 /* extend flag for other debug masks */
+#define DSCH 0x0002 /* scheduling debug mask */
+#define DPROC 0x0004 /* process control debug mask */
+#define DPARS 0x0008 /* parsing debug mask */
+#define DLOAD 0x0010 /* database loading debug mask */
+#define DMISC 0x0020 /* misc debug mask */
+#define DTEST 0x0040 /* test mode: don't execute any commands */
+#define DBIT 0x0080 /* bit twiddling shown (long) */
+
+#define CRON_TAB(u) "%s/%s", SPOOL_DIR, u
+#define PPC_NULL ((const char **)NULL)
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#define Skip_Blanks(c, f) \
+ while (c == '\t' || c == ' ') \
+ c = get_char(f);
+
+#define Skip_Nonblanks(c, f) \
+ while (c!='\t' && c!=' ' && c!='\n' && c != EOF) \
+ c = get_char(f);
+
+#define Skip_Line(c, f) \
+ do {c = get_char(f);} while (c != '\n' && c != EOF);
+
+#if DEBUGGING
+# define Debug(mask, message) \
+ if ( (DebugFlags & (mask) ) == (mask) ) \
+ printf message;
+#else /* !DEBUGGING */
+# define Debug(mask, message) \
+ ;
+#endif /* DEBUGGING */
+
+#define MkLower(ch) (isupper(ch) ? tolower(ch) : ch)
+#define MkUpper(ch) (islower(ch) ? toupper(ch) : ch)
+#define Set_LineNum(ln) {Debug(DPARS|DEXT,("linenum=%d\n",ln)); \
+ LineNumber = ln; \
+ }
+
+#define SECONDS_PER_MINUTE 60
+
+#define FIRST_MINUTE 0
+#define LAST_MINUTE 59
+#define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1)
+
+#define FIRST_HOUR 0
+#define LAST_HOUR 23
+#define HOUR_COUNT (LAST_HOUR - FIRST_HOUR + 1)
+
+#define FIRST_DOM 1
+#define LAST_DOM 31
+#define DOM_COUNT (LAST_DOM - FIRST_DOM + 1)
+
+#define FIRST_MONTH 1
+#define LAST_MONTH 12
+#define MONTH_COUNT (LAST_MONTH - FIRST_MONTH + 1)
+
+/* note on DOW: 0 and 7 are both Sunday, for compatibility reasons. */
+#define FIRST_DOW 0
+#define LAST_DOW 7
+#define DOW_COUNT (LAST_DOW - FIRST_DOW + 1)
+
+ /* each user's crontab will be held as a list of
+ * the following structure.
+ *
+ * These are the cron commands.
+ */
diff --git a/usr.sbin/cron/misc.c b/usr.sbin/cron/misc.c
index 53193779777..07ca1452e0c 100644
--- a/usr.sbin/cron/misc.c
+++ b/usr.sbin/cron/misc.c
@@ -1,22 +1,27 @@
+/* $OpenBSD: misc.c,v 1.8 2001/02/18 19:48:35 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: misc.c,v 1.7 2000/08/21 21:08:57 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: misc.c,v 1.8 2001/02/18 19:48:35 millert Exp $";
#endif
/* vix 26jan87 [RCS has the rest of the log]
@@ -33,29 +38,64 @@ static char rcsid[] = "$Id: misc.c,v 1.7 2000/08/21 21:08:57 deraadt Exp $";
#include <sys/file.h>
#include <sys/stat.h>
#include <errno.h>
-#include <string.h>
#include <fcntl.h>
#if defined(SYSLOG)
# include <syslog.h>
#endif
+#if defined(LOG_CRON) && defined(LOG_FILE)
+# undef LOG_FILE
+#endif
+
#if defined(LOG_DAEMON) && !defined(LOG_CRON)
-#define LOG_CRON LOG_DAEMON
+# define LOG_CRON LOG_DAEMON
#endif
static int LogFD = ERR;
-
+/*
+ * glue_strings is the overflow-safe equivalent of
+ * sprintf(buffer, "%s%c%s", a, separator, b);
+ *
+ * returns 1 on success, 0 on failure. 'buffer' MUST NOT be used if
+ * glue_strings fails.
+ */
int
-strcmp_until(left, right, until)
- char *left;
- char *right;
- int until;
+glue_strings(buffer, buffer_size, a, b, separator)
+ char *buffer;
+ int buffer_size;
+ char *a;
+ char *b;
+ int separator;
{
- register int diff;
+ char *buf;
+ char *buf_end;
+
+ if (buffer_size <= 0)
+ return (0);
+ buf_end = buffer + buffer_size;
+ buf = buffer;
+
+ for ( /* nothing */; buf < buf_end && *a != '\0'; buf++, a++ )
+ *buf = *a;
+ if (buf == buf_end)
+ return (0);
+ if (separator != '/' || buf == buffer || buf[-1] != '/')
+ *buf++ = separator;
+ if (buf == buf_end)
+ return (0);
+ for ( /* nothing */; buf < buf_end && *b != '\0'; buf++, b++ )
+ *buf = *b;
+ if (buf == buf_end)
+ return (0);
+ *buf = '\0';
+ return (1);
+}
+int
+strcmp_until(const char *left, const char *right, int until) {
while (*left && *left != until && *left == *right) {
left++;
right++;
@@ -63,12 +103,9 @@ strcmp_until(left, right, until)
if ((*left=='\0' || *left == until) &&
(*right=='\0' || *right == until)) {
- diff = 0;
- } else {
- diff = *left - *right;
+ return (0);
}
-
- return diff;
+ return (*left - *right);
}
@@ -99,7 +136,7 @@ strdtb(s)
/* the difference between the position of the null character and
* the position of the first character of the string is the length.
*/
- return x - s;
+ return (x - s);
}
@@ -116,7 +153,7 @@ set_debug_flags(flags)
#if !DEBUGGING
printf("this program was compiled without debugging enabled\n");
- return FALSE;
+ return (FALSE);
#else /* DEBUGGING */
@@ -125,13 +162,13 @@ set_debug_flags(flags)
DebugFlags = 0;
while (*pc) {
- char **test;
- int mask;
+ const char **test;
+ int mask;
/* try to find debug flag name in our list.
*/
for ( test = DebugFlagNames, mask = 1;
- *test && strcmp_until(*test, pc, ',');
+ *test != NULL && strcmp_until(*test, pc, ',');
test++, mask <<= 1
)
;
@@ -140,7 +177,7 @@ set_debug_flags(flags)
fprintf(stderr,
"unrecognized debug flag <%s> <%s>\n",
flags, pc);
- return FALSE;
+ return (FALSE);
}
DebugFlags |= mask;
@@ -164,7 +201,7 @@ set_debug_flags(flags)
fprintf(stderr, "\n");
}
- return TRUE;
+ return (TRUE);
#endif /* DEBUGGING */
}
@@ -251,6 +288,9 @@ acquire_daemonlock(closeflag)
int closeflag;
{
static FILE *fp = NULL;
+ char buf[3*MAX_FNAME];
+ char pidfile[MAX_FNAME];
+ int fd, otherpid;
if (closeflag && fp) {
fclose(fp);
@@ -259,14 +299,15 @@ acquire_daemonlock(closeflag)
}
if (!fp) {
- char pidfile[MAX_FNAME];
- char buf[MAX_TEMPSTR];
- int fd, otherpid;
-
- if (snprintf(pidfile, sizeof pidfile, PIDFILE,
- PIDDIR) >= sizeof pidfile ||
- (fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1 ||
- (fp = fdopen(fd, "r+")) == NULL) {
+ if (!glue_strings(pidfile, sizeof pidfile, PIDDIR,
+ PIDFILE, '/')) {
+ fprintf(stderr, "%s%s: path too long\n",
+ PIDDIR, PIDFILE);
+ log_it("CRON", getpid(), "DEATH", "path too long");
+ exit(ERROR_EXIT);
+ }
+ if ((-1 == (fd = open(pidfile, O_RDWR|O_CREAT, 0644))) ||
+ (NULL == (fp = fdopen(fd, "r+")))) {
snprintf(buf, sizeof buf, "can't open or create %s: %s",
pidfile, strerror(errno));
fprintf(stderr, "%s: %s\n", ProgramName, buf);
@@ -279,8 +320,8 @@ acquire_daemonlock(closeflag)
fscanf(fp, "%d", &otherpid);
snprintf(buf, sizeof buf,
- "can't lock %s, otherpid may be %d: %s",
- pidfile, otherpid, strerror(save_errno));
+ "can't lock %s, otherpid may be %d: %s",
+ pidfile, otherpid, strerror(save_errno));
fprintf(stderr, "%s: %s\n", ProgramName, buf);
log_it("CRON", getpid(), "DEATH", buf);
exit(ERROR_EXIT);
@@ -290,7 +331,7 @@ acquire_daemonlock(closeflag)
}
rewind(fp);
- fprintf(fp, "%d\n", getpid());
+ fprintf(fp, "%ld\n", (long)getpid());
fflush(fp);
(void) ftruncate(fileno(fp), ftell(fp));
@@ -310,7 +351,7 @@ get_char(file)
ch = getc(file);
if (ch == '\n')
Set_LineNum(LineNumber + 1)
- return ch;
+ return (ch);
}
@@ -352,7 +393,7 @@ get_string(string, size, file, terms)
if (size > 0)
*string = '\0';
- return ch;
+ return (ch);
}
@@ -412,9 +453,9 @@ in_file(string, file)
if (line[0] != '\0')
line[strlen(line)-1] = '\0';
if (0 == strcmp(line, string))
- return TRUE;
+ return (TRUE);
}
- return FALSE;
+ return (FALSE);
}
@@ -450,37 +491,38 @@ allowed(username)
#if defined(ALLOW_ONLY_ROOT)
return (strcmp(username, ROOT_USER) == 0);
#else
- return TRUE;
+ return (TRUE);
#endif
}
void
log_it(username, xpid, event, detail)
- char *username;
+ const char *username;
int xpid;
- char *event;
- char *detail;
+ const char *event;
+ const char *detail;
{
- PID_T pid = xpid;
+#if defined(LOG_FILE) || DEBUGGING
+ PID_T pid = xpid;
+#endif
#if defined(LOG_FILE)
- char *msg;
- TIME_T now = time((TIME_T) 0);
- register struct tm *t = localtime(&now);
- int msglen;
+ char *msg;
+ size_t msglen;
+ TIME_T now = time((TIME_T) 0);
+ struct tm *t = localtime(&now);
#endif /*LOG_FILE*/
#if defined(SYSLOG)
- static int syslog_open = 0;
+ static int syslog_open = 0;
#endif
#if defined(LOG_FILE)
/* we assume that MAX_TEMPSTR will hold the date, time, &punctuation.
*/
msglen = strlen(username) + strlen(event) + strlen(detail) +
- MAX_TEMPSTR);
- msg = malloc(msglen);
- if (!msg)
+ MAX_TEMPSTR;
+ if ((msg = malloc(msglen)) == NULL)
return;
if (LogFD < OK) {
@@ -499,10 +541,12 @@ log_it(username, xpid, event, detail)
* to the log file.
*/
snprintf(msg, msglen, "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n",
- username,
- t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, pid,
- event, detail);
+ username,
+ t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, pid,
+ event, detail);
+ /* we have to run strlen() because sprintf() returns (char*) on old BSD
+ */
if (LogFD < OK || write(LogFD, msg, strlen(msg)) < OK) {
if (LogFD >= OK)
perror(LOG_FILE);
@@ -533,8 +577,8 @@ log_it(username, xpid, event, detail)
#if DEBUGGING
if (DebugFlags) {
- fprintf(stderr, "log_it: (%s %d) %s (%s)\n",
- username, pid, event, detail);
+ fprintf(stderr, "log_it: (%s %ld) %s (%s)\n",
+ username, (long)pid, event, detail);
}
#endif
}
@@ -555,12 +599,12 @@ log_close() {
*/
char *
first_word(s, t)
- register char *s; /* string we want the first word of */
- register char *t; /* terminators, implicitly including \0 */
+ char *s; /* string we want the first word of */
+ char *t; /* terminators, implicitly including \0 */
{
static char retbuf[2][MAX_TEMPSTR + 1]; /* sure wish C had GC */
static int retsel = 0;
- register char *rb, *rp;
+ char *rb, *rp;
/* select a return buffer */
retsel = 1-retsel;
@@ -579,7 +623,7 @@ first_word(s, t)
/* finish the return-string and return it */
*rp = '\0';
- return rb;
+ return (rb);
}
@@ -588,13 +632,18 @@ first_word(s, t)
*/
void
mkprint(dst, src, len)
- register char *dst;
- register unsigned char *src;
- register int len;
+ char *dst;
+ unsigned char *src;
+ int len;
{
+ /*
+ * XXX
+ * We know this routine can't overflow the dst buffer because mkprints()
+ * allocated enough space for the worst case.
+ */
while (len-- > 0)
{
- register unsigned char ch = *src++;
+ unsigned char ch = *src++;
if (ch < ' ') { /* control character */
*dst++ = '^';
@@ -618,15 +667,15 @@ mkprint(dst, src, len)
*/
char *
mkprints(src, len)
- register unsigned char *src;
- register unsigned int len;
+ unsigned char *src;
+ unsigned int len;
{
- register char *dst = malloc(len*4 + 1);
+ char *dst = malloc(len*4 + 1);
if (dst)
mkprint(dst, src, len);
- return dst;
+ return (dst);
}
@@ -638,9 +687,9 @@ char *
arpadate(clock)
time_t *clock;
{
- static char ret[64]; /* zone name might be >3 chars */
time_t t = clock ? *clock : time(NULL);
struct tm *tm = localtime(&t);
+ static char ret[64]; /* zone name might be >3 chars */
char *qmark;
size_t len;
int hours = tm->tm_gmtoff / 3600;
@@ -654,23 +703,22 @@ arpadate(clock)
if (len == 0) {
ret[0] = '?';
ret[1] = '\0';
- return ret;
+ return (ret);
}
qmark = strchr(ret, '?');
if (qmark && len - (qmark - ret) >= 6) {
snprintf(qmark, 6, "% .2d%.2d", hours, minutes);
qmark[5] = ' ';
}
- return ret;
+ return (ret);
}
#endif /*MAIL_DATE*/
-
#ifdef HAVE_SAVED_UIDS
static uid_t save_euid;
-int swap_uids() { save_euid = geteuid(); return seteuid(getuid()); }
-int swap_uids_back() { return seteuid(save_euid); }
+int swap_uids() { save_euid = geteuid(); return (seteuid(getuid())); }
+int swap_uids_back() { return (seteuid(save_euid)); }
#else /*HAVE_SAVED_UIDS*/
-int swap_uids() { return setreuid(geteuid(), getuid()); }
-int swap_uids_back() { return swap_uids(); }
+int swap_uids() { return (setreuid(geteuid(), getuid())); }
+int swap_uids_back() { return (swap_uids()); }
#endif /*HAVE_SAVED_UIDS*/
diff --git a/usr.sbin/cron/pathnames.h b/usr.sbin/cron/pathnames.h
index bd46f47afb4..e01e0321843 100644
--- a/usr.sbin/cron/pathnames.h
+++ b/usr.sbin/cron/pathnames.h
@@ -1,28 +1,25 @@
+/* $OpenBSD: pathnames.h,v 1.3 2001/02/18 19:48:36 millert Exp $ */
+
/* Copyright 1993,1994 by Paul Vixie
* All rights reserved
- *
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
- *
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
*/
-
/*
- * $Id: pathnames.h,v 1.2 1998/03/30 06:59:46 deraadt Exp $
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
-#if (defined(BSD)) && (BSD >= 199103) || defined(__linux) || defined(AIX)
-# include <paths.h>
-#endif /*BSD*/
-
#ifndef CRONDIR
/* CRONDIR is where crond(8) and crontab(1) both chdir
* to; SPOOL_DIR, ALLOW_FILE, DENY_FILE, and LOG_FILE
@@ -45,11 +42,13 @@
* that ALLOW_FILE and DENY_FILE must both be defined
* in order to enable the allow/deny code. If neither
* LOG_FILE or SYSLOG is defined, we don't log. If
- * both are defined, we log both ways.
+ * both are defined, we log both ways. Note that if
+ * LOG_CRON is defined by <syslog.h>, LOG_FILE will not
+ * be used.
*/
-#define ALLOW_FILE "allow" /*-*/
-#define DENY_FILE "deny" /*-*/
-/* #define LOG_FILE "log" -*/
+#define ALLOW_FILE "allow"
+#define DENY_FILE "deny"
+#define LOG_FILE "log"
/* where should the daemon stick its PID?
*/
@@ -58,7 +57,7 @@
#else
# define PIDDIR "/etc/"
#endif
-#define PIDFILE "%scron.pid"
+#define PIDFILE "cron.pid"
/* 4.3BSD-style crontab */
#define SYSCRONTAB "/etc/crontab"
@@ -79,3 +78,7 @@
#ifndef _PATH_DEFPATH
# define _PATH_DEFPATH "/usr/bin:/bin"
#endif
+
+#ifndef _PATH_TMP
+# define _PATH_TMP "/tmp"
+#endif
diff --git a/usr.sbin/cron/popen.c b/usr.sbin/cron/popen.c
index 15d7e50cbcd..e13db8842b4 100644
--- a/usr.sbin/cron/popen.c
+++ b/usr.sbin/cron/popen.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: popen.c,v 1.8 2001/02/18 19:48:36 millert Exp $ */
/*
* Copyright (c) 1988 The Regents of the University of California.
* All rights reserved.
@@ -24,22 +25,14 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: popen.c,v 1.7 2000/08/21 21:01:21 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: popen.c,v 1.8 2001/02/18 19:48:36 millert Exp $";
static char sccsid[] = "@(#)popen.c 5.7 (Berkeley) 2/14/89";
#endif /* not lint */
#include "cron.h"
-#include <signal.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <grp.h>
-
-#if defined(LOGIN_CAP)
-# include <login_cap.h>
-#endif
-
#define MAX_ARGS 100
+#define MAX_GARGS 1000
#define WANT_GLOBBING 0
/*
@@ -52,37 +45,34 @@ static int fds;
FILE *
cron_popen(program, type, e)
- char *program, *type;
+ char *program;
+ char *type;
entry *e;
{
- register char *cp;
- FILE *iop;
+ char *cp;
+ FILE * volatile iop;
int argc, pdes[2];
PID_T pid;
char *argv[MAX_ARGS + 1];
#if WANT_GLOBBING
char **pop, *vv[2];
int gargc;
- char *gargv[1000];
+ char *gargv[MAX_GARGS];
extern char **glob(), **copyblk();
#endif
-#ifdef __GNUC__
- (void) &iop; /* Avoid vfork clobbering */
-#endif
-
- if ((*type != 'r' && *type != 'w') || type[1])
- return(NULL);
+ if ((*type != 'r' && *type != 'w') || type[1] != '\0')
+ return (NULL);
if (!pids) {
- if ((fds = getdtablesize()) <= 0)
- return(NULL);
- if (!(pids = (PID_T *)malloc((u_int)(fds * sizeof(PID_T)))))
- return(NULL);
+ if ((fds = sysconf(_SC_OPEN_MAX)) <= 0)
+ return (NULL);
+ if (!(pids = (PID_T *)malloc((size_t)(fds * sizeof(PID_T)))))
+ return (NULL);
bzero((char *)pids, fds * sizeof(PID_T));
}
if (pipe(pdes) < 0)
- return(NULL);
+ return (NULL);
/* break up string into pieces */
for (argc = 0, cp = program; argc < MAX_ARGS; cp = NULL)
@@ -100,7 +90,7 @@ cron_popen(program, type, e)
pop = copyblk(vv);
}
argv[argc] = (char *)pop; /* save to free later */
- while (*pop && gargc < 1000)
+ while (*pop && gargc < MAX_GARGS)
gargv[gargc++] = *pop++;
}
gargv[gargc] = NULL;
@@ -144,14 +134,14 @@ cron_popen(program, type, e)
}
#else
if (setgid(e->gid) ||
- setgroups(0, NULL) ||
- initgroups(env_get("LOGNAME", e->envp), e->gid))
- _exit(1);
+ setgroups(0, NULL) ||
+ initgroups(env_get("LOGNAME", e->envp), e->gid))
+ _exit(1);
setlogin(env_get("LOGNAME", e->envp));
if (setuid(e->uid))
_exit(1);
chdir(env_get("HOME", e->envp));
-#endif
+#endif /* LOGIN_CAP */
}
#if WANT_GLOBBING
execvp(gargv[0], gargv);
@@ -177,14 +167,14 @@ pfree:
free((char *)argv[argc]);
}
#endif
- return(iop);
+ return (iop);
}
int
cron_pclose(iop)
FILE *iop;
{
- register int fdes;
+ int fdes;
int omask;
WAIT_T stat_loc;
PID_T pid;
@@ -194,7 +184,7 @@ cron_pclose(iop)
* `popened' command, or, if already `pclosed'.
*/
if (pids == 0 || pids[fdes = fileno(iop)] == 0)
- return(-1);
+ return (-1);
(void)fclose(iop);
omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1)
diff --git a/usr.sbin/cron/structs.h b/usr.sbin/cron/structs.h
new file mode 100644
index 00000000000..7dd49ae87d7
--- /dev/null
+++ b/usr.sbin/cron/structs.h
@@ -0,0 +1,64 @@
+/* $OpenBSD: structs.h,v 1.1 2001/02/18 19:48:36 millert Exp $ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+typedef int time_min; /* time in minutes */
+
+typedef struct _entry {
+ struct _entry *next;
+ uid_t uid;
+ gid_t gid;
+ char **envp;
+ char *cmd;
+ bitstr_t bit_decl(minute, MINUTE_COUNT);
+ bitstr_t bit_decl(hour, HOUR_COUNT);
+ bitstr_t bit_decl(dom, DOM_COUNT);
+ bitstr_t bit_decl(month, MONTH_COUNT);
+ bitstr_t bit_decl(dow, DOW_COUNT);
+ int flags;
+#define MIN_STAR 0x01
+#define HR_STAR 0x02
+#define DOM_STAR 0x04
+#define DOW_STAR 0x08
+#define WHEN_REBOOT 0x10
+#define DONT_LOG 0x20
+} entry;
+
+ /* the crontab database will be a list of the
+ * following structure, one element per user
+ * plus one for the system.
+ *
+ * These are the crontabs.
+ */
+
+typedef struct _user {
+ struct _user *next, *prev; /* links */
+ char *name;
+ time_t mtime; /* last modtime of crontab */
+ entry *crontab; /* this person's crontab */
+} user;
+
+typedef struct _cron_db {
+ user *head, *tail; /* links */
+ time_t mtime; /* last modtime on spooldir */
+} cron_db;
+ /* in the C tradition, we only create
+ * variables for the main program, just
+ * extern them elsewhere.
+ */
+
diff --git a/usr.sbin/cron/user.c b/usr.sbin/cron/user.c
index a2ce35bfed2..7ef42d9271d 100644
--- a/usr.sbin/cron/user.c
+++ b/usr.sbin/cron/user.c
@@ -1,36 +1,37 @@
+/* $OpenBSD: user.c,v 1.3 2001/02/18 19:48:36 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
+ */
+
+/*
+ * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
*
- * Distribute freely, except: 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. May be sold if buildable source is provided to buyer. No
- * warrantee of any kind, express or implied, is included with this
- * software; use at your own risk, responsibility for damages (if any) to
- * anyone resulting from the use of this software rests entirely with the
- * user.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * 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 <paul@vix.com> uunet!decwrl!vixie!paul
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: user.c,v 1.2 1996/11/01 23:27:39 millert Exp $";
+static char rcsid[] = "$OpenBSD: user.c,v 1.3 2001/02/18 19:48:36 millert Exp $";
#endif
/* vix 26jan87 [log is in RCS file]
*/
-
#include "cron.h"
-
void
-free_user(u)
- user *u;
-{
- entry *e, *ne;
+free_user(user *u) {
+ entry *e, *ne;
free(u->name);
for (e = u->crontab; e != NULL; e = ne) {
@@ -40,51 +41,45 @@ free_user(u)
free(u);
}
-
user *
-load_user(crontab_fd, pw, name)
- int crontab_fd;
- struct passwd *pw; /* NULL implies syscrontab */
- char *name;
-{
- char envstr[MAX_ENVSTR];
- FILE *file;
- user *u;
- entry *e;
- int status;
- char **envp, **tenvp;
+load_user(int crontab_fd, struct passwd *pw, const char *name) {
+ char envstr[MAX_ENVSTR];
+ FILE *file;
+ user *u;
+ entry *e;
+ int status, save_errno;
+ char **envp, **tenvp;
if (!(file = fdopen(crontab_fd, "r"))) {
perror("fdopen on crontab_fd in load_user");
- return NULL;
+ return (NULL);
}
Debug(DPARS, ("load_user()\n"))
/* file is open. build user entry, then read the crontab file.
*/
- if ((u = (user *) malloc(sizeof(user))) == NULL) {
- errno = ENOMEM;
- return NULL;
- }
+ if ((u = (user *) malloc(sizeof(user))) == NULL)
+ return (NULL);
if ((u->name = strdup(name)) == NULL) {
+ save_errno = errno;
free(u);
- errno = ENOMEM;
- return NULL;
+ errno = save_errno;
+ return (NULL);
}
u->crontab = NULL;
- /*
- * init environment. this will be copied/augmented for each entry.
+ /* init environment. this will be copied/augmented for each entry.
*/
if ((envp = env_init()) == NULL) {
+ save_errno = errno;
free(u->name);
free(u);
- return NULL;
+ errno = save_errno;
+ return (NULL);
}
- /*
- * load the crontab
+ /* load the crontab
*/
while ((status = load_env(envstr, file)) >= OK) {
switch (status) {
@@ -103,8 +98,10 @@ load_user(crontab_fd, pw, name)
if ((tenvp = env_set(envp, envstr))) {
envp = tenvp;
} else {
+ save_errno = errno;
free_user(u);
u = NULL;
+ errno = save_errno;
goto done;
}
break;
@@ -115,5 +112,5 @@ load_user(crontab_fd, pw, name)
env_free(envp);
fclose(file);
Debug(DPARS, ("...load_user() done\n"))
- return u;
+ return (u);
}