update for newest version of vixie's cron, as of May 27 1993

This commit is contained in:
cgd 1993-05-28 08:33:52 +00:00
parent 01eda6ff10
commit 9eccc35a44
22 changed files with 698 additions and 168 deletions

36
libexec/crond/CHANGES.V2 Normal file
View File

@ -0,0 +1,36 @@
Vixie Cron Changes from V1 to V2
Paul Vixie
8-Feb-1988
Many changes were made in a rash of activity about six months ago, the exact
list of which is no longer clear in my memory. I know that V1 used a file
called POKECRON in /usr/spool/cron to tell it that it was time to re-read
all the crontab files; V2 uses the modtime the crontab directory as a flag to
check out the crontab files; those whose modtime has changed will be re-read,
and the others left alone. Note that the crontab(1) command will do a utimes
call to make sure the mtime of the dir changes, since the filename/inode will
often remain the same after a replacement and the mtime wouldn't change in
that case.
8-Feb-88: made it possible to use much larger environment variable strings.
V1 allowed 100 characters; V2 allows 1000. This was needed for PATH
variables on some systems. Thanks to Toerless Eckert for this idea.
E-mail: UUCP: ...pyramid!fauern!faui10!eckert
16-Feb-88: added allow/deny, moved /usr/spool/cron/crontabs to
/usr/lib/cron/tabs. allow and deny are /usr/lib/cron/{allow,deny},
since the sysv naming for this depends on 'at' using the same
dir, which would be stupid (hint: use /usr/{lib,spool}/at).
22-Feb-88: made it read the spool directory for crontabs and look each one
up using getpwnam() rather than reading all passwds with getpwent()
and trying to open each crontab.
9-Dec-88: made it sync to :00 after the minute, makes cron predictable.
added logging to /var/cron/log.
14-Apr-90: (actually, changes since December 1989)
fixed a number of bugs reported from the net and from John Gilmore.
added syslog per Keith Bostic. security features including not
being willing to run a command owned or writable by other than
the owner of the crontab 9not working well yet)

85
libexec/crond/CONVERSION Normal file
View File

@ -0,0 +1,85 @@
$Header: /cvsroot/src/libexec/crond/Attic/CONVERSION,v 1.1 1993/05/28 08:33:55 cgd Exp $
Conversion of BSD 4.[23] crontab files:
Edit your current crontab (/usr/lib/crontab) into little pieces, with each
users' commands in a different file. This is different on 4.2 and 4.3,
but I'll get to that below. The biggest feature of this cron is that you
can move 'news' and 'uucp' cron commands into files owned and maintainable
by those two users. You also get to rip all the fancy 'su' footwork out
of the cron commands. On 4.3, there's no need for the 'su' stuff since the
user name appears on each command -- but I'd still rather have separate
crontabs with seperate environments and so on.
Leave the original /usr/lib/crontab! This cron doesn't use it, so you may
as well keep it around for a while in case something goes wakko with this
fancy version.
Most commands in most crontabs are run by root, have to run by root, and
should continue to be run by root. They still have to be in their own file;
I recommend /etc/crontab.src or /usr/adm/crontab.src.
'uucp's commands need their own file; how about /usr/lib/uucp/crontab.src?
'news' also, perhaps in /usr/lib/news/crontab.src...
I say `how about' and `perhaps' because it really doesn't matter to anyone
(except you) where you put the crontab source files. The `crontab' command
COPIES them into a protected directory (CRONDIR/SPOOL_DIR in cron.h), named
after the user whose crontab it is. If you want to examine, replace, or
delete a crontab, the `crontab' command does all of those things. The
various `crontab.src' (my suggested name for them) files are just source
files---they have to be copied to SPOOLDIR using `crontab' before they'll be
executed.
On 4.2, your crontab might have a few lines like this:
5 * * * * su uucp < /usr/lib/uucp/uudemon.hr
10 4 * * * su uucp < /usr/lib/uucp/uudemon.day
15 5 * * 0 su uucp < /usr/lib/uucp/uudemon.wk
...or like this:
5 * * * * echo /usr/lib/uucp/uudemon.hr | su uucp
10 4 * * * echo /usr/lib/uucp/uudemon.day | su uucp
15 5 * * 0 echo /usr/lib/uucp/uudemon.wk | su uucp
On 4.3, they'd look a little bit better, but not much:
5 * * * * uucp /usr/lib/uucp/uudemon.hr
10 4 * * * uucp /usr/lib/uucp/uudemon.day
15 5 * * 0 uucp /usr/lib/uucp/uudemon.wk
For this cron, you'd create /usr/lib/uucp/crontab.src (or wherever you want
to keep uucp's commands) which would look like this:
# /usr/lib/uucp/crontab.src - uucp's crontab
#
PATH=/usr/lib/uucp:/bin:/usr/bin
SHELL=/bin/sh # otherwise it's uucico
HOME=/usr/lib/uucp # '' '' /usr/spool/uucppublic
#
5 * * * * uudemon.hr
10 4 * * * uudemon.day
15 5 * * 0 uudemon.wk
The application to the `news' cron commands (if any) is left for you to
figure out. Likewise if there are any other cruddy-looking 'su' commands in
your crontab commands, you don't need them anymore: just find a good place
to put the `crontab.src' (or whatever you want to call it) file for that
user, put the cron commands into it, and install it using the `crontab'
command (probably with "-u USERNAME", but see the man page).
If you run a 4.2-derived cron, you could of course just install your current
crontab in toto as root's crontab. It would work exactly the way your
current one does, barring the extra steps in installing or changing it.
There would still be advantages to this cron, mostly that you get mail if
there is any output from your cron commands.
One note about getting mail from cron: you will probably find, after you
install this version of cron, that your cron commands are generating a lot
of irritating output. The work-around for this is to redirect all EXPECTED
output to a per-execution log file, which you can examine if you want to
see the output from the "last time" a command was executed; if you get any
UNEXPECTED output, it will be mailed to you. This takes a while to get
right, but it's amazingly convenient. Trust me.

88
libexec/crond/FEATURES Normal file
View File

@ -0,0 +1,88 @@
$Header: /cvsroot/src/libexec/crond/Attic/FEATURES,v 1.1 1993/05/28 08:33:57 cgd Exp $
Features of Vixie's cron relative to BSD 4.[23] and SysV crons:
-- Environment variables can be set in each crontab. SHELL, USER,
and HOME are set from the user's passwd entry; all except USER
can be changed in the crontab. PATH is especially useful to
set there. TZ can be set, but cron ignores it other than passing
it on through to the commands it runs. Format is
variable=value
Blanks surrounding the '=' will be eaten; other blanks in value are
okay. Leading or trailing blanks can be preserved by quoting, single
or double quotes are okay, just so they match.
PATH=.:/bin:/usr/bin
SHELL=/bin/sh
FOOBAR = this is a long blanky example
Above, FOOBAR would get `this is a long blanky example' as its value.
SHELL and HOME will be examined when it's time to run a command; if
you don't change them, they default to your /etc/passwd entry.
*DANGER*, WILL ROBINSON! This means that all 'uucp' logins should set
SHELL=/bin/sh or cron will try to use /usr/lib/uucp/uucico as the
shell. This won't work.
MAILTO, if set to the login name of a user on your system, will be the
person that cron mails the output of commands in that crontab. This is
useful if you decide on BINMAIL when configuring cron.h, since binmail
doesn't know anything about aliasing.
Setting SHELL=/bin/sh will in general speed up your commands since it
is a much smaller shell than the one you probably use normally (csh
or ksh) and has enough features to work non-interactively.
-- Weekdays can be specified by name. Case is not significant, but only
the first three letters should be specified.
-- Months can likewise be specified by name. Three letters only.
-- Ranges and lists can be mixed. Standard crons won't allow '1,3-5'.
-- Ranges can specify 'step' values. '10-16/2' is like '10,12,14,16'.
-- Sunday is both day 0 and day 7 -- apparently BSD and ATT disagree
about this.
-- Each user gets their own crontab file. This is a win over BSD 4.2,
where only root has one, and over BSD 4.3, where they made the crontab
format incompatible and although the commands can be run by non-root
uid's, root is still the only one who can edit the crontab file. This
feature mimics the SysV cron.
-- The 'crontab' command is loosely compatible with SysV, but has more
options which just generally make more sense. Running crontab with
no arguments will print a cute little summary of the command syntax.
-- Comments and blank lines are allowed in the crontab file. Comments
must be on a line by themselves; leading whitespace is ignored, and
a '#' introduces the comment.
-- (big win) If the `crontab' command changes anything in any crontab, it
tells the 'cron' daemon, who reloads all the tables before running the
next iteration. In some crons, you have to kill and restart the
daemon whenever you change a crontab. In other crons, the crontab
file is reread and reparsed every minute even if it didn't change.
-- In order to support the automatic reload, the crontab files are not
readable or writable except by 'crontab' or 'cron'. This is not a
problem, since 'crontab' will let you do pretty much whatever you
want to your own crontab, or if you are root, to anybody's crontab.
-- If any output is generated by a command (on stdout OR stderr), it will
be mailed to the owner of the crontab that contained the command (or
MAILTO, see discussion of environment variables, above). The headers
of the mail message will include the command that was run, and a
complete list of the environment that was passed to it, which will
contain (at least) the USER (LOGNAME on SysV), HOME, and SHELL.
-- the dom/dow situation is odd. '* * 1,15 * Sun' will run on the
first and fifteenth AND every Sunday; '* * * * Sun' will run *only*
on Sundays; '* * 1,15 * *' will run *only* the 1st and 15th. this
is why we keep 'e->dow_star' and 'e->dom_star'. I didn't think up
this behaviour; it's how cron has always worked but the documentation
hasn't been very clear.

69
libexec/crond/INSTALL Normal file
View File

@ -0,0 +1,69 @@
$Header: /cvsroot/src/libexec/crond/Attic/INSTALL,v 1.1 1993/05/28 08:33:59 cgd Exp $
*** This does not work on ATT SysV yet, and given the feature overlap,
it may never do so.
Read the comments at the top of the Makefile, then edit the area marked
'configurable stuff'.
Edit config.h. The stuff I expect you to change is down a bit from the
top of the file, but it's clearly marked.
You don't have to create the /var/cron or /var/cron/tabs directories, since
both the daemon and the `crontab' program will do this the first time they
run if they don't exist. You do need to have a /var, though -- just "mkdir
/var" if you don't have one, or you can "mkdir /usr/var; ln -s /usr/var /var"
if you expect your /var to have a lot of stuff in it.
You will also need /usr/local/etc and /usr/local/bin directories unless you
change the Makefile. These will have to be created by hand, but if you are
a long-time Usenet user you probably have them already. /usr/local/man is
where I keep my man pages, but I have the source for `man' and you probably
do not. Therefore you may have to put the man pages into /usr/man/manl,
which will be hard since there will be name collisions. (Note that the man
command was originally written by Bill Joy before he left Berkeley, and it
contains no AT&T code, so it is in UUNET's archive of freely-distributable
BSD code.)
say:
make all
su and say:
make install
Note that if I can get you to "su and say" something just by asking, you have
a very serious security problem on your system and you should look into it.
Edit your /usr/lib/crontab file into little pieces -- see the CONVERSION file
for help on this.
Use the `crontab' command to install all the little pieces you just created.
Some examples (see below before trying any of these!)
crontab -u uucp -r /usr/lib/uucp/crontab.src
crontab -u news -r /usr/lib/news/crontab.src
crontab -u root -r /usr/adm/crontab.src
Notes on above examples: (1) the .src files are copied at the time the
command is issued; changing the source files later will have no effect until
they are reinstalled with another `crontab -r' command. (2) The crontab
command will affect the crontab of the person using the command unless `-u
USER' is given; `-u' only works for root. When using most `su' commands
under most BSD's, `crontab' will still think of you as yourself even though
you may think of yourself as root -- so use `-u' liberally. (3) the `-r'
option stands for `replace'; check the man page for crontab(1) for other
possibilities.
Kill your existing cron daemon -- do `ps aux' and look for /etc/cron.
Edit your /etc/rc or /etc/rc.local, looking for the line that starts up
/etc/cron. Comment it out and add a line to start the new cron daemon
-- usually /usr/local/etc/crond, unless you changed it in the Makefile.
Start up this cron daemon yourself as root. Just type /usr/local/etc/crond
(or whatever); no '&' is needed since the cron daemon forks itself and the
process you executed returns immediately.
ATT notes: for those people unfortunate enough to be stuck on a AT&T UNIX,
you will need the public-domain "libndir", found in the B News source and in
any comp.sources.unix archive. You will also need to hack the code some.

30
libexec/crond/MANIFEST Normal file
View File

@ -0,0 +1,30 @@
(this now split up between /usr/src/libexec/crond and /usr/src/usr.bin/crontab
-cgd)
File Name Archive # Description
-----------------------------------------------------------
CHANGES.V2 1
CONVERSION 1
FEATURES 1
INSTALL 1
MANIFEST 1 This shipping list
Makefile 1
README 1
THANKS 1
arpadate.c 1
bitstring.3 1
bitstring.h 1
config.h 2
cron.h 2
crond.8 1
crond.c 2
crontab.1 1
crontab.5 2
crontab.c 2
database.c 2
do_command.c 3
entry.c 3
env.c 1
job.c 1
misc.c 3
user.c 1

View File

@ -1,13 +1,13 @@
# Makefile for vixie's cron
#
# $Header: /cvsroot/src/libexec/crond/Attic/Makefile.vixie,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $
# $Header: /cvsroot/src/libexec/crond/Attic/Makefile.vixie,v 1.2 1993/05/28 08:34:03 cgd Exp $
#
# vix 03mar88 [moved to RCS, rest of log is in there]
# vix 30mar87 [goodbye, time.c; hello, getopt]
# vix 12feb87 [cleanup for distribution]
# vix 30dec86 [written]
#/* Copyright 1988,1990 by Paul Vixie
#/* Copyright 1988,1990,1993 by Paul Vixie
# * All rights reserved
# *
# * Distribute freely, except: don't remove my name from the source or
@ -21,8 +21,7 @@
# *
# * 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
# * paul@vix.com || {hoptoad,pacbell,decwrl}!vixie!paul
# */
# NOTES:
@ -36,9 +35,7 @@
# SHELL is for the 'augumented make' systems where 'make' imports
# SHELL from the environment and then uses it to run its commands.
# if your environment SHELL variable is /bin/csh, make goes real
# slow and sometimes does the wrong thing. BINDIR is where the
# 'crontab' command goes, and should be a common place like /usr/bin.
# LIBDIR is where the cron daemon lives; /usr/etc is common.
# slow and sometimes does the wrong thing.
#
# this package needs the 'bitstring macros' library, which is
# available from me or from the comp.sources.unix archive. if you
@ -50,7 +47,7 @@
#################################### begin configurable stuff
#<<DESTROOT is assumed to have ./etc, ./bin, and ./man subdirectories>>
DESTROOT = /usr/
DESTROOT = $(DESTDIR)/usr/local
#<<CRONDIR will be created by crond or crontab if nec'y>>
CRONDIR = /var/cron
#<<need bitstring.h>>
@ -60,8 +57,8 @@ INCLUDE = -I.
#LIBS = /usr/local/lib/getopt.o
LIBS =
#<<optimize or debug?>>
OPTIM = -O -fstrength-reduce
#OPTIM = -g
#OPTIM = -O
OPTIM = -g
#<<want -x flag for debugging?>>
DEBUGGING = -DDEBUGGING=1
#DEBUGGING = -DDEBUGGING=0
@ -84,10 +81,10 @@ INFOS = README CHANGES.V2 FEATURES INSTALL CONVERSION THANKS
MANPAGES = bitstring.3 crontab.5 crontab.1 crond.8
HEADERS = bitstring.h cron.h config.h
SOURCES = crond.c crontab.c database.c do_command.c \
entry.c env.c job.c misc.c user.c
entry.c env.c job.c misc.c user.c arpadate.c
SHAR_SOURCE = $(INFOS) $(MANPAGES) Makefile $(HEADERS) $(SOURCES)
LINT_CROND = crond.c database.c user.c entry.c \
misc.c job.c do_command.c env.c
misc.c job.c do_command.c env.c arpadate.c
LINT_CRONTAB = crontab.c misc.c entry.c env.c
CRON_OBJ = crond.o database.o user.o entry.o \
misc.o job.o do_command.o env.o
@ -108,10 +105,10 @@ crontab : $(CRONTAB_OBJ)
$(CC) -o crontab $(CRONTAB_OBJ) $(LIBS)
install : all
install -c -m 111 -o root -s crond $(DESTROOT)/libexec/
install -c -m 111 -o root -s crond $(DESTROOT)/etc/
install -c -m 4111 -o root -s crontab $(DESTROOT)/bin/
#install -c crontab.1 $(DESTROOT)/man/man1/crontab.1
#install -c crond.8 $(DESTROOT)/man/man8/crond.8
install -c crontab.1 $(DESTROOT)/man/man1/crontab.1
install -c crond.8 $(DESTROOT)/man/man8/crond.8
install -c crontab.5 $(DESTROOT)/man/man5/crontab.5
clean :; rm -f *.o crond crontab a.out core tags *~ #*

View File

@ -1,25 +1,27 @@
Vixie's Cron V2.1
May 29, 1991
Vixie's Cron V3.0
May 29, 1993
[V2.1 was May 29, 1991]
[V2.0 was July 5, 1990]
[V2.0-beta was December 9, 1988]
[V1.0 was May 6, 1987]
Paul Vixie
This is a version of 'cron' that is known to run on BSD 4.[23] systems. It
is functionally based on the SysV cron, which means that each user can have
This is a version of 'cron' that is known to run on BSD 4.x systems. It is
functionally based on the SysV cron, which means that each user can have
their own crontab file (all crontab files are stored in a read-protected
directory, usually /var/cron/tabs). No direct support is provided for
'at'; you can continue to run 'atrun' from the crontab as you have been
doing. If you don't have atrun (i.e., System V) you are in trouble.
directory, usually /var/cron/tabs). No direct support is provided for 'at';
you can continue to run 'atrun' from the crontab as you have been doing. If
you don't have atrun (i.e., System V) you might be in trouble. (I don't use
'at' myself so I don't care.)
A messages is logged each time a command is executed; also, the files
"allow" and "deny" in /var/cron can be used to control access to the
"crontab" command (which installs crontabs). It hasn't been tested on
SysV, although some effort has gone into making the port an easy one.
A message is logged each time a command is executed; also, the files "allow"
and "deny" in /var/cron can be used to control access to the "crontab"
command (which installs crontabs). It hasn't been tested on SysV, although
some effort has gone into making the port an easy one.
The code was all written by me, and is (quoted from Makefile):
#/* Copyright 1988,1990 by Paul Vixie
#/* Copyright 1988,1990,1991,1993 by Paul Vixie
# * All rights reserved
# *
# * Distribute freely, except: don't remove my name from the source or
@ -33,23 +35,24 @@ The code was all written by me, and is (quoted from Makefile):
# *
# * 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
# * paul@vix.com || {hoptoad,pacbell,decwrl}!vixie!paul
# */
This is more or less the copyright that USENET contributed software usually
has. Since ATT couldn't use this version if they had to freely distribute
source, and since I'd love to see them use it, I'll offer some rediculously
source, and since I'd love to see them use it, I'll offer some ridiculously
low license fee just to have them take it. In the unlikely event that they
do this, I will continue to support and distribute the pseudo-PD version, so
please, don't flame me for wanting my work to see a wider distribution.
This version of cron has appeared in BSD 4.4, BSD/386, 386BSD, and Linux.
To use this: Sorry, folks, there is no cutesy 'Configure' script. You'll
have to go edit a couple of files... So, here's the checklist:
Read all the FEATURES, INSTALL, and CONVERSION files
Edit config.h
Edit Makefile
Edit config.h
(both of these files have instructions inside; note that
some things in config.h are definable in Makefile and are
therefore surrounded by #ifndef...#endif)
@ -70,14 +73,14 @@ have to go edit a couple of files... So, here's the checklist:
if you like it, change your /etc/{rc,rc.local} to use it instead of
the old one.
$Header: /cvsroot/src/libexec/crond/Attic/README,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $
$Header: /cvsroot/src/libexec/crond/Attic/README,v 1.2 1993/05/28 08:34:05 cgd Exp $
$Source: /cvsroot/src/libexec/crond/Attic/README,v $
$Revision: 1.1.1.1 $
$Revision: 1.2 $
$Log: README,v $
Revision 1.1.1.1 1993/03/21 09:45:37 cgd
initial import of 386bsd-0.1 sources
Revision 1.2 1993/05/28 08:34:05 cgd
update for newest version of vixie's cron, as of May 27 1993
Revision 2.2 91/05/29 11:37:38 vixie
Revision 2.2 1991/05/29 11:37:38 vixie
vixie
Revision 2.1 90/07/18 00:23:54 vixie

27
libexec/crond/arpadate.c Normal file
View File

@ -0,0 +1,27 @@
#include <time.h>
#include "cron.h"
/* Sat, 27 Feb 93 11:44:51 CST
* 123456789012345678901234567
*/
char *
arpadate(
time_t *clock
) {
time_t t = clock ?*clock :time();
struct tm *tm = localtime(&t);
static char ret[30]; /* zone name might be >3 chars */
(void) sprintf(ret, "%s, %2d %s %2d %02d:%02d:%02d %s",
DowNames[tm->tm_wday],
tm->tm_mday,
MonthNames[tm->tm_mon],
tm->tm_year,
tm->tm_hour,
tm->tm_min,
tm->tm_sec,
tm->tm_zone);
return ret;
}

View File

@ -1,9 +1,9 @@
/* config.h - configurables for Vixie Cron
*
* $Header: /cvsroot/src/libexec/crond/Attic/config.h,v 1.2 1993/05/11 08:16:02 glass Exp $
* $Header: /cvsroot/src/libexec/crond/Attic/config.h,v 1.3 1993/05/28 08:34:09 cgd Exp $
*/
/* Copyright 1988,1990 by Paul Vixie
/* Copyright 1988,1990,1993 by Paul Vixie
* All rights reserved
*
* Distribute freely, except: don't remove my name from the source or
@ -24,6 +24,24 @@
#ifndef _CONFIG_FLAG
#define _CONFIG_FLAG
#if defined(BSD)
# define OLDBSD BSD
# undef BSD
# include <sys/param.h>
# if !defined(BSD)
# define BSD OLDBSD
# endif /*BSD*/
# undef OLDBSD
#endif /*BSD*/
#if (defined(BSD)) && (BSD >= 199103)
# include <paths.h>
#endif /*BSD*/
#if !defined(_PATH_SENDMAIL)
# define _PATH_SENDMAIL "/usr/lib/sendmail"
#endif /*SENDMAIL*/
/*
* these are site-dependent
*/
@ -36,17 +54,27 @@
* (hint: MAILTO= was added for this reason).
*/
# define MAILCMD "/usr/sbin/sendmail -F\"Cron Daemon\" -odi -oem -or0s %s" /*-*/
#define MAILCMD _PATH_SENDMAIL /*-*/
#define MAILARGS "%s -F\"Cron Daemon\" -odi -oem -or0s -t" /*-*/
/* -Fx = set full-name of sender
* -odi = Option Deliverymode Interactive
* -oem = Option Errors Mailedtosender
* -or0s = Option Readtimeout -- don't time out
* -t = recipients are in To: headers
*/
/* # define MAILCMD "/bin/mail -d %s" /*-*/
/* #define MAILCMD "/bin/mail" /*-*/
/* #define MAILARGS "%s -d \"%s\"" /*-*/
/* -d = undocumented but common flag: deliver locally?
*/
/* #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
* generate the Date: header.
*/
#ifndef CRONDIR
/* CRONDIR is where crond(8) and crontab(1) both chdir
* to; SPOOL_DIR, ALLOW_FILE, DENY_FILE, and LOG_FILE
@ -75,7 +103,7 @@
*/
#define ALLOW_FILE "allow" /*-*/
#define DENY_FILE "deny" /*-*/
#define LOG_FILE "log" /*-*/
/*#define LOG_FILE "log" /*-*/
/* if ALLOW_FILE and DENY_FILE are not defined or are
* defined but neither exists, should crontab(1) be
@ -110,6 +138,24 @@
/* where should the daemon stick its PID?
*/
#define PIDFILE "/var/run/crond.pid"
#ifdef _PATH_VARRUN
# define PIDDIR _PATH_VARRUN
#else
# define PIDDIR "/etc/"
#endif
#if defined(BSD) && (BSD >= 199103)
# define PIDFILE "%scron.pid"
#else
# define PIDFILE "%scrond.pid"
#endif
/* what editor to use if no EDITOR or VISUAL
* environment variable specified.
*/
#if defined(_PATH_VI)
# define EDITOR _PATH_VI
#else
# define EDITOR "/usr/ucb/vi"
#endif
#endif /*CONFIG_FLAG*/

View File

@ -1,11 +1,14 @@
/* cron.h - header for vixie's cron
*
* $Header: /cvsroot/src/libexec/crond/Attic/cron.h,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $
* $Header: /cvsroot/src/libexec/crond/Attic/cron.h,v 1.2 1993/05/28 08:34:11 cgd Exp $
* $Source: /cvsroot/src/libexec/crond/Attic/cron.h,v $
* $Revision: 1.1.1.1 $
* $Revision: 1.2 $
* $Log: cron.h,v $
* Revision 1.1.1.1 1993/03/21 09:45:37 cgd
* initial import of 386bsd-0.1 sources
* Revision 1.2 1993/05/28 08:34:11 cgd
* update for newest version of vixie's cron, as of May 27 1993
*
* Revision 2.2 1992/12/18 18:47:42 vixie
* vix/ckp
*
* Revision 2.1 90/07/18 00:23:47 vixie
* Baseline for 4.4BSD release
@ -26,7 +29,7 @@
* vix 30dec86 [written]
*/
/* Copyright 1988,1990 by Paul Vixie
/* Copyright 1988,1990,1993 by Paul Vixie
* All rights reserved
*
* Distribute freely, except: don't remove my name from the source or
@ -199,8 +202,8 @@ typedef struct _entry
typedef struct _user
{
struct _user *next, *prev; /* links */
int uid; /* uid from passwd file */
int gid; /* gid from passwd file */
uid_t uid; /* uid from passwd file */
gid_t gid; /* gid from passwd file */
char **envp; /* environ for commands */
time_t mtime; /* last modtime of crontab */
entry *crontab; /* this person's crontab */

View File

@ -1,4 +1,4 @@
.\" $Header: /cvsroot/src/libexec/crond/Attic/crond.8,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $
.\" $Header: /cvsroot/src/libexec/crond/Attic/crond.8,v 1.2 1993/05/28 08:34:12 cgd Exp $
.\"
.\"/* Copyright 1988,1990 by Paul Vixie
.\" * All rights reserved

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/crond.c,v 1.2 1993/03/28 17:24:43 glass Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/crond.c,v 1.3 1993/05/28 08:34:14 cgd Exp $";
#endif
/* Copyright 1988,1990 by Paul Vixie
@ -33,10 +33,10 @@ static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/crond.c,v 1.2 1
# include <sys/resource.h>
#endif /*BSD*/
extern int fork(), unlink();
/*extern int fprintf(), fork(), unlink();
extern time_t time();
extern void exit();
extern unsigned sleep();
extern unsigned sleep();*/
void
usage()
@ -262,7 +262,7 @@ sigchld_handler()
for (;;)
{
pid = wait3((int *) &waiter, WNOHANG, (struct rusage *)0);
pid = wait3(&waiter, WNOHANG, (struct rusage *)0);
switch (pid)
{
case -1:

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/database.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/database.c,v 1.2 1993/05/28 08:34:16 cgd Exp $";
#endif
/* vix 26jan87 [RCS has the log]
@ -48,8 +48,7 @@ load_database(old_db)
extern user *load_user(), *find_user();
extern char *env_get();
static DIR *dir = NULL;
DIR *dir;
struct stat statbuf;
struct direct *dp;
cron_db new_db;
@ -83,18 +82,15 @@ load_database(old_db)
return;
}
/* make sure the dir is open. only happens the first time, since
* the DIR is static and we don't close it. Rewind the dir.
/* we used to keep this dir open all the time, for the sake of
* efficiency. however, we need to close it in every fork, and
* we fork a lot more often than the mtime of the dir changes.
*/
if (dir == NULL)
if (!(dir = opendir(SPOOL_DIR)))
{
if (!(dir = opendir(SPOOL_DIR)))
{
log_it("CROND", getpid(), "OPENDIR FAILED", SPOOL_DIR);
(void) exit(ERROR_EXIT);
}
log_it("CROND", getpid(), "OPENDIR FAILED", SPOOL_DIR);
(void) exit(ERROR_EXIT);
}
(void) rewinddir(dir);
/* something's different. make a new database, moving unchanged
* elements from the old database, reloading elements that have
@ -108,7 +104,7 @@ load_database(old_db)
{
extern struct passwd *getpwnam();
struct passwd *pw;
int crontab_fd;
int crontab_fd = -1;
char fname[MAXNAMLEN+1],
tabname[MAXNAMLEN+1];
@ -193,6 +189,8 @@ next_crontab:
close(crontab_fd);
}
}
closedir(dir);
/* if we don't do this, then when our children eventually call
* getpwnam() in do_command.c's child_process to verify MAILTO=,
* they will screw us up (and v-v).

View File

@ -1,19 +1,16 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/do_command.c,v 1.3 1993/05/26 18:45:07 guido Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/do_command.c,v 1.4 1993/05/28 08:34:17 cgd Exp $";
#endif
/* $Source: /cvsroot/src/libexec/crond/Attic/do_command.c,v $
* $Revision: 1.3 $
* $Revision: 1.4 $
* $Log: do_command.c,v $
* Revision 1.3 1993/05/26 18:45:07 guido
* Weird security hole removed. Thanks to cor@hacktic.nl
* Revision 1.4 1993/05/28 08:34:17 cgd
* update for newest version of vixie's cron, as of May 27 1993
*
* Revision 1.2 1993/03/28 17:24:44 glass
* cleanup so that crond compiles quietly
* Revision 2.2 1992/12/18 18:46:57 vixie
* vix/ckp
*
* Revision 1.1.1.1 93/03/21 09:52:52 cgd
* initial import of 386bsd-0.1 sources
*
* Revision 2.1 90/07/18 00:23:38 vixie
* Baseline for 4.4BSD release
*
@ -78,7 +75,7 @@ do_command(cmd, u)
{
extern int fork(), _exit();
extern void child_process(), log_it();
extern char *env_get();
extern char *env_get(), arpadate();
Debug(DPROC, ("[%d] do_command(%s, (%s,%d,%d))\n",
getpid(), cmd, env_get(USERENV, u->envp), u->uid, u->gid))
@ -106,7 +103,7 @@ do_command(cmd, u)
}
void
static void
child_process(cmd, u)
char *cmd;
user *u;
@ -181,6 +178,16 @@ child_process(cmd, u)
*input_data++ = '\0';
}
/* set our directory, uid and gid. Set gid first, since once
* we set uid, we've lost root privledges. (oops!)
*/
setgid(u->gid);
# if defined(BSD)
initgroups(env_get(USERENV, u->envp), u->gid);
# endif
setuid(u->uid); /* you aren't root after this... */
chdir(env_get("HOME", u->envp));
/* fork again, this time so we can exec the user's command. Vfork()
* is okay this time, since we are going to exec() pretty quickly.
* I'm assuming that closing pipe ends &whatnot will not affect our
@ -239,16 +246,6 @@ child_process(cmd, u)
do_univ(u);
# endif
/* set our directory, uid and gid. Set gid first, since once
* we set uid, we've lost root privledges. (oops!)
*/
setgid(u->gid);
# if defined(BSD)
initgroups(env_get(USERENV, u->envp), u->gid);
# endif
setuid(u->uid); /* you aren't root after this... */
chdir(env_get("HOME", u->envp));
/* exec the command.
*/
{
@ -271,10 +268,10 @@ child_process(cmd, u)
getpid(), shell, shell, cmd))
*/
# ifdef bad_idea
/* files writable by non-owner are a no-no
/* files writable by non-owner are a no-no, if we are
* running with privileges.
*/
{
if (u->uid == ROOT_UID) {
struct stat sb;
if (0 != stat(cmd, &sb)) {
@ -286,14 +283,13 @@ child_process(cmd, u)
"crond: %s writable by nonowner\n",
cmd);
_exit(ERROR_EXIT);
} else if (sb.st_uid & 022) {
} else if (sb.st_uid != u->uid) {
fprintf(stderr,
"crond: %s owned by uid %d\n",
cmd, sb.st_uid);
_exit(ERROR_EXIT);
}
}
# endif /*bad_idea*/
execle(shell, shell, "-c", cmd, (char *)0, u->envp);
fprintf(stderr, "execl: couldn't exec `%s'\n", shell);
@ -433,18 +429,14 @@ child_process(cmd, u)
if (mailto)
{
extern FILE *popen();
extern char *print_cmd();
extern char *sprintf(), *print_cmd();
register char **env;
auto char mailcmd[MAX_COMMAND];
auto char hostname[MAXHOSTNAMELEN];
(void) gethostname(hostname, MAXHOSTNAMELEN);
(void) sprintf(mailcmd, MAILCMD, mailto);
setgid(u->gid);
# if defined(BSD)
initgroups(env_get(USERENV, u->envp), u->gid);
# endif
setuid(u->uid); /* you aren't root after this... */
(void) sprintf(mailcmd, MAILARGS,
MAILCMD, mailto);
if (!(mail = popen(mailcmd, "w")))
{
perror(MAILCMD);
@ -456,7 +448,10 @@ child_process(cmd, u)
"Subject: cron for %s@%s said this\n",
usernm, first_word(hostname, ".")
);
fprintf(mail, "Date: %s", ctime(&TargetTime));
# if defined(MAIL_DATE)
fprintf(mail, "Date: %s",
arpadate(&TargetTime));
# endif /* MAIL_DATE */
fprintf(mail, "X-Cron-Cmd: <%s>\n", cmd);
for (env = u->envp; *env; env++)
fprintf(mail, "X-Cron-Env: <%s>\n",
@ -480,6 +475,18 @@ child_process(cmd, u)
putc(ch, mail);
}
/* if the cron job output ended on something other
* than a newline, add a newline here. this helps
* keep mailboxes from being corrupted; apparently
* /bin/mail versions that use \n\nFrom as a marker
* do not guarantee that messages end on newlines,
* which causes follow-on messages to glue together.
*/
if (mailto && (ch != '\n')) {
bytes++;
putc(ch, mail);
}
/* only close pipe if we opened it -- i.e., we're
* mailing...
*/
@ -527,7 +534,7 @@ child_process(cmd, u)
Debug(DPROC, ("[%d] waiting for grandchild #%d to finish\n",
getpid(), children))
pid = wait((int *) &waiter);
pid = wait(&waiter);
if (pid < OK) {
Debug(DPROC, ("[%d] no more grandchildren--mail written?\n",
getpid()))

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/entry.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/entry.c,v 1.2 1993/05/28 08:34:19 cgd Exp $";
#endif
/* vix 26jan87 [RCS'd; rest of log is in RCS file]

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/env.c,v 1.2 1993/03/28 17:24:46 glass Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/env.c,v 1.3 1993/05/28 08:34:20 cgd Exp $";
#endif
/* Copyright 1988,1990 by Paul Vixie
@ -92,6 +92,7 @@ load_env(envstr, f)
* FALSE = not an env setting (file was repositioned)
* TRUE = was an env setting
*/
char *strcpy(), *sprintf();
long filepos;
int fileline;
char name[MAX_TEMPSTR], val[MAX_ENVSTR];

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/job.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/job.c,v 1.2 1993/05/28 08:34:21 cgd Exp $";
#endif
/* Copyright 1988,1990 by Paul Vixie

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/misc.c,v 1.4 1993/05/11 08:16:03 glass Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/misc.c,v 1.5 1993/05/28 08:34:22 cgd Exp $";
#endif
/* vix 26jan87 [RCS has the rest of the log]
@ -7,7 +7,7 @@ static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/misc.c,v 1.4 19
* vix 30dec86 [written]
*/
/* Copyright 1988,1990 by Paul Vixie
/* Copyright 1988,1990,1993 by Paul Vixie
* All rights reserved
*
* Distribute freely, except: don't remove my name from the source or
@ -21,8 +21,8 @@ static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/misc.c,v 1.4 19
*
* 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
* Paul Vixie, 3477 South Court, Palo Alto, CA, 94306, USA, +1 415 858 2736
* paul@vix.com || paul@vixie.sf.ca.us || {hoptoad,pacbell,decwrl}!vixie!paul
*/
@ -32,16 +32,14 @@ static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/misc.c,v 1.4 19
#include <sys/ioctl.h>
#include <sys/file.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#if defined(ATT)
# include <fcntl.h>
#endif
#ifdef SYSLOG
#include <syslog.h>
#if defined(SYSLOG)
# include <syslog.h>
#endif
void log_it(), be_different(), acquire_daemonlock();
@ -49,6 +47,8 @@ char *
savestr(str)
char *str;
{
extern int strlen();
extern char *malloc(), *strcpy();
/**/ char *temp;
temp = malloc((unsigned) (strlen(str) + 1));
@ -289,6 +289,7 @@ be_different()
* do an IOCTL to void tty association
*/
extern int getpid(), setpgrp(), open(), ioctl(), close();
auto int fd;
(void) setpgrp(0, getpid());
@ -328,13 +329,17 @@ be_different()
void
acquire_daemonlock()
{
int fd = open(PIDFILE, O_RDWR|O_CREAT, 0644);
FILE *fp = fdopen(fd, "r+");
int pid = getpid(), otherpid;
char pidfile[MAX_FNAME];
FILE *fp;
int fd, pid = getpid(), otherpid;
char buf[MAX_TEMPSTR];
if (fd < 0 || fp == NULL) {
sprintf(buf, "can't open or create %s, errno %d", PIDFILE, errno);
(void) sprintf(pidfile, PIDFILE, PIDDIR);
if ((-1 == (fd = open(pidfile, O_RDWR|O_CREAT, 0644)))
|| (NULL == (fp = fdopen(fd, "r+")))
) {
sprintf(buf, "can't open or create %s: %s",
pidfile, strerror(errno));
log_it("CROND", pid, "DEATH", buf);
exit(ERROR_EXIT);
}
@ -343,8 +348,8 @@ acquire_daemonlock()
int save_errno = errno;
fscanf(fp, "%d", &otherpid);
sprintf(buf, "can't lock %s, otherpid may be %d, errno %d",
PIDFILE, otherpid, save_errno);
sprintf(buf, "can't lock %s, otherpid may be %d: %s",
pidfile, otherpid, strerror(save_errno));
log_it("CROND", pid, "DEATH", buf);
exit(ERROR_EXIT);
}
@ -352,7 +357,8 @@ acquire_daemonlock()
rewind(fp);
fprintf(fp, "%d\n", pid);
fflush(fp);
ftruncate(fd, ftell(fp));
(void) ftruncate(fd, ftell(fp));
(void) fcntl(fd, F_SETFD, 1);
/* abandon fd and fp even though the file is open. we need to
* keep it open and locked, but we don't need the handles elsewhere.
@ -535,6 +541,9 @@ log_it(username, pid, event, detail)
char *detail;
{
#if defined(LOG_FILE)
extern struct tm *localtime();
extern long time();
extern char *malloc();
auto char *msg;
auto long now = time((long *) 0);
register struct tm *t = localtime(&now);
@ -557,8 +566,11 @@ log_it(username, pid, event, detail)
if (log_fd < OK) {
log_fd = open(LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0600);
if (log_fd < OK) {
fprintf(stderr, "%s: can't open log file\n", ProgramName);
fprintf(stderr, "%s: can't open log file\n",
ProgramName);
perror(LOG_FILE);
} else {
(void) fcntl(log_fd, F_SETFD, 1);
}
}
@ -691,9 +703,35 @@ mkprints(src, len)
register unsigned char *src;
register unsigned int len;
{
extern char *malloc();
register char *dst = malloc(len*4 + 1);
mkprint(dst, src, len);
return dst;
}
/* Sat, 27 Feb 93 11:44:51 CST
* 123456789012345678901234567
*/
char *
arpadate(
time_t *clock
) {
time_t t = clock ?*clock :time(NULL);
struct tm *tm = localtime(&t);
static char ret[30]; /* zone name might be >3 chars */
(void) sprintf(ret, "%s, %2d %s %2d %02d:%02d:%02d %s",
DowNames[tm->tm_wday],
tm->tm_mday,
MonthNames[tm->tm_mon],
tm->tm_year,
tm->tm_hour,
tm->tm_min,
tm->tm_sec,
tm->tm_zone);
return ret;
}

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/user.c,v 1.2 1993/03/28 17:24:49 glass Exp $";
static char rcsid[] = "$Header: /cvsroot/src/libexec/crond/Attic/user.c,v 1.3 1993/05/28 08:34:23 cgd Exp $";
#endif
/* vix 26jan87 [log is in RCS file]
@ -54,7 +54,7 @@ load_user(crontab_fd, name, uid, gid, dir, shell)
char *dir;
char *shell;
{
char **env_init(), **env_set();
char *malloc(), *sprintf(), **env_init(), **env_set();
int load_env();
entry *load_entry();

View File

@ -1,4 +1,4 @@
.\" $Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.1,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $
.\" $Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.1,v 1.2 1993/05/28 08:34:31 cgd Exp $
.\"
.\"/* Copyright 1988,1990 by Paul Vixie
.\" * All rights reserved
@ -22,7 +22,7 @@
.SH NAME
crontab \- maintain crontab files for individual users
.SH SYNOPSIS
crontab [ -u user ] { -l | -d | -r file }
crontab [ -u user ] { -l | -d | -e | -r file }
.SH DESCRIPTION
.I Crontab
is the program used to install, deinstall or list the tables
@ -75,6 +75,12 @@ The
option causes the current crontab to be deleted.
.PP
The
.I -e
option allows you to edit the current crontab. It makes a copy of the
crontab, starts up your editor via the VISUAL or EDITOR environment
variables, and then installs your new crontab after your editor exits.
.PP
The
.I -r
option is used to replace the current
crontab (if any) with the contents of the named file.

View File

@ -1,4 +1,4 @@
.\" $Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.5.5,v 1.1 1993/03/28 17:27:07 glass Exp $
.\" $Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.5.5,v 1.2 1993/05/28 08:34:32 cgd Exp $
.\"
.\"/* Copyright 1988,1990 by Paul Vixie
.\" * All rights reserved

View File

@ -1,5 +1,5 @@
#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.c,v 1.2 1993/03/28 17:27:09 glass Exp $";
static char rcsid[] = "$Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.c,v 1.3 1993/05/28 08:34:33 cgd Exp $";
#endif
/* Revision 1.5 87/05/02 17:33:22 paul
@ -24,22 +24,9 @@ static char rcsid[] = "$Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.c,v 1
* Initial revision
*/
/* 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
/*
* ++COPYRIGHT++
* --COPYRIGHT--
*/
@ -54,29 +41,33 @@ static char rcsid[] = "$Header: /cvsroot/src/usr.bin/crontab/Attic/crontab.c,v 1
# 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}
static enum {opt_unknown, opt_list, opt_delete, opt_edit, opt_replace}
Option;
extern void log_it();
extern char *getenv(), *strcpy();
extern int getuid();
extern struct passwd *getpwnam();
extern int getopt(), optind;
extern char *optarg;
extern void log_it(); /* misc.c */
#if DEBUGGING
static char *Options[] = {"???", "list", "delete", "replace"};
static char *Options[] = {"???", "list", "delete", "edit", "replace"};
#endif
void
static 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, " ... -e (edit user's crontab)\n");
fprintf(stderr, " ... -r file (replace user's crontab)\n");
exit(ERROR_EXIT);
}
@ -86,8 +77,8 @@ main(argc, argv)
int argc;
char *argv[];
{
void parse_args(), set_cron_uid(), set_cron_cwd(),
list_cmd(), delete_cmd(), replace_cmd();
void parse_args(), set_cron_uid(), set_cron_cwd(),
list_cmd(), delete_cmd(), edit_cmd(), replace_cmd();
Pid = getpid();
ProgramName = argv[0];
@ -111,23 +102,20 @@ main(argc, argv)
break;
case opt_delete: delete_cmd();
break;
case opt_edit: edit_cmd();
break;
case opt_replace: replace_cmd();
break;
}
}
void
static 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;
@ -143,7 +131,7 @@ parse_args(argc, argv)
strcpy(RealUser, User);
Filename[0] = '\0';
Option = opt_unknown;
while (EOF != (argch = getopt(argc, argv, "u:ldr:x:")))
while (EOF != (argch = getopt(argc, argv, "u:lder:x:")))
{
switch (argch)
{
@ -176,6 +164,11 @@ parse_args(argc, argv)
usage();
Option = opt_delete;
break;
case 'e':
if (Option != opt_unknown)
usage();
Option = opt_edit;
break;
case 'r':
if (Option != opt_unknown)
usage();
@ -195,9 +188,9 @@ parse_args(argc, argv)
if (Option == opt_replace) {
if (!Filename[0]) {
/* getopt(3) says this can't be true
* but I'm paranoid today.
* but I'm feeling extra paranoid today.
*/
fprintf(stderr, "filename must be given for -a or -r\n");
fprintf(stderr, "filename must be given for -r\n");
usage();
}
/* we have to open the file here because we're going to
@ -219,10 +212,9 @@ parse_args(argc, argv)
}
void
static void
list_cmd()
{
extern errno;
char n[MAX_FNAME];
FILE *f;
int ch;
@ -247,7 +239,7 @@ list_cmd()
}
void
static void
delete_cmd()
{
extern errno;
@ -269,7 +261,7 @@ delete_cmd()
}
void
static void
check_error(msg)
char *msg;
{
@ -278,7 +270,111 @@ check_error(msg)
}
void
static void
edit_cmd()
{
char n[MAX_FNAME], tn[MAX_FNAME], *editor;
FILE *f, *tf;
int ch, t, pid;
struct stat before, after;
log_it(RealUser, Pid, "BEGIN EDIT", 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);
}
(void) sprintf(tn, "/tmp/crontab.%d", getpid());
if (-1 == (t = open(tn, O_CREAT|O_RDWR, 0600))) {
perror(tn);
exit(ERROR_EXIT);
}
if (fchown(t, getuid(), -1) < OK)
{
perror("chown");
goto fatal;
}
if (!(tf = fdopen(t, "r+"))) {
perror("fdopen");
goto fatal;
}
/* copy the crontab to the temp file. skip top two comments since we
* added them during the 'replace'.
*/
Set_LineNum(1)
t = 0;
while (EOF != (ch = get_char(f))) {
if (t < 2) {
t += (ch == '\n');
} else {
putc(ch, tf);
}
}
fflush(tf); rewind(tf);
fclose(f);
if (ferror(tf)) {
fprintf(stderr, "%s: error while writing new crontab to %s\n",
ProgramName, tn);
fclose(tf);
fatal:
unlink(tn);
exit(ERROR_EXIT);
}
if ((!(editor = getenv("VISUAL")))
&& (!(editor = getenv("EDITOR")))
) {
editor = EDITOR;
}
(void) fstat(fileno(tf), &before);
fclose(tf);
pid = VFORK();
if (pid < 0) {
perror("fork");
goto fatal;
}
if (pid == 0) {
extern char **environ;
char *argv[3];
/* CHILD */
setuid(getuid()); /* give up euid which is root */
argv[0] = editor;
argv[1] = tn;
argv[2] = NULL;
fprintf(stderr, "[%s %s]\n", editor, tn);
execve(editor, argv, environ);
perror(editor);
exit(ERROR_EXIT);
}
(void) wait((int *)0);
if (!(tf = fopen(tn, "r"))) {
perror(tn);
goto fatal;
}
(void) fstat(fileno(tf), &after);
if (after.st_mtime == before.st_mtime) {
fprintf(stderr, "[no changes were made to the crontab]\n");
fclose(tf);
} else {
fprintf(stderr, "[new crontab now being installed]\n");
NewCrontab = tf;
replace_cmd(); /* closes NewCrontab */
}
unlink(tn);
}
static void
replace_cmd()
{
entry *load_entry();
@ -382,7 +478,7 @@ replace_cmd()
}
void
static void
poke_daemon()
{
#if defined(BSD)