Deliver 1.00 patch #5
Chip Salzenberg
chip at ateng.ateng.com
Wed Nov 30 08:14:08 AEST 1988
This is an offical patch for deliver 1.00. Please apply it.
Patch number: 5
Date: 29 Nov 1988
Priority: SKY-HIGH
Changes:
The big change: Temp files are kept with modes of zero. The
filenames given to delivery files in $HEADER and $BODY are now
*copies* of the original temp files. This is an important change;
it prevents errant delivery files from stomping on the real temp
files, which are later copied into mailboxes.
Temp files are no longer given to a user when writing to his
mailbox.
Makefile target "clobber" now implies "clean".
New program "uid" eliminates klugy test for root in Makefile.
Index: patchlevel.h
Prereq: 4
***************
*** 1 ****
! #define PATCHLEVEL 4
--- 1 ----
! #define PATCHLEVEL 5
Index: Makefile
***************
*** 1,4 ****
! # $Header: Makefile,v 1.8 88/11/21 13:11:27 network Exp $
#
# Makefile for deliver
#
--- 1,4 ----
! # $Header: Makefile,v 1.11 88/11/28 18:45:20 network Exp $
#
# Makefile for deliver
#
***************
*** 71,76 ****
--- 71,78 ----
SRC2 = main.c mbox.c procs.c subs.c sysdep.c uucp.c
SRCS = $(SRC1) $(SRC2)
+ UIDSRC = uid.c
+
OBJS = context.o copymsg.o debug.o dest.o dfile.o lock.o \
main.o mbox.o procs.o subs.o sysdep.o uucp.o
***************
*** 81,106 ****
.PHONY: all install lint shar clean clobber
#
# How to compile and link the program.
#
! all: deliver
deliver: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(OBJS): $(HDRS)
! clean::
! rm -f $(OBJS)
!
! #
! # This is a klugy way to determine if you are root or not.
! # I'm open to suggestions! (Remember that 'su' counts.)
! #
!
! install: deliver
! @if [ ! -w /etc ]; \
then \
- echo ""; \
echo "Sorry! You must be root to install deliver."; \
exit 1; \
fi
--- 83,106 ----
.PHONY: all install lint shar clean clobber
#
+ # "make clobber" implies "make clean".
+ #
+
+ clobber:: clean
+
+ #
# How to compile and link the program.
#
! all: deliver uid
!
deliver: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(OBJS): $(HDRS)
! install: deliver uid
! @if [ `./uid -uU | fgrep '(root)' | wc -l` -ne 2 ]; \
then \
echo "Sorry! You must be root to install deliver."; \
exit 1; \
fi
***************
*** 109,127 ****
chown root $(BIN)/deliver
chmod 4711 $(BIN)/deliver
clobber::
rm -f deliver
#
# Look for fuzz.
#
! lint: lint.out
! lint.out: $(HDRS) $(SRCS)
! lint $(SRCS) -lc $(LIBS) >lint.out
clean::
! rm -f lint.out
#
# Make distribution sharchives.
--- 109,146 ----
chown root $(BIN)/deliver
chmod 4711 $(BIN)/deliver
+ clean::
+ rm -f $(OBJS)
clobber::
rm -f deliver
#
+ # A little program to check on user and group id's.
+ # (I wish that the System V "id" program were available everywhere.)
+ #
+
+ uid: $(UIDSRC) sysdep.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(UIDSRC) sysdep.o $(LIBS)
+ @rm -f $@.o
+ uid: config.h
+
+ clobber::
+ rm -f uid
+
+ #
# Look for fuzz.
#
! lint: deliver.lint uid.lint
+ deliver.lint: $(HDRS) $(SRCS)
+ lint $(SRCS) -lc $(LIBS) >$@
+
+ uid.lint: uid.c
+ lint uid.c -lc $(LIBS) >$@
+
clean::
! rm -f *.lint
#
# Make distribution sharchives.
***************
*** 128,135 ****
#
shar: $(DELSHAR).01 $(DELSHAR).02 $(DELSHAR).03
! $(DELSHAR).01: $(DOCS) $(MF) $(HDRS)
! $(SHAR) >$@ $(DOCS) $(MF) $(HDRS)
$(DELSHAR).02: $(SRC1)
$(SHAR) >$@ $(SRC1)
$(DELSHAR).03: $(SRC2)
--- 147,154 ----
#
shar: $(DELSHAR).01 $(DELSHAR).02 $(DELSHAR).03
! $(DELSHAR).01: $(DOCS) $(MF) $(HDRS) $(UIDSRC)
! $(SHAR) >$@ $(DOCS) $(MF) $(HDRS) $(UIDSRC)
$(DELSHAR).02: $(SRC1)
$(SHAR) >$@ $(SRC1)
$(DELSHAR).03: $(SRC2)
Index: copymsg.c
***************
*** 1,9 ****
! /* $Header: copymsg.c,v 1.2 88/11/18 12:17:40 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.2 88/11/18 12:17:40 network
* patch2: Improved signal handling.
* patch2: Make sure all environment variables are always provided.
--- 1,13 ----
! /* $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.
+ *
* Revision 1.2 88/11/18 12:17:40 network
* patch2: Improved signal handling.
* patch2: Make sure all environment variables are always provided.
***************
*** 51,57 ****
* Create temporary files to hold the header and message body.
*/
! for (t = 0; t < T_MAX; ++t)
{
int fd;
--- 55,61 ----
* Create temporary files to hold the header and message body.
*/
! for (t = T_HDR; t <= T_BODY; ++t)
{
int fd;
***************
*** 77,83 ****
if (verbose)
{
message("header=%s, body=%s\n",
! tfile[T_HEADER], tfile[T_BODY]);
}
/*
--- 81,87 ----
if (verbose)
{
message("header=%s, body=%s\n",
! tfile[T_HDR], tfile[T_BODY]);
}
/*
***************
*** 152,162 ****
* Finally! Write the From_ line.
*/
! (void) fputs("From ", dfp[T_HEADER]);
! (void) fputs(sender, dfp[T_HEADER]);
! (void) fputc(' ', dfp[T_HEADER]);
(void) time(&now);
! (void) fputs(ctime(&now), dfp[T_HEADER]);
/*
* Copy the rest of the header (if any).
--- 156,166 ----
* Finally! Write the From_ line.
*/
! (void) fputs("From ", dfp[T_HDR]);
! (void) fputs(sender, dfp[T_HDR]);
! (void) fputc(' ', dfp[T_HDR]);
(void) time(&now);
! (void) fputs(ctime(&now), dfp[T_HDR]);
/*
* Copy the rest of the header (if any).
***************
*** 198,204 ****
if (isspace(buf[0]))
; /* continuation */
else if (ISFROM(buf) || (buf[0] == '>'))
! (void) fputc('>', dfp[T_HEADER]);
else
{
/* look for the colon on a header label */
--- 202,208 ----
if (isspace(buf[0]))
; /* continuation */
else if (ISFROM(buf) || (buf[0] == '>'))
! (void) fputc('>', dfp[T_HDR]);
else
{
/* look for the colon on a header label */
***************
*** 212,218 ****
/* Write the line to the header file. */
! (void) fputs(buf, dfp[T_HEADER]);
}
/*
--- 216,222 ----
/* Write the line to the header file. */
! (void) fputs(buf, dfp[T_HDR]);
}
/*
***************
*** 221,227 ****
* to produce a valid message.
*/
! (void) fputc('\n', dfp[T_HEADER]);
/*
* Copy the body (if any).
--- 225,231 ----
* to produce a valid message.
*/
! (void) fputc('\n', dfp[T_HDR]);
/*
* Copy the body (if any).
***************
*** 268,274 ****
* let's not keep it secret.
*/
! for (t = 0; t < T_MAX; ++t)
{
if (ferror(dfp[t]))
{
--- 272,278 ----
* let's not keep it secret.
*/
! for (t = T_HDR; t <= T_BODY; ++t)
{
if (ferror(dfp[t]))
{
***************
*** 286,291 ****
--- 290,374 ----
}
/*----------------------------------------------------------------------
+ * Create another copy of each temp file, for security reasons.
+ * Also, put their names in the environment.
+ */
+
+ int
+ copy_again()
+ {
+ int r, t;
+
+ for (r = T_HDR, t = T_HDRCOPY; r <= T_BODY; ++r, ++t)
+ {
+ /*
+ * If the file exists, remove it but keep its name.
+ * Otherwise, make a new name and put that name in
+ * the environment.
+ */
+
+ if (tfile[t])
+ (void) unlink(tfile[t]);
+ else
+ {
+ tfile[t] = tempfile();
+ if (tenv[t])
+ alloc_env(tenv[t], tfile[t]);
+ }
+
+ /*
+ * Create the file and copy the contents of the
+ * original file to it.
+ */
+
+ if (tfd[t] != -1)
+ (void) close(tfd[t]);
+
+ if ((tfd[t] = tcreate(tfile[t])) == -1)
+ return -1;
+
+ (void) lseek(tfd[r], 0L, 0);
+ if (copyfd(tfd[r], tfd[t]) < 0)
+ return -1;
+ }
+
+ if (verbose)
+ {
+ message("copy_again: header to %s, body to %s\n",
+ tfile[T_HDRCOPY], tfile[T_BODYCOPY]);
+ }
+
+ return 0;
+ }
+
+ /*----------------------------------------------------------------------
+ * Copy a file via file descriptors.
+ */
+
+ int
+ copyfd(src_fd, dest_fd)
+ int src_fd;
+ int dest_fd;
+ {
+ char buf[BUFSIZ];
+ int rd, wr;
+
+ while ((rd = read(src_fd, buf, sizeof(buf))) > 0)
+ {
+ if ((wr = write(dest_fd, buf, (unsigned) rd)) != rd)
+ {
+ if (wr == -1)
+ syserr("can't write in copyfd");
+ else
+ error("write error -- disk full?\n");
+ return -1;
+ }
+ }
+
+ return 0;
+ }
+
+ /*----------------------------------------------------------------------
* Return a pointer to a temporary filename, or NULL if error.
*/
***************
*** 315,321 ****
{
int fd;
! if ((fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
{
syserr("can't create %s", name);
return -1;
--- 398,404 ----
{
int fd;
! if ((fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0)) == -1)
{
syserr("can't create %s", name);
return -1;
Index: deliver.h
***************
*** 1,8 ****
! /* $Header: deliver.h,v 1.5 88/11/18 12:16:55 network Exp $
*
* General pull-it-together include file.
*
* $Log: deliver.h,v $
* Revision 1.5 88/11/18 12:16:55 network
* patch2: Improved signal handling.
* patch2: Make sure all environment variables are always provided.
--- 1,12 ----
! /* $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.
+ *
* Revision 1.5 88/11/18 12:16:55 network
* patch2: Improved signal handling.
* patch2: Make sure all environment variables are always provided.
***************
*** 63,74 ****
extern int trust_delfiles; /* Do we trust the delivery files? */
/* Temp file indices: */
! #define T_HEADER 0 /* Temp file for message header */
! #define T_BODY 1 /* Temp file for message body */
! #define T_MAX 2 /* Number of temp files */
extern char *ttype[T_MAX]; /* Temp file types (for messages) */
extern char *tfile[T_MAX]; /* Temp file names */
extern int tfd[T_MAX]; /* Temp file fd's */
extern SIGFLAG got_sig; /* We caught a signal and should exit */
--- 67,81 ----
extern int trust_delfiles; /* Do we trust the delivery files? */
/* Temp file indices: */
! #define T_HDR 0 /* Message header */
! #define T_BODY 1 /* Message body */
! #define T_HDRCOPY 2 /* Copy of message header */
! #define T_BODYCOPY 3 /* Copy of message body */
! #define T_MAX 4 /* Number of temp files */
extern char *ttype[T_MAX]; /* Temp file types (for messages) */
extern char *tfile[T_MAX]; /* Temp file names */
+ extern char *tenv[T_MAX]; /* Temp file environment names */
extern int tfd[T_MAX]; /* Temp file fd's */
extern SIGFLAG got_sig; /* We caught a signal and should exit */
Index: dfile.c
***************
*** 1,8 ****
! /* $Header: dfile.c,v 1.5 88/11/26 13:20:45 network Exp $
*
* Filter destination(s) through delivery file(s).
*
* $Log: dfile.c,v $
* Revision 1.5 88/11/26 13:20:45 network
* patch4: Add return type of signal handlers to config.h.
* patch4: Provide a version of getopt() for systems that lack it.
--- 1,12 ----
! /* $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.
+ *
* Revision 1.5 88/11/26 13:20:45 network
* patch4: Add return type of signal handlers to config.h.
* patch4: Provide a version of getopt() for systems that lack it.
***************
*** 256,265 ****
return -1;
}
! /* Make sure that the temp files are readable to the new process. */
! give_temps(ct);
/* Here we go! */
if (verbose)
--- 260,275 ----
return -1;
}
! /* Copy the temp files again */
! if (copy_again() < 0)
! return -1;
+ /* Allow the given user to own and read the copies */
+
+ if (give_temps(ct) < 0)
+ return -1;
+
/* Here we go! */
if (verbose)
***************
*** 376,392 ****
* This is needed because the temps are readable by owner only.
*/
give_temps(ct)
CONTEXT *ct;
{
! int t;
if (!ct)
! return;
! for (t = 0; t < T_MAX; ++t)
{
if (chown(tfile[t], ct->uid, ct->gid) == -1)
! syserr("can't chown %s", tfile[t]);
}
}
--- 386,415 ----
* This is needed because the temps are readable by owner only.
*/
+ int
give_temps(ct)
CONTEXT *ct;
{
! int err, t;
if (!ct)
! return -1;
! err = 0;
! for (t = T_HDRCOPY; t <= T_BODYCOPY; ++t)
{
+ if (chmod(tfile[t], 0600) == -1)
+ {
+ 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;
! }
}
+
+ return err ? -1 : 0;
}
Index: main.c
***************
*** 1,8 ****
! /* $Header: main.c,v 1.8 88/11/26 13:20:51 network Exp $
*
* A program to deliver local mail with some flexibility.
*
* $Log: main.c,v $
* Revision 1.8 88/11/26 13:20:51 network
* patch4: Add return type of signal handlers to config.h.
* patch4: Provide a version of getopt() for systems that lack it.
--- 1,12 ----
! /* $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.
+ *
* Revision 1.8 88/11/26 13:20:51 network
* patch4: Add return type of signal handlers to config.h.
* patch4: Provide a version of getopt() for systems that lack it.
***************
*** 92,100 ****
int trust_user = FALSE;
int trust_delfiles = FALSE;
! char *ttype[T_MAX] = { "header", "body" };
! char *tfile[T_MAX] = { NULL, NULL };
! int tfd[T_MAX] = { -1, -1 };
/*
* Local functions.
--- 96,105 ----
int trust_user = FALSE;
int trust_delfiles = FALSE;
! char *ttype[T_MAX] = { "header", "body", "header copy", "body copy" };
! char *tfile[T_MAX] = { NULL, NULL, NULL, NULL };
! char *tenv[T_MAX] = { NULL, NULL, ENV_HEADER, ENV_BODY };
! int tfd[T_MAX] = { -1, -1, -1, -1 };
/*
* Local functions.
***************
*** 476,481 ****
--- 481,488 ----
for (t = 0; t < T_MAX; ++t)
{
+ if (tfd[t] != -1)
+ (void) close(tfd[t]);
if (tfile[t] && unlink(tfile[t]) == -1)
syserr("can't unlink %s", tfile[t]);
}
***************
*** 610,618 ****
alloc_env(ENV_HOSTNAME, hostname);
if (sender && *sender)
alloc_env(ENV_SENDER, sender);
-
- alloc_env(ENV_HEADER, tfile[T_HEADER]);
- alloc_env(ENV_BODY, tfile[T_BODY]);
alloc_env("IFS", " \t\n");
}
--- 617,622 ----
Index: mbox.c
***************
*** 1,8 ****
! /* $Header: mbox.c,v 1.2 88/09/14 19:42:06 network Exp $
*
* Finally! Put the message in the specified mailbox(es).
*
* $Log: mbox.c,v $
* Revision 1.2 88/09/14 19:42:06 network
* Portability to System V and BSD.
* General fixup.
--- 1,12 ----
! /* $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.
+ *
* Revision 1.2 88/09/14 19:42:06 network
* Portability to System V and BSD.
* General fixup.
***************
*** 29,35 ****
static mbox_dest();
static int mbox_write();
- static int mbox_copy();
/*----------------------------------------------------------------------
* Deliver mail to all valid destinations.
--- 33,38 ----
***************
*** 93,100 ****
if (d->class == CL_MBOX)
{
- give_temps(ct);
-
if (sfork() == 0)
{
if (become(ct, !boxdelivery) < 0)
--- 96,101 ----
***************
*** 217,223 ****
(void) lseek(fd, 0L, 2); /* No error check: may be a special file */
! for (t = 0; t < T_MAX; ++t)
{
if (lseek(tfd[t], 0L, 0) == -1)
{
--- 218,224 ----
(void) lseek(fd, 0L, 2); /* No error check: may be a special file */
! for (t = T_HDR; t <= T_BODY; ++t)
{
if (lseek(tfd[t], 0L, 0) == -1)
{
***************
*** 226,246 ****
break;
}
! switch (mbox_copy(tfd[t], fd))
{
- case 1:
- syserr("can't read %s file %s", ttype[t], tfile[t]);
ret = -1;
break;
- case 2:
- syserr("can't write to mailbox %s as %s",
- mailbox, ct->name);
- ret = -1;
- break;
- default:
- continue;
}
- break;
}
if (verbose)
--- 227,237 ----
break;
}
! if (copyfd(tfd[t], fd) < 0)
{
ret = -1;
break;
}
}
if (verbose)
***************
*** 256,284 ****
ret = -1;
return ret;
- }
-
- /*----------------------------------------------------------------------
- * Copy the named file to the given file descriptor.
- */
-
- static int
- mbox_copy(ifd, ofd)
- int ifd;
- int ofd;
- {
- char buf[BUFSIZ];
- int rd;
-
- while ((rd = read(ifd, buf, sizeof(buf))) > 0)
- {
- errno = 255; /* to avoid bogus syserr() output */
- if (write(ofd, buf, (unsigned) rd) != rd)
- return 2;
- }
-
- if (rd == -1)
- return 1;
-
- return 0;
}
--- 247,250 ----
Index: uid.c
***************
*** 0 ****
--- 1,143 ----
+ /* $Header: uid.c,v 1.2 88/11/28 18:08:20 network Exp $
+ *
+ * I wish the System V "id" program were universally available; but it
+ * isn't, so I've written this replacement.
+ *
+ * usage: uid [-options]
+ *
+ * Default action is to print one line in the manner of "id":
+ * uid=201(chip) gid=50(group) euid=0(root) egid=0(root)
+ * (Note that the "euid" and "egid" entries are not output if they are
+ * the same as the "uid" and "gid" values.)
+ *
+ * If an option string is specified, it disables the normal behavior in
+ * favor of displaying id information, one per line, in the order that
+ * the options appear in the option string. Legal options are:
+ * u real uid
+ * g real gid
+ * U effective uid
+ * G effective gid
+ *
+ * NOTE: This program is not a paragon of good style.
+ * It's just something I needed for a Makefile.
+ *
+ * $Log: uid.c,v $
+ * Revision 1.2 88/11/28 18:08:20 network
+ * patch5: Copy temp files before handing them to delivery files.
+ * patch5: Introduce "uid" program.
+ *
+ */
+
+ #include <stdio.h>
+ #include <pwd.h>
+ #include <grp.h>
+ #include "config.h"
+
+ #ifdef NULL
+ #undef NULL
+ #endif
+ #define NULL 0
+
+ extern struct passwd *getpwuid();
+ extern struct group *getgrgid();
+
+ char *progname = "uid";
+
+ char *uid_desc();
+ char *gid_desc();
+
+ main(argc, argv)
+ int argc;
+ char **argv;
+ {
+ int uid, gid, euid, egid;
+ int c, lines, errcount;
+
+ uid = getuid();
+ gid = getgid();
+ euid = geteuid();
+ egid = getegid();
+
+ errcount = 0;
+ lines = 0;
+
+ while ((c = getopt(argc, argv, "ugUG")) != EOF)
+ {
+ switch (c)
+ {
+ case 'u':
+ (void) printf("%s\n", uid_desc(uid));
+ ++lines;
+ break;
+
+ case 'g':
+ (void) printf("%s\n", gid_desc(gid));
+ ++lines;
+ break;
+
+ case 'U':
+ (void) printf("%s\n", uid_desc(euid));
+ ++lines;
+ break;
+
+ case 'G':
+ (void) printf("%s\n", gid_desc(egid));
+ ++lines;
+ break;
+
+ case '?':
+ ++errcount;
+ break;
+ }
+ }
+
+ if (errcount)
+ {
+ (void) fprintf(stderr, "usage: uid [-ugUG]\n");
+ exit(1);
+ }
+
+ if (lines == 0)
+ {
+ (void) printf("uid=%s", uid_desc(uid));
+ (void) printf(" gid=%s", gid_desc(gid));
+
+ if (euid != uid)
+ (void) printf(" euid=%s", uid_desc(euid));
+ if (egid != gid)
+ (void) printf(" egid=%s", gid_desc(egid));
+
+ (void) printf("\n");
+ }
+
+ exit(0);
+ /* NOTREACHED */
+ }
+
+ char *
+ uid_desc(uid)
+ int uid;
+ {
+ struct passwd *pw;
+ static char buf[80];
+
+ (void) sprintf(buf, "%d", uid);
+ if ((pw = getpwuid(uid)) != NULL)
+ (void) sprintf(buf + strlen(buf), "(%s)", pw->pw_name);
+
+ return buf;
+ }
+
+ char *
+ gid_desc(gid)
+ int gid;
+ {
+ struct group *gr;
+ static char buf[80];
+
+ (void) sprintf(buf, "%d", gid);
+ if ((gr = getgrgid(gid)) != NULL)
+ (void) sprintf(buf + strlen(buf), "(%s)", gr->gr_name);
+
+ return buf;
+ }
Index: uucp.c
***************
*** 1,4 ****
! /* $Header: uucp.c,v 1.1 88/06/06 09:39:42 chip 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.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
***************
*** 5,10 ****
--- 5,14 ----
* do anything fancy here. We just hand the message to uux.
*
* $Log: uucp.c,v $
+ * Revision 1.2 88/11/28 18:08:23 network
+ * patch5: Copy temp files before handing them to delivery files.
+ * patch5: Introduce "uid" program.
+ *
* Revision 1.1 88/06/06 09:39:42 chip
* Initial revision
*
***************
*** 109,115 ****
int fd;
char buf[BUFSIZ];
! if ((fd = dup(tfd[T_HEADER])) == -1)
{
syserr("can't dup header fd");
return -1;
--- 113,119 ----
int fd;
char buf[BUFSIZ];
! if ((fd = dup(tfd[T_HDR])) == -1)
{
syserr("can't dup header fd");
return -1;
--
Chip Salzenberg <chip at ateng.com> or <uunet!ateng!chip>
A T Engineering Me? Speak for my company? Surely you jest!
Beware of programmers carrying screwdrivers.
More information about the Comp.sources.bugs
mailing list