Deliver 2.0 Patch #9
Chip Salzenberg
chip at tct.uucp
Thu Mar 8 03:21:40 AEST 1990
NOTE: THIS IS PART OF A COMBINED PATCH. APPLY PATCHES 7-9 TOGETHER.
This patch contains changes to the following files:
patchlevel.h
main.c
mbox.c
procs.c
subs.c
sysdep.c
uucp.c
Index: patchlevel.h
Prereq: 8
***************
*** 1,1 ****
! #define PATCHLEVEL 8
--- 1,1 ----
! #define PATCHLEVEL 9
Index: main.c
***************
*** 1,3 ****
! /* $Header: main.c,v 2.7 90/02/06 11:56:40 chip Exp $
*
* A program to deliver local mail with some flexibility.
--- 1,3 ----
! /* $Header: main.c,v 2.12 90/03/07 11:00:58 chip Exp $
*
* A program to deliver local mail with some flexibility.
***************
*** 4,7 ****
--- 4,28 ----
*
* $Log: main.c,v $
+ * Revision 2.12 90/03/07 11:00:58 chip
+ * Debugging messages only when verbose. (Sigh.)
+ *
+ * Revision 2.11 90/03/06 13:11:53 chip
+ * Run error delivery file after normal delivery;
+ * then call delivery routines again afterward.
+ *
+ * Revision 2.10 90/03/06 12:21:13 chip
+ * Move logging into log.c and address parsing into addr.c.
+ * New: error delivery file for messages that fail.
+ * Major rearrangement of delivery file code.
+ *
+ * Revision 2.9 90/02/23 15:05:15 chip
+ * Clean up the setuid/setgid renunciation logic.
+ *
+ * Revision 2.8 90/02/23 14:16:47 chip
+ * Support "#!" in delivery files.
+ * Support "user|program" and "user?error" from delivery files.
+ * Improve debugging and error message formatting.
+ * Rearrange code for clarity.
+ *
* Revision 2.7 90/02/06 11:56:40 chip
* Enforce MBX_MODE regardless of UMASK.
***************
*** 35,39 ****
#include "patchlevel.h"
#include <signal.h>
- #include <time.h>
/*
--- 56,59 ----
***************
*** 50,56 ****
*/
! static char sys_dfl[] = SYS_DELIVER;
! static char post_dfl[] = POST_DELIVER;
! static char user_dfl[] = USER_DELIVER;
/*
--- 70,77 ----
*/
! static char dfl_sys[] = SYS_DELIVER;
! static char dfl_post[] = POST_DELIVER;
! static char dfl_err[] = ERR_DELIVER;
! static char dfl_user[] = USER_DELIVER;
/*
***************
*** 71,77 ****
int rec_level = 0;
int rec_parent = -1;
! char *sys_deliver = sys_dfl;
! char *post_deliver = post_dfl;
! char *user_deliver = user_dfl;
char *sender = NULL;
char *hostname = NULL;
--- 92,99 ----
int rec_level = 0;
int rec_parent = -1;
! char *sys_deliver = dfl_sys;
! char *post_deliver = dfl_post;
! char *err_deliver = dfl_err;
! char *user_deliver = dfl_user;
char *sender = NULL;
char *hostname = NULL;
***************
*** 87,91 ****
int trust_user = FALSE;
int trust_delfiles = FALSE;
-
FILE *log = NULL;
char *logfile = NULL;
--- 109,112 ----
***************
*** 127,136 ****
progname = basename(argv[0]);
- #ifdef USG
- /* System V requires that we ask for the time zone. Used later. */
-
- tzset();
- #endif
-
/* Special hack -- handle the recursion level and parent first. */
--- 148,151 ----
***************
*** 208,213 ****
--- 223,231 ----
if ((p = getenv(ENV_POSTDEL)) != NULL && *p)
post_deliver = p;
+ if ((p = getenv(ENV_ERRDEL)) != NULL && *p)
+ err_deliver = p;
if ((p = getenv(ENV_USERDEL)) != NULL && *p)
user_deliver = p;
+
if ((p = getenv(ENV_SENDER)) != NULL && *p)
sender = p;
***************
*** 217,221 ****
/* Parse command line arguments */
! while ((c = getopt(argc, argv, "vdAntbs:p:u:r:h:")) != EOF)
{
switch (c)
--- 235,239 ----
/* Parse command line arguments */
! while ((c = getopt(argc, argv, "vdAntbs:p:e:u:r:h:")) != EOF)
{
switch (c)
***************
*** 249,252 ****
--- 267,274 ----
post_deliver = optarg;
break;
+ case 'e':
+ if (*optarg)
+ err_deliver = optarg;
+ break;
case 'u':
if (*optarg)
***************
*** 266,290 ****
}
! #ifdef ERRLOG
! /* If we're delivering and not being verbose, keep an error log. */
! if (!dryrun && !verbose)
{
! errlogfile = tempfile();
! if ((errlog = ftcreate(errlogfile)) == NULL)
! syserr("can't create %s", errlogfile);
! }
! #endif
!
! #ifdef LOG
! /* If we're delivering and the log file exists, keep data for it. */
!
! if (!dryrun && exists(LOG))
! {
! logfile = tempfile();
! if ((log = ftcreate(logfile)) == NULL)
! syserr("can't create %s", logfile);
}
- #endif
/* If no destinations were given, forget it. */
--- 288,303 ----
}
! /* Open temporary log files. */
!
! openlogs();
! /* Figure out the name of this host, unless we've been told. */
!
! if (!hostname && (hostname = gethost()) == NULL)
{
! hostname = "unknown";
! error("unable to determine host name; using \"%s\"\n",
! hostname);
}
/* If no destinations were given, forget it. */
***************
*** 296,309 ****
}
! /* Figure out the name of this host */
!
! if ((hostname = gethost()) == NULL)
! {
! hostname = "unknown";
! error("unable to determine host name; using \"%s\"\n",
! hostname);
! }
!
! /* Print a debugging message */
if (verbose)
--- 309,313 ----
}
! /* If debugging, print a nice banner. */
if (verbose)
***************
*** 313,317 ****
}
! /* Do we trust our caller? */
if (trusted_uid(real_uid))
--- 317,325 ----
}
! /*
! * Renounce setuid privileges if:
! * 1. We don't trust the real user id, OR
! * 2. The caller is using non-default delivery file names.
! */
if (trusted_uid(real_uid))
***************
*** 318,334 ****
trust_user = TRUE;
! /* Do we trust our delivery files? */
!
! if (strcmp(sys_dfl, sys_deliver) == 0
! && strcmp(post_dfl, post_deliver) == 0
! && strcmp(user_dfl, user_deliver) == 0)
trust_delfiles = TRUE;
! /* Renounce special privileges if something insecure was requested. */
!
! if (!trust_user && !trust_delfiles)
{
! if (setgid(eff_gid = real_gid) == -1
! || setuid(eff_uid = real_uid) == -1)
{
syserr("can't renounce setuid privileges");
--- 326,339 ----
trust_user = TRUE;
! if (strcmp(dfl_sys, sys_deliver) == 0
! && strcmp(dfl_post, post_deliver) == 0
! && strcmp(dfl_err, err_deliver) == 0
! && strcmp(dfl_user, user_deliver) == 0)
trust_delfiles = TRUE;
! if ((!trust_user && !trust_delfiles)
! && (eff_uid != real_uid || eff_gid != real_gid))
{
! if (setuid(real_uid) == -1)
{
syserr("can't renounce setuid privileges");
***************
*** 335,338 ****
--- 340,358 ----
leave(1);
}
+ if (setgid(real_gid) == -1)
+ {
+ syserr("can't renounce setgid privileges");
+ leave(1);
+ }
+
+ if ((eff_uid = geteuid()) != real_uid
+ || (eff_gid = getegid()) != real_gid)
+ {
+ error("kernel bug: can't renounce setuid/setgid");
+ leave(1);
+ }
+
+ if (verbose)
+ message("renounced setuid privileges\n");
}
***************
*** 410,530 ****
if (rec_level > REC_LIMIT)
! {
! error("recursion limit (%d) exceeded; writing to %s:%s",
! REC_LIMIT, eff_ct->ct_name, MBX_UNDEL);
- (void) dest(eff_ct->ct_name, MBX_UNDEL);
- }
-
/*
! * Else, if all arguments are mailbox names...
*/
else if (boxdelivery)
! {
! int a;
! if (verbose)
! message("mailbox delivery as %s\n", real_ct->ct_name);
! /*
! * Consider all arguments as mailbox filenames.
! */
! for (a = optind; a < argc; ++a)
! (void) dest(real_ct->ct_name, argv[a]);
if (verbose)
! dumpdests("(should all be mailboxes)");
}
/*
! * Else, arguments are addresses.
*/
! else
! {
! /* Run all destinations though the system delivery file. */
! if (sys_dfile(argc - optind, argv + optind) >= 0)
! {
! if (verbose)
! dumpdests("after running system delivery file");
! }
! else
! {
! int a;
!
! /*
! * System delivery file is missing or ignored.
! * Use the argument list verbatim.
! */
!
! for (a = optind; a < argc; ++a)
! (void) dest(argv[a], (char *) NULL);
! if (verbose)
! dumpdests("as taken from argument list");
! }
! /*
! * Run each user destination through his delivery file.
! */
! if (user_dfiles() >= 0)
! {
! if (verbose)
! dumpdests("after running user delivery files");
! }
! /*
! * Run each remaining destination though the post-user
! * delivery file.
! */
! if (post_dfile() >= 0)
! {
! if (verbose)
! dumpdests("after running post-user delivery file");
! }
}
! /*
! * Drop mail in mailbox(es).
! */
! mbox_deliver();
! if (verbose)
! dumpdests("after delivery to all mailboxes");
/*
! * Send mail to UUCP address(es).
! */
! uucp_deliver();
if (verbose)
! dumpdests("after delivery to UUCP addresses");
!
! /*
! * Report all results in log file.
! */
! if (log)
! logreport(argc - optind, argv + optind);
! /*
! * Report any errors.
! */
! errcount = report_errors();
! /*
! * All done.
! */
! leave(errcount ? 1 : 0);
! /* NOTREACHED */
}
--- 430,583 ----
if (rec_level > REC_LIMIT)
! main_toodeep();
/*
! * Else if the "-b" flag was specified, arguments are mailboxes.
*/
else if (boxdelivery)
! main_boxes(argc - optind, argv + optind);
! /*
! * Otherwise, arguments are addresses.
! */
! else
! main_addrs(argc - optind, argv + optind);
! /*
! * Do all delivery.
! * If anything happens, print a debugging message.
! */
!
! i = 0;
! i += (mbox_deliver() > 0);
! i += (prog_deliver() > 0);
! i += (uucp_deliver() > 0);
! if (i > 0 && verbose)
! dumpdests("after delivery");
!
! /*
! * If we're not in mailbox mode, and if the error delivery file
! * executes, deliver to any destination(s) that it generated.
! */
+ if (!boxdelivery
+ && (i = err_dfile()) > 0)
+ {
if (verbose)
! dumpdests("after running error delivery file");
!
! i = 0;
! i += (mbox_deliver() > 0);
! i += (prog_deliver() > 0);
! i += (uucp_deliver() > 0);
! if (i > 0 && verbose)
! dumpdests("after delivery to error destinations");
}
/*
! * Report all results in log file.
*/
! logreport(argc - optind, argv + optind);
! /*
! * Report any errors.
! */
! errcount = report_errors(argc - optind, argv + optind);
! /*
! * All done.
! */
! leave(errcount ? 1 : 0);
! /* NOTREACHED */
! }
! /*----------------------------------------------------------------------
! * Normal address handling.
! * Call system delivery file, user delivery files,
! * post-user delivery file, error delivery file.
! */
! main_addrs(ac, av)
! int ac;
! char **av;
! {
! int n;
!
! /* Run all destinations though the system delivery file. */
!
! if (sys_dfile(ac, av) >= 0)
! {
! if (verbose)
! dumpdests("after running system delivery file");
}
+ else
+ {
+ int a;
! /*
! * System delivery file is missing or ignored.
! * Use the argument list verbatim.
! */
! for (a = 0; a < ac; ++a)
! (void) addr_dest(av[a], (CONTEXT *)NULL);
! if (verbose)
! dumpdests("as taken from argument list");
! }
/*
! * Run each user destination through his delivery file.
! */
!
! n = user_dfiles();
! if (n > 0 && verbose)
! dumpdests("after running user delivery files");
!
! /*
! * Run each remaining destination though the post-user
! * delivery file.
! */
!
! n = post_dfile();
! if (n > 0 && verbose)
! dumpdests("after running post-user delivery file");
! }
!
! /*----------------------------------------------------------------------
! * Consider all arguments as mailbox filenames.
! */
! main_boxes(ac, av)
! int ac;
! char **av;
! {
! int a;
if (verbose)
! message("mailbox delivery as %s\n", real_ct->ct_name);
! for (a = 0; a < ac; ++a)
! (void) dest(real_ct->ct_name, CL_MBOX, av[a]);
! if (verbose)
! dumpdests("(should all be mailboxes)");
! }
! /*----------------------------------------------------------------------
! * Recursion too deep. Bail out.
! */
! main_toodeep()
! {
! error("recursion limit (%d) exceeded; writing to %s:%s",
! REC_LIMIT, eff_ct->ct_name, MBX_UNDEL);
! dest_undel(eff_ct->ct_name);
}
***************
*** 545,548 ****
--- 598,602 ----
message("-s file Specify the system delivery filename.\n");
message("-p file Specify the post-user delivery filename.\n");
+ message("-e file Specify the error delivery filename.\n");
message("-u file Specify the user delivery filename.\n");
message("-r from Specify the address to appear in the \"From \" line.\n");
***************
*** 582,594 ****
savelogs();
! /* Discard temporary logs. */
! if (! leavetemps)
! {
! if (logfile && unlink(logfile) == -1)
! (void) syserr("can't remove %s", logfile);
! if (errlogfile && unlink(errlogfile) == -1)
! (void) syserr("can't remove %s", logfile);
! }
/* "I am outa here." */
--- 636,643 ----
savelogs();
! /* Discard temporary logs unless user requested otherwise. */
! if (!leavetemps)
! tosslogs();
/* "I am outa here." */
***************
*** 644,706 ****
/*----------------------------------------------------------------------
- * Write a report to the log file.
- */
-
- logreport(ac, av)
- int ac;
- char **av;
- {
- int a;
-
- if (!log)
- return;
-
- logstart(log);
-
- if (sender && *sender)
- (void) fprintf(log, "sender: %s\n", sender);
- if (boxdelivery)
- (void) fprintf(log, "mailbox%s:", (ac > 1) ? "es" : "");
- else
- (void) fprintf(log, "destination%s:", (ac > 1) ? "s" : "");
- for (a = 0; a < ac; ++a)
- (void) fprintf(log, " \"%s\"", av[a]);
- (void) fputc('\n', log);
-
- logstate("delivered", ST_DONE);
- logstate("failed", ST_ERROR);
-
- logdone(log);
- }
-
- /*----------------------------------------------------------------------
- * Log the destinations with the given state.
- * If any are found, the list is prefixed with the given description.
- */
-
- logstate(desc, state)
- char *desc;
- DSTATE state;
- {
- DEST *d;
- int count;
-
- count = 0;
- for (d = first_dest(); d; d = next_dest(d))
- {
- if (d->d_state != state)
- continue;
-
- if (++count == 1)
- (void) fprintf(log, "%s:", desc);
- (void) fprintf(log, " %s", d->d_name);
- if (d->d_mailbox)
- (void) fprintf(log, ":%s", d->d_mailbox);
- }
- if (count)
- (void) fputc('\n', log);
- }
-
- /*----------------------------------------------------------------------
* Report any errors to stderr.
* Return an error count.
--- 693,696 ----
***************
*** 708,726 ****
int
! report_errors()
{
! DEST *d;
! int count = 0;
! for (d = first_dest(); d; d = next_dest(d))
! {
if (d->d_state != ST_ERROR)
continue;
! if (++count == 1)
{
! error(
! "delivery to the following address(es) failed on host %s:\n",
! hostname);
}
--- 698,734 ----
int
! report_errors(ac, av)
! int ac;
! char **av;
{
! DEST **dv;
! int i, count, errcount;
!
! if ((dv = dest_array(&count)) == NULL)
! return 0;
!
! errcount = 0;
! for (i = 0; i < count; ++i)
! {
! DEST *d;
! char *e;
! int len;
! d = dv[i];
!
if (d->d_state != ST_ERROR)
continue;
! if (++errcount == 1)
{
! int a;
!
! error("delivery error on host %s.\n", hostname);
! message("Delivery to %s address%s failed:\n",
! ac ? "these" : "this",
! ac ? "es" : "");
! for (a = 0; a < ac; ++a)
! message("\t%s\n", av[a]);
! message("Reason(s) for failure:\n");
}
***************
*** 727,833 ****
message("\t\"%s\"", d->d_name);
if (d->d_class == CL_MBOX)
! message(", mailbox \"%s\"", d->d_mailbox);
! message(": %s\n", derrmsg(d->d_error));
! }
!
! return count;
! }
!
! /*----------------------------------------------------------------------
! * Save log data in the real logfiles.
! */
!
! savelogs()
! {
! /* If logs weren't kept, forget it. */
!
! if (!log && !errlog)
! return;
!
! /* If temporary logs contain anything, append them to real logs. */
!
! if ((log && ftell(log) > 0)
! || (errlog && ftell(errlog) > 0))
! {
! if (create_lockfile(LOGLOCK) == 0)
! {
! applog(&log, LOG);
! errdone();
! applog(&errlog, ERRLOG);
! (void) remove_lockfile(LOGLOCK);
! }
! }
! }
!
! /*----------------------------------------------------------------------
! * Append a temporary log file to a real logfile.
! * We pass a FILE **, so that it can be set to NULL when closed;
! * this is important, since errlog is used by syserr().
! * Note: The logfile is ass_u_med to be locked already!
! */
!
! applog(fpp, realfile)
! FILE **fpp;
! char *realfile;
! {
! FILE *fp = fpp ? *fpp : NULL;
! int fd, realfd;
!
! /* If log data weren't kept, never mind. */
!
! if (fp == NULL)
! return;
!
! /* Flush buffered data. */
!
! (void) fflush(fp);
!
! /* If the file is empty, never mind. */
!
! if (ftell(fp) == 0)
! {
! (void) fclose(fp);
! *fpp = NULL;
! return;
! }
!
! /* Get an fd and close the stream. */
!
! if ((fd = dup(fileno(fp))) == -1)
! {
! syserr("can't dup log fd");
! (void) fclose(fp);
! *fpp = NULL;
! return;
! }
! (void) fclose(fp);
! *fpp = NULL;
!
! /*
! * Open the real logfile, creating it if necessary.
! * Note that there is no race condition since the logs are locked.
! */
!
! #ifdef O_CREAT
! realfd = open(realfile, O_WRONLY|O_CREAT, 0666);
! #else
! if ((realfd = open(realfile, O_WRONLY)) == -1)
! realfd = creat(realfile, 0666);
! #endif
! if (realfd == -1)
! syserr("can't open %s for writing", logfile);
! else
! {
! /* Append the temporary log to the real log. */
! (void) lseek(fd, 0L, 0);
! (void) lseek(realfd, 0L, 2);
! (void) copyfd(fd, realfd);
! (void) close(realfd);
}
! /* Close the temporary log. */
! (void) close(fd);
}
--- 735,752 ----
message("\t\"%s\"", d->d_name);
if (d->d_class == CL_MBOX)
! message(", mailbox \"%s\"", d->d_param);
! else if (d->d_class == CL_PROG)
! message(", program \"%s\"", d->d_param);
! e = derrmsg(d);
! len = strlen(d->d_name) + strlen(e);
! if (d->d_param)
! len += strlen(d->d_param);
! message(":%s%s\n", (len > 60) ? "\n\t\t" : " ", derrmsg(d));
}
! free((char *) dv);
! return errcount;
}
Index: mbox.c
***************
*** 1,3 ****
! /* $Header: mbox.c,v 2.3 90/02/06 11:56:42 chip Exp $
*
* Finally! Put the message in the specified mailbox(es).
--- 1,3 ----
! /* $Header: mbox.c,v 2.5 90/02/23 16:35:55 chip Exp $
*
* Finally! Put the message in the specified mailbox(es).
***************
*** 4,7 ****
--- 4,16 ----
*
* $Log: mbox.c,v $
+ * Revision 2.5 90/02/23 16:35:55 chip
+ * \Fix problems determining legality of user references.
+ *
+ * Revision 2.4 90/02/23 14:16:50 chip
+ * Support "#!" in delivery files.
+ * Support "user|program" and "user?error" from delivery files.
+ * Improve debugging and error message formatting.
+ * Rearrange code for clarity.
+ *
* Revision 2.3 90/02/06 11:56:42 chip
* Enforce MBX_MODE regardless of UMASK.
***************
*** 34,37 ****
--- 43,47 ----
*/
+ static prog_one();
static mbox_one();
static int mbox_write();
***************
*** 38,63 ****
/*----------------------------------------------------------------------
! * Deliver mail to all valid destinations.
*/
mbox_deliver()
{
DEST *d;
for (d = first_dest(); d; d = next_dest(d))
{
! switch (d->d_class)
{
! case CL_USER:
! case CL_MBOX:
! if (d->d_state == ST_WORKING)
! mbox_one(d);
! break;
}
}
}
/*----------------------------------------------------------------------
! * Deliver mail to one destination.
*/
--- 48,160 ----
/*----------------------------------------------------------------------
! * Deliver mail to all valid program (pipe) destinations.
! * Return count of programs to which we tried to write.
! */
!
! int
! prog_deliver()
! {
! DEST *d;
! int progcount;
!
! progcount = 0;
! for (d = first_dest(); d; d = next_dest(d))
! {
! if (d->d_state != ST_WORKING)
! continue;
!
! if (d->d_class == CL_PROG)
! {
! prog_one(d);
! ++progcount;
! }
! }
!
! return progcount;
! }
!
! /*----------------------------------------------------------------------
! * Deliver mail to one program.
! */
!
! static
! prog_one(d)
! DEST *d;
! {
! CONTEXT *ct;
! char *av[4];
! int fd;
!
! if (printaddrs)
! (void) printf("%s|%s\n", d->d_name, d->d_param);
!
! if (dryrun)
! {
! d->d_state = ST_DONE;
! return;
! }
!
! if ((ct = name_context(d->d_name)) == NULL)
! {
! dest_err(d, E_NSUSER);
! return;
! }
!
! if (! ok_context(eff_uid, real_uid, real_gid, ct))
! {
! dest_err(d, E_CTPERM);
! return;
! }
!
! av[0] = SHELL;
! av[1] = "-c";
! av[2] = d->d_param;
! av[3] = NULL;
! if ((fd = ct_openv(ct, av[0], av, O_WRONLY)) == -1)
! {
! dest_err(d, E_PIPE);
! return;
! }
!
! (void) lseek(tfd[T_HDR], 0L, 0);
! (void) lseek(tfd[T_BODY], 0L, 0);
! if (copyfd(tfd[T_HDR], fd) < 0 || copyfd(tfd[T_BODY], fd) < 0)
! dest_err(d, E_PIPE);
!
! if (ct_close(fd))
! dest_err(d, E_PROG);
! else
! d->d_state = ST_DONE;
! }
!
! /*----------------------------------------------------------------------
! * Deliver mail to all valid mailbox destinations.
! * Return count of mailboxes to which we tried to write.
*/
+ int
mbox_deliver()
{
DEST *d;
+ int mboxcount;
+ mboxcount = 0;
for (d = first_dest(); d; d = next_dest(d))
{
! if (d->d_state != ST_WORKING)
! continue;
!
! if (d->d_class == CL_USER || d->d_class == CL_MBOX)
{
! mbox_one(d);
! ++mboxcount;
}
}
+
+ return mboxcount;
}
/*----------------------------------------------------------------------
! * Deliver mail to one mailbox destination.
*/
***************
*** 73,77 ****
(void) printf("%s", d->d_name);
if (d->d_class == CL_MBOX)
! (void) printf(":%s", d->d_mailbox);
(void) printf("\n");
}
--- 170,174 ----
(void) printf("%s", d->d_name);
if (d->d_class == CL_MBOX)
! (void) printf(":%s", d->d_param);
(void) printf("\n");
}
***************
*** 89,93 ****
}
! if (! ok_context(ct))
{
dest_err(d, E_CTPERM);
--- 186,190 ----
}
! if (! ok_context(eff_uid, real_uid, real_gid, ct))
{
dest_err(d, E_CTPERM);
***************
*** 101,105 ****
if (become(ct, !boxdelivery) < 0)
exit(1);
! if (mbox_write(d->d_mailbox, ct, FALSE) < 0)
exit(1);
exit(0);
--- 198,202 ----
if (become(ct, !boxdelivery) < 0)
exit(1);
! if (mbox_write(d->d_param, ct, FALSE) < 0)
exit(1);
exit(0);
Index: procs.c
***************
*** 1,3 ****
! /* $Header: procs.c,v 2.4 89/11/01 12:19:05 network Exp $
*
* Process management and misc support.
--- 1,3 ----
! /* $Header: procs.c,v 2.6 90/02/23 16:35:59 chip Exp $
*
* Process management and misc support.
***************
*** 4,7 ****
--- 4,16 ----
*
* $Log: procs.c,v $
+ * Revision 2.6 90/02/23 16:35:59 chip
+ * \Fix problems determining legality of user references.
+ *
+ * Revision 2.5 90/02/23 14:16:51 chip
+ * Support "#!" in delivery files.
+ * Support "user|program" and "user?error" from delivery files.
+ * Improve debugging and error message formatting.
+ * Rearrange code for clarity.
+ *
* Revision 2.4 89/11/01 12:19:05 network
* Delintify.
***************
*** 46,50 ****
FILE *
! ct_popenv(ct, prog, av, mode)
CONTEXT *ct;
char *prog;
--- 55,59 ----
FILE *
! ct_fopenv(ct, prog, av, mode)
CONTEXT *ct;
char *prog;
***************
*** 52,55 ****
--- 61,116 ----
char *mode;
{
+ FILE *fp;
+ int fd, m;
+
+ if (mode && mode[0] == 'r' && mode[1] == 0)
+ m = O_RDONLY;
+ else if (mode && mode[0] == 'w' && mode[1] == 0)
+ m = O_WRONLY;
+ else
+ return NULL;
+
+ if ((fd = ct_openv(ct, prog, av, m)) == -1)
+ return NULL;
+
+ if ((fp = fdopen(fd, mode)) == NULL)
+ (void) ct_close(fd);
+
+ return fp;
+ }
+
+ /*----------------------------------------------------------------------
+ * Close the stream opened by ct_fopen().
+ */
+
+ ct_fclose(fp)
+ FILE *fp;
+ {
+ int fd;
+
+ if (fp)
+ {
+ fd = dup(fileno(fp));
+ (void) fclose(fp);
+ }
+ else
+ fd = -1;
+
+ return ct_close(fd);
+ }
+
+ /*----------------------------------------------------------------------
+ * Like popen(), but execute the child in a specific context.
+ * Also, the argument list is already a vector.
+ * And return a file descriptor instead of a FILE *.
+ */
+
+ int
+ ct_openv(ct, prog, av, mode)
+ CONTEXT *ct;
+ char *prog;
+ char **av;
+ int mode;
+ {
char ch;
int child, parent;
***************
*** 56,68 ****
int pfd[2];
! if (!ct || !prog || !av || !mode)
return NULL;
! if (mode[0] == 'r' && mode[1] == 0)
child = 1, parent = 0;
! else if (mode[0] == 'w' && mode[1] == 0)
child = 0, parent = 1;
else
! return NULL;
/* We can't have more than one child at a time. */
--- 117,132 ----
int pfd[2];
! if (!ct || !prog || !av)
return NULL;
! if (mode == O_RDONLY)
child = 1, parent = 0;
! else if (mode == O_WRONLY)
child = 0, parent = 1;
else
! {
! error("in ct_open: invalid mode");
! return -1;
! }
/* We can't have more than one child at a time. */
***************
*** 70,75 ****
if (child_pid >= 0)
{
! error("in ct_popen: a process is already open\n");
! return NULL;
}
--- 134,139 ----
if (child_pid >= 0)
{
! error("in ct_open: a process is already open");
! return -1;
}
***************
*** 76,84 ****
/* Make a stab at predicting uid-related failure. */
! if (! ok_context(ct))
{
! error("in ct_popen: no permissions to become %s\n",
! ct->ct_name);
! return NULL;
}
--- 140,147 ----
/* Make a stab at predicting uid-related failure. */
! if (! ok_context(eff_uid, real_uid, real_gid, ct))
{
! error("in ct_open: no permissions to become %s", ct->ct_name);
! return -1;
}
***************
*** 88,92 ****
{
syserr("can't create a pipe");
! return NULL;
}
--- 151,155 ----
{
syserr("can't create a pipe");
! return -1;
}
***************
*** 97,101 ****
int a;
! message("Spawning");
for (a = 0; av[a]; ++a)
message(" %s", av[a]);
--- 160,164 ----
int a;
! message("%s: spawning", progname);
for (a = 0; av[a]; ++a)
message(" %s", av[a]);
***************
*** 161,180 ****
(void) close(pfd[1]);
(void) await_child();
! return NULL;
}
(void) close(pfd[child]);
! return fdopen(pfd[parent], mode);
}
/*----------------------------------------------------------------------
! * Close the stream opened by ct_popen().
*/
! ct_pclose(fp)
! FILE *fp;
{
! if (fp)
! (void) fclose(fp);
return await_child();
}
--- 224,243 ----
(void) close(pfd[1]);
(void) await_child();
! return -1;
}
(void) close(pfd[child]);
! return pfd[parent];
}
/*----------------------------------------------------------------------
! * Close the file descriptor opened by ct_open().
*/
! ct_close(fd)
! int fd;
{
! if (fd != -1)
! (void) close(fd);
return await_child();
}
***************
*** 298,305 ****
if (st & 0xFF)
{
! error("child process died%s due to signal %d.\n",
((st & 0x80) ? " and dumped core" : ""),
(st & 0x7F));
-
return -1;
}
--- 361,367 ----
if (st & 0xFF)
{
! error("child process died%s due to signal %d.",
((st & 0x80) ? " and dumped core" : ""),
(st & 0x7F));
return -1;
}
***************
*** 307,312 ****
if (verbose)
{
! message("child process exited with status %d.\n",
! (st >> 8) & 0xFF);
}
--- 369,374 ----
if (verbose)
{
! message("%s: child process exited with status %d.\n",
! progname, (st >> 8) & 0xFF);
}
Index: subs.c
***************
*** 1,3 ****
! /* $Header: subs.c,v 2.4 90/02/06 11:56:46 chip Exp $
*
* Miscellaneous subroutines.
--- 1,3 ----
! /* $Header: subs.c,v 2.6 90/03/06 12:21:17 chip Exp $
*
* Miscellaneous subroutines.
***************
*** 4,7 ****
--- 4,18 ----
*
* $Log: subs.c,v $
+ * Revision 2.6 90/03/06 12:21:17 chip
+ * Move logging into log.c and address parsing into addr.c.
+ * New: error delivery file for messages that fail.
+ * Major rearrangement of delivery file code.
+ *
+ * Revision 2.5 90/02/23 14:16:56 chip
+ * Support "#!" in delivery files.
+ * Support "user|program" and "user?error" from delivery files.
+ * Improve debugging and error message formatting.
+ * Rearrange code for clarity.
+ *
* Revision 2.4 90/02/06 11:56:46 chip
* Enforce MBX_MODE regardless of UMASK.
***************
*** 286,307 ****
return path;
- }
-
- /*----------------------------------------------------------------------
- * Check an address for validity.
- */
-
- valid_address(addr)
- char *addr;
- {
- char *p;
- static char sanitize[] = SANITIZE;
-
- for (p = addr; *p; ++p)
- {
- if (strchr(sanitize, *p))
- return FALSE;
- }
-
- return TRUE;
}
--- 297,299 ----
Index: sysdep.c
***************
*** 1,3 ****
! /* $Header: sysdep.c,v 2.6 90/02/06 11:56:43 chip Exp $
*
* Routines which are (or might well be) system-dependant.
--- 1,3 ----
! /* $Header: sysdep.c,v 2.8 90/03/06 12:21:16 chip Exp $
*
* Routines which are (or might well be) system-dependant.
***************
*** 6,9 ****
--- 6,20 ----
*
* $Log: sysdep.c,v $
+ * Revision 2.8 90/03/06 12:21:16 chip
+ * Move logging into log.c and address parsing into addr.c.
+ * New: error delivery file for messages that fail.
+ * Major rearrangement of delivery file code.
+ *
+ * Revision 2.7 90/02/23 14:16:52 chip
+ * Support "#!" in delivery files.
+ * Support "user|program" and "user?error" from delivery files.
+ * Improve debugging and error message formatting.
+ * Rearrange code for clarity.
+ *
* Revision 2.6 90/02/06 11:56:43 chip
* Enforce MBX_MODE regardless of UMASK.
***************
*** 33,37 ****
#include "deliver.h"
#include <errno.h>
- #include <time.h>
#ifdef HAS_STDARG
#include <stdarg.h>
--- 44,47 ----
***************
*** 178,368 ****
else
(void) fprintf(fp, ": unknown system error %d\n", e);
- }
-
- /*----------------------------------------------------------------------
- * Record any interesting information in the error log file.
- */
-
- errinfo()
- {
- if (!errlog)
- return;
-
- /* Log undelivered mail. */
-
- errundel();
-
- /* If any errors have been logged, record the failed header. */
-
- if (ftell(errlog) > 0)
- errheader();
- }
-
- /*----------------------------------------------------------------------
- * Log undelivered mail.
- *
- * Note that this algorithm assumes that delivery to the MBX_UNDEL mailbox
- * is always worth reporting.
- */
-
- errundel()
- {
- DEST *d;
-
- if (!errlog)
- return;
-
- for (d = first_dest(); d; d = next_dest(d))
- {
- if (d->d_state == ST_DONE
- && d->d_class == CL_MBOX
- && strcmp(d->d_mailbox, MBX_UNDEL) == 0)
- {
- CONTEXT *ct;
- char *home;
-
- if ((ct = name_context(d->d_name)) != NULL)
- home = ct->ct_home;
- else
- home = "~"; /* should never happen */
-
- errstart();
- (void) fprintf(errlog,
- "Undelivered mail for %s put in %s/%s\n",
- d->d_name, home, MBX_UNDEL);
- }
- }
- }
-
- /*----------------------------------------------------------------------
- * Log the message header.
- */
-
- errheader()
- {
- FILE *hfp;
- int hfd;
-
- if (!errlog)
- return;
-
- /* Copy the failed message's header. */
-
- hfd = dup(tfd[T_HDR]);
- hfp = (hfd < 0) ? NULL : fdopen(hfd, "r");
- if (hfp == NULL)
- {
- (void) fprintf(errlog, "%s: can't open header file %s\n",
- progname, tfile[T_HDR]);
- }
- else
- {
- int c, oc;
-
- (void) fprintf(errlog, "+ Header:\n");
-
- (void) fseek(hfp, 0L, 0);
- oc = '\n';
- while ((c = getc(hfp)) != EOF)
- {
- if (oc != '\n' || c != '\n')
- {
- if (oc == '\n')
- (void) fputs("| ", errlog);
- (void) putc(c, errlog);
- }
- oc = c;
- }
-
- (void) fclose(hfp);
- }
- }
-
- /*----------------------------------------------------------------------
- * Record a time stamp in the error log file.
- */
-
- errstart()
- {
- /* If we've already written a time stamp, don't do it again. */
-
- if (!errlog || ftell(errlog) > 0)
- return;
-
- /* Write a time stamp and various useful info. */
-
- logstart(errlog);
- (void) fprintf(errlog, "process %d", getpid());
- if (rec_parent > 0)
- (void) fprintf(errlog, ", parent %d", rec_parent);
- (void) fprintf(errlog, ": %s %s\n", progname, version);
- }
-
- /*----------------------------------------------------------------------
- * Record the end of this process's error log entry.
- */
-
- errdone()
- {
- /* If we never wrote to the error log file, do nothing. */
-
- if (!errlog || ftell(errlog) == 0)
- return;
-
- /* Write a simple closing line for the error log entry. */
-
- (void) fprintf(errlog, "process %d", getpid());
- if (rec_parent > 0)
- (void) fprintf(errlog, ", parent %d", rec_parent);
- (void) fprintf(errlog, ": exit\n");
-
- logdone(errlog);
- }
-
- /*----------------------------------------------------------------------
- * Start a log entry.
- * Various useful info goes here -- especially a timestamp.
- */
-
- logstart(fp)
- FILE *fp;
- {
- struct tm *lt;
- time_t now;
- static char month[12][4] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
-
- (void) time(&now);
- lt = localtime(&now);
-
- (void) fputc('\n', fp);
- if (rec_level)
- (void) fprintf(fp, "[%d]", rec_level);
- else
- (void) fputs("---", fp);
- (void) fputs("------------------------ ", fp);
- (void) fprintf(fp, "%d %s %d, %02d:%02d:%02d %s\n",
- lt->tm_mday, month[lt->tm_mon], lt->tm_year + 1900,
- lt->tm_hour, lt->tm_min, lt->tm_sec,
- #ifdef USG
- tzname[lt->tm_isdst ? 1 : 0]
- #else
- lt->tm_zone
- #endif
- );
- }
-
- /*----------------------------------------------------------------------
- * Write a concluding marker to the given logfile.
- * This marker separates instances of Deliver at recursion level zero.
- */
-
- logdone(fp)
- FILE *fp;
- {
- if (rec_level == 0)
- (void) fputs("===========================\n\n", fp);
}
--- 188,191 ----
Index: uucp.c
***************
*** 1,3 ****
! /* $Header: uucp.c,v 2.3 89/12/19 16:26:41 network Exp $
*
* Handle mail destined for other hosts via UUCP.
--- 1,3 ----
! /* $Header: uucp.c,v 2.4 90/02/23 14:16:54 chip Exp $
*
* Handle mail destined for other hosts via UUCP.
***************
*** 6,9 ****
--- 6,15 ----
*
* $Log: uucp.c,v $
+ * Revision 2.4 90/02/23 14:16:54 chip
+ * Support "#!" in delivery files.
+ * Support "user|program" and "user?error" from delivery files.
+ * Improve debugging and error message formatting.
+ * Rearrange code for clarity.
+ *
* Revision 2.3 89/12/19 16:26:41 network
* Execute UUCP in real, not effective, context.
***************
*** 31,37 ****
--- 37,45 ----
/*----------------------------------------------------------------------
* Send mail to UUCP addresses (if any).
+ * Return count of UUCP addresses for which delivery was attempted.
* This is a simple implementation: invoke uux once per address.
*/
+ int
uucp_deliver()
{
***************
*** 38,41 ****
--- 46,50 ----
DEST *d;
char *uux;
+ int uucpcount;
static char uux1[] = "/bin/uux";
static char uux2[] = "/usr/bin/uux";
***************
*** 48,54 ****
{
error("can't find uux!?\n");
! return;
}
for (d = first_dest(); d; d = next_dest(d))
{
--- 57,64 ----
{
error("can't find uux!?\n");
! return -1;
}
+ uucpcount = 0;
for (d = first_dest(); d; d = next_dest(d))
{
***************
*** 62,65 ****
--- 72,77 ----
continue;
+ ++uucpcount;
+
if (printaddrs)
(void) printf("%s\n", d->d_name);
***************
*** 82,92 ****
av[3] = who;
av[4] = NULL;
! if ((uux_fp = ct_popenv(real_ct, uux, av, "w")) == NULL)
continue;
if (uucp_copy(uux_fp) < 0)
! dest_err(d, E_UUX);
! if (ct_pclose(uux_fp))
{
/* "No such host" overrides piping problems. */
--- 94,104 ----
av[3] = who;
av[4] = NULL;
! if ((uux_fp = ct_fopenv(real_ct, uux, av, "w")) == NULL)
continue;
if (uucp_copy(uux_fp) < 0)
! dest_err(d, E_PIPE);
! if (ct_fclose(uux_fp))
{
/* "No such host" overrides piping problems. */
***************
*** 96,99 ****
--- 108,113 ----
d->d_state = ST_DONE;
}
+
+ return uucpcount;
}
--
Chip Salzenberg at ComDev/TCT <chip%tct at ateng.com>, <uunet!ateng!tct!chip>
"The Usenet, in a very real sense, does not exist."
More information about the Comp.sources.bugs
mailing list