v23i028: A cron/crontab replacement, Part01/01

Rich Salz rsalz at bbn.com
Wed Oct 10 23:53:36 AEST 1990


Submitted-by: Paul A Vixie <vixie at vixie.sf.ca.us>
Posting-number: Volume 23, Issue 28
Archive-name: vixie-cron/part01

[ I used the first version of this a few years ago at an old job.
  It was wonderful. --r$  ]

At long last.  Here is Cron V2.  It has been submitted to Berkeley for 4.4BSD;
since it didn't make it into 4.3-Reno, I'm going to quench the demand for it
by posting it here.  Here's the README:

=====
Vixie's Cron V2.0
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.

The code was all written by me, and is (quoted from Makefile):

#/* 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 at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!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
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)
	'make'
	'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
		changes.
	if you like it, change your /etc/{rc,rc.local} to use it instead of
		the old one.

$Header: README,v 2.1 90/07/18 00:23:54 vixie Exp $
$Source: /jove_u3/vixie/src/cron/RCS/README,v $
$Revision: 2.1 $
$Log:	README,v $
Revision 2.1  90/07/18  00:23:54  vixie
Baseline for 4.4BSD release

Revision 2.0  88/12/10  04:57:50  vixie
V2 Beta

Revision 1.2  87/07/10  11:36:45  paul
misc

Revision 1.1  87/07/10  11:15:05  paul
Initial revision
=====

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 3)."
# Contents:  CHANGES.V2 CONVERSION FEATURES INSTALL MANIFEST Makefile
#   README THANKS bitstring.3 bitstring.h config.h crond.8 crontab.1
#   env.c job.c user.c
# Wrapped by vixie at volition.pa.dec.com on Wed Jul 18 00:32:47 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'CHANGES.V2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'CHANGES.V2'\"
else
echo shar: Extracting \"'CHANGES.V2'\" \(1786 characters\)
sed "s/^X//" >'CHANGES.V2' <<'END_OF_FILE'
Vixie Cron		Changes from V1 to V2
Paul Vixie
X8-Feb-1988
X
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.
X
X8-Feb-88: made it possible to use much larger environment variable strings.
X	V1 allowed 100 characters; V2 allows 1000.  This was needed for PATH
X	variables on some systems.  Thanks to Toerless Eckert for this idea.
X	E-mail: UUCP: ...pyramid!fauern!faui10!eckert
X
X16-Feb-88: added allow/deny, moved /usr/spool/cron/crontabs to
X	/usr/lib/cron/tabs.  allow and deny are /usr/lib/cron/{allow,deny},
X	since the sysv naming for this depends on 'at' using the same
X	dir, which would be stupid (hint: use /usr/{lib,spool}/at).
X
X22-Feb-88: made it read the spool directory for crontabs and look each one
X	up using getpwnam() rather than reading all passwds with getpwent()
X	and trying to open each crontab.
X
X9-Dec-88: made it sync to :00 after the minute, makes cron predictable.
X	added logging to /var/cron/log.
X
X14-Apr-90: (actually, changes since December 1989)
X	fixed a number of bugs reported from the net and from John Gilmore.
X	added syslog per Keith Bostic.  security features including not
X	being willing to run a command owned or writable by other than
X	the owner of the crontab 9not working well yet)
END_OF_FILE
if test 1786 -ne `wc -c <'CHANGES.V2'`; then
    echo shar: \"'CHANGES.V2'\" unpacked with wrong size!
fi
# end of 'CHANGES.V2'
fi
if test -f 'CONVERSION' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'CONVERSION'\"
else
echo shar: Extracting \"'CONVERSION'\" \(3914 characters\)
sed "s/^X//" >'CONVERSION' <<'END_OF_FILE'
X$Header: CONVERSION,v 2.1 90/07/18 00:27:18 vixie Exp $
X
Conversion of BSD 4.[23] crontab files:
X
XEdit 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.
X
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.
X
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.
X
X'uucp's commands need their own file; how about /usr/lib/uucp/crontab.src?
X'news' also, perhaps in /usr/lib/news/crontab.src...
X
I say `how about' and `perhaps' because it really doesn't matter to anyone
X(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.
X
On 4.2, your crontab might have a few lines like this:
X
X	5 * * * *   su uucp < /usr/lib/uucp/uudemon.hr
X	10 4 * * *  su uucp < /usr/lib/uucp/uudemon.day
X	15 5 * * 0  su uucp < /usr/lib/uucp/uudemon.wk
X
X...or like this:
X
X	5 * * * *   echo /usr/lib/uucp/uudemon.hr | su uucp
X	10 4 * * *  echo /usr/lib/uucp/uudemon.day | su uucp
X	15 5 * * 0  echo /usr/lib/uucp/uudemon.wk | su uucp
X
On 4.3, they'd look a little bit better, but not much:
X
X	5 * * * *   uucp  /usr/lib/uucp/uudemon.hr
X	10 4 * * *  uucp  /usr/lib/uucp/uudemon.day
X	15 5 * * 0  uucp  /usr/lib/uucp/uudemon.wk
X
XFor this cron, you'd create /usr/lib/uucp/crontab.src (or wherever you want
to keep uucp's commands) which would look like this:
X
X	# /usr/lib/uucp/crontab.src - uucp's crontab
X	#
X	PATH=/usr/lib/uucp:/bin:/usr/bin
X	SHELL=/bin/sh				# otherwise it's uucico
X	HOME=/usr/lib/uucp			# '' '' /usr/spool/uucppublic
X	#
X	5 * * * *   uudemon.hr
X	10 4 * * *  uudemon.day
X	15 5 * * 0  uudemon.wk
X
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).
X
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.
X
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.
X
END_OF_FILE
if test 3914 -ne `wc -c <'CONVERSION'`; then
    echo shar: \"'CONVERSION'\" unpacked with wrong size!
fi
# end of 'CONVERSION'
fi
if test -f 'FEATURES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'FEATURES'\"
else
echo shar: Extracting \"'FEATURES'\" \(4078 characters\)
sed "s/^X//" >'FEATURES' <<'END_OF_FILE'
X$Header: INFO.features,v 2.0 88/12/10 04:57:35 vixie Exp $
X
XFeatures of Vixie's cron relative to BSD 4.[23] and SysV crons:
X
X--	Environment variables can be set in each crontab.  SHELL, USER,
X	and HOME are set from the user's passwd entry; all except USER
X	can be changed in the crontab.  PATH is especially useful to
X	set there.  TZ can be set, but cron ignores it other than passing
X	it on through to the commands it runs.  Format is
X
X		variable=value
X
X	Blanks surrounding the '=' will be eaten; other blanks in value are
X	okay.  Leading or trailing blanks can be preserved by quoting, single
X	or double quotes are okay, just so they match.
X
X		PATH=.:/bin:/usr/bin
X		SHELL=/bin/sh
X		FOOBAR = this is a long blanky example
X
X	Above, FOOBAR would get `this is a long blanky example' as its value.
X
X	SHELL and HOME will be examined when it's time to run a command; if
X	you don't change them, they default to your /etc/passwd entry.
X
X	*DANGER*, WILL ROBINSON! This means that all 'uucp' logins should set
X	SHELL=/bin/sh or cron will try to use /usr/lib/uucp/uucico as the
X	shell.  This won't work.
X
X	MAILTO, if set to the login name of a user on your system, will be the
X	person that cron mails the output of commands in that crontab.  This is
X	useful if you decide on BINMAIL when configuring cron.h, since binmail
X	doesn't know anything about aliasing.
X
X	Setting SHELL=/bin/sh will in general speed up your commands since it
X	is a much smaller shell than the one you probably use normally (csh
X	or ksh) and has enough features to work non-interactively.
X
X--	Weekdays can be specified by name.  Case is not significant, but only
X	the first three letters should be specified.
X
X--	Months can likewise be specified by name.  Three letters only.
X
X--	Ranges and lists can be mixed.  Standard crons won't allow '1,3-5'.
X
X--	Ranges can specify 'step' values.  '10-16/2' is like '10,12,14,16'.
X
X--	Sunday is both day 0 and day 7 -- apparently BSD and ATT disagree
X	about this.
X
X--	Each user gets their own crontab file.  This is a win over BSD 4.2,
X	where only root has one, and over BSD 4.3, where they made the crontab
X	format incompatible and although the commands can be run by non-root
X	uid's, root is still the only one who can edit the crontab file.  This
X	feature mimics the SysV cron.
X
X--	The 'crontab' command is loosely compatible with SysV, but has more
X	options which just generally make more sense.  Running crontab with
X	no arguments will print a cute little summary of the command syntax.
X
X--	Comments and blank lines are allowed in the crontab file.  Comments
X	must be on a line by themselves; leading whitespace is ignored, and
X	a '#' introduces the comment.
X
X--	(big win) If the `crontab' command changes anything in any crontab, it
X	tells the 'cron' daemon, who reloads all the tables before running the
X	next iteration.  In some crons, you have to kill and restart the
X	daemon whenever you change a crontab.  In other crons, the crontab
X	file is reread and reparsed every minute even if it didn't change.
X
X--	In order to support the automatic reload, the crontab files are not
X	readable or writable except by 'crontab' or 'cron'.  This is not a
X	problem, since 'crontab' will let you do pretty much whatever you
X	want to your own crontab, or if you are root, to anybody's crontab.
X
X--	If any output is generated by a command (on stdout OR stderr), it will
X	be mailed to the owner of the crontab that contained the command (or
X	MAILTO, see discussion of environment variables, above).  The headers
X	of the mail message will include the command that was run, and a
X	complete list of the environment that was passed to it, which will
X	contain (at least) the USER (LOGNAME on SysV), HOME, and SHELL.
X
X--	the dom/dow situation is odd.  '* * 1,15 * Sun' will run on the
X	first and fifteenth AND every Sunday;  '* * * * Sun' will run *only*
X	on Sundays;  '* * 1,15 * *' will run *only* the 1st and 15th.  this
X	is why we keep 'e->dow_star' and 'e->dom_star'.  I didn't think up
X	this behaviour; it's how cron has always worked but the documentation
X	hasn't been very clear.
END_OF_FILE
if test 4078 -ne `wc -c <'FEATURES'`; then
    echo shar: \"'FEATURES'\" unpacked with wrong size!
fi
# end of 'FEATURES'
fi
if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'INSTALL'\"
else
echo shar: Extracting \"'INSTALL'\" \(3212 characters\)
sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
X$Header: INSTALL,v 2.1 90/07/18 00:23:36 vixie Exp $
X
X*** This does not work on ATT SysV yet, and given the feature overlap,
X    it may never do so.
X
Read the comments at the top of the Makefile, then edit the area marked
X'configurable stuff'.
X
XEdit config.h.  The stuff I expect you to change is down a bit from the
top of the file, but it's clearly marked.  
X
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
X/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.
X
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.)
X
say:
X	make all
X
su and say:
X	make install
X
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.
X
XEdit your /usr/lib/crontab file into little pieces -- see the CONVERSION file
for help on this.
X
Use the `crontab' command to install all the little pieces you just created.
Some examples (see below before trying any of these!)
X
X	crontab -u uucp -r /usr/lib/uucp/crontab.src
X	crontab -u news -r /usr/lib/news/crontab.src
X	crontab -u root -r /usr/adm/crontab.src
X
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.
X
Kill your existing cron daemon -- do `ps aux' and look for /etc/cron.
X
XEdit your /etc/rc or /etc/rc.local, looking for the line that starts up
X/etc/cron.  Comment it out and add a line to start the new cron daemon
X-- usually /usr/local/etc/crond, unless you changed it in the Makefile.
X
Start up this cron daemon yourself as root.  Just type /usr/local/etc/crond
X(or whatever); no '&' is needed since the cron daemon forks itself and the
process you executed returns immediately.
X
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.
END_OF_FILE
if test 3212 -ne `wc -c <'INSTALL'`; then
    echo shar: \"'INSTALL'\" unpacked with wrong size!
fi
# end of 'INSTALL'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(858 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X CHANGES.V2                 1	
X CONVERSION                 1	
X FEATURES                   1	
X INSTALL                    1	
X MANIFEST                   1	This shipping list
X Makefile                   1	
X README                     1	
X THANKS                     1	
X bitstring.3                1	
X bitstring.h                1	
X config.h                   1	
X cron.h                     2	
X crond.8                    1	
X crond.c                    2	
X crontab.1                  1	
X crontab.5                  2	
X crontab.c                  2	
X database.c                 2	
X do_command.c               3	
X entry.c                    2	
X env.c                      1	
X job.c                      1	
X misc.c                     3	
X user.c                     1	
END_OF_FILE
if test 858 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(4475 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile for vixie's cron
X#
X# $Header: Makefile,v 2.2 90/07/18 00:23:57 vixie Locked $
X#
X# vix 03mar88 [moved to RCS, rest of log is in there]
X# vix 30mar87 [goodbye, time.c; hello, getopt]
X# vix 12feb87 [cleanup for distribution]
X# vix 30dec86 [written]
X
X#/* Copyright 1988,1990 by Paul Vixie
X# * All rights reserved
X# *
X# * Distribute freely, except: don't remove my name from the source or
X# * documentation (don't take credit for my work), mark your changes (don't
X# * get me blamed for your possible bugs), don't alter or remove this
X# * notice.  May be sold if buildable source is provided to buyer.  No
X# * warrantee of any kind, express or implied, is included with this
X# * software; use at your own risk, responsibility for damages (if any) to
X# * anyone resulting from the use of this software rests entirely with the
X# * user.
X# *
X# * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X# * I'll try to keep a version up to date.  I can be reached as follows:
X# * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X# * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X# */
X
X# NOTES:
X#	'make' can be done by anyone
X#	'make install' must be done by root
X#
X#	this package needs getopt(3), bitstring(3), and BSD install(8).
X#
X#	the configurable stuff in this makefile consists of compilation
X#	options (use -O, cron runs forever) and destination directories.
X#	SHELL is for the 'augumented make' systems where 'make' imports
X#	SHELL from the environment and then uses it to run its commands.
X#	if your environment SHELL variable is /bin/csh, make goes real
X#	slow and sometimes does the wrong thing.  BINDIR is where the
X#	'crontab' command goes, and should be a common place like /usr/bin.
X#	LIBDIR is where the cron daemon lives; /usr/etc is common.
X#
X#	this package needs the 'bitstring macros' library, which is
X#	available from me or from the comp.sources.unix archive.  if you
X#	put 'bitstring.h' in a non-standard place (i.e., not intuited by
X#	cc(1)), you will have to define INCLUDE to set the include
X#	directory for cc.  INCLUDE should be `-Isomethingorother'.
X#
X#	there's more configuration info in config.h; edit that first!
X
X#################################### begin configurable stuff
X#<<DESTROOT is assumed to have ./etc, ./bin, and ./man subdirectories>>
DESTROOT	=	$(DESTDIR)/usr/local
X#<<CRONDIR will be created by crond or crontab if nec'y>>
CRONDIR		=	/var/cron
X#<<need bitstring.h>>
INCLUDE		=	-I.
X#INCLUDE	=
X#<<need getopt()>>
X#LIBS		=	/usr/local/lib/getopt.o
LIBS		=
X#<<optimize or debug?>>
X#OPTIM		=	-O
OPTIM		=	-g
X#<<want -x flag for debugging?>>
DEBUGGING	=	-DDEBUGGING=1
X#DEBUGGING	=	-DDEBUGGING=0
X#<<ATT or BSD?>>
X# (ATT untested)
X#COMPAT		=	-DATT
COMPAT		=	-DBSD
X#<<lint flags of choice?>>
LINTFLAGS	=	-hbxa $(INCLUDE) $(COMPAT) $(DEBUGGING)
X#<<want to use a nonstandard CC?>>
X#CC		=	vcc
X#<<manifest defines>>
DEFS		=	'-DCRONDIR="$(CRONDIR)"'
X#################################### end configurable stuff
X
SHELL		=	/bin/sh
CFLAGS		=	$(OPTIM) $(INCLUDE) $(COMPAT) $(DEBUGGING) $(DEFS)
X
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 \
X			entry.c env.c job.c misc.c user.c
SHAR_SOURCE	=	$(INFOS) $(MANPAGES) Makefile $(HEADERS) $(SOURCES)
LINT_CROND	=	crond.c database.c user.c entry.c \
X			misc.c job.c do_command.c env.c
LINT_CRONTAB	=	crontab.c misc.c entry.c env.c
CRON_OBJ	=	crond.o database.o user.o entry.o \
X			misc.o job.o do_command.o env.o
CRONTAB_OBJ	=	crontab.o misc.o entry.o env.o
X
all		:	crond crontab
X
lint		:
X			lint $(LINTFLAGS) $(LINT_CROND) $(LIBS) \
X			|grep -v "constant argument to NOT" 2>&1
X			lint $(LINTFLAGS) $(LINT_CRONTAB) $(LIBS) \
X			|grep -v "constant argument to NOT" 2>&1
X
crond		:	$(CRON_OBJ)
X			$(CC) -o crond $(CRON_OBJ) $(LIBS)
X
crontab		:	$(CRONTAB_OBJ)
X			$(CC) -o crontab $(CRONTAB_OBJ) $(LIBS)
X
install		:	all
X			install -c -m 111 -o root -s crond $(DESTROOT)/etc/
X			install -c -m 4111 -o root -s crontab $(DESTROOT)/bin/
X			install -c crontab.1 $(DESTROOT)/man/man1/crontab.1
X			install -c crond.8   $(DESTROOT)/man/man8/crond.8
X			install -c crontab.5 $(DESTROOT)/man/man5/crontab.5
X
clean		:;	rm -f *.o crond crontab a.out core tags *~ #*
X
kit		:	$(SHAR_SOURCE)
X			makekit -m -s50k $(SHAR_SOURCE)
X
X$(CRON_OBJ)	:	cron.h config.h Makefile
X$(CRONTAB_OBJ)	:	cron.h config.h Makefile
END_OF_FILE
if test 4475 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(3631 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Vixie's Cron V2.0
July 5, 1990
X[V2.0-beta was December 9, 1988]
X[V1.0 was May 6, 1987]
Paul Vixie
X
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
X'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.
X
A messages is logged each time a command is executed; also, the files
X"allow" and "deny" in /var/cron can be used to control access to the
X"crontab" command (which installs crontabs).  It hasn't been tested on
SysV, although some effort has gone into making the port an easy one.
X
The code was all written by me, and is (quoted from Makefile):
X
X#/* Copyright 1988,1990 by Paul Vixie
X# * All rights reserved
X# *
X# * Distribute freely, except: don't remove my name from the source or
X# * documentation (don't take credit for my work), mark your changes (don't
X# * get me blamed for your possible bugs), don't alter or remove this
X# * notice.  May be sold if buildable source is provided to buyer.  No
X# * warrantee of any kind, express or implied, is included with this
X# * software; use at your own risk, responsibility for damages (if any) to
X# * anyone resulting from the use of this software rests entirely with the
X# * user.
X# *
X# * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X# * I'll try to keep a version up to date.  I can be reached as follows:
X# * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X# * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X# */
X
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.
X
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:
X
X	Read all the FEATURES, INSTALL, and CONVERSION files
X	Edit config.h
X	Edit Makefile
X		(both of these files have instructions inside; note that
X		 some things in config.h are definable in Makefile and are
X		 therefore surrounded by #ifndef...#endif)
X	'make'
X	'su' and 'make install'
X		(you may have to install the man pages by hand)
X	kill your existing cron process
X		(actually you can run your existing cron if you want, but why?)
X	build new crontabs using /usr/lib/{crontab,crontab.local}
X		(either put them all in "root"'s crontab, or divide it up
X		 and rip out all the 'su' commands, collapse the lengthy
X		 lists into ranges with steps -- basically, this step is
X		 as much work as you want to make it)
X	start up the new cron
X		(must be done as root)
X	watch it. test it with 'crontab -r' and watch the daemon track your
X		changes.
X	if you like it, change your /etc/{rc,rc.local} to use it instead of
X		the old one.
X
X$Header: README,v 2.1 90/07/18 00:23:54 vixie Exp $
X$Source: /jove_u3/vixie/src/cron/RCS/README,v $
X$Revision: 2.1 $
X$Log:	README,v $
Revision 2.1  90/07/18  00:23:54  vixie
Baseline for 4.4BSD release
X
Revision 2.0  88/12/10  04:57:50  vixie
V2 Beta
X
Revision 1.2  87/07/10  11:36:45  paul
misc
X
Revision 1.1  87/07/10  11:15:05  paul
Initial revision
END_OF_FILE
if test 3631 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'THANKS' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'THANKS'\"
else
echo shar: Extracting \"'THANKS'\" \(1598 characters\)
sed "s/^X//" >'THANKS' <<'END_OF_FILE'
X15 January 1990
Paul Vixie
X
Many people have contributed to cron.  Many more than I can remember, in fact.
Rich Salz and Carl Gutekunst were each of enormous help to me in V1; Carl for
helping me understand UNIX well enough to write it, and Rich for helping me
get the features right.
X
John Gilmore wrote me a wonderful review of V2, which took me a whole year to
answer even though it made me clean up some really awful things in the code.
X(According to John the most awful things are still in here, of course.)
X
Paul Close made a suggestion which led to /etc/crond.pid and the mutex locking
on it.  Kevin Braunsdorf of Purdue made a suggestion that led to @reboot and
its brothers and sisters; he also sent some diffs that lead cron toward compil-
ability with System V, though without at(1) capabilities, this cron isn't going
to be that useful on System V.  Bob Alverson fixed a silly bug in the line
number counting.  Brian Reid made suggestions which led to the run queue and
the source-file labelling in installed crontabs.
X
Scott Narveson ported V2 to a Sequent, and sent in the most useful single batch
of diffs I got from anybody.  Changes attributable to Scott are:
X	-> sendmail won't time out if the command is slow to generate output
X	-> day-of-week names aren't off by one anymore
X	-> crontab says the right thing if you do something you shouldn't do
X	-> crontab(5) man page is longer and more informative
X	-> misc changes related to the side effects of fclose()
X	-> Sequent "universe" support added (may also help on Pyramids)
X	-> null pw_shell is dealt with now; default is /bin/sh
END_OF_FILE
if test 1598 -ne `wc -c <'THANKS'`; then
    echo shar: \"'THANKS'\" unpacked with wrong size!
fi
# end of 'THANKS'
fi
if test -f 'bitstring.3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitstring.3'\"
else
echo shar: Extracting \"'bitstring.3'\" \(3395 characters\)
sed "s/^X//" >'bitstring.3' <<'END_OF_FILE'
X.\" Copyright (c) 1989 The Regents of the University of California.
X.\" All rights reserved.
X.\"
X.\" This code is derived from software contributed to Berkeley by
X.\" Paul Vixie.
X.\"
X.\" Redistribution and use in source and binary forms are permitted
X.\" provided that the above copyright notice and this paragraph are
X.\" duplicated in all such forms and that any documentation,
X.\" advertising materials, and other materials related to such
X.\" distribution and use acknowledge that the software was developed
X.\" by the University of California, Berkeley.  The name of the
X.\" University may not be used to endorse or promote products derived
X.\" from this software without specific prior written permission.
X.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X.\"
X.\"	@(#)bitstring.3	5.1 (Berkeley) 12/13/89
X.\"
X.TH BITSTRING 3  "December 13, 1989"
X.UC 4
X.SH NAME
bit_alloc, bit_clear, bit_decl, bit_ffs, bit_nclear, bit_nset,
bit_set, bitstr_size, bit_test \- bit-string manipulation macros
X.SH SYNOPSIS
X.ft B
X.nf
X#include <bitstring.h>
X
name = bit_alloc(nbits)
bitstr_t *name;
int nbits;
X
bit_decl(name, nbits)
bitstr_t name;
int nbits;
X
bit_clear(name, bit)
bitstr_t name;
int bit;
X
bit_ffc(name, nbits, value)
bitstr_t name;
int nbits, *value;
X
bit_ffs(name, nbits, value)
bitstr_t name;
int nbits, *value;
X
bit_nclear(name, start, stop)
bitstr_t name;
int start, stop;
X
bit_nset(name, start, stop)
bitstr_t name;
int start, stop;
X
bit_set(name, bit)
bitstr_t name;
int bit;
X
bitstr_size(nbits)
int nbits;
X
bit_test(name, bit)
bitstr_t name;
int bit;
X.fi
X.ft R
X.SH DESCRIPTION
These macros operate on strings of bits.
X.PP
X.I Bit_alloc
returns a pointer of type
X.I bitstr_t\ *
to sufficient space to store
X.I nbits
bits, or NULL if no space is available.
X.PP
X.I Bit_decl
is a macro for allocating sufficient space to store
X.I nbits
bits on the stack.
X.PP
X.I Bitstr_size
returns the number of elements of type
X.I bitstr_t
necessary to store
X.I nbits
bits.
This is useful for copying bit strings.
X.PP
X.I Bit_clear
and
X.I bit_set
clear or set the zero-based numbered bit
X.IR bit ,
in the bit string
X.IR name .
X.PP
X.I Bit_nset
and
X.I bit_nclear
set or clear the zero-based numbered bits from
X.I start
to
X.I stop
in the bit string
X.IR name .
X.PP
X.I Bit_test
evaluates to zero if the zero-based numbered bit
X.I bit
of bit string
X.I name
is set, and non-zero otherwise.
X.PP
X.I Bit_ffs
sets
X.I *value
to the zero-based number of the first bit set in the array of
X.I nbits
bits referenced by
X.IR name .
If no bits are set,
X.I *value
is set to -1.
X.PP
X.I Bit_ffc
sets
X.I *value
to the zero-based number of the first bit not set in the array of
X.I nbits
bits referenced by
X.IR name .
If all bits are set,
X.I value
is set to -1.
X.SH EXAMPLE
X.nf
X.in +5
X#include <limits.h>
X#include <bitstring.h>
X
X...
X#define	LPR_BUSY_BIT		0
X#define	LPR_FORMAT_BIT		1
X#define	LPR_DOWNLOAD_BIT	2
X...
X#define	LPR_AVAILABLE_BIT	9
X#define	LPR_MAX_BITS		10
X
make_lpr_available()
X{
X	bitstr_t bit_decl(bitlist, LPR_MAX_BITS);
X	...
X	bit_nclear(bitlist, 0, LPR_MAX_BITS - 1);
X	...
X	if (!bit_test(bitlist, LPR_BUSY_BIT)) {
X		bit_clear(bitlist, LPR_FORMAT_BIT);
X		bit_clear(bitlist, LPR_DOWNLOAD_BIT);
X		bit_set(bitlist, LPR_AVAILABLE_BIT);
X	}
X}
X.fi
X.SH "SEE ALSO"
malloc(3)
END_OF_FILE
if test 3395 -ne `wc -c <'bitstring.3'`; then
    echo shar: \"'bitstring.3'\" unpacked with wrong size!
fi
# end of 'bitstring.3'
fi
if test -f 'bitstring.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitstring.h'\"
else
echo shar: Extracting \"'bitstring.h'\" \(3656 characters\)
sed "s/^X//" >'bitstring.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Paul Vixie.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X *	@(#)bitstring.h	5.2 (Berkeley) 4/4/90
X */
X
typedef	unsigned char bitstr_t;
X
X/* internal macros */
X				/* byte of the bitstring bit is in */
X#define	_bit_byte(bit) \
X	((bit) >> 3)
X
X				/* mask for the bit within its byte */
X#define	_bit_mask(bit) \
X	(1 << ((bit)&0x7))
X
X/* external macros */
X				/* bytes in a bitstring of nbits bits */
X#define	bitstr_size(nbits) \
X	((((nbits) - 1) >> 3) + 1)
X
X				/* allocate a bitstring */
X#define	bit_alloc(nbits) \
X	(bitstr_t *)malloc(1, \
X	    (unsigned int)_bitstr_size(nbits) * sizeof(bitstr_t))
X
X				/* allocate a bitstring on the stack */
X#define	bit_decl(name, nbits) \
X	(name)[bitstr_size(nbits)]
X
X				/* is bit N of bitstring name set? */
X#define	bit_test(name, bit) \
X	((name)[_bit_byte(bit)] & _bit_mask(bit))
X
X				/* set bit N of bitstring name */
X#define	bit_set(name, bit) \
X	(name)[_bit_byte(bit)] |= _bit_mask(bit)
X
X				/* clear bit N of bitstring name */
X#define	bit_clear(name, bit) \
X	(name)[_bit_byte(bit)] &= ~_bit_mask(bit)
X
X				/* clear bits start ... stop in bitstring */
X#define	bit_nclear(name, start, stop) { \
X	register bitstr_t *_name = name; \
X	register int _start = start, _stop = stop; \
X	register int _startbyte = _bit_byte(_start); \
X	register int _stopbyte = _bit_byte(_stop); \
X	_name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \
X	while (++_startbyte < _stopbyte) \
X		_name[_startbyte] = 0; \
X	_name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \
X}
X
X				/* set bits start ... stop in bitstring */
X#define	bit_nset(name, start, stop) { \
X	register bitstr_t *_name = name; \
X	register int _start = start, _stop = stop; \
X	register int _startbyte = _bit_byte(_start); \
X	register int _stopbyte = _bit_byte(_stop); \
X	_name[_startbyte] |= 0xff << ((start)&0x7); \
X	while (++_startbyte < _stopbyte) \
X	    _name[_startbyte] = 0xff; \
X	_name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \
X}
X
X				/* find first bit clear in name */
X#define	bit_ffc(name, nbits, value) { \
X	register bitstr_t *_name = name; \
X	register int _byte, _nbits = nbits; \
X	register int _stopbyte = _bit_byte(_nbits), _value = -1; \
X	for (_byte = 0; _byte <= _stopbyte; ++_byte) \
X		if (_name[_byte] != 0xff) { \
X			_value = _byte << 3; \
X			for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \
X			    ++_value, _stopbyte >>= 1); \
X			break; \
X		} \
X	*(value) = _value; \
X}
X
X				/* find first bit set in name */
X#define	bit_ffs(name, nbits, value) { \
X	register bitstr_t *_name = name; \
X	register int _byte, _nbits = nbits; \
X	register int _stopbyte = _bit_byte(_nbits), _value = -1; \
X	for (_byte = 0; _byte <= _stopbyte; ++_byte) \
X		if (_name[_byte]) { \
X			_value = _byte << 3; \
X			for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \
X			    ++_value, _stopbyte >>= 1); \
X			break; \
X		} \
X	*(value) = _value; \
X}
END_OF_FILE
if test 3656 -ne `wc -c <'bitstring.h'`; then
    echo shar: \"'bitstring.h'\" unpacked with wrong size!
fi
# end of 'bitstring.h'
fi
if test -f 'config.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'config.h'\"
else
echo shar: Extracting \"'config.h'\" \(3929 characters\)
sed "s/^X//" >'config.h' <<'END_OF_FILE'
X/* config.h - configurables for Vixie Cron
X *
X * $Header: config.h,v 2.1 90/07/18 00:24:35 vixie Exp $
X */
X
X/* Copyright 1988,1990 by Paul Vixie
X * All rights reserved
X *
X * Distribute freely, except: don't remove my name from the source or
X * documentation (don't take credit for my work), mark your changes (don't
X * get me blamed for your possible bugs), don't alter or remove this
X * notice.  May be sold if buildable source is provided to buyer.  No
X * warrantee of any kind, express or implied, is included with this
X * software; use at your own risk, responsibility for damages (if any) to
X * anyone resulting from the use of this software rests entirely with the
X * user.
X *
X * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X * I'll try to keep a version up to date.  I can be reached as follows:
X * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X */
X
X#ifndef	_CONFIG_FLAG
X#define	_CONFIG_FLAG
X
X/*
X * these are site-dependent
X */
X			/*
X			 * choose one of these MAILCMD commands.  I use
X			 * /bin/mail for speed; it makes biff bark but doesn't
X			 * do aliasing.  /usr/lib/sendmail does aliasing but is
X			 * a hog for short messages.  aliasing is not needed
X			 * if you make use of the MAILTO= feature in crontabs.
X			 * (hint: MAILTO= was added for this reason).
X			 */
X
X# define MAILCMD "/usr/lib/sendmail -F\"Cron Daemon\" -odi -oem -or0s %s" /*-*/
X			/* -Fx	 = set full-name of sender
X			 * -odi	 = Option Deliverymode Interactive
X			 * -oem	 = Option Errors Mailedtosender
X			 * -or0s = Option Readtimeout -- don't time out
X			 */
X
X/* # define MAILCMD "/bin/mail -d  %s"		/*-*/
X			/* -d = undocumented but common flag: deliver locally?
X			 */
X
X#ifndef CRONDIR
X			/* CRONDIR is where crond(8) and crontab(1) both chdir
X			 * to; SPOOL_DIR, ALLOW_FILE, DENY_FILE, and LOG_FILE
X			 * are all relative to this directory.
X			 *
X			 * this can and should be set in the Makefile.
X			 */
X# define CRONDIR	"/var/cron"
X#endif
X
X			/* SPOOLDIR is where the crontabs live.
X			 * This directory will have its modtime updated
X			 * whenever crontab(1) changes a crontab; this is
X			 * the signal for crond(8) to look at each individual
X			 * crontab file and reload those whose modtimes are
X			 * newer than they were last time around (or which
X			 * didn't exist last time around...)
X			 */
X#define SPOOL_DIR	"tabs"
X
X			/* undefining these turns off their features.  note
X			 * that ALLOW_FILE and DENY_FILE must both be defined
X			 * in order to enable the allow/deny code.  If neither
X			 * LOG_FILE or SYSLOG is defined, we don't log.  If
X			 * both are defined, we log both ways.
X			 */
X#define	ALLOW_FILE	"allow"		/*-*/
X#define DENY_FILE	"deny"		/*-*/
X#define LOG_FILE	"log"		/*-*/
X
X			/* if ALLOW_FILE and DENY_FILE are not defined or are
X			 * defined but neither exists, should crontab(1) be
X			 * usable only by root?
X			 */
X/*#define ALLOW_ONLY_ROOT			/*-*/
X
X			/* if you want to use syslog(3) instead of appending
X			 * to CRONDIR/LOG_FILE (/var/cron/log, e.g.), define
X			 * SYSLOG here.  Note that quite a bit of logging
X			 * info is written, and that you probably don't want
X			 * to use this on 4.2bsd since everything goes in
X			 * /usr/spool/mqueue/syslog.  On 4.[34]bsd you can
X			 * tell /etc/syslog.conf to send cron's logging to
X			 * a separate file.
X			 */
X/*#define SYSLOG	 			/*-*/
X
X			/* this is the name of the environment variable
X			 * that contains the user name.  it isn't read by
X			 * cron, but it is SET by crond in the environments
X			 * it creates for subprocesses.  on BSD, it will
X			 * always be USER; on SysV it could be LOGNAME or
X			 * something else.
X			 */
X#if defined(BSD)
X# define USERENV	"USER"
X#endif
X#if defined(ATT)
X# define USERENV	"LOGNAME"
X#endif
X
X			/* where should the daemon stick its PID?
X			 */
X#define PIDFILE		"/etc/crond.pid"
X
X#endif /*CONFIG_FLAG*/
END_OF_FILE
if test 3929 -ne `wc -c <'config.h'`; then
    echo shar: \"'config.h'\" unpacked with wrong size!
fi
# end of 'config.h'
fi
if test -f 'crond.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crond.8'\"
else
echo shar: Extracting \"'crond.8'\" \(2165 characters\)
sed "s/^X//" >'crond.8' <<'END_OF_FILE'
X.\" $Header: crond.8,v 2.1 90/07/18 00:23:40 vixie Exp $
X.\" 
X.\"/* Copyright 1988,1990 by Paul Vixie
X.\" * All rights reserved
X.\" *
X.\" * Distribute freely, except: don't remove my name from the source or
X.\" * documentation (don't take credit for my work), mark your changes (don't
X.\" * get me blamed for your possible bugs), don't alter or remove this
X.\" * notice.  May be sold if buildable source is provided to buyer.  No
X.\" * warrantee of any kind, express or implied, is included with this
X.\" * software; use at your own risk, responsibility for damages (if any) to
X.\" * anyone resulting from the use of this software rests entirely with the
X.\" * user.
X.\" *
X.\" * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X.\" * I'll try to keep a version up to date.  I can be reached as follows:
X.\" * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X.\" * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X.\" */
X.TH CROND 8 "15 Nov 1988"
X.UC 4
X.SH NAME
crond \- daemon to execute scheduled commands (Vixie Cron)
X.SH SYNOPSIS
crond
X.SH DESCRIPTION
X.I Crond
should be started from /etc/rc or /etc/rc.local.  It will return immediately,
so you don't need to start it with '&'.
X.PP
X.I Crond
searches /var/cron/tabs for crontab files which are named after accounts in
X/etc/passwd; crontabs found are loaded into memory.
X.I Crond
then wakes up every minute, examining all stored crontabs, checking each
command to see if it should be run in the current minute.  When executing
commands, any output is mailed to the owner of the crontab (or to the user
named in the MAILTO environment variable in the crontab, if such exists).
X.PP
Additionally,
X.I crond
checks each minute to see if its spool directory's modtime has changed, and
if it has,
X.I crond
will then examine the modtime on all crontabs and reload those which have
changed.  Thus
X.I crond
need not be restarted whenever a crontab file is modified.  Note that the
X.IR Crontab (1)
command updates the modtime of the spool directory whenever it changes a
crontab.
X.SH "SEE ALSO"
crontab(1), crontab(5)
X.SH AUTHOR
X.nf
Paul Vixie, paul at vixie.sf.ca.us
END_OF_FILE
if test 2165 -ne `wc -c <'crond.8'`; then
    echo shar: \"'crond.8'\" unpacked with wrong size!
fi
# end of 'crond.8'
fi
if test -f 'crontab.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'crontab.1'\"
else
echo shar: Extracting \"'crontab.1'\" \(2789 characters\)
sed "s/^X//" >'crontab.1' <<'END_OF_FILE'
X.\" $Header: crontab.1,v 2.1 90/07/18 00:23:43 vixie Exp $
X.\"
X.\"/* Copyright 1988,1990 by Paul Vixie
X.\" * All rights reserved
X.\" *
X.\" * Distribute freely, except: don't remove my name from the source or
X.\" * documentation (don't take credit for my work), mark your changes (don't
X.\" * get me blamed for your possible bugs), don't alter or remove this
X.\" * notice.  May be sold if buildable source is provided to buyer.  No
X.\" * warrantee of any kind, express or implied, is included with this
X.\" * software; use at your own risk, responsibility for damages (if any) to
X.\" * anyone resulting from the use of this software rests entirely with the
X.\" * user.
X.\" *
X.\" * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X.\" * I'll try to keep a version up to date.  I can be reached as follows:
X.\" * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X.\" * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X.\" */
X.TH CRONTAB 1 "9 December 1988"
X.UC 4
X.SH NAME
crontab \- maintain crontab files for individual users
X.SH SYNOPSIS
crontab [ -u user ] { -l | -d | -r file }
X.SH DESCRIPTION
X.I Crontab
is the program used to install, deinstall or list the tables
used to drive the
X.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
X.IR crond (8)
or
X.I crontab
programs.
X.PP
If the
X.I allow
file exists, then you must be listed therein in order to be allowed to use
this command.  If the
X.I allow
file does not exist but the
X.I deny
file does exist, then you must \fBnot\fR be listed in the
X.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.
X.PP
If the
X.I -u
option is given, it specifies the name of the user whose crontab is to be
tweaked.  If this option is not given,
X.I crontab
examines "your" crontab, i.e., the crontab of the person executing the
command.  Note that
X.IR su (8)
can confuse
X.I crontab
and that if you are running inside of
X.IR su (8)
you should always use the
X.I -u
option for safety's sake.
X.PP
The
X.I -l
option causes the current crontab to be displayed on standard output.
X.PP
The
X.I -d
option causes the current crontab to be deleted.
X.PP
The
X.I -r
option is used to replace the current
crontab (if any) with the contents of the named file.
X.SH "SEE ALSO"
crontab(5), crond(8)
X.SH FILES
X.nf
X/var/cron/allow
X/var/cron/deny
X.fi
X.SH DIAGNOSTICS
A fairly informative usage message appears if you run it with a bad command
line.
X.SH AUTHOR
X.nf
Paul Vixie, paul at vixie.sf.ca.us
END_OF_FILE
if test 2789 -ne `wc -c <'crontab.1'`; then
    echo shar: \"'crontab.1'\" unpacked with wrong size!
fi
# end of 'crontab.1'
fi
if test -f 'env.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'env.c'\"
else
echo shar: Extracting \"'env.c'\" \(3475 characters\)
sed "s/^X//" >'env.c' <<'END_OF_FILE'
X#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: env.c,v 2.2 90/07/18 00:23:48 vixie Exp $";
X#endif
X
X/* Copyright 1988,1990 by Paul Vixie
X * All rights reserved
X *
X * Distribute freely, except: don't remove my name from the source or
X * documentation (don't take credit for my work), mark your changes (don't
X * get me blamed for your possible bugs), don't alter or remove this
X * notice.  May be sold if buildable source is provided to buyer.  No
X * warrantee of any kind, express or implied, is included with this
X * software; use at your own risk, responsibility for damages (if any) to
X * anyone resulting from the use of this software rests entirely with the
X * user.
X *
X * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X * I'll try to keep a version up to date.  I can be reached as follows:
X * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X */
X
X
X#include "cron.h"
X
X
char **
env_init()
X{
X	extern char	*malloc();
X	register char	**p = (char **) malloc(sizeof(char **));
X
X	p[0] = NULL;
X	return p;
X}
X
X
char **
env_set(envp, envstr)
X	char	**envp;
X	char	*envstr;
X{
X	extern char	*realloc(), *savestr();
X	register int	count, found;
X	register char	**p;
X
X	/*
X	 * count the number of elements, including the null pointer;
X	 * also set 'found' to -1 or index of entry if already in here.
X	 */
X	found = -1;
X	for (count = 0;  envp[count] != NULL;  count++)
X	{
X		if (!strcmp_until(envp[count], envstr, '='))
X			found = count;
X	}
X	count++;		/* for the null pointer
X				 */
X
X	if (found != -1)
X	{
X		/*
X		 * it exists already, so just free the existing setting,
X		 * save our new one there, and return the existing array.
X		 */
X		free(envp[found]);
X		envp[found] = savestr(envstr);
X		return envp;
X	}
X
X	/*
X	 * it doesn't exist yet, so resize the array, move null pointer over
X	 * one, save our string over the old null pointer, and return resized
X	 * array.
X	 */
X	p = (char **) realloc(
X			(char *)   envp,
X			(unsigned) ((count+1) * sizeof(char **))
X	);
X	p[count] = p[count-1];
X	p[count-1] = savestr(envstr);
X	return p;
X}
X
X
int
load_env(envstr, f)
X	char	*envstr;
X	FILE	*f;
X{
X	/* return	ERR = end of file
X	 *		FALSE = not an env setting (file was repositioned)
X	 *		TRUE = was an env setting
X	 */
X	char	*strcpy(), *sprintf();
X	long	filepos;
X	int	fileline;
X	char	name[MAX_TEMPSTR], val[MAX_ENVSTR];
X	int	fields, strdtb();
X	void	skip_comments();
X
X	filepos = ftell(f);
X	fileline = LineNumber;
X	skip_comments(f);
X	if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
X		return ERR;
X
X	Debug(DPARS, ("load_env, read <%s>\n", envstr))
X
X	name[0] = val[0] = '\0';
X	fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val);
X	if (fields != 2)
X	{
X		Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields))
X		fseek(f, filepos, 0);
X		Set_LineNum(fileline);
X		return FALSE;
X	}
X
X	/* 2 fields from scanf; looks like an env setting
X	 */
X
X	/*
X	 * process value string
X	 */
X	{
X		int	len = strdtb(val);
X
X		if (len >= 2)
X			if (val[0] == '\'' || val[0] == '"')
X				if (val[len-1] == val[0])
X				{
X					val[len-1] = '\0';
X					(void) strcpy(val, val+1);
X				}
X	}
X
X	(void) sprintf(envstr, "%s=%s", name, val);
X	Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
X	return TRUE;
X}
X
X
char *
env_get(name, envp)
X	char	*name;
X	char	**envp;
X{
X	char	*index();
X
X	for (;  *envp;  envp++)
X		if (!strcmp_until(*envp, name, '='))
X			return index(*envp, '=') + 1;
X	return NULL;
X}
END_OF_FILE
if test 3475 -ne `wc -c <'env.c'`; then
    echo shar: \"'env.c'\" unpacked with wrong size!
fi
# end of 'env.c'
fi
if test -f 'job.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'job.c'\"
else
echo shar: Extracting \"'job.c'\" \(1722 characters\)
sed "s/^X//" >'job.c' <<'END_OF_FILE'
X#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: job.c,v 1.2 90/07/18 00:23:59 vixie Exp $";
X#endif
X
X/* Copyright 1988,1990 by Paul Vixie
X * All rights reserved
X *
X * Distribute freely, except: don't remove my name from the source or
X * documentation (don't take credit for my work), mark your changes (don't
X * get me blamed for your possible bugs), don't alter or remove this
X * notice.  May be sold if buildable source is provided to buyer.  No
X * warrantee of any kind, express or implied, is included with this
X * software; use at your own risk, responsibility for damages (if any) to
X * anyone resulting from the use of this software rests entirely with the
X * user.
X *
X * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X * I'll try to keep a version up to date.  I can be reached as follows:
X * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X */
X
X
X#include "cron.h"
X
X
typedef	struct	_job
X	{
X		struct _job	*next;
X		char		*cmd;
X		user		*u;
X	}
X	job;
X
X
static job	*jhead = NULL, *jtail = NULL;
X
X
void
job_add(cmd, u)
X	register char *cmd;
X	register user *u;
X{
X	register job *j;
X
X	/* if already on queue, keep going */
X	for (j=jhead; j; j=j->next)
X		if (j->cmd == cmd && j->u == u) { return; }
X
X	/* build a job queue element */
X	j = (job*)malloc(sizeof(job));
X	j->next = (job*) NULL;
X	j->cmd = cmd;
X	j->u = u;
X
X	/* add it to the tail */
X	if (!jhead) { jhead=j; }
X	else { jtail->next=j; }
X	jtail = j;
X}
X
X
int
job_runqueue()
X{
X	register job	*j;
X	register int	run = 0;
X
X	for (j=jhead; j; j=j->next) {
X		do_command(j->cmd, j->u);
X		free(j);
X		run++;
X	}
X	jhead = jtail = NULL;
X	return run;
X}
END_OF_FILE
if test 1722 -ne `wc -c <'job.c'`; then
    echo shar: \"'job.c'\" unpacked with wrong size!
fi
# end of 'job.c'
fi
if test -f 'user.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'user.c'\"
else
echo shar: Extracting \"'user.c'\" \(2780 characters\)
sed "s/^X//" >'user.c' <<'END_OF_FILE'
X#if !defined(lint) && !defined(LINT)
static char rcsid[] = "$Header: user.c,v 2.1 90/07/18 00:23:45 vixie Exp $";
X#endif
X
X/* vix 26jan87 [log is in RCS file]
X */
X
X/* Copyright 1988,1990 by Paul Vixie
X * All rights reserved
X *
X * Distribute freely, except: don't remove my name from the source or
X * documentation (don't take credit for my work), mark your changes (don't
X * get me blamed for your possible bugs), don't alter or remove this
X * notice.  May be sold if buildable source is provided to buyer.  No
X * warrantee of any kind, express or implied, is included with this
X * software; use at your own risk, responsibility for damages (if any) to
X * anyone resulting from the use of this software rests entirely with the
X * user.
X *
X * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
X * I'll try to keep a version up to date.  I can be reached as follows:
X * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013,
X * paul at vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul
X */
X
X
X#include "cron.h"
X
X
void
free_user(u)
X	user	*u;
X{
X	void	free_entry();
X	int	free();
X	entry	*e;
X	char	**env;
X
X	for (e = u->crontab;  e != NULL;  e = e->next)
X		free_entry(e);
X	for (env = u->envp;  *env;  env++)
X		(void) free(*env);
X	(void) free(u->envp);
X	(void) free(u);
X}
X
X
user *
load_user(crontab_fd, name, uid, gid, dir, shell)
X	int	crontab_fd;
X	char	*name;
X	int	uid;
X	int	gid;
X	char	*dir;
X	char	*shell;
X{
X	char	*malloc(), *sprintf(), **env_init(), **env_set();
X	int	load_env();
X	entry	*load_entry();
X
X	char	envstr[MAX_ENVSTR];
X	FILE	*file;
X	user	*u;
X	entry	*e;
X	int	status;
X
X	if (!(file = fdopen(crontab_fd, "r")))
X	{
X		perror("fdopen on crontab_fd in load_user");
X		return NULL;
X	}
X
X	Debug(DPARS, ("load_user()\n"))
X
X	/* file is open.  build user entry, then read the crontab file.
X	 */
X	u = (user *) malloc(sizeof(user));
X	u->uid     = uid;
X	u->gid     = gid;
X	u->envp    = env_init();
X	u->crontab = NULL;
X
X	/*
X	 * do auto env settings that the user could reset in the cron tab
X	 */
X	sprintf(envstr, "SHELL=%s", (*shell) ?shell :"/bin/sh");
X	u->envp = env_set(u->envp, envstr);
X
X	sprintf(envstr, "HOME=%s", dir);
X	u->envp = env_set(u->envp, envstr);
X
X	/* load the crontab
X	 */
X	while ((status = load_env(envstr, file)) >= OK)
X	{
X		if (status == TRUE)
X		{
X			u->envp = env_set(u->envp, envstr);
X		}
X		else
X		{
X			if (NULL != (e = load_entry(file, NULL)))
X			{
X				e->next = u->crontab;
X				u->crontab = e;
X			}
X		}
X	}
X
X	/*
X	 * do automatic env settings that should have precedence over any
X	 * set in the cron tab.
X	 */
X	(void) sprintf(envstr, "%s=%s", USERENV, name);
X	u->envp = env_set(u->envp, envstr);
X
X	/*
X	 * done. close file, return pointer to 'user' structure
X	 */
X	fclose(file);
X
X	Debug(DPARS, ("...load_user() done\n"))
X
X	return u;
X}
END_OF_FILE
if test 2780 -ne `wc -c <'user.c'`; then
    echo shar: \"'user.c'\" unpacked with wrong size!
fi
# end of 'user.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list