aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/crontab
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/crontab')
-rw-r--r--usr.bin/crontab/Makefile19
-rw-r--r--usr.bin/crontab/crontab.193
-rw-r--r--usr.bin/crontab/crontab.386bsd27
-rw-r--r--usr.bin/crontab/crontab.5188
-rw-r--r--usr.bin/crontab/crontab.c417
5 files changed, 744 insertions, 0 deletions
diff --git a/usr.bin/crontab/Makefile b/usr.bin/crontab/Makefile
new file mode 100644
index 000000000000..64577960205a
--- /dev/null
+++ b/usr.bin/crontab/Makefile
@@ -0,0 +1,19 @@
+#
+# PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
+# -------------------- ----- ----------------------
+# CURRENT PATCH LEVEL: 1 00131
+# -------------------- ----- ----------------------
+#
+# 06 Apr 93 Adam Glass Fixed so manual pages install, install crontab
+# with proper permissions and owners
+#
+PROG= crontab
+SRCS= crontab.c misc.c entry.c env.c
+CFLAGS+=-I${.CURDIR} -I${.CURDIR}/../../libexec/crond -DDEBUGGING=1 -DBSD -DCRONDIR='"/var/cron"' -fstrength-reduce
+BINOWN =root
+BINMODE=4111
+MAN1= crontab.1
+MAN5= crontab.5
+
+.include <bsd.prog.mk>
+.PATH: ${.CURDIR}/../../libexec/crond
diff --git a/usr.bin/crontab/crontab.1 b/usr.bin/crontab/crontab.1
new file mode 100644
index 000000000000..ab1acbb1abe9
--- /dev/null
+++ b/usr.bin/crontab/crontab.1
@@ -0,0 +1,93 @@
+.\" $Header: /a/cvs/386BSD/src/usr.bin/crontab/crontab.1,v 1.1.1.1 1993/06/12 14:53:53 rgrimes Exp $
+.\"
+.\"/* Copyright 1988,1990 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, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
+.\" * paul@vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
+.\" */
+.TH CRONTAB 1 "9 December 1988"
+.UC 4
+.SH NAME
+crontab \- maintain crontab files for individual users
+.SH SYNOPSIS
+crontab [ -u user ] { -l | -d | -r file }
+.SH DESCRIPTION
+.I Crontab
+is the program used to install, deinstall or list the tables
+used to drive the
+.IR crond (8)
+daemon in Vixie Cron. Each user has their own crontab, and though these are
+files in /var, they are not readable or writable by anyone or anything
+except the super-user or the
+.IR crond (8)
+or
+.I crontab
+programs.
+.PP
+If the
+.I allow
+file exists, then you must be listed therein in order to be allowed to use
+this command. If the
+.I allow
+file does not exist but the
+.I deny
+file does exist, then you must \fBnot\fR be listed in the
+.I deny
+file in order to use this command. If neither of these files exists, then
+depending on site-dependent configuration parameters, only the super user
+will be allowed to use this command, or all users will be able to use this
+command.
+.PP
+If the
+.I -u
+option is given, it specifies the name of the user whose crontab is to be
+tweaked. If this option is not given,
+.I crontab
+examines "your" crontab, i.e., the crontab of the person executing the
+command. Note that
+.IR su (8)
+can confuse
+.I crontab
+and that if you are running inside of
+.IR su (8)
+you should always use the
+.I -u
+option for safety's sake.
+.PP
+The
+.I -l
+option causes the current crontab to be displayed on standard output.
+.PP
+The
+.I -d
+option causes the current crontab to be deleted.
+.PP
+The
+.I -r
+option is used to replace the current
+crontab (if any) with the contents of the named file.
+.SH "SEE ALSO"
+crontab(5), crond(8)
+.SH FILES
+.nf
+/var/cron/allow
+/var/cron/deny
+.fi
+.SH DIAGNOSTICS
+A fairly informative usage message appears if you run it with a bad command
+line.
+.SH AUTHOR
+.nf
+Paul Vixie, paul@vixie.sf.ca.us
diff --git a/usr.bin/crontab/crontab.386bsd b/usr.bin/crontab/crontab.386bsd
new file mode 100644
index 000000000000..9070efa38c02
--- /dev/null
+++ b/usr.bin/crontab/crontab.386bsd
@@ -0,0 +1,27 @@
+# /etc/crontab.src - root's crontab for Vixie's cron
+#
+# PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
+# -------------------- ----- ----------------------
+# CURRENT PATCH LEVEL: 1 00131
+# -------------------- ----- ----------------------
+#
+# 06 Apr 93 Adam Glass Fixed to be a better template for 386bsd
+#
+SHELL=/bin/sh
+PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
+HOME=/var/log
+#
+#minute hour mday month wday command
+#
+#0/10 * * * * /etc/dmesg - >> messages
+#0/15 * * * * /usr/lib/atrun
+#37 4 * * * ./cronrun-day > cronout-day 2>&1
+#43 4 * * Sun ./cronrun-wk > cronout-wk 2>&1
+#51 4 1 * * ./cronrun-mon > cronout-mon 2>&1
+0/15 * * * * /usr/libexec/atrun
+0 2 * * * /etc/daily > /var/log/daily.out 2>&1
+30 3 * * 6 /etc/weekly > /var/log/weekly.out 2>&1
+30 5 1 * * /etc/monthly > /var/log/monthly.out 2>&1
+#45 * * * * /bin/echo /usr/local/bin/uucico -r1 | /bin/su uucpa
+#0-59/5 * * * * /usr/local/bin/uucico -r1
+#37 * * * * touch /var/spool/uucp/jpunix/C./C.A0000
diff --git a/usr.bin/crontab/crontab.5 b/usr.bin/crontab/crontab.5
new file mode 100644
index 000000000000..3ea488704842
--- /dev/null
+++ b/usr.bin/crontab/crontab.5
@@ -0,0 +1,188 @@
+.\" $Header: /a/cvs/386BSD/src/usr.bin/crontab/crontab.5,v 1.1 1993/07/02 07:25:42 root Exp $
+.\"
+.\"/* Copyright 1988,1990 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, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
+.\" * paul@vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
+.\" */
+.TH CRONTAB 5 "15 January 1990"
+.UC 4
+.SH NAME
+crontab \- tables for driving cron
+.SH DESCRIPTION
+A
+.I crontab
+file contains instructions to the
+.IR crond (8)
+daemon of the general form: ``run this command at this time on this date''.
+Each user has their own crontab, and commands in any given crontab will be
+executed as the user who owns the crontab. Uucp and News will usually have
+their own crontabs, eliminating the need for explicitly running
+.IR su (1)
+as part of a cron command.
+.PP
+Blank lines and leading spaces and tabs are ignored. Lines whose first
+non-space character is a pound-sign (#) are comments, and are ignored.
+Note that comments are not allowed on the same line as cron commands, since
+they will be taken to be part of the command. Similarly, comments are not
+allowed on the same line as environment variable settings.
+.PP
+An active line in a crontab will be either an environment setting or a cron
+command. An environment setting is of the form,
+.PP
+ name = value
+.PP
+where the spaces around the equal-sign (=) are optional, and any subsequent
+non-leading spaces in
+.I value
+will be part of the value assigned to
+.IR name .
+The
+.I value
+string may be placed in quotes (single or double, but matching) to preserve
+leading or trailing blanks.
+.PP
+Several environment variables are set up
+automatically by the
+.IR crond (8)
+daemon from the /etc/passwd line of the crontab's owner: USER, HOME, and SHELL.
+HOME and SHELL may be overridden by settings in the crontab; USER may not.
+.PP
+(Note: for UUCP, always set SHELL=/bin/sh, or
+.IR crond (8)
+will cheerfully try to execute your commands using /usr/lib/uucp/uucico.)
+.PP
+(Another note: the USER variable is sometimes called LOGNAME or worse on
+System V... on these systems, LOGNAME will be set rather than USER.)
+.PP
+In addition to USER, HOME, and SHELL,
+.IR crond (8)
+will look at MAILTO if it has any reason to send mail as a result of running
+commands in ``this'' crontab. If MAILTO is defined (and non-empty), mail is
+sent to the user so named. If MAILTO is defined but empty (MAILTO=""), no
+mail will be sent. Otherwise mail is sent to the owner of the crontab. This
+option is useful if you decide on /bin/mail instead of /usr/lib/sendmail as
+your mailer when you install cron -- /bin/mail doesn't do aliasing, and UUCP
+usually doesn't read its mail.
+.PP
+The format of a cron command is very much the V7 standard, with a number of
+upward-compatible extensions. Each line has five time and date fields,
+followed by a command. Commands are executed by
+.IR crond (8)
+when the minute, hour, and month of year fields match the current time,
+.I and
+when at least one of the two day fields (day of month, or day of week)
+match the current time (see ``Note'' below).
+.IR crond (8)
+examines cron entries once every minute.
+The time and date fields are:
+.IP
+.ta 1.5i
+field allowed values
+.br
+----- --------------
+.br
+minute 0-59
+.br
+hour 0-23
+.br
+day of month 0-31
+.br
+month 0-12 (or names, see below)
+.br
+day of week 0-7 (0 or 7 is Sun, or use names)
+.br
+.PP
+A field may be an asterisk (*), which always matches the
+current time.
+.PP
+Ranges of numbers are allowed. Ranges are two numbers separated
+with a hyphen. The specified range is inclusive. For example,
+8-11 for an ``hours'' entry specifies execution at hours 8, 9, 10
+and 11.
+.PP
+Lists are allowed. A list is a set of numbers (or ranges)
+separated by commas. Examples: ``1,2,5,9'', ``0-4,8-12''.
+.PP
+Step values can be used in conjunction with ranges. Following
+a range with ``/<number>'' specifies skips of the number's value
+through the range. For example, ``0-23/2'' can be used in the hours
+field to specify command execution every other hour (the alternative
+in the V7 standard is ``0,2,4,6,8,10,12,14,16,18,20,22'').
+.PP
+Names can also be used for the ``month'' and ``day of week''
+fields. Use the first three letters of the particular
+day or month (case doesn't matter). Ranges or
+lists of names are not allowed.
+.PP
+The ``sixth'' field (the rest of the line) specifies the command to be
+run.
+The entire command portion of the line, up to a newline or %
+character, will be executed by the user's login shell or by the shell
+specified in the SHELL variable of the cronfile.
+Percent-signs (%) in the command, unless escaped with backslash
+(\\), will be changed into newline characters, and all data
+after the first % will be sent to the command as standard
+input.
+.PP
+Note: The day of a command's execution can be specified by two
+fields \(em day of month, and day of week. If both fields are
+restricted (ie, aren't *), the command will be run when
+.I either
+field matches the current time. For example,
+.br
+``30 4 1,15 * 5''
+would cause a command to be run at 4:30 am on the 1st and 15th of each
+month, plus every Friday.
+.SH EXAMPLE CRON FILE
+.nf
+
+# use /bin/sh to run commands, no matter what /etc/passwd says
+SHELL=/bin/sh
+# mail any output to `paul', no matter whose crontab this is
+MAILTO=paul
+#
+# run five minutes after midnight, every day
+5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
+# run at 2:15pm on the first of every month -- output mailed to paul
+15 14 1 * * $HOME/bin/monthly
+# run at 10 pm on weekdays, annoy Joe
+0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
+23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
+5 4 * * sun echo "run at 5 after 4 every sunday"
+.fi
+.SH SEE ALSO
+crond(8), crontab(1)
+.SH EXTENSIONS
+When specifying day of week, both day 0 and day 7 will be considered Sunday.
+BSD and ATT seem to disagree about this.
+.PP
+Lists and ranges are allowed to co-exist in the same field. "1-3,7-9" would
+be rejected by ATT or BSD cron -- they want to see "1-3" or "7,8,9" ONLY.
+.PP
+Ranges can include "steps", so "1-9/2" is the same as "1,3,5,7,9".
+.PP
+Names of months or days of the week can be specified by name.
+.PP
+Environment variables can be set in the crontab. In BSD or ATT, the
+environment handed to child processes is basically the one from /etc/rc.
+.PP
+Command output is mailed to the crontab owner (BSD can't do this), can be
+mailed to a person other than the crontab owner (SysV can't do this), or the
+feature can be turned off and no mail will be sent at all (SysV can't do this
+either).
+.SH AUTHOR
+.nf
+Paul Vixie, paul@vixie.sf.ca.us
diff --git a/usr.bin/crontab/crontab.c b/usr.bin/crontab/crontab.c
new file mode 100644
index 000000000000..e65dbbdb3d32
--- /dev/null
+++ b/usr.bin/crontab/crontab.c
@@ -0,0 +1,417 @@
+#if !defined(lint) && !defined(LINT)
+static char rcsid[] = "$Header: /a/cvs/386BSD/src/usr.bin/crontab/crontab.c,v 1.1.1.1 1993/06/12 14:53:53 rgrimes Exp $";
+#endif
+
+/* Revision 1.5 87/05/02 17:33:22 paul
+ * pokecron? (RCS file has the rest of the log)
+ *
+ * Revision 1.5 87/05/02 17:33:22 paul
+ * baseline for mod.sources release
+ *
+ * Revision 1.4 87/03/31 13:11:48 paul
+ * I won't say that rs@mirror gave me this idea but crontab uses getopt() now
+ *
+ * Revision 1.3 87/03/30 23:43:48 paul
+ * another suggestion from rs@mirror:
+ * use getpwuid(getuid)->pw_name instead of getenv("USER")
+ * this is a boost to security...
+ *
+ * Revision 1.2 87/02/11 17:40:12 paul
+ * changed command syntax to allow append and replace instead of append as
+ * default and no replace at all.
+ *
+ * Revision 1.1 87/01/26 23:49:06 paul
+ * Initial revision
+ *
+ * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
+ * -------------------- ----- ----------------------
+ * CURRENT PATCH LEVEL: 1 00131
+ * -------------------- ----- ----------------------
+ *
+ * 06 Apr 93 Adam Glass Fixes so it compiles quitely
+ *
+ */
+
+/* Copyright 1988,1990 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, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
+ * paul@vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
+ */
+
+
+#define MAIN_PROGRAM
+
+
+#include "cron.h"
+#include <pwd.h>
+#include <errno.h>
+#include <sys/file.h>
+#if defined(BSD)
+# include <sys/time.h>
+#endif /*BSD*/
+
+/* extern char *sprintf(); */
+
+
+static int Pid;
+static char User[MAX_UNAME], RealUser[MAX_UNAME];
+static char Filename[MAX_FNAME];
+static FILE *NewCrontab;
+static int CheckErrorCount;
+static enum {opt_unknown, opt_list, opt_delete, opt_replace}
+ Option;
+
+extern void log_it();
+
+#if DEBUGGING
+static char *Options[] = {"???", "list", "delete", "replace"};
+#endif
+
+void
+usage()
+{
+ fprintf(stderr, "usage: %s [-u user] ...\n", ProgramName);
+ fprintf(stderr, " ... -l (list user's crontab)\n");
+ fprintf(stderr, " ... -d (delete user's crontab)\n");
+ fprintf(stderr, " ... -r file (replace user's crontab)\n");
+ exit(ERROR_EXIT);
+}
+
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ void parse_args(), set_cron_uid(), set_cron_cwd(),
+ list_cmd(), delete_cmd(), replace_cmd();
+
+ Pid = getpid();
+ ProgramName = argv[0];
+#if defined(BSD)
+ setlinebuf(stderr);
+#endif
+ parse_args(argc, argv); /* sets many globals, opens a file */
+ set_cron_uid();
+ set_cron_cwd();
+ if (!allowed(User)) {
+ fprintf(stderr,
+ "You (%s) are not allowed to use this program (%s)\n",
+ User, ProgramName);
+ fprintf(stderr, "See crontab(1) for more information\n");
+ log_it(RealUser, Pid, "AUTH", "crontab command not allowed");
+ exit(ERROR_EXIT);
+ }
+ switch (Option)
+ {
+ case opt_list: list_cmd();
+ break;
+ case opt_delete: delete_cmd();
+ break;
+ case opt_replace: replace_cmd();
+ break;
+ }
+}
+
+
+ void
+parse_args(argc, argv)
+ int argc;
+ char *argv[];
+{
+ void usage();
+ char *getenv(), *strcpy();
+ int getuid();
+ struct passwd *getpwnam();
+ extern int getopt(), optind;
+ extern char *optarg;
+
+ struct passwd *pw;
+ int argch;
+
+ if (!(pw = getpwuid(getuid())))
+ {
+ fprintf(stderr, "%s: your UID isn't in the passwd file.\n",
+ ProgramName);
+ fprintf(stderr, "bailing out.\n");
+ exit(ERROR_EXIT);
+ }
+ strcpy(User, pw->pw_name);
+ strcpy(RealUser, User);
+ Filename[0] = '\0';
+ Option = opt_unknown;
+ while (EOF != (argch = getopt(argc, argv, "u:ldr:x:")))
+ {
+ switch (argch)
+ {
+ case 'x':
+ if (!set_debug_flags(optarg))
+ usage();
+ break;
+ case 'u':
+ if (getuid() != ROOT_UID)
+ {
+ fprintf(stderr,
+ "must be privileged to use -u\n");
+ exit(ERROR_EXIT);
+ }
+ if ((struct passwd *)NULL == getpwnam(optarg))
+ {
+ fprintf(stderr, "%s: user `%s' unknown\n",
+ ProgramName, optarg);
+ exit(ERROR_EXIT);
+ }
+ (void) strcpy(User, optarg);
+ break;
+ case 'l':
+ if (Option != opt_unknown)
+ usage();
+ Option = opt_list;
+ break;
+ case 'd':
+ if (Option != opt_unknown)
+ usage();
+ Option = opt_delete;
+ break;
+ case 'r':
+ if (Option != opt_unknown)
+ usage();
+ Option = opt_replace;
+ (void) strcpy(Filename, optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ endpwent();
+
+ if (Option == opt_unknown || argv[optind] != NULL)
+ usage();
+
+ if (Option == opt_replace) {
+ if (!Filename[0]) {
+ /* getopt(3) says this can't be true
+ * but I'm paranoid today.
+ */
+ fprintf(stderr, "filename must be given for -a or -r\n");
+ usage();
+ }
+ /* we have to open the file here because we're going to
+ * chdir(2) into /var/cron before we get around to
+ * reading the file.
+ */
+ if (!strcmp(Filename, "-")) {
+ NewCrontab = stdin;
+ } else {
+ if (!(NewCrontab = fopen(Filename, "r"))) {
+ perror(Filename);
+ exit(ERROR_EXIT);
+ }
+ }
+ }
+
+ Debug(DMISC, ("user=%s, file=%s, option=%s\n",
+ User, Filename, Options[(int)Option]))
+}
+
+
+ void
+list_cmd()
+{
+ extern errno;
+ char n[MAX_FNAME];
+ FILE *f;
+ int ch;
+
+ log_it(RealUser, Pid, "LIST", User);
+ (void) sprintf(n, CRON_TAB(User));
+ if (!(f = fopen(n, "r")))
+ {
+ if (errno == ENOENT)
+ fprintf(stderr, "no crontab for %s\n", User);
+ else
+ perror(n);
+ exit(ERROR_EXIT);
+ }
+
+ /* file is open. copy to stdout, close.
+ */
+ Set_LineNum(1)
+ while (EOF != (ch = get_char(f)))
+ putchar(ch);
+ fclose(f);
+}
+
+
+ void
+delete_cmd()
+{
+ extern errno;
+ int unlink();
+ void poke_daemon();
+ char n[MAX_FNAME];
+
+ log_it(RealUser, Pid, "DELETE", User);
+ (void) sprintf(n, CRON_TAB(User));
+ if (unlink(n))
+ {
+ if (errno == ENOENT)
+ fprintf(stderr, "no crontab for %s\n", User);
+ else
+ perror(n);
+ exit(ERROR_EXIT);
+ }
+ poke_daemon();
+}
+
+
+ void
+check_error(msg)
+ char *msg;
+{
+ CheckErrorCount += 1;
+ fprintf(stderr, "\"%s\", line %d: %s\n", Filename, LineNumber, msg);
+}
+
+
+ void
+replace_cmd()
+{
+ entry *load_entry();
+ int load_env();
+ int unlink();
+ void free_entry();
+ void check_error();
+ void poke_daemon();
+ extern errno;
+
+ char n[MAX_FNAME], envstr[MAX_ENVSTR], tn[MAX_FNAME];
+ FILE *tmp;
+ int ch;
+ entry *e;
+ int status;
+ time_t now = time(NULL);
+
+ (void) sprintf(n, "tmp.%d", Pid);
+ (void) sprintf(tn, CRON_TAB(n));
+ if (!(tmp = fopen(tn, "w"))) {
+ perror(tn);
+ exit(ERROR_EXIT);
+ }
+
+ /* write a signature at the top of the file. for brian.
+ */
+ fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now));
+ fprintf(tmp, "# (Cron version -- %s)\n", rcsid);
+
+ /* copy the crontab to the tmp
+ */
+ Set_LineNum(1)
+ while (EOF != (ch = get_char(NewCrontab)))
+ putc(ch, tmp);
+ fclose(NewCrontab);
+ fflush(tmp); rewind(tmp);
+
+ if (ferror(tmp)) {
+ fprintf(stderr, "%s: error while writing new crontab to %s\n",
+ ProgramName, tn);
+ fclose(tmp); unlink(tn);
+ exit(ERROR_EXIT);
+ }
+
+ /* check the syntax of the file being installed.
+ */
+
+ /* BUG: was reporting errors after the EOF if there were any errors
+ * in the file proper -- kludged it by stopping after first error.
+ * vix 31mar87
+ */
+ CheckErrorCount = 0;
+ while (!CheckErrorCount && (status = load_env(envstr, tmp)) >= OK)
+ {
+ if (status == FALSE)
+ {
+ if (NULL != (e = load_entry(NewCrontab, check_error)))
+ free((char *) e);
+ }
+ }
+
+ if (CheckErrorCount != 0)
+ {
+ fprintf(stderr, "errors in crontab file, can't install.\n");
+ fclose(tmp); unlink(tn);
+ exit(ERROR_EXIT);
+ }
+
+ if (fchown(fileno(tmp), ROOT_UID, -1) < OK)
+ {
+ perror("chown");
+ fclose(tmp); unlink(tn);
+ exit(ERROR_EXIT);
+ }
+
+ if (fchmod(fileno(tmp), 0600) < OK)
+ {
+ perror("chown");
+ fclose(tmp); unlink(tn);
+ exit(ERROR_EXIT);
+ }
+
+ if (fclose(tmp) == EOF) {
+ perror("fclose");
+ unlink(tn);
+ exit(ERROR_EXIT);
+ }
+
+ (void) sprintf(n, CRON_TAB(User));
+ if (rename(tn, n))
+ {
+ fprintf(stderr, "%s: error renaming %s to %s\n",
+ ProgramName, tn, n);
+ perror("rename");
+ unlink(tn);
+ exit(ERROR_EXIT);
+ }
+ log_it(RealUser, Pid, "REPLACE", User);
+
+ poke_daemon();
+}
+
+
+ void
+poke_daemon()
+{
+#if defined(BSD)
+ 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;
+ }
+#endif /*BSD*/
+#if defined(ATT)
+ if (utime(SPOOL_DIR, NULL) < OK)
+ {
+ fprintf(stderr, "crontab: can't update mtime on spooldir\n");
+ perror(SPOOL_DIR);
+ return;
+ }
+#endif /*ATT*/
+}