[comp.sources.unix] v20i027: Deliver, flexible email delivery system, Patch1

rsalz@uunet.uu.net (Rich Salz) (10/16/89)

Submitted-by: Chip Salzenberg <chip@ateng.com>
Posting-number: Volume 20, Issue 27
Archive-name: deliver2.0/patch1
Patch-to: Volume 20, Issue 23-26

Changes in patch #1 to Deliver 2.0:

1.  If a delivery file produces no output, the message isn't thrown
    away.  Instead, it is put in an "undelivered mail" mailbox.  This
    change should prevent lost mail due to broken delivery files.

2.  If a delivery file outputs the string "DROP", the "undelivered mail"
    safety net is removed.  Think of this as: "Yes, I want to toss it."

3.  Don't bother to recopy temp files when executing system and post-
    user delivery files.  There's no security problem with them.

4.  New configuration items:
	SAFEPATH        Safe directories for PATH environment var.
	MBX_UNDEL       Mailbox for undelivered mail.
	DFILE_DROP      Special delivery file output string:  "Drop msg."

5.  New sample delivery file, "u-notify".  This one writes a message on
    your terminal when new mail arrives.

6.  Miscellaneous bug fixes.

This patch contains changes to the following files:
	patchlevel.h
	Makefile
	config.h
	copymsg.c
	deliver.8
	deliver.h
	dest.c
	dfile.c
	misc.h
	procs.c
	subs.c
	samples/u-notify

#! /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 shell archive."
# Contents:  patch1
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'patch1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patch1'\"
else
echo shar: Extracting \"'patch1'\" \(22320 characters\)
sed "s/^X//" >'patch1' <<'END_OF_FILE'
X
XIndex: patchlevel.h
XPrereq: 0
X***************
X*** 1,1 ****
X! #define PATCHLEVEL 0
X--- 1,1 ----
X! #define PATCHLEVEL 1
X
XIndex: Makefile
X***************
X*** 1,3 ****
X! # $Header: Makefile,v 2.2 89/06/09 13:19:53 network Exp $
X  #
X  # Makefile for deliver
X--- 1,3 ----
X! # $Header: Makefile,v 2.4 89/10/02 10:58:56 network Exp $
X  #
X  # Makefile for deliver
X***************
X*** 29,32 ****
X--- 29,35 ----
X  #       Your local sharchive generator.
X  #
X+ # CC
X+ #       Your favorite C compiler.
X+ #
X  # CFLAGS
X  #       Compile-time flags to cc.
X***************
X*** 33,36 ****
X--- 36,40 ----
X  #       For BSD systems, include "-DBSD".
X  #       For USG (System III and System V) systems, include "-DUSG".
X+ #       For Xenix systems, don't define anything.
X  #
X  # LDFLAGS
X***************
X*** 43,49 ****
X  # BIN
X  #       Target directory for installation; /usr/bin is recommended.
X! #       You may use /usr/local/bin (or whatever), but you must be sure
X! #       that the directory you choose is in your PATH during mail
X! #       transmission and delivery.
X  #
X  # DELSHAR
X--- 47,53 ----
X  # BIN
X  #       Target directory for installation; /usr/bin is recommended.
X! #       You may use /usr/local/bin (or whatever), but if you do,
X! #       be sure that the directory you choose is in your SAFEPATH
X! #       as defined in config.h.
X  #
X  # DELSHAR
X***************
X*** 54,57 ****
X--- 58,62 ----
X  COPY =  cp
X  SHAR =  shar
X+ CC = cc
X  CFLAGS = -O
X  LDFLAGS = -i
X***************
X*** 71,76 ****
X  DELSRC1 = context.c copymsg.c
X  DELSRC2 = debug.c dest.c dfile.c lock.c main.c
X! DELSRC3 = mbox.c procs.c subs.c sysdep.c unctime.y uucp.c
X! DELSRCS = $(DELSRC1) $(DELSRC2) $(DELSRC3)
X  UIDSRCS = uid.c
X  HDRSRCS = header.c
X--- 76,84 ----
X  DELSRC1 = context.c copymsg.c
X  DELSRC2 = debug.c dest.c dfile.c lock.c main.c
X! DELSRC3 = mbox.c procs.c subs.c sysdep.c uucp.c
X! DELYY   = unctime.y
X! DELYC   = unctime.c
X! DELSRCY = $(DELSRC1) $(DELSRC2) $(DELSRC3) $(DELYY)
X! DELSRCC = $(DELSRC1) $(DELSRC2) $(DELSRC3) $(DELYC)
X  UIDSRCS = uid.c
X  HDRSRCS = header.c
X***************
X*** 126,132 ****
X  	$(CC) $(LDFLAGS) -o $@ $(DELOBJS) $(COMOBJS) $(LIBS)
X  $(DELOBJS): $(HDRS)
X  
X  clean::
X! 	rm -f $(DELOBJS)
X  clobber::
X  	rm -f deliver
X--- 134,141 ----
X  	$(CC) $(LDFLAGS) -o $@ $(DELOBJS) $(COMOBJS) $(LIBS)
X  $(DELOBJS): $(HDRS)
X+ unctime.o: unctime.c
X  
X  clean::
X! 	rm -f $(DELOBJS) $(DELYC)
X  clobber::
X  	rm -f deliver
X***************
X*** 170,175 ****
X  lint: deliver.lint uid.lint
X  
X! deliver.lint: $(HDRS) $(DELSRCS) $(COMSRCS)
X! 	lint $(DELSRCS) $(COMSRCS) -lc $(LIBS) >$@
X  
X  uid.lint: config.h $(UIDSRCS) $(COMSRCS)
X--- 179,184 ----
X  lint: deliver.lint uid.lint
X  
X! deliver.lint: $(HDRS) $(DELSRCC) $(COMSRCS)
X! 	lint $(DELSRCC) $(COMSRCS) -lc $(LIBS) >$@
X  
X  uid.lint: config.h $(UIDSRCS) $(COMSRCS)
X***************
X*** 190,195 ****
X  $(DELSHAR).03: $(DELSRC2)
X  	$(SHAR) >$@ $(DELSRC2)
X! $(DELSHAR).04: $(DELSRC3)
X! 	$(SHAR) >$@ $(DELSRC3)
X  
X  clobber::
X--- 199,204 ----
X  $(DELSHAR).03: $(DELSRC2)
X  	$(SHAR) >$@ $(DELSRC2)
X! $(DELSHAR).04: $(DELSRC3) $(DELYY)
X! 	$(SHAR) >$@ $(DELSRC3) $(DELYY)
X  
X  clobber::
X
XIndex: config.h
X***************
X*** 1,3 ****
X! /* $Header: config.h,v 2.2 89/06/09 13:07:38 network Exp $
X   *
X   * Deliver configuration.
X--- 1,3 ----
X! /* $Header: config.h,v 2.3 89/09/29 18:16:52 network Exp $
X   *
X   * Deliver configuration.
X***************
X*** 4,7 ****
X--- 4,12 ----
X   *
X   * $Log:	config.h,v $
X+  * Revision 2.3  89/09/29  18:16:52  network
X+  * Save message when delivery file produces no output,
X+  * unless delivery file output the "DROP" string.
X+  * Don't recopy temp files for sys and post-user delfiles.
X+  * 
X   * Revision 2.2  89/06/09  13:07:38  network
X   * Adapt to BSD quirks.
X***************
X*** 58,62 ****
X   */
X  
X! #ifdef __STDC__
X  #define SIGFLAG sig_atomic_t
X  #else
X--- 63,67 ----
X   */
X  
X! #if __STDC__
X  #define SIGFLAG sig_atomic_t
X  #else
X***************
X*** 127,131 ****
X   */
X  
X! #ifdef __STDC__
X  #define HAS_STDARG
X  #else
X--- 132,136 ----
X   */
X  
X! #if __STDC__
X  #define HAS_STDARG
X  #else
X***************
X*** 177,180 ****
X--- 182,197 ----
X  
X  /*----------------------------------------------------------------------
X+  * Safe directories for child processes' PATH variables.
X+  * Note that including "." is a security hole.
X+  * For the superuser, "/etc:" is automatically prepended.
X+  */
X+ 
X+ #ifdef BSD
X+ #define SAFEPATH  "/bin:/usr/ucb:/usr/bin"
X+ #else
X+ #define SAFEPATH  "/bin:/usr/bin"
X+ #endif
X+ 
X+ /*----------------------------------------------------------------------
X   * Characters that may not appear in addresses.
X   * (This string should include all metacharacters for your chosen shell.)
X***************
X*** 198,201 ****
X--- 215,220 ----
X   * Define MBX_MODE to the file access modes for new mailboxes.
X   * (System V requires group write permissions, i.e. 0020.)
X+  *
X+  * Define MBX_UNDEL to the mailbox for undelivered mail.
X   */
X  
X***************
X*** 211,215 ****
X--- 230,244 ----
X  #endif
X  
X+ #define MBX_UNDEL     "Undel.mail"
X+ 
X  /*----------------------------------------------------------------------
X+  * Delivery file directives.
X+  * When delivery files output these strings as "user names", they
X+  * are considered instructions.
X+  */
X+ 
X+ #define DFILE_DROP    "DROP"            /* Drop this message    */
X+ 
X+ /*----------------------------------------------------------------------
X   * Names of delivery files.
X   *
X
XIndex: copymsg.c
X***************
X*** 1,3 ****
X! /* $Header: copymsg.c,v 2.1 89/06/09 12:25:16 network Exp $
X   *
X   * Take the message from standard input and write it to two temp files,
X--- 1,3 ----
X! /* $Header: copymsg.c,v 2.2 89/09/29 18:17:53 network Exp $
X   *
X   * Take the message from standard input and write it to two temp files,
X***************
X*** 5,8 ****
X--- 5,13 ----
X   *
X   * $Log:	copymsg.c,v $
X+  * Revision 2.2  89/09/29  18:17:53  network
X+  * Save message when delivery file produces no output,
X+  * unless delivery file output the "DROP" string.
X+  * Don't recopy temp files for sys and post-user delfiles.
X+  * 
X   * Revision 2.1  89/06/09  12:25:16  network
X   * Update RCS revisions.
X***************
X*** 344,349 ****
X  
X  /*----------------------------------------------------------------------
X   * Create another copy of each temp file, for security reasons.
X!  * Also, put their names in the environment.
X   */
X  
X--- 349,379 ----
X  
X  /*----------------------------------------------------------------------
X+  * Don't bother copying message.
X+  * Put the original names in the environment.
X+  */
X+ 
X+ int
X+ dont_copy()
X+ {
X+ 	int     r, t;
X+ 
X+ 	for (r = T_HDR, t = T_HDRCOPY; r <= T_BODY; ++r, ++t)
X+ 	{
X+ 		if (tenv[t] && tfile[r])
X+ 			alloc_env(tenv[t], tfile[r]);
X+ 	}
X+ 
X+ 	if (verbose)
X+ 	{
X+ 		message("dont_copy: header is %s, body is %s\n",
X+ 			tfile[T_HDR], tfile[T_BODY]);
X+ 	}
X+ 
X+ 	return 0;
X+ }
X+ 
X+ /*----------------------------------------------------------------------
X   * Create another copy of each temp file, for security reasons.
X!  * Also, put the names of the copies in the environment.
X   */
X  
X
XIndex: deliver.8
X***************
X*** 1,3 ****
X! .\" $Header: deliver.8,v 2.1 89/06/09 12:25:19 network Exp $
X  .\"
X  .\" Man page for deliver.
X--- 1,3 ----
X! .\" $Header: deliver.8,v 2.2 89/10/04 10:49:10 network Exp $
X  .\"
X  .\" Man page for deliver.
X***************
X*** 4,7 ****
X--- 4,10 ----
X  .\"
X  .\" $Log:	deliver.8,v $
X+ .\" Revision 2.2  89/10/04  10:49:10  network
X+ .\" Document the "Undel.mail" and "DROP" features.
X+ .\" 
X  .\" Revision 2.1  89/06/09  12:25:19  network
X  .\" Update RCS revisions.
X***************
X*** 192,196 ****
X  to control delivery to users.  Note that delivery files do
X  .I not
X! control delivery to explicitly named mailboxes.
X  .PP
X  On each system the postmaster may create a
X--- 195,201 ----
X  to control delivery to users.  Note that delivery files do
X  .I not
X! control delivery to explicitly named mailboxes.  (See the
X! .B \-b
X! option.)
X  .PP
X  On each system the postmaster may create a
X***************
X*** 287,307 ****
X  an absolute pathname, it is interpreted relative to the home directory of
X  the named user.
X! .PP
X! .B NOTE 1:
X  When
X  .I deliver
X! executes a delivery file, it expects that delivery file to explicitly name
X! all users (and, optionally, mailboxes) where the message should be
X! delivered.  If a delivery file does not name any users in its output, then
X! the message will not be delivered to anyone whose mail delivery is
X! controlled by that delivery file.
X  .PP
X! Therefore, a user delivery file containing only "exit" will keep the given
X! user from receiving any mail.  A system delivery file containing only "exit"
X! will cause
X! .B all
X! mail to disappear.  So be careful!
X! .PP
X! .B NOTE 2:
X  If
X  .I deliver
X--- 292,319 ----
X  an absolute pathname, it is interpreted relative to the home directory of
X  the named user.
X! .SH "UNDELIVERED MAIL"
X  When
X  .I deliver
X! executes a delivery file, it expects a complete list of all users (and,
X! optionally, mailboxes) that should receive the message.  If a delivery file
X! produces no output,
X! .I deliver
X! saves the message in the "undelivered mail" mailbox named "Undel.mail" in
X! the home directory of the delivery file's owner.  (System and post-user
X! delivery files are "owned" by root.)
X  .PP
X! Sometimes a delivery file writer really does want
X! .I deliver
X! to drop a message.  For example, if a delivery file stores a message by
X! running "deliver -b", then there's no need for the parent
X! .I deliver
X! to save the message again.  A delivery file can tell
X! .I deliver
X! not to save the message by outputting the string "DROP".  A delivery file's
X! outputting "DROP" the "undelivered mail" safety net for that delivery file.
X! Think of "DROP" as shorthand for: "Trust me.  I know what I'm doing."
X! However, if the delivery file outputs any names and/or addresses in addition
X! to "DROP", then "DROP" has no effect.
X! .SH "SECURITY"
X  If
X  .I deliver
X***************
X*** 312,316 ****
X  create a security problem.
X  .PP
X- .B NOTE 3:
X  All user delivery files are executed in the context of the user in whose
X  home directory they reside.  A user's "context" includes the uid, gid, and
X--- 324,327 ----
X***************
X*** 317,321 ****
X  home directory as specified in /etc/passwd.
X  .PP
X- .B NOTE 4:
X  For security reasons, if a user's home directory is writable to the world,
X  .I deliver
X--- 328,331 ----
X***************
X*** 322,326 ****
X  will ignore any delivery file that might be found there.
X  .PP
X- .B NOTE 5:
X  For security reasons,
X  .I deliver
X--- 332,335 ----
X
XIndex: deliver.h
X***************
X*** 1,3 ****
X! /* $Header: deliver.h,v 2.1 89/06/09 12:25:21 network Exp $
X   *
X   * General pull-it-together include file.
X--- 1,3 ----
X! /* $Header: deliver.h,v 2.2 89/09/29 18:17:56 network Exp $
X   *
X   * General pull-it-together include file.
X***************
X*** 4,7 ****
X--- 4,12 ----
X   *
X   * $Log:	deliver.h,v $
X+  * Revision 2.2  89/09/29  18:17:56  network
X+  * Save message when delivery file produces no output,
X+  * unless delivery file output the "DROP" string.
X+  * Don't recopy temp files for sys and post-user delfiles.
X+  * 
X   * Revision 2.1  89/06/09  12:25:21  network
X   * Update RCS revisions.
X***************
X*** 71,74 ****
X--- 76,80 ----
X  
X  char    *basename();
X+ char    *relpath();
X  char    *gethost();
X  char    *copystr();
X
XIndex: dest.c
X***************
X*** 1,3 ****
X! /* $Header: dest.c,v 2.1 89/06/09 12:25:22 network Exp $
X   *
X   * Operations on the list of mail destinations.
X--- 1,3 ----
X! /* $Header: dest.c,v 2.2 89/09/29 18:17:57 network Exp $
X   *
X   * Operations on the list of mail destinations.
X***************
X*** 4,7 ****
X--- 4,12 ----
X   *
X   * $Log:	dest.c,v $
X+  * Revision 2.2  89/09/29  18:17:57  network
X+  * Save message when delivery file produces no output,
X+  * unless delivery file output the "DROP" string.
X+  * Don't recopy temp files for sys and post-user delfiles.
X+  * 
X   * Revision 2.1  89/06/09  12:25:22  network
X   * Update RCS revisions.
X***************
X*** 75,78 ****
X--- 80,85 ----
X  	if (class == CL_MBOX)
X  		d->d_mailbox = copystr(mailbox);
X+ 	else
X+ 		d->d_mailbox = NULL;
X  
X  	/*
X
XIndex: dfile.c
X***************
X*** 1,3 ****
X! /* $Header: dfile.c,v 2.1 89/06/09 12:25:24 network Exp $
X   *
X   * Filter destination(s) through delivery file(s).
X--- 1,3 ----
X! /* $Header: dfile.c,v 2.2 89/09/29 18:17:59 network Exp $
X   *
X   * Filter destination(s) through delivery file(s).
X***************
X*** 4,7 ****
X--- 4,12 ----
X   *
X   * $Log:	dfile.c,v $
X+  * Revision 2.2  89/09/29  18:17:59  network
X+  * Save message when delivery file produces no output,
X+  * unless delivery file output the "DROP" string.
X+  * Don't recopy temp files for sys and post-user delfiles.
X+  * 
X   * Revision 2.1  89/06/09  12:25:24  network
X   * Update RCS revisions.
X***************
X*** 31,35 ****
X  	 */
X  
X! 	if (stat(sys_deliver, &st) == -1)
X  	{
X  		if (verbose)
X--- 36,40 ----
X  	 */
X  
X! 	if (stat(relpath(eff_ct->ct_home, sys_deliver), &st) == -1)
X  	{
X  		if (verbose)
X***************
X*** 87,92 ****
X  
X  	if (fac > 2)
X! 		(void) do_dfile(eff_ct, fav, (DEST *)NULL);
X  
X  	free((char *) fav);
X  
X--- 92,110 ----
X  
X  	if (fac > 2)
X! 	{
X! 		/*
X! 		 * If we get nothing back from the system delivery file,
X! 		 * put the message in the "undelivered" mailbox.
X! 		 */
X  
X+ 		if (do_dfile(eff_ct, fav, (DEST *)NULL) <= 0)
X+ 		{
X+ 			if (verbose)
X+ 				message("sys_dfile: no output\n");
X+ 
X+ 			(void) dest(eff_ct->ct_name, MBX_UNDEL);
X+ 		}
X+ 	}
X+ 
X  	free((char *) fav);
X  
X***************
X*** 110,114 ****
X  	 */
X  
X! 	if (stat(post_deliver, &st) == -1)
X  	{
X  		if (verbose)
X--- 128,132 ----
X  	 */
X  
X! 	if (stat(relpath(eff_ct->ct_home, post_deliver), &st) == -1)
X  	{
X  		if (verbose)
X***************
X*** 136,140 ****
X  		++num_dests;
X  
X! 	fav = (char **) zalloc((num_dests + 3) * sizeof(char **));
X  	fav[0] = shell;
X  	fav[1] = post_deliver;
X--- 154,158 ----
X  		++num_dests;
X  
X! 	fav = (char **) zalloc((num_dests + 3) * sizeof(char *));
X  	fav[0] = shell;
X  	fav[1] = post_deliver;
X***************
X*** 155,160 ****
X  
X  	if (fac > 2)
X! 		(void) do_dfile(eff_ct, fav, (DEST *)NULL);
X  
X  	free((char *) fav);
X  
X--- 173,191 ----
X  
X  	if (fac > 2)
X! 	{
X! 		/*
X! 		 * If we get nothing back from the post-user delivery file,
X! 		 * put the message in the "undelivered" mailbox.
X! 		 */
X  
X+ 		if (do_dfile(eff_ct, fav, (DEST *)NULL) <= 0)
X+ 		{
X+ 			if (verbose)
X+ 				message("post_dfile: no output\n");
X+ 
X+ 			(void) dest(eff_ct->ct_name, MBX_UNDEL);
X+ 		}
X+ 	}
X+ 
X  	free((char *) fav);
X  
X***************
X*** 214,219 ****
X  {
X  	CONTEXT *ct;
X! 	char    *fav[4];
X! 	char    udel_path[100];
X  	struct stat st;
X  
X--- 245,249 ----
X  {
X  	CONTEXT *ct;
X! 	char    *s, *udel_path, *fav[4];
X  	struct stat st;
X  
X***************
X*** 252,257 ****
X  	 */
X  
X! 	(void) sprintf(udel_path, "%s/%s", ct->ct_home, user_deliver);
X! 	if (stat(udel_path, &st) == -1)
X  	{
X  		if (verbose)
X--- 282,287 ----
X  	 */
X  
X! 	s = relpath(ct->ct_home, user_deliver);
X! 	if (stat(s, &st) == -1)
X  	{
X  		if (verbose)
X***************
X*** 259,267 ****
X  		return;
X  	}
X  
X  	/*
X! 	 * Time to run the file!
X! 	 * We put this dest on hold, so that it will be ignored unless
X! 	 * the delivery file names it.
X  	 */
X  
X--- 289,297 ----
X  		return;
X  	}
X+ 	udel_path = copystr(s);
X  
X  	/*
X! 	 * Put this destination on hold.
X! 	 * It will be ignored unless it's named by a delivery file.
X  	 */
X  
X***************
X*** 268,271 ****
X--- 298,305 ----
X  	d->d_state = ST_HOLD;
X  
X+ 	/*
X+ 	 * Time to run the file!
X+ 	 */
X+ 
X  	fav[0] = shell;
X  	fav[1] = udel_path;
X***************
X*** 272,276 ****
X  	fav[2] = d->d_name;
X  	fav[3] = NULL;
X! 	(void) do_dfile(ct, fav, d);
X  }
X  
X--- 306,324 ----
X  	fav[2] = d->d_name;
X  	fav[3] = NULL;
X! 
X! 	if (do_dfile(ct, fav, d) <= 0)
X! 	{
X! 		/*
X! 		 * If we get nothing back from the user delivery file,
X! 		 * put the message in the user's "undelivered" mailbox.
X! 		 */
X! 
X! 		if (verbose)
X! 			message("one_dfile: no output\n");
X! 
X! 		(void) dest(ct->ct_name, MBX_UNDEL);
X! 	}
X! 
X! 	free(udel_path);
X  }
X  
X***************
X*** 277,280 ****
X--- 325,329 ----
X  /*----------------------------------------------------------------------
X   * Process a delivery file.
X+  * Return the count of valid destinations we got back from it.
X   */
X  
X***************
X*** 287,290 ****
X--- 336,340 ----
X  	FILE    *fp;
X  	char    *name, *mailbox;
X+ 	int     count;
X  
X  	if (!ct)
X***************
X*** 301,314 ****
X  	}
X  
X! 	/* Copy the temp files again */
X  
X! 	if (copy_again() < 0)
X! 		return -1;
X  
X! 	/* Allow the given user to own and read the copies */
X  
X! 	if (give_temps(ct) < 0)
X! 		return -1;
X  
X  	/* Here we go! */
X  
X--- 351,379 ----
X  	}
X  
X! 	/*
X! 	 * We trust the superuser not to stomp on the temp files.
X! 	 * Other users get copies of the temp files.
X! 	 */
X  
X! 	if (ct->ct_uid == 0)
X! 	{
X! 		/* We trust the superuser; don't bother copying again */
X  
X! 		if (dont_copy() < 0)
X! 			return -1;
X! 	}
X! 	else
X! 	{
X! 		/* Copy the temp files again */
X  
X! 		if (copy_again() < 0)
X! 			return -1;
X  
X+ 		/* Allow the given user to own and read the copies */
X+ 
X+ 		if (give_temps(ct) < 0)
X+ 			return -1;
X+ 	}
X+ 
X  	/* Here we go! */
X  
X***************
X*** 326,329 ****
X--- 391,396 ----
X  	 */
X  
X+ 	count = 0;
X+ 
X  	while (dfile_gets(fp, &name, &mailbox) >= 0)
X  	{
X***************
X*** 330,333 ****
X--- 397,409 ----
X  		DEST    *nd;
X  
X+ 		++count;
X+ 
X+ 		if (strcmp(name, DFILE_DROP) == 0)
X+ 		{
X+ 			if (verbose)
X+ 				message("delivery file says OK to drop\n");
X+ 			continue;
X+ 		}
X+ 
X  		nd = dest(name, mailbox);
X  		if (nd->d_state == ST_HOLD)
X***************
X*** 349,355 ****
X  				dest_err(nd, E_CTPERM);
X  		}
X  	}
X  
X! 	return ct_pclose(fp);
X  }
X  
X--- 425,436 ----
X  				dest_err(nd, E_CTPERM);
X  		}
X+ 
X+ 		if (nd->d_state != ST_ERROR)
X+ 			++count;
X  	}
X  
X! 	(void) ct_pclose(fp);
X! 
X! 	return count;
X  }
X  
X
XIndex: misc.h
X***************
X*** 1,3 ****
X! /* $Header: misc.h,v 2.1 89/06/09 12:25:35 network Exp $
X   *
X   * Miscellaneous definitions.
X--- 1,3 ----
X! /* $Header: misc.h,v 2.2 89/10/02 10:36:43 network Exp $
X   *
X   * Miscellaneous definitions.
X***************
X*** 4,7 ****
X--- 4,10 ----
X   *
X   * $Log:	misc.h,v $
X+  * Revision 2.2  89/10/02  10:36:43  network
X+  * Declare exit() as void.
X+  * 
X   * Revision 2.1  89/06/09  12:25:35  network
X   * Update RCS revisions.
X***************
X*** 72,75 ****
X--- 75,79 ----
X  extern  long    time();
X  extern  void    free();
X+ extern  void    exit();
X  
X  #ifdef DECLARE_SIGNAL
X
XIndex: procs.c
X***************
X*** 1,3 ****
X! /* $Header: procs.c,v 2.1 89/06/09 12:25:37 network Exp $
X   *
X   * Process management and misc support.
X--- 1,3 ----
X! /* $Header: procs.c,v 2.2 89/09/29 18:18:03 network Exp $
X   *
X   * Process management and misc support.
X***************
X*** 4,7 ****
X--- 4,12 ----
X   *
X   * $Log:	procs.c,v $
X+  * Revision 2.2  89/09/29  18:18:03  network
X+  * Save message when delivery file produces no output,
X+  * unless delivery file output the "DROP" string.
X+  * Don't recopy temp files for sys and post-user delfiles.
X+  * 
X   * Revision 2.1  89/06/09  12:25:37  network
X   * Update RCS revisions.
X***************
X*** 174,178 ****
X  int     chd;
X  {
X! 	char    env_path[32];
X  
X  	/*
X--- 179,183 ----
X  int     chd;
X  {
X! 	char    env_path[sizeof(SAFEPATH) + 8];
X  
X  	/*
X***************
X*** 199,204 ****
X  	/* Set up the environment */
X  
X! 	(void) sprintf(env_path, "%s:/bin:/usr/bin",
X! 			((ct->ct_uid == 0) ? "/etc" : "."));
X  	alloc_env("HOME", ct->ct_home);
X  	alloc_env("PATH", env_path);
X--- 204,212 ----
X  	/* Set up the environment */
X  
X! 	env_path[0] = '\0';
X! 	if (ct->ct_uid == 0)
X! 	    (void) strcat(env_path, "/etc:");
X! 	(void) strcat(env_path, SAFEPATH);
X! 
X  	alloc_env("HOME", ct->ct_home);
X  	alloc_env("PATH", env_path);
X
XIndex: subs.c
X***************
X*** 1,3 ****
X! /* $Header: subs.c,v 2.1 89/06/09 12:25:39 network Exp $
X   *
X   * Miscellaneous subroutines.
X--- 1,3 ----
X! /* $Header: subs.c,v 2.2 89/09/29 18:18:05 network Exp $
X   *
X   * Miscellaneous subroutines.
X***************
X*** 4,7 ****
X--- 4,12 ----
X   *
X   * $Log:	subs.c,v $
X+  * Revision 2.2  89/09/29  18:18:05  network
X+  * Save message when delivery file produces no output,
X+  * unless delivery file output the "DROP" string.
X+  * Don't recopy temp files for sys and post-user delfiles.
X+  * 
X   * Revision 2.1  89/06/09  12:25:39  network
X   * Update RCS revisions.
X***************
X*** 27,30 ****
X--- 32,40 ----
X  		return;
X  
X+ 	/* If it's the same value it already has, don't bother. */
X+ 
X+ 	if ((s = getenv(name)) != NULL && strcmp(s, value) == 0)
X+ 		return;
X+ 
X  	s = zalloc((unsigned) (strlen(name) + strlen(value) + 2));
X  	(void) sprintf(s, "%s=%s", name, value);
X***************
X*** 147,150 ****
X--- 157,195 ----
X  
X  /*----------------------------------------------------------------------
X+  * Return the given pathname relative to the given directory.
X+  * No fancy checking for "." and ".." -- sorry.
X+  */
X+ 
X+ char *
X+ relpath(dir, file)
X+ char    *dir, *file;
X+ {
X+ 	static  char    *path;
X+ 	static  unsigned pathsize;
X+ 	unsigned n;
X+ 
X+ 	if (file[0] == '/')
X+ 		return file;
X+ 
X+ 	n = strlen(dir) + strlen(file) + 2;
X+ 	if (pathsize < n)
X+ 	{
X+ 		pathsize = n + 64;      /* gas */
X+ 		if (path)
X+ 			path = srealloc(path, pathsize);
X+ 		else
X+ 			path = zalloc(pathsize);
X+ 	}
X+ 
X+ 	(void) strcpy(path, dir);
X+ 	n = strlen(path);
X+ 	if (n == 0 || path[n - 1] != '/')
X+ 		path[n++] = '/';
X+ 	(void) strcpy(path + n, file);
X+ 
X+ 	return path;
X+ }
X+ 
X+ /*----------------------------------------------------------------------
X   * Check an address for validity.
X   */
X
XIndex: samples/u-notify
X***************
X*** 1,0 ****
X--- 1,25 ----
X+ : u-notify
X+ # A user delivery file that tells you when new mail arrives.
X+ 
X+ user="$1"
X+ 
X+ # Keep the mail.
X+ 
X+ echo $user
X+ 
X+ # Now notify myself (if I'm logged in).
X+ 
X+ T1=`who | awk '$1 == "'"$user"'" { print $2 }'`
X+ if [ "$T1" ]
X+ then
X+     # If I'm logged in multiple times,
X+     # write to the terminal that was most recently busy.
X+ 
X+     T2=`cd /dev; ls -t $T1 | sed 1q`
X+     for t in $T2
X+     do
X+ 	  echo "\n `date '+%D %H:%M'` --" \
X+ 	       "you have new mail from `header -f From $HEADER`" \
X+ 	       >/dev/$t
X+     done
X+ fi
X
END_OF_FILE
if test 22320 -ne `wc -c <'patch1'`; then
    echo shar: \"'patch1'\" unpacked with wrong size!
fi
# end of 'patch1'
fi
echo shar: End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.