v23i005: Deliver 2.0 patches, Part05/10
Rich Salz
rsalz at bbn.com
Fri Aug 31 03:04:29 AEST 1990
Submitted-by: Chip Salzenberg <tct!chip at uunet.uu.net>
Posting-number: Volume 23, Issue 5
Archive-name: deliver2.0pch/part05
Changes in patch #6 to Deliver 2.0:
1. The UMASK value was interfering with the MBX_MODE (mailbox
permissions) value. Fixed.
2. Logging was failing in interesting (!) ways on systems without
three-argument open() and O_APPEND. Fixed with a log lockfile.
3. The log format has been adjusted to emphasize the difference
between separate invocations of Deliver and recursive calls.
This patch contains changes to the following files:
patchlevel.h
config.h
copymsg.c
deliver.h
main.c
mbox.c
subs.c
sysdep.c
Index: patchlevel.h
Prereq: 5
***************
*** 1,1 ****
! #define PATCHLEVEL 5
--- 1,1 ----
! #define PATCHLEVEL 6
Index: config.h
***************
*** 1,3 ****
! /* $Header: config.h,v 2.6 89/12/14 17:42:25 network Exp $
*
* Deliver configuration.
--- 1,3 ----
! /* $Header: config.h,v 2.7 90/02/06 11:56:37 chip Exp $
*
* Deliver configuration.
***************
*** 4,7 ****
--- 4,12 ----
*
* $Log: config.h,v $
+ * Revision 2.7 90/02/06 11:56:37 chip
+ * Enforce MBX_MODE regardless of UMASK.
+ * Enforce ordered logging with a log lockfile.
+ * Revise log format.
+ *
* Revision 2.6 89/12/14 17:42:25 network
* Rework setvbuf() configuration to avoid errors.
***************
*** 291,295 ****
* Log file names.
* Errors and warnings are output to stderr and to this file.
! * To disable logging, don't define LOGFILE.
*/
--- 296,302 ----
* Log file names.
* Errors and warnings are output to stderr and to this file.
! * To disable logging, don't define LOG.
! * To disable error logging, don't define ERRLOG.
! * Define LOGLOCK to be the temp file controlling access to log files.
*/
***************
*** 296,299 ****
--- 303,307 ----
#define LOG "/usr/adm/deliver.log"
#define ERRLOG "/usr/adm/deliver.errlog"
+ #define LOGLOCK "/tmp/dl.loglock"
/*----------------------------------------------------------------------
Index: copymsg.c
***************
*** 1,3 ****
! /* $Header: copymsg.c,v 2.3 89/11/27 14:18:29 network Exp $
*
* Take the message from standard input and write it to two temp files,
--- 1,3 ----
! /* $Header: copymsg.c,v 2.4 90/02/06 11:56:38 chip Exp $
*
* Take the message from standard input and write it to two temp files,
***************
*** 5,8 ****
--- 5,13 ----
*
* $Log: copymsg.c,v $
+ * Revision 2.4 90/02/06 11:56:38 chip
+ * Enforce MBX_MODE regardless of UMASK.
+ * Enforce ordered logging with a log lockfile.
+ * Revise log format.
+ *
* Revision 2.3 89/11/27 14:18:29 network
* Strip trailing spaces from date on From_ line.
***************
*** 32,42 ****
&& (p)[3] == 'm' && (p)[4] == ' ')
- /*
- * Local functions.
- */
-
- static char *tempfile();
- static int tcreate();
-
/*----------------------------------------------------------------------
* Copy the message on the standard input to two temp files:
--- 37,40 ----
***************
*** 457,513 ****
return 0;
- }
-
- /*----------------------------------------------------------------------
- * Return a pointer to a temporary filename, or NULL if error.
- */
-
- static char *
- tempfile()
- {
- static char template[] = "/tmp/dl.XXXXXX";
- char *f;
-
- f = zalloc(32);
- (void) strcpy(f, template);
- if (mktemp(f) == NULL)
- {
- error("can't create temporary file");
- return NULL;
- }
- return f;
- }
-
- /*----------------------------------------------------------------------
- * Create a file, or complain if it doesn't work.
- */
-
- static int
- tcreate(name)
- char *name;
- {
- 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;
}
--- 455,458 ----
Index: deliver.h
***************
*** 1,3 ****
! /* $Header: deliver.h,v 2.5 89/11/10 12:23:51 network Exp $
*
* General pull-it-together include file.
--- 1,3 ----
! /* $Header: deliver.h,v 2.6 90/02/06 11:54:45 chip Exp $
*
* General pull-it-together include file.
***************
*** 4,7 ****
--- 4,12 ----
*
* $Log: deliver.h,v $
+ * Revision 2.6 90/02/06 11:54:45 chip
+ * Enforce MBX_MODE regardless of UMASK.
+ * Enforce ordered logging with a log lockfile.
+ * Revise log format.
+ *
* Revision 2.5 89/11/10 12:23:51 network
* Handle recursion.
***************
*** 70,75 ****
extern FILE *log; /* File to log deliveries */
extern FILE *errlog; /* File to log messages and errors */
! extern int errused; /* Error log used flag */
extern int tty_input; /* Is our input coming from a tty? */
--- 75,81 ----
extern FILE *log; /* File to log deliveries */
+ extern char *logfile; /* Temporary file for log */
extern FILE *errlog; /* File to log messages and errors */
! extern char *errlogfile; /* Temporary file for error log */
extern int tty_input; /* Is our input coming from a tty? */
***************
*** 94,97 ****
--- 100,104 ----
*/
+ char *tempfile();
char *basename();
char *relpath();
***************
*** 105,108 ****
--- 112,116 ----
CONTEXT *uid_context();
+ FILE *ftcreate();
FILE *ct_popenv();
int ct_pclose();
Index: main.c
***************
*** 1,3 ****
! /* $Header: main.c,v 2.6 89/12/19 16:45:26 network Exp $
*
* A program to deliver local mail with some flexibility.
--- 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.
***************
*** 4,7 ****
--- 4,12 ----
*
* $Log: main.c,v $
+ * Revision 2.7 90/02/06 11:56:40 chip
+ * Enforce MBX_MODE regardless of UMASK.
+ * Enforce ordered logging with a log lockfile.
+ * Revise log format.
+ *
* Revision 2.6 89/12/19 16:45:26 network
* Include <time.h> for the functions.
***************
*** 84,89 ****
FILE *log = NULL;
FILE *errlog = NULL;
! int errused = FALSE;
int tty_input = FALSE;
--- 89,95 ----
FILE *log = NULL;
+ char *logfile = NULL;
FILE *errlog = NULL;
! char *errlogfile = NULL;
int tty_input = FALSE;
***************
*** 260,275 ****
}
! #ifdef LOG
! /* If we're delivering and the log file exists, open it. */
! if (!dryrun && exists(LOG))
! log = fopen(LOG, "a");
#endif
! #ifdef ERRLOG
! /* If we're delivering and not being verbose, open the error log. */
! if (!dryrun && !verbose)
! errlog = fopen(ERRLOG, "a");
#endif
--- 266,289 ----
}
! #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
***************
*** 545,550 ****
--- 559,568 ----
int code;
{
+ /* Report vital statistics if something went wrong. */
+
errinfo();
+ /* Discard temporary files. */
+
if (! leavetemps)
{
***************
*** 560,565 ****
}
! errend();
exit(code);
}
--- 578,597 ----
}
! /* Save temporary logs by appending to real logfiles. */
+ 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." */
+
exit(code);
}
***************
*** 624,628 ****
return;
! timestamp(log);
if (sender && *sender)
--- 656,660 ----
return;
! logstart(log);
if (sender && *sender)
***************
*** 639,643 ****
logstate("failed", ST_ERROR);
! (void) fflush(log);
}
--- 671,675 ----
logstate("failed", ST_ERROR);
! logdone(log);
}
***************
*** 700,703 ****
--- 732,833 ----
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);
}
Index: mbox.c
***************
*** 1,3 ****
! /* $Header: mbox.c,v 2.2 89/11/01 11:51:05 network Exp $
*
* Finally! Put the message in the specified mailbox(es).
--- 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).
***************
*** 4,7 ****
--- 4,12 ----
*
* $Log: mbox.c,v $
+ * Revision 2.3 90/02/06 11:56:42 chip
+ * Enforce MBX_MODE regardless of UMASK.
+ * Enforce ordered logging with a log lockfile.
+ * Revise log format.
+ *
* Revision 2.2 89/11/01 11:51:05 network
* Fix error code; unknown user is now reported correctly.
***************
*** 153,156 ****
--- 158,163 ----
while ((fd = open(mailbox, O_WRONLY)) == -1)
{
+ int um;
+
if (errno != ENOENT)
{
***************
*** 159,173 ****
}
#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;
--- 166,184 ----
}
+ um = umask(0); /* save old umask; set it to zero */
#ifdef O_CREAT
fd = open(mailbox, O_WRONLY|O_CREAT|O_EXCL, MBX_MODE);
#else
fd = creat(mailbox, MBX_MODE);
#endif
+ (void) umask(um); /* restore umask; ass_u_me errno unchanged */
+
if (fd == -1)
{
+ /* If the error is "file already there", try again. */
+ if (errno == EEXIST)
+ continue;
+
+ /* Something is very wrong... */
syserr("can't create %s", mailbox);
break;
Index: subs.c
***************
*** 1,3 ****
! /* $Header: subs.c,v 2.3 89/11/01 10:37:58 network Exp $
*
* Miscellaneous subroutines.
--- 1,3 ----
! /* $Header: subs.c,v 2.4 90/02/06 11:56:46 chip Exp $
*
* Miscellaneous subroutines.
***************
*** 4,7 ****
--- 4,12 ----
*
* $Log: subs.c,v $
+ * Revision 2.4 90/02/06 11:56:46 chip
+ * Enforce MBX_MODE regardless of UMASK.
+ * Enforce ordered logging with a log lockfile.
+ * Revise log format.
+ *
* Revision 2.3 89/11/01 10:37:58 network
* Add exists() function.
***************
*** 34,37 ****
--- 39,117 ----
return (stat(path, &st) == 0);
+ }
+
+ /*----------------------------------------------------------------------
+ * Return a pointer to a temporary filename, or NULL if error.
+ */
+
+ char *
+ tempfile()
+ {
+ static char template[] = "/tmp/dl.XXXXXX";
+ char *f;
+
+ f = zalloc(32);
+ (void) strcpy(f, template);
+ if (mktemp(f) == NULL)
+ {
+ error("can't create temporary file");
+ return NULL;
+ }
+ return f;
+ }
+
+ /*----------------------------------------------------------------------
+ * Create a file and return an fd, or complain if it doesn't work.
+ * The file is opened for read/write.
+ */
+
+ int
+ tcreate(name)
+ char *name;
+ {
+ 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;
+ }
+
+ /*----------------------------------------------------------------------
+ * Create a file and return a FILE *, or complain if it doesn't work.
+ * The file is opened for read/write.
+ */
+
+ FILE *
+ ftcreate(name)
+ char *name;
+ {
+ FILE *fp;
+ int fd;
+
+ if ((fd = tcreate(name)) == -1)
+ return NULL;
+
+ if ((fp = fdopen(fd, "r+")) == NULL)
+ (void) close(fd);
+
+ return fp;
}
Index: sysdep.c
***************
*** 1,3 ****
! /* $Header: sysdep.c,v 2.5 89/12/19 16:29:47 network Exp $
*
* Routines which are (or might well be) system-dependant.
--- 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.
***************
*** 6,9 ****
--- 6,14 ----
*
* $Log: sysdep.c,v $
+ * Revision 2.6 90/02/06 11:56:43 chip
+ * Enforce MBX_MODE regardless of UMASK.
+ * Enforce ordered logging with a log lockfile.
+ * Revise log format.
+ *
* Revision 2.5 89/12/19 16:29:47 network
* Make timezone handling portable to System V.
***************
*** 190,194 ****
/* If any errors have been logged, record the failed header. */
! if (errused)
errheader();
}
--- 195,199 ----
/* If any errors have been logged, record the failed header. */
! if (ftell(errlog) > 0)
errheader();
}
***************
*** 280,290 ****
errstart()
{
- /* For the sake of V7, manually seek to EOF. */
-
- (void) fseek(errlog, 0L, 2);
-
/* If we've already written a time stamp, don't do it again. */
! if (errused)
return;
--- 285,291 ----
errstart()
{
/* If we've already written a time stamp, don't do it again. */
! if (!errlog || ftell(errlog) > 0)
return;
***************
*** 291,295 ****
/* Write a time stamp and various useful info. */
! timestamp(errlog);
(void) fprintf(errlog, "process %d", getpid());
if (rec_parent > 0)
--- 292,296 ----
/* Write a time stamp and various useful info. */
! logstart(errlog);
(void) fprintf(errlog, "process %d", getpid());
if (rec_parent > 0)
***************
*** 296,303 ****
(void) fprintf(errlog, ", parent %d", rec_parent);
(void) fprintf(errlog, ": %s %s\n", progname, version);
-
- /* Remember that we've written the time stamp. */
-
- errused = TRUE;
}
--- 297,300 ----
***************
*** 306,314 ****
*/
! errend()
{
/* If we never wrote to the error log file, do nothing. */
! if (!errused)
return;
--- 303,311 ----
*/
! errdone()
{
/* If we never wrote to the error log file, do nothing. */
! if (!errlog || ftell(errlog) == 0)
return;
***************
*** 319,330 ****
(void) fprintf(errlog, ", parent %d", rec_parent);
(void) fprintf(errlog, ": exit\n");
! (void) fflush(errlog);
}
/*----------------------------------------------------------------------
! * Write a timestamp to the given file.
*/
! timestamp(fp)
FILE *fp;
{
--- 316,329 ----
(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;
{
***************
*** 342,346 ****
if (rec_level)
(void) fprintf(fp, "[%d]", rec_level);
! (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,
--- 341,347 ----
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,
***************
*** 352,355 ****
--- 353,368 ----
#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);
}
exit 0 # Just in case...
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.
More information about the Comp.sources.unix
mailing list