chip@ateng.ateng.com (Chip Salzenberg) (02/11/89)
This is an offical patch for deliver 1.00. Please apply it. Patch number: 7 Date: 10 Feb 1989 Priority: REQUIRED for V7, LOW otherwise Changes: Deliver was originally written without concern for portability to Unix Classic (V7). However, a particularly dedicated V7 user, Pete Alleman <digitran!pja>, ported deliver to V7. Loathe to throw away the results of his labor, I have taken his ideas and incorporated them into the offical deliver sources. Thanks, Pete. BTW, Berkeley sites should be able to compile without BSD defined, since V7 is a subset of BSD. Index: patchlevel.h Prereq: 6 *************** *** 1 **** ! #define PATCHLEVEL 6 --- 1 ---- ! #define PATCHLEVEL 7 Index: config.h *************** *** 1,8 **** ! /* $Header: config.h,v 1.6 88/11/26 13:19:37 network Exp $ * * Deliver configuration. * * $Log: config.h,v $ * Revision 1.6 88/11/26 13:19:37 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. --- 1,14 ---- ! /* $Header: config.h,v 1.8 89/02/10 18:08:24 network Exp $ * * Deliver configuration. * * $Log: config.h,v $ + * Revision 1.8 89/02/10 18:08:24 network + * Fix location of mailboxes. + * + * Revision 1.7 89/02/10 15:45:51 network + * V7 support. + * * Revision 1.6 88/11/26 13:19:37 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. *************** *** 33,38 **** --- 39,54 ---- */ /*---------------------------------------------------------------------- + * SCO Xenix System V compilers define M_SYSV, which implies USG. + */ + + #ifdef M_SYSV + #ifndef USG + #define USG + #endif + #endif + + /*---------------------------------------------------------------------- * Trusted users. * Deliver permits "trusted" users to specify delivery filenames * without renouncing setuid privileges. Essentially, these users *************** *** 97,106 **** --- 113,124 ---- /*---------------------------------------------------------------------- * How to get the host name. + * Define one. * * HOSTFILE file containing name (Xenix) * UNAME uname() (System V) * GETHOSTNAME gethostname() (BSD) + * HOSTNAME host name string (V7) */ #ifdef M_XENIX *************** *** 111,125 **** #else #ifdef BSD #define GETHOSTNAME #endif #endif #endif /*---------------------------------------------------------------------- * Are vprintf() and friends available? */ ! #ifndef BSD #define HAS_VPRINTF #endif --- 129,161 ---- #else #ifdef BSD #define GETHOSTNAME + #else + #define HOSTNAME "cleese" #endif #endif #endif /*---------------------------------------------------------------------- + * Is <varargs.h> or <stdarg.h> available? + */ + + #ifdef __STDC__ + #define HAS_STDARG + #else + #ifdef USG + #define HAS_VARARGS + #else + #ifdef BSD + #define HAS_VARARGS + #endif + #endif + #endif + + /*---------------------------------------------------------------------- * Are vprintf() and friends available? */ ! #ifdef USG #define HAS_VPRINTF #endif *************** *** 127,133 **** * Is putenv() available? */ ! #ifndef BSD #define HAS_PUTENV #endif --- 163,169 ---- * Is putenv() available? */ ! #ifdef USG #define HAS_PUTENV #endif *************** *** 135,141 **** * Is getopt() available? */ ! #ifndef BSD #define HAS_GETOPT #endif --- 171,177 ---- * Is getopt() available? */ ! #ifdef USG #define HAS_GETOPT #endif *************** *** 163,191 **** /*---------------------------------------------------------------------- * Standard mailbox location. * ! * Define either MAILBOX_NAME or MAILBOX_DIR. ! * If MAILBOX_NAME is defined, then the default mailbox is a file with * that name in the user's home directory. ! * If MAILBOX_DIR is defined, then the default mailbox is a file in that * directory with the same name as the user. * ! * Define MAILBOX_GROUP if all mailboxes must be owned by a specific group. ! * (System V requires this feature.) If MAILBOX_GROUP is not defined, * mailboxes will have their groups set to the recipients' default group. * ! * Define MAILBOX_MODE to the file access modes for new mailboxes. * (System V requires group write permissions, i.e. 0020.) */ ! #ifdef USG ! /* #define MAILBOX_NAME "mbox" */ ! #define MAILBOX_DIR "/usr/mail" ! #define MAILBOX_MODE 0660 ! #define MAILBOX_GROUP "mail" #else ! /* #define MAILBOX_NAME "mbox" */ ! #define MAILBOX_DIR "/usr/spool/mail" ! #define MAILBOX_MODE 0600 #endif /*---------------------------------------------------------------------- --- 199,227 ---- /*---------------------------------------------------------------------- * Standard mailbox location. * ! * Define either MBX_NAME or MBOX_DIR. ! * If MBX_NAME is defined, then the default mailbox is a file with * that name in the user's home directory. ! * If MBX_DIR is defined, then the default mailbox is a file in that * directory with the same name as the user. * ! * Define MBX_GROUP if all mailboxes must be owned by a specific group. ! * (System V requires this feature.) If MBX_GROUP is not defined, * mailboxes will have their groups set to the recipients' default group. * ! * Define MBX_MODE to the file access modes for new mailboxes. * (System V requires group write permissions, i.e. 0020.) */ ! #if defined(USG) && !defined(M_XENIX) ! /* #define MBX_NAME "mbox" */ ! #define MBX_DIR "/usr/mail" ! #define MBX_MODE 0660 ! #define MBX_GROUP "mail" #else ! /* #define MBX_NAME "mbox" */ ! #define MBX_DIR "/usr/spool/mail" ! #define MBX_MODE 0600 #endif /*---------------------------------------------------------------------- Index: context.c *************** *** 1,4 **** ! /* $Header: context.c,v 1.3 88/09/14 19:41:40 network Exp $ * * User context manager. * This module exists for efficiency reasons; I could just call getpwnam() --- 1,4 ---- ! /* $Header: context.c,v 1.4 89/02/10 15:46:09 network Exp $ * * User context manager. * This module exists for efficiency reasons; I could just call getpwnam() *************** *** 5,10 **** --- 5,13 ---- * every time I need context info. * * $Log: context.c,v $ + * Revision 1.4 89/02/10 15:46:09 network + * V7 support. + * * Revision 1.3 88/09/14 19:41:40 network * Portability to System V and BSD. * General fixup. *************** *** 49,57 **** struct passwd *pw; CONTEXT *ct; ! for (ct = ctlist; ct; ct = ct->next) { ! if (strcmp(ct->name, name) == 0) return ct; } --- 52,60 ---- struct passwd *pw; CONTEXT *ct; ! for (ct = ctlist; ct; ct = ct->ct_next) { ! if (strcmp(ct->ct_name, name) == 0) return ct; } *************** *** 72,80 **** struct passwd *pw; CONTEXT *ct; ! for (ct = ctlist; ct; ct = ct->next) { ! if (ct->uid == uid) return ct; } --- 75,83 ---- struct passwd *pw; CONTEXT *ct; ! for (ct = ctlist; ct; ct = ct->ct_next) { ! if (ct->ct_uid == uid) return ct; } *************** *** 96,107 **** CONTEXT *ct; ct = (CONTEXT *) zalloc(sizeof(CONTEXT)); ! ct->uid = pw->pw_uid; ! ct->gid = pw->pw_gid; ! ct->name = copystr(pw->pw_name); ! ct->home = copystr(pw->pw_dir); ! ct->next = ctlist; ctlist = ct; return ct; --- 99,110 ---- CONTEXT *ct; ct = (CONTEXT *) zalloc(sizeof(CONTEXT)); ! ct->ct_uid = pw->pw_uid; ! ct->ct_gid = pw->pw_gid; ! ct->ct_name = copystr(pw->pw_name); ! ct->ct_home = copystr(pw->pw_dir); ! ct->ct_next = ctlist; ctlist = ct; return ct; *************** *** 119,125 **** return FALSE; if (eff_uid == 0 ! || ((real_uid == ct->uid) && (real_gid == ct->gid))) return TRUE; else return FALSE; --- 122,128 ---- return FALSE; if (eff_uid == 0 ! || ((real_uid == ct->ct_uid) && (real_gid == ct->ct_gid))) return TRUE; else return FALSE; *************** *** 129,135 **** * Look up a group ID by name. */ ! #ifdef MAILBOX_GROUP int group_id(name) --- 132,138 ---- * Look up a group ID by name. */ ! #ifdef MBX_GROUP int group_id(name) *************** *** 143,146 **** return grp->gr_gid; } ! #endif /* MAILBOX_GROUP */ --- 146,149 ---- return grp->gr_gid; } ! #endif /* MBX_GROUP */ Index: context.h *************** *** 1,8 **** ! /* $Header: context.h,v 1.1 88/06/06 09:37:40 chip Exp $ * * User context, as found in /etc/passwd. * * $Log: context.h,v $ * Revision 1.1 88/06/06 09:37:40 chip * Initial revision * --- 1,11 ---- ! /* $Header: context.h,v 1.2 89/02/10 15:46:13 network Exp $ * * User context, as found in /etc/passwd. * * $Log: context.h,v $ + * Revision 1.2 89/02/10 15:46:13 network + * V7 support. + * * Revision 1.1 88/06/06 09:37:40 chip * Initial revision * *************** *** 14,22 **** #define CONTEXT struct context CONTEXT { ! CONTEXT *next; ! int uid; ! int gid; ! char *name; ! char *home; }; --- 17,25 ---- #define CONTEXT struct context CONTEXT { ! CONTEXT *ct_next; ! int ct_uid; ! int ct_gid; ! char *ct_name; ! char *ct_home; }; Index: copymsg.c *************** *** 1,9 **** ! /* $Header: copymsg.c,v 1.3 88/11/28 18:07:46 network Exp $ * * Take the message from standard input and write it to two temp files, * one for the header (including the empty line) and one for the body. * * $Log: copymsg.c,v $ * Revision 1.3 88/11/28 18:07:46 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. --- 1,12 ---- ! /* $Header: copymsg.c,v 1.4 89/02/10 15:46:17 network Exp $ * * Take the message from standard input and write it to two temp files, * one for the header (including the empty line) and one for the body. * * $Log: copymsg.c,v $ + * Revision 1.4 89/02/10 15:46:17 network + * V7 support. + * * Revision 1.3 88/11/28 18:07:46 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. *************** *** 145,151 **** /* else use our real ID */ else ! sender = real_ct->name; /* debugging message */ --- 148,154 ---- /* else use our real ID */ else ! sender = real_ct->ct_name; /* debugging message */ *************** *** 398,408 **** { int fd; ! if ((fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0)) == -1) { syserr("can't create %s", name); return -1; } return fd; } --- 401,425 ---- { int fd; ! #ifdef O_CREAT ! fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0); ! #else ! fd = creat(name, 0); ! #endif ! if (fd == -1) { syserr("can't create %s", name); return -1; } + + #ifndef O_CREAT + (void) close(fd); + if ((fd = open(name, 2)) == -1) + { + syserr("can't re-open %s", name); + return -1; + } + #endif return fd; } Index: debug.c *************** *** 1,8 **** ! /* $Header: debug.c,v 1.2 88/11/26 13:20:38 network Exp $ * * Debugging output. * * $Log: debug.c,v $ * Revision 1.2 88/11/26 13:20:38 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. --- 1,11 ---- ! /* $Header: debug.c,v 1.3 89/02/10 15:46:24 network Exp $ * * Debugging output. * * $Log: debug.c,v $ + * Revision 1.3 89/02/10 15:46:24 network + * V7 support. + * * Revision 1.2 88/11/26 13:20:38 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. *************** *** 28,42 **** message("Destinations %s:\n", when); for (d = first_dest(); d; d = next_dest(d)) { ! message("\t%s", d->name); ! switch (d->class) { case CL_USER: /* it's understood */ break; case CL_MBOX: ! message(", mailbox='%s'", d->mailbox); break; case CL_UUCP: message(" (UUCP)"); --- 31,45 ---- message("Destinations %s:\n", when); for (d = first_dest(); d; d = next_dest(d)) { ! message("\t%s", d->d_name); ! switch (d->d_class) { case CL_USER: /* it's understood */ break; case CL_MBOX: ! message(", mailbox='%s'", d->d_mailbox); break; case CL_UUCP: message(" (UUCP)"); *************** *** 43,49 **** break; } message("; "); ! switch (d->state) { case ST_WORKING: message("Working"); --- 46,52 ---- break; } message("; "); ! switch (d->d_state) { case ST_WORKING: message("Working"); *************** *** 55,61 **** message("Done"); break; case ST_ERROR: ! message("Error (%s)", d->error); break; } message("\n"); --- 58,64 ---- message("Done"); break; case ST_ERROR: ! message("Error (%s)", derrmsg(d->d_error)); break; } message("\n"); Index: deliver.h *************** *** 1,8 **** ! /* $Header: deliver.h,v 1.6 88/11/28 18:07:53 network Exp $ * * General pull-it-together include file. * * $Log: deliver.h,v $ * Revision 1.6 88/11/28 18:07:53 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. --- 1,11 ---- ! /* $Header: deliver.h,v 1.7 89/02/10 15:46:27 network Exp $ * * General pull-it-together include file. * * $Log: deliver.h,v $ + * Revision 1.7 89/02/10 15:46:27 network + * V7 support. + * * Revision 1.6 88/11/28 18:07:53 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. *************** *** 28,34 **** */ #include <stdio.h> - #include <fcntl.h> #include <ctype.h> #include "config.h" --- 31,36 ---- *************** *** 87,92 **** --- 89,95 ---- char *basename(); char *gethost(); char *copystr(); + char *derrmsg(); char *zalloc(); char *srealloc(); Index: dest.c *************** *** 1,8 **** ! /* $Header: dest.c,v 1.3 88/11/26 13:20:42 network Exp $ * * Operations on the list of mail destinations. * * $Log: dest.c,v $ * Revision 1.3 88/11/26 13:20:42 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. --- 1,11 ---- ! /* $Header: dest.c,v 1.4 89/02/10 15:46:31 network Exp $ * * Operations on the list of mail destinations. * * $Log: dest.c,v $ + * Revision 1.4 89/02/10 15:46:31 network + * V7 support. + * * Revision 1.3 88/11/26 13:20:42 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. *************** *** 46,57 **** else class = CL_USER; ! for (d = HEADPTR->next; d != HEADPTR; d = d->next) { ! if (d->class != class) continue; ! if (strcmp(d->name, name) != 0) continue; /* --- 49,60 ---- else class = CL_USER; ! for (d = HEADPTR->d_next; d != HEADPTR; d = d->d_next) { ! if (d->d_class != class) continue; ! if (strcmp(d->d_name, name) != 0) continue; /* *************** *** 60,66 **** */ if (class == CL_MBOX ! && strcmp(d->mailbox, mailbox) != 0) continue; /* --- 63,69 ---- */ if (class == CL_MBOX ! && strcmp(d->d_mailbox, mailbox) != 0) continue; /* *************** *** 75,85 **** */ d = (DEST *) zalloc(sizeof(DEST)); ! d->class = class; ! d->state = ST_WORKING; ! d->name = copystr(name); if (class == CL_MBOX) ! d->mailbox = copystr(mailbox); /* * Check address for validity. --- 78,88 ---- */ d = (DEST *) zalloc(sizeof(DEST)); ! d->d_class = class; ! d->d_state = ST_WORKING; ! d->d_name = copystr(name); if (class == CL_MBOX) ! d->d_mailbox = copystr(mailbox); /* * Check address for validity. *************** *** 86,101 **** */ if (!valid_address(name)) ! { ! d->state = ST_ERROR; ! d->error = "Invalid address string"; ! } ! else if (class != CL_UUCP ! && name_context(name) == NULL) ! { ! d->state = ST_ERROR; ! d->error = "No such user"; ! } /* * Put new address at the end of of the chain. --- 89,97 ---- */ if (!valid_address(name)) ! dest_err(d, E_IVADDR); ! else if (class != CL_UUCP && name_context(name) == NULL) ! dest_err(d, E_NSUSER); /* * Put new address at the end of of the chain. *************** *** 102,111 **** * (This is important! Other code depends on it.) */ ! d->prev = HEADPTR->prev; ! d->next = HEADPTR; ! d->prev->next = d; ! d->next->prev = d; return d; } --- 98,107 ---- * (This is important! Other code depends on it.) */ ! d->d_prev = HEADPTR->d_prev; ! d->d_next = HEADPTR; ! d->d_prev->d_next = d; ! d->d_next->d_prev = d; return d; } *************** *** 117,124 **** DEST * first_dest() { ! if (HEADPTR->next != HEADPTR) ! return HEADPTR->next; return NULL; } --- 113,120 ---- DEST * first_dest() { ! if (HEADPTR->d_next != HEADPTR) ! return HEADPTR->d_next; return NULL; } *************** *** 131,138 **** next_dest(d) DEST *d; { ! if (d && (d = d->next) != HEADPTR) return d; return NULL; } --- 127,166 ---- next_dest(d) DEST *d; { ! if (d && (d = d->d_next) != HEADPTR) return d; return NULL; + } + + /*---------------------------------------------------------------------- + * Return an error message given a DERROR. + */ + + char * + derrmsg(e) + DERROR e; + { + static char unknown_buf[40]; + + switch (e) + { + case E_IVADDR: + return "Invalid address string"; + case E_NSUSER: + return "No such user"; + case E_NSHOST: + return "No such host (UUCP addresses)"; + case E_CTPERM: + return "No permissions for that context"; + case E_CTLOST: + return "Context lost (should never happen)"; + case E_MBOX: + return "Can't write to mailbox"; + case E_UUX: + return "Can't pipe to uux"; + } + + (void) sprintf(unknown_buf, "Unknown error %d", e); + return unknown_buf; } Index: dest.h *************** *** 1,8 **** ! /* $Header: dest.h,v 1.1 88/06/06 09:37:48 chip Exp $ * * Description of a mail destination and its state. * * $Log: dest.h,v $ * Revision 1.1 88/06/06 09:37:48 chip * Initial revision * --- 1,11 ---- ! /* $Header: dest.h,v 1.2 89/02/10 15:46:38 network Exp $ * * Description of a mail destination and its state. * * $Log: dest.h,v $ + * Revision 1.2 89/02/10 15:46:38 network + * V7 support. + * * Revision 1.1 88/06/06 09:37:48 chip * Initial revision * *************** *** 30,47 **** } DSTATE; /*---------------------------------------------------------------------- * Structure describing a mail destination. */ #define DEST struct dest DEST { ! DEST *next; /* next destination in the chain */ ! DEST *prev; /* previous destination in the chain */ ! DCLASS class; /* destination class */ ! DSTATE state; /* destination state */ ! int dfdone; /* boolean -- delivery file was run */ ! char *name; /* context for delivery */ ! char *mailbox; /* mailbox name or NULL for default */ ! char *error; /* error message (if state is ERROR) */ }; --- 33,69 ---- } DSTATE; /*---------------------------------------------------------------------- + * Types of destination errors. + */ + + typedef enum { + E_IVADDR, /* invalid address string */ + E_NSUSER, /* no such user */ + E_NSHOST, /* no such host (UUCP addresses) */ + E_CTPERM, /* no permissions for that context */ + E_CTLOST, /* context lost (should never happen) */ + E_MBOX, /* can't write to mailbox */ + E_UUX /* can't pipe to uux */ + } DERROR; + + /*---------------------------------------------------------------------- * Structure describing a mail destination. */ #define DEST struct dest DEST { ! DEST *d_next; /* next destination in the chain */ ! DEST *d_prev; /* previous destination in the chain */ ! DCLASS d_class; /* destination class */ ! DSTATE d_state; /* destination state */ ! DERROR d_error; /* error message (if state is ERROR) */ ! int d_dfdone; /* boolean -- delivery file was run */ ! char *d_name; /* context for delivery */ ! char *d_mailbox; /* mailbox name or NULL for default */ }; + /*---------------------------------------------------------------------- + * Action macros. + */ + + #define dest_err(d,m) ((d)->d_state = ST_ERROR, (d)->d_error = (m)) Index: dfile.c *************** *** 1,8 **** ! /* $Header: dfile.c,v 1.6 88/11/28 18:07:57 network Exp $ * * Filter destination(s) through delivery file(s). * * $Log: dfile.c,v $ * Revision 1.6 88/11/28 18:07:57 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. --- 1,11 ---- ! /* $Header: dfile.c,v 1.7 89/02/10 15:46:42 network Exp $ * * Filter destination(s) through delivery file(s). * * $Log: dfile.c,v $ + * Revision 1.7 89/02/10 15:46:42 network + * V7 support. + * * Revision 1.6 88/11/28 18:07:57 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. *************** *** 148,159 **** nfound = 0; for (d = first_dest(); d; d = next_dest(d)) { ! if (d->class == CL_USER ! && d->state == ST_WORKING ! && !d->dfdone) { one_dfile(d); ! d->dfdone = TRUE; } } } while (nfound > 0); --- 151,162 ---- nfound = 0; for (d = first_dest(); d; d = next_dest(d)) { ! if (d->d_class == CL_USER ! && d->d_state == ST_WORKING ! && !d->d_dfdone) { one_dfile(d); ! d->d_dfdone = TRUE; } } } while (nfound > 0); *************** *** 173,182 **** char udel_path[100]; struct stat st; ! if ((ct = name_context(d->name)) == NULL) { ! d->state = ST_ERROR; ! d->error = "Missing context in user_dfile_one()"; return; } --- 176,184 ---- char udel_path[100]; struct stat st; ! if ((ct = name_context(d->d_name)) == NULL) { ! dest_err(d, E_CTLOST); return; } *************** *** 187,198 **** * Thanks to Jon Zeeff for this hint... */ ! if (stat(ct->home, &st) == -1 || (st.st_mode & S_IFMT) != S_IFDIR) { if (verbose) message("user %s: home directory %s is missing!\n", ! ct->name, ct->home); return; } --- 189,200 ---- * Thanks to Jon Zeeff for this hint... */ ! if (stat(ct->ct_home, &st) == -1 || (st.st_mode & S_IFMT) != S_IFDIR) { if (verbose) message("user %s: home directory %s is missing!\n", ! ct->ct_name, ct->ct_home); return; } *************** *** 200,206 **** { if (verbose) message("user %s: home directory is writable to the world!\n", ! ct->name); return; } --- 202,208 ---- { if (verbose) message("user %s: home directory is writable to the world!\n", ! ct->ct_name); return; } *************** *** 208,218 **** * If there is no delivery file to execute, just return. */ ! (void) sprintf(udel_path, "%s/%s", ct->home, user_deliver); if (stat(udel_path, &st) == -1) { if (verbose) ! message("%s has no delivery file\n", d->name); return; } --- 210,220 ---- * If there is no delivery file to execute, just return. */ ! (void) sprintf(udel_path, "%s/%s", ct->ct_home, user_deliver); if (stat(udel_path, &st) == -1) { if (verbose) ! message("%s has no delivery file\n", d->d_name); return; } *************** *** 222,232 **** * the delivery file names it. */ ! d->state = ST_HOLD; fav[0] = shell; fav[1] = udel_path; ! fav[2] = d->name; fav[3] = NULL; (void) do_dfile(ct, fav, d); } --- 224,234 ---- * the delivery file names it. */ ! d->d_state = ST_HOLD; fav[0] = shell; fav[1] = udel_path; ! fav[2] = d->d_name; fav[3] = NULL; (void) do_dfile(ct, fav, d); } *************** *** 250,261 **** if (! ok_context(ct)) { if (d) ! { ! d->state = ST_ERROR; ! d->error = "No permissions for that context"; ! } else ! message("No permissions to run as %s\n", ct); return -1; } --- 252,260 ---- if (! ok_context(ct)) { if (d) ! dest_err(d, E_CTPERM); else ! message("No permissions to run as %s\n", ct->ct_name); return -1; } *************** *** 273,283 **** /* Here we go! */ if (verbose) ! message("Processing delivery file as %s\n", ct->name); if ((fp = ct_popenv(ct, shell, av, "r")) == NULL) { ! error("can't execute delivery file as %s\n", ct->name); leave(1); } --- 272,282 ---- /* Here we go! */ if (verbose) ! message("Processing delivery file as %s\n", ct->ct_name); if ((fp = ct_popenv(ct, shell, av, "r")) == NULL) { ! error("can't execute delivery file as %s\n", ct->ct_name); leave(1); } *************** *** 290,297 **** DEST *nd; nd = dest(name, mailbox); ! if (nd->state == ST_HOLD) ! nd->state = ST_WORKING; /* * If the delivery file specified a mailbox, verify --- 289,296 ---- DEST *nd; nd = dest(name, mailbox); ! if (nd->d_state == ST_HOLD) ! nd->d_state = ST_WORKING; /* * If the delivery file specified a mailbox, verify *************** *** 299,318 **** * permissions for the requested context. */ ! if ((nd->state == ST_WORKING) && (mailbox != NULL)) { CONTEXT *nct; if ((nct = name_context(name)) == NULL) ! { ! nd->state = ST_ERROR; ! nd->error = "Lost context in do_dfile()"; ! } else if (! ok_context(nct)) ! { ! nd->state = ST_ERROR; ! nd->error = "No permissions for that context"; ! } } } --- 298,311 ---- * permissions for the requested context. */ ! if ((nd->d_state == ST_WORKING) && (mailbox != NULL)) { CONTEXT *nct; if ((nct = name_context(name)) == NULL) ! dest_err(nd, E_CTLOST); else if (! ok_context(nct)) ! dest_err(nd, E_CTPERM); } } *************** *** 403,412 **** syserr("can't chmod %s", tfile[t]); ++err; } ! if (chown(tfile[t], ct->uid, ct->gid) == -1) { syserr("can't chown %s to %d/%d", ! tfile[t], ct->uid, ct->gid); ++err; } } --- 396,405 ---- syserr("can't chmod %s", tfile[t]); ++err; } ! if (chown(tfile[t], ct->ct_uid, ct->ct_gid) == -1) { syserr("can't chown %s to %d/%d", ! tfile[t], ct->ct_uid, ct->ct_gid); ++err; } } Index: getopt.c *************** *** 1,15 **** ! /* $Header: getopt.c,v 1.2 88/11/30 16:24:50 network Exp $ * * A version of the public-domain getopt() function, as found * in the SVID and fine Unix manuals everywhere. * * $Log: getopt.c,v $ * Revision 1.2 88/11/30 16:24:50 network * patch6: Separate getopt() into its own module. * */ #include "config.h" /*---------------------------------------------------------------------- * Get command line options. --- 1,20 ---- ! /* $Header: getopt.c,v 1.3 89/02/10 15:46:49 network Exp $ * * A version of the public-domain getopt() function, as found * in the SVID and fine Unix manuals everywhere. * * $Log: getopt.c,v $ + * Revision 1.3 89/02/10 15:46:49 network + * V7 support. + * * Revision 1.2 88/11/30 16:24:50 network * patch6: Separate getopt() into its own module. * */ + #include <stdio.h> #include "config.h" + #include "misc.h" /*---------------------------------------------------------------------- * Get command line options. Index: lock.c *************** *** 1,9 **** ! /* $Header: lock.c,v 1.2 88/08/30 16:13:14 network Exp $ * * Mailbox locking. * Local hacks for mailbox access should be grafted here. * * $Log: lock.c,v $ * Revision 1.2 88/08/30 16:13:14 network * Portability fixes from Ronald Karr <tron@uts.amdahl.com>. * --- 1,15 ---- ! /* $Header: lock.c,v 1.4 89/02/10 17:59:46 network Exp $ * * Mailbox locking. * Local hacks for mailbox access should be grafted here. * * $Log: lock.c,v $ + * Revision 1.4 89/02/10 17:59:46 network + * Fix typo. + * + * Revision 1.3 89/02/10 15:46:52 network + * V7 support. + * * Revision 1.2 88/08/30 16:13:14 network * Portability fixes from Ronald Karr <tron@uts.amdahl.com>. * *************** *** 65,71 **** */ int ! lock_name(name) char *name; { #ifdef ML_DOTLOCK --- 71,77 ---- */ int ! name_lock(name) char *name; { #ifdef ML_DOTLOCK *************** *** 100,106 **** */ int ! unlock_name(name) char *name; { int ret = 0; --- 106,112 ---- */ int ! name_unlock(name) char *name; { int ret = 0; *************** *** 132,138 **** */ int ! lock_fd(fd) int fd; { #ifdef ML_FCNTL --- 138,144 ---- */ int ! fd_lock(fd) int fd; { #ifdef ML_FCNTL *************** *** 185,191 **** */ int ! unlock_fd(fd) int fd; { #ifdef ML_FCNTL --- 191,197 ---- */ int ! fd_unlock(fd) int fd; { #ifdef ML_FCNTL *************** *** 312,324 **** create_lockfile(name) char *name; { ! int tries, fd; for (tries = 0; tries < 10; ++tries) { if (tries) snooze(3); if ((fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0)) >= 0) { (void) close(fd); --- 318,349 ---- create_lockfile(name) char *name; { ! #ifndef O_CREAT ! char *othername, *p; ! #endif ! int fd, tries; + #ifndef O_CREAT + othername = zalloc(strlen(name) + 20); /* fudge (???) */ + (void) strcpy(othername, name); + (void) sprintf(basename(othername), ".dl.%d", getpid()); + if ((fd = creat(othername, 0)) == -1) + { + syserr("can't create %s", othername); + return -1; + } + (void) close(fd); + if (verbose) + message("created pre-lockfile %s\n", name); + #endif + for (tries = 0; tries < 10; ++tries) { if (tries) snooze(3); + #ifdef O_CREAT + if ((fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0)) >= 0) { (void) close(fd); *************** *** 327,337 **** return 0; } ! if (verbose && (tries == 0)) { ! message("Waiting to create %s (try #%d)\n", ! name, tries + 1); } } syserr("can't create lockfile %s", name); --- 352,373 ---- return 0; } ! #else /* not O_CREAT */ ! ! if (link(othername, name) == 0) { ! if (unlink(othername) == -1) ! syserr("can't remove %s", othername); ! free(othername); ! if (verbose) ! message("created lockfile %s\n", name); ! return 0; } + + #endif /* not O_CREAT */ + + if (verbose && (tries == 0)) + message("Waiting to create %s\n", name); } syserr("can't create lockfile %s", name); Index: main.c *************** *** 1,8 **** ! /* $Header: main.c,v 1.9 88/11/28 18:08:03 network Exp $ * * A program to deliver local mail with some flexibility. * * $Log: main.c,v $ * Revision 1.9 88/11/28 18:08:03 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. --- 1,11 ---- ! /* $Header: main.c,v 1.10 89/02/10 15:46:59 network Exp $ * * A program to deliver local mail with some flexibility. * * $Log: main.c,v $ + * Revision 1.10 89/02/10 15:46:59 network + * V7 support. + * * Revision 1.9 88/11/28 18:08:03 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. *************** *** 59,66 **** * Local data */ ! static char sys_default[] = SYS_DELIVER; ! static char user_default[] = USER_DELIVER; /* * Global data --- 62,69 ---- * Local data */ ! static char sys_dfl[] = SYS_DELIVER; ! static char user_dfl[] = USER_DELIVER; /* * Global data *************** *** 77,84 **** char version[32] = "1.0"; char *shell = SHELL; ! char *sys_deliver = sys_default; ! char *user_deliver = user_default; char *sender = NULL; char *hostname = NULL; --- 80,87 ---- char version[32] = "1.0"; char *shell = SHELL; ! char *sys_deliver = sys_dfl; ! char *user_deliver = user_dfl; char *sender = NULL; char *hostname = NULL; *************** *** 120,127 **** /* Make sure that stdout and stderr are interleaved correctly */ ! (void) Linebuf(stdout); ! (void) Linebuf(stderr); /* Figure out the name used to invoke this program. */ --- 123,130 ---- /* Make sure that stdout and stderr are interleaved correctly */ ! Linebuf(stdout); ! Linebuf(stderr); /* Figure out the name used to invoke this program. */ *************** *** 261,268 **** /* Do we trust our delivery files? */ ! if (strcmp(sys_default, sys_deliver) == 0 ! && strcmp(user_default, user_deliver) == 0) trust_delfiles = TRUE; /* Renounce special privileges if something insecure was requested. */ --- 264,271 ---- /* Do we trust our delivery files? */ ! if (strcmp(sys_dfl, sys_deliver) == 0 ! && strcmp(user_dfl, user_deliver) == 0) trust_delfiles = TRUE; /* Renounce special privileges if something insecure was requested. */ *************** *** 291,298 **** if (verbose) { message("effective uid = %s (%d/%d); real uid = %s (%d/%d)\n", ! eff_ct->name, eff_ct->uid, eff_ct->gid, ! real_ct->name, real_ct->uid, real_ct->gid); } /* Let's be sane about the file creation mask. */ --- 294,301 ---- if (verbose) { message("effective uid = %s (%d/%d); real uid = %s (%d/%d)\n", ! eff_ct->ct_name, eff_ct->ct_uid, eff_ct->ct_gid, ! real_ct->ct_name, real_ct->ct_uid, real_ct->ct_gid); } /* Let's be sane about the file creation mask. */ *************** *** 361,367 **** int a; if (verbose) ! message("mailbox delivery as %s\n", real_ct->name); /* * Consider all arguments as mailbox filenames. --- 364,370 ---- int a; if (verbose) ! message("mailbox delivery as %s\n", real_ct->ct_name); /* * Consider all arguments as mailbox filenames. *************** *** 368,374 **** */ for (a = optind; a < argc; ++a) ! (void) dest(real_ct->name, argv[a]); if (verbose) dumpdests("(should all be mailboxes)"); --- 371,377 ---- */ for (a = optind; a < argc; ++a) ! (void) dest(real_ct->ct_name, argv[a]); if (verbose) dumpdests("(should all be mailboxes)"); *************** *** 550,556 **** for (d = first_dest(); d; d = next_dest(d)) { ! if (d->state != ST_ERROR) continue; if (++count == 1) --- 553,559 ---- for (d = first_dest(); d; d = next_dest(d)) { ! if (d->d_state != ST_ERROR) continue; if (++count == 1) *************** *** 560,569 **** hostname); } ! message("\t\"%s\"", d->name); ! if (d->class == CL_MBOX) ! message(", mailbox \"%s\"", d->mailbox); ! message(": %s\n", d->error); } return count; --- 563,572 ---- hostname); } ! 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; *************** *** 583,589 **** for (n = t; *n; ++n) { ! if ((ct = name_context(*n)) != NULL && uid == ct->uid) return TRUE; } --- 586,592 ---- for (n = t; *n; ++n) { ! if ((ct = name_context(*n)) != NULL && uid == ct->ct_uid) return TRUE; } Index: mbox.c *************** *** 1,8 **** ! /* $Header: mbox.c,v 1.3 88/11/28 18:08:13 network Exp $ * * Finally! Put the message in the specified mailbox(es). * * $Log: mbox.c,v $ * Revision 1.3 88/11/28 18:08:13 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. --- 1,11 ---- ! /* $Header: mbox.c,v 1.4 89/02/10 15:47:10 network Exp $ * * Finally! Put the message in the specified mailbox(es). * * $Log: mbox.c,v $ + * Revision 1.4 89/02/10 15:47:10 network + * V7 support. + * * Revision 1.3 88/11/28 18:08:13 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. *************** *** 31,37 **** * Local functions. */ ! static mbox_dest(); static int mbox_write(); /*---------------------------------------------------------------------- --- 34,40 ---- * Local functions. */ ! static mbox_one(); static int mbox_write(); /*---------------------------------------------------------------------- *************** *** 44,55 **** for (d = first_dest(); d; d = next_dest(d)) { ! switch (d->class) { case CL_USER: case CL_MBOX: ! if (d->state == ST_WORKING) ! mbox_dest(d); break; } } --- 47,58 ---- 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; } } *************** *** 60,66 **** */ static ! mbox_dest(d) DEST *d; { CONTEXT *ct; --- 63,69 ---- */ static ! mbox_one(d) DEST *d; { CONTEXT *ct; *************** *** 68,106 **** if (printaddrs) { ! (void) printf("%s", d->name); ! if (d->class == CL_MBOX) ! (void) printf(":%s", d->mailbox); (void) printf("\n"); } if (dryrun) { ! d->state = ST_DONE; return; } ! if ((ct = name_context(d->name)) == NULL) { ! d->state = ST_ERROR; ! d->error = "Lost context in mbox_dest()"; return; } if (! ok_context(ct)) { ! d->state = ST_ERROR; ! d->error = "No permissions for that context"; return; } ! if (d->class == CL_MBOX) { if (sfork() == 0) { if (become(ct, !boxdelivery) < 0) exit(1); ! if (mbox_write(d->mailbox, ct, FALSE) < 0) exit(1); exit(0); } --- 71,107 ---- if (printaddrs) { ! (void) printf("%s", d->d_name); ! if (d->d_class == CL_MBOX) ! (void) printf(":%s", d->d_mailbox); (void) printf("\n"); } if (dryrun) { ! d->d_state = ST_DONE; return; } ! if ((ct = name_context(d->d_name)) == NULL) { ! dest_err(d, E_CTLOST); return; } if (! ok_context(ct)) { ! dest_err(d, E_CTPERM); return; } ! if (d->d_class == CL_MBOX) { if (sfork() == 0) { if (become(ct, !boxdelivery) < 0) exit(1); ! if (mbox_write(d->d_mailbox, ct, FALSE) < 0) exit(1); exit(0); } *************** *** 113,122 **** char mailbox[100]; (void) sprintf(mailbox, "%s/%s", ! #ifdef MAILBOX_DIR ! MAILBOX_DIR, d->name #else ! d->home, MAILBOX_NAME #endif ); --- 114,123 ---- char mailbox[100]; (void) sprintf(mailbox, "%s/%s", ! #ifdef MBX_DIR ! MBX_DIR, d->d_name #else ! d->d_home, MBX_NAME #endif ); *************** *** 125,136 **** } if (ret >= 0) ! d->state = ST_DONE; else ! { ! d->state = ST_ERROR; ! d->error = "Error writing to mailbox"; ! } } /*---------------------------------------------------------------------- --- 126,134 ---- } if (ret >= 0) ! d->d_state = ST_DONE; else ! dest_err(d, E_MBOX); } /*---------------------------------------------------------------------- *************** *** 145,163 **** CONTEXT *ct; int is_sys; { ! int fd, t; int ret = 0; if (verbose) { message("As %s, delivering to %s mailbox %s\n", ! ct->name, (is_sys ? "system" : "user"), mailbox); } ! if (lock_name(mailbox) < 0) return -1; ! while ((fd = open(mailbox, O_RDWR)) == -1) { if (errno != ENOENT) { --- 143,162 ---- CONTEXT *ct; int is_sys; { ! struct stat st; ! int fd, t, mbox_uid, mbox_gid; int ret = 0; if (verbose) { message("As %s, delivering to %s mailbox %s\n", ! ct->ct_name, (is_sys ? "system" : "user"), mailbox); } ! if (name_lock(mailbox) < 0) return -1; ! while ((fd = open(mailbox, O_WRONLY)) == -1) { if (errno != ENOENT) { *************** *** 165,218 **** break; } ! if ((fd = open(mailbox, O_RDWR|O_CREAT|O_EXCL, ! MAILBOX_MODE)) != -1) { ! /* Make sure the mailbox receives the correct modes */ ! int mbox_gid = ct->gid; ! #ifdef MAILBOX_GROUP ! if (is_sys) ! { ! static int mbox_gid_sv = -2; ! if (mbox_gid_sv == -2) ! mbox_gid_sv = group_id(MAILBOX_GROUP); ! if (mbox_gid_sv < 0) ! message("%s: no such group\n", MAILBOX_GROUP); ! else ! mbox_gid = mbox_gid_sv; ! } ! #endif /* MAILBOX_GROUP */ ! if (chown(mailbox, ct->uid, mbox_gid) == -1) ! { ! /* print a message, but that's all. (???) */ ! syserr("can't chown %s to %d,%d", ! mailbox, ct->uid, mbox_gid); ! } ! break; } ! if (errno != EEXIST) { ! syserr("can't create %s", mailbox); break; } } if (fd == -1) { ! (void) unlock_name(mailbox); return -1; } ! if (lock_fd(fd) < 0) { (void) close(fd); ! (void) unlock_name(mailbox); return -1; } --- 164,237 ---- break; } ! #ifdef O_CREAT ! fd = open(mailbox, O_WRONLY|O_CREAT|O_EXCL, MBX_MODE); ! ! /* If it exists now, try open() again. */ ! if (fd == -1 && errno == EEXIST) ! continue; ! #else ! fd = creat(mailbox, MBX_MODE); ! #endif ! if (fd == -1) { ! syserr("can't create %s", mailbox); ! break; ! } ! /* Make sure the mailbox receives the correct modes */ ! mbox_uid = ct->ct_uid; ! mbox_gid = ct->ct_gid; ! #ifdef MBX_GROUP ! if (is_sys) ! { ! static int mbox_sv_gid = -2; ! if (mbox_sv_gid == -2) ! mbox_sv_gid = group_id(MBX_GROUP); ! if (mbox_sv_gid < 0) ! message("%s: no such group\n", MBX_GROUP); ! else ! mbox_gid = mbox_sv_gid; } + #endif /* MBX_GROUP */ ! if (fstat(fd, &st) == -1) { ! syserr("can't fstat open mailbox?!"); ! (void) close(fd); ! fd = -1; break; } + + /* Change mailbox ownership if it's not already correct. */ + + if ((st.st_uid != mbox_uid || st.st_gid != mbox_gid) + && chown(mailbox, mbox_uid, mbox_gid) == -1) + { + /* print a message, but that's all. (???) */ + syserr("can't chown %s to %d,%d", + mailbox, mbox_uid, mbox_gid); + } + + /* It's open now, so we can stop looping now. */ + + break; } if (fd == -1) { ! (void) name_unlock(mailbox); return -1; } ! if (fd_lock(fd) < 0) { (void) close(fd); ! (void) name_unlock(mailbox); return -1; } *************** *** 240,249 **** message("wrote message to %s\n", mailbox); } ! if (unlock_fd(fd) < 0) ret = -1; (void) close(fd); ! if (unlock_name(mailbox) < 0) ret = -1; return ret; --- 259,268 ---- message("wrote message to %s\n", mailbox); } ! if (fd_unlock(fd) < 0) ret = -1; (void) close(fd); ! if (name_unlock(mailbox) < 0) ret = -1; return ret; Index: misc.h *************** *** 1,8 **** ! /* $Header: misc.h,v 1.4 88/11/26 13:21:01 network Exp $ * * Miscellaneous definitions. * * $Log: misc.h,v $ * Revision 1.4 88/11/26 13:21:01 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. --- 1,11 ---- ! /* $Header: misc.h,v 1.5 89/02/10 15:47:15 network Exp $ * * Miscellaneous definitions. * * $Log: misc.h,v $ + * Revision 1.5 89/02/10 15:47:15 network + * V7 support. + * * Revision 1.4 88/11/26 13:21:01 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. *************** *** 27,39 **** * Non-portable include files */ ! #ifdef BSD ! #include <strings.h> ! #else #include <string.h> #include <memory.h> #endif /* * Constants */ --- 30,46 ---- * Non-portable include files */ ! #ifdef USG ! #include <fcntl.h> #include <string.h> #include <memory.h> #endif + #ifdef BSD + #include <strings.h> + #include <sys/file.h> + #endif + /* * Constants */ *************** *** 46,51 **** --- 53,64 ---- #define FALSE 0 #define TRUE 1 + #ifndef O_RDONLY + #define O_RDONLY 0 + #define O_WRONLY 1 + #define O_RDWR 2 + #endif + /* * Macros. */ *************** *** 55,67 **** #define GETSIZE(buf) (int) (sizeof(buf) - 1) /* ! * Public data */ extern char **environ; /* ! * Library functions */ extern char *ctime(); --- 68,80 ---- #define GETSIZE(buf) (int) (sizeof(buf) - 1) /* ! * Public data. */ extern char **environ; /* ! * Common library functions. */ extern char *ctime(); *************** *** 76,104 **** extern SIGTYPE (*signal())(); /* ! * Library differences */ ! #ifdef BSD ! extern int setlinebuf(); #define strchr index #define strrchr rindex ! #define memcpy(d,s,n) bcopy(s,d,n) #define Zero(d,n) bzero(d,n) ! #define Linebuf(f) setlinebuf(f) ! #else /* not BSD */ extern int setvbuf(); - #define Zero(d,n) memset(d,0,(int)(n)) - #ifdef XENIX_SETVBUF ! #define Linebuf(f) setvbuf(f, _IOLBF, (char *)NULL, BUFSIZ) #else ! #define Linebuf(f) setvbuf(f, (char *)NULL, _IOLBF, BUFSIZ) #endif ! #endif /* not BSD */ --- 89,149 ---- extern SIGTYPE (*signal())(); /* ! * String search functions. */ ! #ifndef USG ! #ifndef BSD ! extern char *index(); ! extern char *rindex(); ! #endif /* not BSD */ #define strchr index #define strrchr rindex ! ! #endif ! ! /* ! * Memory copy and zero. ! */ ! ! #ifdef USG ! #define Copy(d,s,n) (void) memcpy(d,s,n) ! #define Zero(d,n) (void) memset(d,0,(int)(n)) ! #else /* not USG */ ! #ifdef BSD ! #define Copy(d,s,n) bcopy(s,d,n) #define Zero(d,n) bzero(d,n) ! #else /* not BSD */ ! #define MEMFUNCS /* define Copy() and Zero() in sysdep.c */ ! #endif /* not BSD */ ! #endif /* not USG */ ! /* ! * Line-buffering on stdio files. ! */ + #ifdef USG + extern int setvbuf(); #ifdef XENIX_SETVBUF ! #define Linebuf(f) (void) setvbuf(f, _IOLBF, (char *)NULL, BUFSIZ) #else ! #define Linebuf(f) (void) setvbuf(f, (char *)NULL, _IOLBF, BUFSIZ) #endif ! #else /* not USG */ ! #ifdef BSD ! ! extern int setlinebuf(); ! ! #define Linebuf(f) (void) setlinebuf(f) ! ! #else /* not BSD */ ! ! #define Linebuf(f) /* can't do it */ ! ! #endif /* not BSD */ ! #endif /* not USG */ Index: procs.c *************** *** 1,8 **** ! /* $Header: procs.c,v 1.3 88/11/26 13:21:07 network Exp $ * * Process management and misc support. * * $Log: procs.c,v $ * Revision 1.3 88/11/26 13:21:07 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. --- 1,11 ---- ! /* $Header: procs.c,v 1.4 89/02/10 15:47:31 network Exp $ * * Process management and misc support. * * $Log: procs.c,v $ + * Revision 1.4 89/02/10 15:47:31 network + * V7 support. + * * Revision 1.3 88/11/26 13:21:07 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. *************** *** 73,79 **** if (! ok_context(ct)) { ! error("in ct_popen: no permissions to become %s\n", ct->name); return NULL; } --- 76,83 ---- if (! ok_context(ct)) { ! error("in ct_popen: no permissions to become %s\n", ! ct->ct_name); return NULL; } *************** *** 186,204 **** * Note the importance of doing the setgid() before the setuid(). */ ! if (setgid(ct->gid) == -1) { ! syserr("can't setgid to %d", ct->gid); return -1; } ! if (setuid(ct->uid) == -1) { ! syserr("can't setgid to %u", ct->uid); return -1; } ! if (chd && chdir(ct->home) == -1) { ! syserr("can't chdir to %s", ct->home); return -1; } --- 190,208 ---- * Note the importance of doing the setgid() before the setuid(). */ ! if (setgid(ct->ct_gid) == -1) { ! syserr("can't setgid to %d", ct->ct_gid); return -1; } ! if (setuid(ct->ct_uid) == -1) { ! syserr("can't setgid to %u", ct->ct_uid); return -1; } ! if (chd && chdir(ct->ct_home) == -1) { ! syserr("can't chdir to %s", ct->ct_home); return -1; } *************** *** 205,212 **** /* Set up the environment */ (void) sprintf(env_path, "%s:/bin:/usr/bin", ! ((ct->uid == 0) ? "/etc" : ".")); ! alloc_env("HOME", ct->home); alloc_env("PATH", env_path); /* I guess it worked. */ --- 209,216 ---- /* Set up the environment */ (void) sprintf(env_path, "%s:/bin:/usr/bin", ! ((ct->ct_uid == 0) ? "/etc" : ".")); ! alloc_env("HOME", ct->ct_home); alloc_env("PATH", env_path); /* I guess it worked. */ Index: subs.c *************** *** 1,8 **** ! /* $Header: subs.c,v 1.5 88/11/26 13:21:11 network Exp $ * * Miscellaneous subroutines. * * $Log: subs.c,v $ * Revision 1.5 88/11/26 13:21:11 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. --- 1,11 ---- ! /* $Header: subs.c,v 1.6 89/02/10 15:47:40 network Exp $ * * Miscellaneous subroutines. * * $Log: subs.c,v $ + * Revision 1.6 89/02/10 15:47:40 network + * V7 support. + * * Revision 1.5 88/11/26 13:21:11 network * patch4: Add return type of signal handlers to config.h. * patch4: Provide a version of getopt() for systems that lack it. *************** *** 56,62 **** if ((p = malloc(size)) == NULL) nomem(); ! (void) Zero(p, size); return p; } --- 59,65 ---- if ((p = malloc(size)) == NULL) nomem(); ! Zero(p, size); return p; } Index: sysdep.c *************** *** 1,4 **** ! /* $Header: sysdep.c,v 1.6 88/11/30 16:24:56 network Exp $ * * Routines which are (or might well be) system-dependant. * I've put the message routines here since you may need to use --- 1,4 ---- ! /* $Header: sysdep.c,v 1.7 89/02/10 15:47:44 network Exp $ * * Routines which are (or might well be) system-dependant. * I've put the message routines here since you may need to use *************** *** 5,10 **** --- 5,13 ---- * the ANSI <stdarg.h> instead of <varargs.h>. * * $Log: sysdep.c,v $ + * Revision 1.7 89/02/10 15:47:44 network + * V7 support. + * * Revision 1.6 88/11/30 16:24:56 network * patch6: Separate getopt() into its own module. * *************** *** 31,37 **** --- 34,57 ---- #include "deliver.h" #include <errno.h> + #ifdef HAS_STDARG + #include <stdarg.h> + #else + #ifdef HAS_VARARGS #include <varargs.h> + #else + /* + * Non-portable home-grown varargs. Use at your own risk. + * Especially note that if sizeof(int) > sizeof(short), then + * "va_arg(..,short)" is broken. + */ + typedef char *va_list; + #define va_dcl int va_alist; + #define va_start(ap) ap = (char *) &va_alist + #define va_arg(ap,type) *(type *)(ap += sizeof(type), ap - sizeof(type)) + #define va_end(ap) /* nothing */ + #endif + #endif #ifdef UNAME #include <sys/utsname.h> *************** *** 59,75 **** * Print a message. */ ! /* VARARGS1 */ ! message(fmt, va_alist) ! char *fmt; ! va_dcl { ! va_list args; ! va_start(args); ! (void) vfprintf(stderr, fmt, args); ! va_end(args); } /*---------------------------------------------------------------------- --- 79,104 ---- * Print a message. */ ! /* VARARGS */ ! #ifdef HAS_STDARG ! message(char *fmt, ...) ! #else ! message(va_alist) va_dcl ! #endif { ! va_list ap; ! #ifdef HAS_STDARG ! va_start(ap, fmt); ! #else ! char *fmt; ! va_start(ap); ! fmt = va_arg(ap, char *); ! #endif ! (void) vfprintf(stderr, fmt, ap); ! ! va_end(ap); } /*---------------------------------------------------------------------- *************** *** 76,93 **** * Print an error message. */ ! /* VARARGS1 */ ! error(fmt, va_alist) ! char *fmt; ! va_dcl { ! va_list args; ! va_start(args); (void) fprintf(stderr, "%s: ", progname); ! (void) vfprintf(stderr, fmt, args); ! va_end(args); } /*---------------------------------------------------------------------- --- 105,131 ---- * Print an error message. */ ! /* VARARGS */ ! #ifdef HAS_STDARG ! error(char *fmt, ...) ! #else ! error(va_alist) va_dcl ! #endif { ! va_list ap; + #ifdef HAS_STDARG + va_start(ap, fmt); + #else + char *fmt; + va_start(ap); + fmt = va_arg(ap, char *); + #endif + (void) fprintf(stderr, "%s: ", progname); ! (void) vfprintf(stderr, fmt, ap); ! va_end(ap); } /*---------------------------------------------------------------------- *************** *** 94,116 **** * Report an error returned from a system call. */ ! /* VARARGS1 */ ! syserr(fmt, va_alist) ! char *fmt; ! va_dcl { int e = errno; ! va_list args; ! va_start(args); (void) fprintf(stderr, "%s: ", progname); ! (void) vfprintf(stderr, fmt, args); if (e <= sys_nerr) (void) fprintf(stderr, ": %s\n", sys_errlist[e]); else (void) fprintf(stderr, ": unknown system error %d\n", e); ! va_end(args); } /*---------------------------------------------------------------------- --- 132,163 ---- * Report an error returned from a system call. */ ! /* VARARGS */ ! #ifdef HAS_STDARG ! syserr(char *fmt, ...) ! #else ! syserr(va_alist) va_dcl ! #endif { int e = errno; ! va_list ap; + #ifdef HAS_STDARG + va_start(ap, fmt); + #else + char *fmt; + va_start(ap); + fmt = va_arg(ap, char *); + #endif + (void) fprintf(stderr, "%s: ", progname); ! (void) vfprintf(stderr, fmt, ap); if (e <= sys_nerr) (void) fprintf(stderr, ": %s\n", sys_errlist[e]); else (void) fprintf(stderr, ": unknown system error %d\n", e); ! va_end(ap); } /*---------------------------------------------------------------------- *************** *** 193,198 **** --- 240,259 ---- #endif /* GETHOSTNAME */ /*---------------------------------------------------------------------- + * Return a pre-defined HOSTNAME. + */ + + #ifdef HOSTNAME + + char * + gethost() + { + return HOSTNAME; + } + + #endif /* HOSTNAME */ + + /*---------------------------------------------------------------------- * Variable-argument-list output, System V style. */ *************** *** 277,284 **** {} env_size = i + 10; /* arbitrary */ env_array = (char **) zalloc(env_size * sizeof(char *)); ! (void) memcpy((char *)env_array, (char *)environ, ! (int) ((i + 1) * sizeof(char *))); environ = env_array; } else if (environ != env_array) --- 338,345 ---- {} env_size = i + 10; /* arbitrary */ env_array = (char **) zalloc(env_size * sizeof(char *)); ! Copy((char *)env_array, (char *)environ, ! (int) ((i + 1) * sizeof(char *))); environ = env_array; } else if (environ != env_array) *************** *** 311,313 **** --- 372,407 ---- } #endif /* !HAS_PUTENV */ + + /*---------------------------------------------------------------------- + * Memory copy. + */ + + #ifdef MEMFUNCS + + Copy(dest, src, len) + char *dest; + char *src; + int len; + { + while (len-- > 0) + *dest++ = *src++; + } + + #endif + + /*---------------------------------------------------------------------- + * Memory clear. + */ + + #ifdef MEMFUNCS + + Zero(dest, len) + char *dest; + int len; + { + while (len-- > 0) + *dest++ = 0; + } + + #endif Index: uucp.c *************** *** 1,4 **** ! /* $Header: uucp.c,v 1.2 88/11/28 18:08:23 network Exp $ * * Handle mail destined for other hosts via UUCP. * Deliver is intended as a very low-level program, so we don't --- 1,4 ---- ! /* $Header: uucp.c,v 1.3 89/02/10 15:47:51 network Exp $ * * Handle mail destined for other hosts via UUCP. * Deliver is intended as a very low-level program, so we don't *************** *** 5,10 **** --- 5,13 ---- * do anything fancy here. We just hand the message to uux. * * $Log: uucp.c,v $ + * Revision 1.3 89/02/10 15:47:51 network + * V7 support. + * * Revision 1.2 88/11/28 18:08:23 network * patch5: Copy temp files before handing them to delivery files. * patch5: Introduce "uid" program. *************** *** 55,75 **** char rmail[40]; char who[BUFSIZ]; ! if (d->class != CL_UUCP || d->state != ST_WORKING) continue; if (printaddrs) ! (void) printf("%s\n", d->name); if (dryrun) { ! d->state = ST_DONE; continue; } ! bang = strchr(d->name, '!'); *bang = 0; ! (void) sprintf(rmail, "%s!rmail", d->name); *bang++ = '!'; (void) sprintf(who, "(%s)", bang); --- 58,78 ---- char rmail[40]; char who[BUFSIZ]; ! if (d->d_class != CL_UUCP || d->d_state != ST_WORKING) continue; if (printaddrs) ! (void) printf("%s\n", d->d_name); if (dryrun) { ! d->d_state = ST_DONE; continue; } ! bang = strchr(d->d_name, '!'); *bang = 0; ! (void) sprintf(rmail, "%s!rmail", d->d_name); *bang++ = '!'; (void) sprintf(who, "(%s)", bang); *************** *** 82,101 **** continue; if (uucp_copy(uux_fp) < 0) ! { ! d->state = ST_ERROR; ! d->error = "Error piping to uux"; ! } if (ct_pclose(uux_fp)) { ! /* Overrides any problems with uucp_copy() */ ! ! d->state = ST_ERROR; ! d->error = "UUCP not available to that host"; } else ! d->state = ST_DONE; } } --- 85,99 ---- continue; if (uucp_copy(uux_fp) < 0) ! dest_err(d, E_UUX); if (ct_pclose(uux_fp)) { ! /* "No such host" overrides piping problems. */ ! dest_err(d, E_NSHOST); } else ! d->d_state = ST_DONE; } } -- Chip Salzenberg <chip@ateng.com> or <uunet!ateng!chip> A T Engineering Me? Speak for my company? Surely you jest! "It's no good. They're tapping the lines."