Commit 6ecd5583 authored by Matthias Klumpp's avatar Matthias Klumpp
Browse files

Import Upstream version 3.0pl1

Vixie Cron Changes from V2 to V3
Paul Vixie
The crontab command now conforms to POSIX 1003.2. This means that when you
install it, if you have any "crontab" command lines floating around in shell
scripts (such as /etc/rc or /etc/rc.local), you will need to change them.
I have integrated several changes made by BSDi for their BSD/386 operating
system; these were offerred to me before I started consulting for them, so
it is safe to say that they were intended for publication. Most notably,
the name of the cron daemon has changed from "crond" to "cron". This was
done for compatibility with 4.3BSD. Another change made for the same reason
is the ability to read in an /etc/crontab file which has an extra field in
each entry, between the time fields and the command. This field is a user
name, and it permits the /etc/crontab command to contain commands which are
to be run by any user on the system. /etc/crontab is not "installed" via
the crontab(1) command; it is automatically read at startup time and it will
be reread whenever it changes.
I also added a "-e" option to crontab(1). Nine people also sent me diffs
to add this option, but I had already implemented it on my own. I actually
released an interrim version (V2.2, I think) for limited testing, and got a
chance to fix a bad security bug in the "-e" option thanks to XXX.
The daemon used to be extraordinarily sloppy in its use of file descriptors.
A heck of a lot of them were left open in spawned jobs, which caused problems
for the daemon and also caused problems with the spawned jobs if they were
shell scripts since "sh" and "csh" have traditionally used hidden file
descriptors to pass information to subshells, and cron was causing them to
think they were subshells. If you had trouble with "sh" or "csh" scripts in
V2, chances are good that V3 will fix your problems.
About a dozen people have reminded me that I forgot to initialize
"crontab_fd" in database.c. Keith Cantrell was the first, so he gets the
Steve Simmons reminded me that once an account has been deleted from the
system, "crontab -u USER -d" will not work. My solution is to suggest to
all of you that before you delete a user's account, you first delete that
user's crontab file if any. From cron's point of view, usernames can never
be treated as arbitrary strings. Either they are valid user names, or they
are not. I will not make an exception for the "-d" case, for security
reasons that I consider reasonable. It is trivial for a root user to delete
the entry by hand if necessary.
Dan O'Neil reminded me that I forgot to reset "log_fd" in misc.c. A lot of
others also reminded me of this, but Dan gets the point. I didn't fix it
there, since the real bug was that it should have been open in the parent.
Peter Kabal reminded me that I forgot to "#ifdef DEBUGGING" some code in
misc.c. Hans Trompert actually told me first, but Peter sent the patch so
he gets the point.
Russell Nelson told me that I'd forgotten to "#include <syslog.h>" in misc.c,
which explains why a lot of other people complained that it wasn't using
syslog even when they configured it that way :-). Steve Simmons told me
first, though, so he gets the point.
An interrim version of the daemon tried to "stat" every file before
executing it; this turned out to be a horribly bad idea since finding the
name of a file from a shell command is a hard job (that's why we have
shells, right?) I removed this bogus code. Dave Burgess gets the point.
Dennis R. Conley sent a suggestion for MMDF systems, which I've added to the
comments in cron.h.
Mike Heisler noted that I use comments in the CONVERSION file which are
documented as illegal in the man pages. Thanks, Mike.
Irving Wolfe sent me some very cheerful changes for a NeXT system, but I
consider the system itself broken and I can't bring myself to #ifdef for
something as screwed up as this system seems to be. However, various others
did send me smaller patches which appear to have cause cron to build and run
correctly on (the latest) NeXT machines, with or without the "-posix" CFLAG.
Irving also asked for a per-job MAILTO, and this was finally added later when
I integrated the BSD/386 changes contributed by BSDi, and generalized some of
the parsing.
Lots of folks complained that the autogenerated "Date:" header wasn't in
ARPA format. I didn't understand this -- either folks will use Sendmail and
not generate a Date: at all (since Sendmail will do it), or folks will use
something other than Sendmail which won't care about Date: formats. But
I've "fixed" it anyway...
Several people suggested that "*" should be able to take a "/step". One person
suggested that "N/step" ought to mean "N-last/step", but that's stretching things
a bit far. "*/step" seems quite intuitive to me, so I've added it. Colin Plumb
sent in the first and most polite request for this feature.
As with every release of Cron, BIND, and seemingly everything else I do, one
user stands out with the most critical but also the most useful analysis.
Cron V3's high score belongs to Peter Holzer, who sent in the nicest looking
patch for the "%" interpretation problem and also helped me understand a
tricky bit of badness in the "log_fd" problem. wins the honors for being the first to point out the
nasty security hole in "crontab -r". 'Nuff said.
Several folks pointed out that log_it() needed to exist even if logging was
disabled. Some day I will create a tool that will compile a subsystem with
every possible combination and permutation of #ifdef options, but meanwhile
thanks to everybody.
job_runqueue() was using storage after freeing it, since Jordan told me back
in 1983 that C let you do that, and I believed him in 1986 when I wrote all
this junk. Linux was the first to die from this error, and the Linux people
sent me the most amazing, um, collection of patches for this problem. Thanks
for all the fish.
Jeremy Bettis reminded me that popen() isn't safe. I grabbed Ken Arnold's
version of popen/pclose from the ftpd and hacked it to taste. We're safe now,
from this at least.
Branko Lankester sent me a very timely and helpful fix for a looming security
problem in my "crontab -e" implementation.
Vixie Cron Changes from V1 to V2
Paul Vixie
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)
$Id: CONVERSION,v 2.2 1993/12/28 08:34:43 vixie 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
On 4.2, your crontab might have a few lines like this:
5 * * * * su uucp < /usr/lib/uucp/
10 4 * * * su uucp < /usr/lib/uucp/
15 5 * * 0 su uucp < /usr/lib/uucp/uudemon.wk
...or like this:
5 * * * * echo /usr/lib/uucp/ | su uucp
10 4 * * * echo /usr/lib/uucp/ | 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/
10 4 * * * uucp /usr/lib/uucp/
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
5 * * * *
10 4 * * *
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.
$Id: FEATURES,v 2.1 1993/12/28 08:34:43 vixie Exp $
Features of Vixie's cron relative to BSD 4.[23] and SysV crons:
-- Environment variables can be set in each crontab. SHELL, USER,
LOGNAME, 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
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.
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 used when it's time to run a command; if
you don't set them, HOME defaults to your /etc/passwd entry
and SHELL defaults to /bin/sh.
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.
-- 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,
the 'cron' daemon will reload 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. I have been told that some AT&T crons do not
act this way and do the more reasonable thing, which is (IMHO) to "or"
the various field-matches together. In that sense this cron may not
be completely similar to some AT&T crons.
/* 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 <> uunet!decwrl!vixie!paul
$Id: INSTALL,v 2.5 1994/01/15 20:43:43 vixie Exp $
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. Also look at pathnames.h.
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.)
LINUX note: /usr/include/paths.h on some linux systems shows _PATH_SENDMAIL
to be /usr/bin/sendmail even though sendmail is installed in /usr/lib.
you should check this out.
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
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/cron, unless you changed it in the Makefile.
Start up this cron daemon yourself as root. Just type /usr/local/etc/cron
(or whatever); no '&' is needed since the 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.
This diff is collapsed.
File Name Archive # Description
MANIFEST 1 This shipping list
Makefile 1
bitstring.3 1
bitstring.h 1
compat.c 1
compat.h 1
config.h 1
cron.8 1
cron.c 1
cron.h 1
crontab.1 1
crontab.5 1
crontab.c 2
database.c 1
do_command.c 2
entry.c 2
env.c 1
externs.h 1
job.c 1
misc.c 2
pathnames.h 1
popen.c 1 1
user.c 1
#/* 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 <> uunet!decwrl!vixie!paul
# */
# Makefile for vixie's cron
# $Id: Makefile,v 2.9 1994/01/15 20:43:43 vixie 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]
# 'make' can be done by anyone
# 'make install' must be done by root
# this package needs getopt(3), bitstring(3), and BSD install(8).
# the configurable stuff in this makefile consists of compilation
# options (use -O, cron runs forever) and destination directories.
# 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.
# this package needs the 'bitstring macros' library, which is
# available from me or from the comp.sources.unix archive. if you
# put 'bitstring.h' in a non-standard place (i.e., not intuited by
# cc(1)), you will have to define INCLUDE to set the include
# directory for cc. INCLUDE should be `-Isomethingorother'.
# there's more configuration info in config.h; edit that first!
#################################### begin configurable stuff
#<<DESTROOT is assumed to have ./etc, ./bin, and ./man subdirectories>>
DESTMAN = $(DESTROOT)/share/man
#<<need bitstring.h>>
#<<need getopt()>>
#<<optimize or debug?>>
OPTIM = -g
#<<ATT or BSD or POSIX?>>
# (ATT untested)
#(BSD is only needed if <sys/params.h> does not define it, as on ULTRIX)
#<<lint flags of choice?>>
#<<want to use a nonstandard CC?>>
#CC = vcc
#<<manifest defines>>
#(SGI IRIX systems need this)
#<<the name of the BSD-like install program>>
#INSTALL = installbsd
INSTALL = install
#<<any special load flags>>
#################################### end configurable stuff
SHELL = /bin/sh
MANPAGES = bitstring.3 crontab.5 crontab.1 cron.8
HEADERS = bitstring.h cron.h config.h pathnames.h \
externs.h compat.h
SOURCES = cron.c crontab.c database.c do_command.c entry.c \
env.c job.c user.c popen.c misc.c compat.c
LINT_CRON = cron.c database.c user.c entry.c compat.c \
misc.c job.c do_command.c env.c popen.c
LINT_CRONTAB = crontab.c misc.c entry.c env.c compat.c
CRON_OBJ = cron.o database.o user.o entry.o job.o do_command.o \
misc.o env.o popen.o compat.o
CRONTAB_OBJ = crontab.o misc.o entry.o env.o compat.o
all : cron crontab
lint :
|grep -v "constant argument to NOT" 2>&1
|grep -v "constant argument to NOT" 2>&1
cron : $(CRON_OBJ)
$(CC) $(LDFLAGS) -o cron $(CRON_OBJ) $(LIBS)
crontab : $(CRONTAB_OBJ)
$(CC) $(LDFLAGS) -o crontab $(CRONTAB_OBJ) $(LIBS)
install : all
$(INSTALL) -c -m 111 -o root -s cron $(DESTSBIN)/
$(INSTALL) -c -m 4111 -o root -s crontab $(DESTBIN)/
sh crontab.1 $(DESTMAN)
sh cron.8 $(DESTMAN)
sh crontab.5 $(DESTMAN)
clean :; rm -f *.o cron crontab a.out core tags *~ #*
kit : $(SHAR_SOURCE)
makekit -m -s99k $(SHAR_SOURCE)
$(CRON_OBJ) : cron.h compat.h config.h externs.h pathnames.h Makefile
$(CRONTAB_OBJ) : cron.h compat.h config.h externs.h pathnames.h Makefile
#/* 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 <> uunet!decwrl!vixie!paul
# */
Vixie Cron V3.0
December 27, 1993
[V2.2 was some time in 1992]
[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
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.
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.
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
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.
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
(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)
'su' and 'make install'
(you may have to install the man pages by hand)
kill your existing cron process
(actually you can run your existing cron if you want, but why?)
build new crontabs using /usr/lib/{crontab,crontab.local}
(either put them all in "root"'s crontab, or divide it up
and rip out all the 'su' commands, collapse the lengthy
lists into ranges with steps -- basically, this step is
as much work as you want to make it)
start up the new cron
(must be done as root)
watch it. test it with 'crontab -r' and watch the daemon track your
if you like it, change your /etc/{rc,rc.local} to use it instead of
the old one.
$Id: README,v 2.3 1993/12/28 08:34:43 vixie Exp $
15 January 1990
Paul Vixie
Many people have contributed to cron. Many more than I can remember, in fact.