Apply by doing:
        cd /usr/src
        patch -p0 < 001_newsyslog.patch
	cd usr.bin/newsyslog
	make
	make install

Index: usr.bin/newsyslog/newsyslog.c
===================================================================
RCS file: /cvs/src/usr.bin/newsyslog/newsyslog.c,v
retrieving revision 1.21
retrieving revision 1.27
diff -u -r1.21 -r1.27
--- usr.bin/newsyslog/newsyslog.c	1999/10/13 17:24:23	1.21
+++ usr.bin/newsyslog/newsyslog.c	1999/11/07 05:31:53	1.27
@@ -1,4 +1,4 @@
-/*	$OpenBSD: newsyslog.c,v 1.21 1999/10/13 17:24:23 millert Exp $	*/
+/*	$OpenBSD: newsyslog.c,v 1.27 1999/11/07 05:31:53 millert Exp $	*/
 
 /*
  * Copyright (c) 1997, Jason Downs.  All rights reserved.
@@ -61,7 +61,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$OpenBSD: newsyslog.c,v 1.21 1999/10/13 17:24:23 millert Exp $";
+static char rcsid[] = "$OpenBSD: newsyslog.c,v 1.27 1999/11/07 05:31:53 millert Exp $";
 #endif /* not lint */
 
 #ifndef CONF
@@ -99,18 +99,17 @@
 #include <unistd.h>
 #include <err.h>
 
-#define kbytes(size)  (((size) + 1023) >> 10)
-
-#define CE_COMPACT	0x01		/* Compact the achived log files */
-#define CE_BINARY	0x02		/* Logfile is in binary, don't add */
+#define CE_ROTATED	0x01		/* Log file has been rotated */
+#define CE_COMPACT	0x02		/* Compact the achived log files */
+#define CE_BINARY	0x04		/* Logfile is in binary, don't add */
 					/* status messages */
-#define CE_MONITOR	0x04		/* Monitory for changes */
+#define CE_MONITOR	0x08		/* Monitory for changes */
 #define NONE -1
         
 struct conf_entry {
         char    *log;           /* Name of the log */
-        int     uid;            /* Owner of log */
-        int     gid;            /* Group of log */
+        uid_t   uid;            /* Owner of log */
+        gid_t   gid;            /* Group of log */
         int     numlogs;        /* Number of logs to keep */
         int     size;           /* Size cutoff to trigger trimming the log */
         int     hours;          /* Hours between log trimming */
@@ -121,8 +120,6 @@
         struct conf_entry       *next; /* Linked list pointer */
 };
 
-extern const char *__progname;
-
 int     verbose = 0;            /* Print out what's going on */
 int     needroot = 1;           /* Root privs are necessary */
 int     noaction = 0;           /* Don't do anything, just show it */
@@ -139,11 +136,11 @@
 void usage __P((void));
 struct conf_entry *parse_file __P((void));
 char *missing_field __P((char *, char *));
-void dotrim __P((char *, int, int, int, int, int, int));
+void dotrim __P((char *, int, int, int, uid_t, gid_t));
 int log_trim __P((char *));
 void compress_log __P((char *));
 int sizefile __P((char *));
-int age_old_log __P((char *, int *));
+int age_old_log __P((char *));
 char *sob __P((char *));
 char *son __P((char *));
 int isnumberstr __P((char *));
@@ -151,24 +148,44 @@
 FILE *openmail __P((void));
 void closemail __P((FILE *));
 void child_killer __P((int));
+void send_hup __P((char *));
 
-int main(argc, argv)
+int
+main(argc, argv)
         int argc;
         char **argv;
 {
         struct conf_entry *p, *q;
 	int status;
         
-        PRS(argc,argv);
+        PRS(argc, argv);
         if (needroot && getuid() && geteuid())
 		errx(1, "You must be root.");
         p = q = parse_file();
 	signal(SIGCHLD, child_killer);
+
+	/* Step 1, rotate all log files */
+        while (q) {
+                do_entry(q);
+                q = q->next;
+        }
+
+	/* Step 2, send a HUP to relevant processes */
+	/* XXX - should avoid HUP'ing the same process multiple times */
+	q = p;
+        while (q) {
+		if (q->flags & CE_ROTATED)
+			send_hup(q->pidfile);
+                q = q->next;
+        }
+
+	/* Step 3, compress the log.0 file if configured to do so and free */
         while (p) {
-                do_entry(p);
-                p=p->next;
+		if ((p->flags & CE_COMPACT) && (p->flags & CE_ROTATED))
+			compress_log(p->log);
+		q = p;
+                p = p->next;
                 free(q);
-                q=p;
         }
 
 	/* Wait for children to finish, then exit */
@@ -177,28 +194,18 @@
         exit(0);
 }
 
-void do_entry(ent)
+void
+do_entry(ent)
         struct conf_entry       *ent;
         
 {
-        int     size, modtime, pid;
-        char    line[BUFSIZ];
-        FILE    *f;
+	int	modtime, size;
 
-        /* First find the pid to HUP */
-        pid = -1;
-        if ((f = fopen(ent->pidfile,"r")) != NULL) {
-        	if (fgets(line,BUFSIZ,f))
-                	pid = atoi(line);
-		(void)fclose(f);
-	}
-        
 	if (verbose)
 		printf("%s <%d%s>: ", ent->log, ent->numlogs,
 			(ent->flags & CE_COMPACT) ? "Z" : "");
         size = sizefile(ent->log);
-	if (age_old_log(ent->log, &modtime) == -1)
-		modtime = 0;
+        modtime = age_old_log(ent->log);
         if (size < 0) {
                 if (verbose)
                         printf("does not exist.\n");
@@ -209,24 +216,52 @@
                         printf(" age (hr): %d [%d] ", modtime, ent->hours);
 		if (monitor && ent->flags & CE_MONITOR)
 			domonitor(ent->log, ent->whom);
-                if (!monitor && ((ent->size > 0) && (size >= ent->size)) ||
+                if (!monitor && (((ent->size > 0) && (size >= ent->size)) ||
                     ((ent->hours > 0) && ((modtime >= ent->hours)
-                                        || (modtime < 0)))) {
+                                        || (modtime < 0))))) {
                         if (verbose)
                                 printf("--> trimming log....\n");
 			if (noaction && !verbose)
 				printf("%s <%d%s>: ", ent->log, ent->numlogs,
 					(ent->flags & CE_COMPACT) ? "Z" : "");
                         dotrim(ent->log, ent->numlogs, ent->flags,
-                               ent->permissions, ent->uid, ent->gid, pid);
-                } else {
-                        if (verbose)
-                                printf("--> skipping\n");
-                }
+                               ent->permissions, ent->uid, ent->gid);
+			ent->flags |= CE_ROTATED;
+                } else if (verbose)
+			printf("--> skipping\n");
         }
 }
+
+/* Send a HUP to the pid specified by pidfile */
+void
+send_hup(pidfile)
+	char	*pidfile;
+{
+	FILE	*f;
+        char    line[BUFSIZ];
+	pid_t	pid = 0;
+
+        if ((f = fopen(pidfile, "r")) == NULL) {
+		warn("can't open %s", pidfile);
+		return;
+	}
+
+	if (fgets(line, sizeof(line), f))
+		pid = atoi(line);
+	(void)fclose(f);
+
+        if (noaction)
+                (void)printf("kill -HUP %d\n", pid);
+	else if (pid == 0)
+		warnx("empty pid file: %s", pidfile);
+	else if (pid < MIN_PID)
+		warnx("preposterous process number: %d", pid);
+	else if (kill(pid, SIGHUP))
+		warnx("warning - could not HUP daemon");
+}
 
-void PRS(argc, argv)
+void
+PRS(argc, argv)
         int argc;
         char **argv;
 {
@@ -238,7 +273,7 @@
         daytime[15] = '\0';
 
         /* Let's get our hostname */
-        (void) gethostname(hostname, sizeof(hostname));
+        (void)gethostname(hostname, sizeof(hostname));
 
 	/* Truncate domain */
 	p = strchr(hostname, '.');
@@ -246,7 +281,7 @@
 		*p = '\0';
 
         optind = 1;             /* Start options parsing */
-        while ((c = getopt(argc,argv,"nrvmf:t:")) != -1) {
+        while ((c = getopt(argc, argv, "nrvmf:t:")) != -1) {
                 switch (c) {
                 case 'n':
                         noaction++; /* This implies needroot as off */
@@ -269,34 +304,39 @@
         }
 }
 
-void usage()
+void
+usage()
 {
-	fprintf(stderr, "usage: %s [-nrvm] [-f config-file]\n", __progname);
+	extern const char *__progname;
+
+	(void)fprintf(stderr, "usage: %s [-nrvm] [-f config-file]\n",
+	    __progname);
 	exit(1);
 }
 
 /* Parse a configuration file and return a linked list of all the logs
  * to process
  */
-struct conf_entry *parse_file()
+struct conf_entry *
+parse_file()
 {
         FILE    *f;
         char    line[BUFSIZ], *parse, *q;
-        char    *errline, *group;
+        char    *errline, *group, *tmp;
         struct conf_entry *first = NULL;
         struct conf_entry *working;
         struct passwd *pass;
         struct group *grp;
 
-        if (strcmp(conf,"-"))
-                f = fopen(conf,"r");
-        else
+        if (strcmp(conf, "-") == 0)
                 f = stdin;
-        if (!f)
-		err(1, conf);
+	else {
+                if ((f = fopen(conf, "r")) == NULL)
+			err(1, "can't open %s", conf);
+	}
 
-        while (fgets(line,BUFSIZ,f)) {
-                if ((line[0]== '\n') || (line[0] == '#'))
+        while (fgets(line, sizeof(line), f)) {
+                if ((line[0] == '\n') || (line[0] == '#'))
                         continue;
                 errline = strdup(line);
 		if (errline == NULL)
@@ -313,58 +353,58 @@
                         working = working->next;
                 }
 
-                q = parse = missing_field(sob(line),errline);
+                q = parse = missing_field(sob(line), errline);
                 *(parse = son(line)) = '\0';
                 working->log = strdup(q);
 		if (working->log == NULL)
 			err(1, "strdup");
 
-                q = parse = missing_field(sob(++parse),errline);
+                q = parse = missing_field(sob(++parse), errline);
                 *(parse = son(parse)) = '\0';
-                if ((group = strchr(q, '.')) != NULL) {
-                    *group++ = '\0';
-                    if (*q) {
-                        if (!(isnumberstr(q))) {
-                            if ((pass = getpwnam(q)) == NULL)
-				errx(1, "Error in config file; unknown user: %s", q);
-                            working->uid = pass->pw_uid;
-                        } else
-                            working->uid = atoi(q);
-                    } else
-                        working->uid = NONE;
-                    
-                    q = group;
-                    if (*q) {
-                        if (!(isnumberstr(q))) {
-                            if ((grp = getgrnam(q)) == NULL)
-				errx(1, "Error in config file; unknown group: %s", q);
-                            working->gid = grp->gr_gid;
-                        } else
-                            working->gid = atoi(q);
-                    } else
-                        working->gid = NONE;
-                    
-                    q = parse = missing_field(sob(++parse),errline);
-                    *(parse = son(parse)) = '\0';
-                } else 
-                    working->uid = working->gid = NONE;
+		if ((group = strchr(q, '.')) != NULL) {
+			*group++ = '\0';
+			if (*q) {
+				if (!(isnumberstr(q))) {
+					if ((pass = getpwnam(q)) == NULL)
+						errx(1, "Error in config file; unknown user: %s", q);
+					working->uid = pass->pw_uid;
+				} else
+					working->uid = atoi(q);
+			} else
+				working->uid = NONE;
+			
+			q = group;
+			if (*q) {
+				if (!(isnumberstr(q))) {
+					if ((grp = getgrnam(q)) == NULL)
+						errx(1, "Error in config file; unknown group: %s", q);
+					working->gid = grp->gr_gid;
+				} else
+					working->gid = atoi(q);
+			} else
+				working->gid = NONE;
+			
+			q = parse = missing_field(sob(++parse), errline);
+			*(parse = son(parse)) = '\0';
+		} else 
+			working->uid = working->gid = NONE;
 
-                if (!sscanf(q,"%o",&working->permissions))
+                if (!sscanf(q, "%o", &working->permissions))
 			errx(1, "Error in config file; bad permissions: %s", q);
 
-                q = parse = missing_field(sob(++parse),errline);
+                q = parse = missing_field(sob(++parse), errline);
                 *(parse = son(parse)) = '\0';
-                if (!sscanf(q,"%d",&working->numlogs) || working->numlogs < 0)
+                if (!sscanf(q, "%d", &working->numlogs) || working->numlogs < 0)
 			errx(1, "Error in config file; bad number: %s", q);
 
-                q = parse = missing_field(sob(++parse),errline);
+                q = parse = missing_field(sob(++parse), errline);
                 *(parse = son(parse)) = '\0';
                 if (isdigit(*q))
                         working->size = atoi(q);
                 else
                         working->size = -1;
                 
-                q = parse = missing_field(sob(++parse),errline);
+                q = parse = missing_field(sob(++parse), errline);
                 *(parse = son(parse)) = '\0';
                 if (isdigit(*q))
                         working->hours = atoi(q);
@@ -400,21 +440,31 @@
                 q = parse = sob(++parse); /* Optional field */
                 *(parse = son(parse)) = '\0';
 		if (q && *q != '\0') {
+			if (strlen(q) >= MAXPATHLEN)
+				errx(1, "%s: pathname too long", q);
 			working->pidfile = strdup(q);
 			if (working->pidfile == NULL)
 				err(1, "strdup");
 		}
+
+		/* Make sure we can't oflow MAXPATHLEN */
+		if (asprintf(&tmp, "%s.%d%s", working->log, working->numlogs,
+		    COMPRESS_POSTFIX) >= MAXPATHLEN)
+			errx(1, "%s: pathname too long", working->log);
                 
+                free(tmp);
                 free(errline);
         }
         if (working)
                 working->next = NULL;
-        (void) fclose(f);
+        (void)fclose(f);
         return(first);
 }
 
-char *missing_field(p, errline)
-        char    *p,*errline;
+char *
+missing_field(p, errline)
+        char    *p;
+	char    *errline;
 {
         if (!p || !*p) {
 		warnx("Missing field in config file line:");
@@ -424,164 +474,170 @@
         return(p);
 }
 
-void dotrim(log, numdays, flags, perm, owner_uid, group_gid, daemon_pid)
+void
+dotrim(log, numdays, flags, perm, owner_uid, group_gid)
         char    *log;
         int     numdays;
         int     flags;
         int     perm;
-        int     owner_uid;
-        int     group_gid;
-	int	daemon_pid;
+        uid_t   owner_uid;
+        gid_t   group_gid;
 {
         char    file1[MAXPATHLEN], file2[MAXPATHLEN];
         char    zfile1[MAXPATHLEN], zfile2[MAXPATHLEN];
         int     fd;
         struct  stat st;
 	int	days = numdays;
-
-        /* Remove oldest log */
-        (void) sprintf(file1,"%s.%d",log,numdays);
-        (void) strcpy(zfile1, file1);
-        (void) strcat(zfile1, COMPRESS_POSTFIX);
 
+        /* Remove oldest log (may not exist) */
+        (void)sprintf(file1, "%s.%d", log, numdays);
+        (void)strcpy(zfile1, file1);
+        (void)strcat(zfile1, COMPRESS_POSTFIX);
         if (noaction) {
-                printf("rm -f %s\n", file1);
-                printf("rm -f %s\n", zfile1);
+                printf("rm -f %s %s\n", file1, zfile1);
         } else {
-                (void) unlink(file1);
-                (void) unlink(zfile1);
+                (void)unlink(file1);
+                (void)unlink(zfile1);
         }
 
         /* Move down log files */
         while (numdays--) {
-                (void) strcpy(file2,file1);
-                (void) sprintf(file1,"%s.%d",log,numdays);
-                (void) strcpy(zfile1, file1);
-                (void) strcpy(zfile2, file2);
+                (void)strcpy(file2, file1);
+                (void)sprintf(file1, "%s.%d", log, numdays);
+                (void)strcpy(zfile1, file1);
+                (void)strcpy(zfile2, file2);
                 if (lstat(file1, &st)) {
-                        (void) strcat(zfile1, COMPRESS_POSTFIX);
-                        (void) strcat(zfile2, COMPRESS_POSTFIX);
-                        if (lstat(zfile1, &st)) continue;
+                        (void)strcat(zfile1, COMPRESS_POSTFIX);
+                        (void)strcat(zfile2, COMPRESS_POSTFIX);
+                        if (lstat(zfile1, &st))
+                        	continue;
                 }
                 if (noaction) {
-                        printf("mv %s %s\n",zfile1,zfile2);
+                        printf("mv %s %s\n", zfile1, zfile2);
                         printf("chmod %o %s\n", perm, zfile2);
-                        printf("chown %d.%d %s\n",
+                        printf("chown %d:%d %s\n",
                                owner_uid, group_gid, zfile2);
                 } else {
-                        (void) rename(zfile1, zfile2);
-                        (void) chmod(zfile2, perm);
-                        (void) chown(zfile2, owner_uid, group_gid);
+                        if (rename(zfile1, zfile2))
+				warn("can't mv %s to %s", zfile1, zfile2);
+                        if (chmod(zfile2, perm))
+				warn("can't chmod %s", zfile2);
+                        if (chown(zfile2, owner_uid, group_gid))
+				warn("can't chown %s", zfile2);
                 }
         }
         if (!noaction && !(flags & CE_BINARY))
-                (void) log_trim(log);  /* Report the trimming to the old log */
+                (void)log_trim(log);  /* Report the trimming to the old log */
 
+	(void)snprintf(file2, sizeof(file2), "%s.XXXXXXXXXX", log);
+        if (noaction)  {
+                printf("Create new log file...\n");
+        } else {
+                if ((fd = mkstemp(file2)) < 0)
+			err(1, "can't start '%s' log", file2);
+                if (fchown(fd, owner_uid, group_gid))
+			err(1, "can't chown '%s' log file", file2);
+                if (fchmod(fd, perm))
+			err(1, "can't chmod '%s' log file", file2);
+                (void)close(fd);
+		/* Add status message */
+                if (!(flags & CE_BINARY) && log_trim(file2))
+			err(1, "can't add status message to log '%s'", file2);
+        }
+
 	if (days == 0) {
 		if (noaction)
-			printf("rm %s\n",log);
-		else
-			(void) unlink(log);
+			printf("rm %s\n", log);
+		else if (unlink(log))
+			warn("can't rm %s", log);
 	} else {
 		if (noaction) 
-	                printf("mv %s to %s\n",log,file1);
-	        else
-	                (void) rename(log,file1);
+	                printf("mv %s to %s\n", log, file1);
+	        else if (rename(log, file1))
+			warn("can't to mv %s to %s", log, file1);
 	}
 
-        if (noaction) 
-                printf("Start new log...");
-        else {
-                fd = creat(log,perm);
-                if (fd < 0)
-			err(1, "can't start \'%s\' log", log);
-                if (fchown(fd, owner_uid, group_gid))
-			err(1, "can't chown \'%s\' log file", log);
-                (void) close(fd);
-                if (!(flags & CE_BINARY))
-                        if (log_trim(log))	/* Add status message */
-                                err(1, "can't add status message to log \'%s\'", log);
-        }
-        if (noaction)
-                printf("chmod %o %s...",perm,log);
-        else
-                (void) chmod(log,perm);
-        if (noaction)
-                printf("kill -HUP %d\n",daemon_pid);
-        else if (daemon_pid < MIN_PID)
-		warnx("preposterous process number: %d", daemon_pid);
-        else if (kill(daemon_pid,SIGHUP))
-		warnx("warning - could not HUP daemon");
-	if (flags & CE_COMPACT) {
-		if (noaction)
-			printf("Compress %s.0\n",log);
-		else
-			compress_log(log);
-	}
+	/* Now move the new log file into place */
+	if (noaction)
+		printf("mv %s to %s\n", file2, log);
+	else if (rename(file2, log))
+		warn("can't to mv %s to %s", file2, log);
 }
 
 /* Log the fact that the logs were turned over */
-int log_trim(log)
+int
+log_trim(log)
 	char    *log;
 {
         FILE    *f;
-        if ((f = fopen(log,"a")) == NULL)
+
+        if ((f = fopen(log, "a")) == NULL)
                 return(-1);
-        fprintf(f,"%s %s newsyslog[%d]: logfile turned over\n",
-                daytime, hostname, getpid());
-        if (fclose(f) == EOF) {
+        (void)fprintf(f, "%s %s newsyslog[%d]: logfile turned over\n",
+	    daytime, hostname, getpid());
+        if (fclose(f) == EOF)
                 err(1, "log_trim: fclose");
-        }
         return(0);
 }
 
 /* Fork off compress or gzip to compress the old log file */
-void compress_log(log)
+void
+compress_log(log)
         char    *log;
 {
-        int     pid;
+        pid_t   pid;
+	char	*base;
         char    tmp[MAXPATHLEN];
         
+	if ((base = strrchr(COMPRESS, '/')) == NULL)
+		base = COMPRESS;
+	else
+		base++;
+	if (noaction) {
+		printf("%s %s.0\n", base, log);
+		return;
+	}
         pid = fork();
-        (void) sprintf(tmp,"%s.0",log);
+        (void)sprintf(tmp, "%s.0", log);
         if (pid < 0) {
 		err(1, "fork");
         } else if (!pid) {
-                (void) execl(COMPRESS,"compress","-f",tmp,0);
+                (void)execl(COMPRESS, base, "-f", tmp, 0);
 		warn(COMPRESS);
 		_exit(1);
         }
 }
 
 /* Return size in kilobytes of a file */
-int sizefile(file)
+int
+sizefile(file)
         char    *file;
 {
         struct stat sb;
 
-        if (stat(file,&sb) < 0)
+        if (stat(file, &sb) < 0)
                 return(-1);
-        return(kbytes(dbtob(sb.st_blocks)));
+        return(sb.st_blocks / (1024.0 / DEV_BSIZE));
 }
 
-/* Return the age of old log file (file.0) */
-int age_old_log(file, mtime)
+/* Return the age (in hours) of old log file (file.0), or -1 if none */
+int
+age_old_log(file)
         char    *file;
-	int	*mtime;
 {
         struct stat sb;
         char tmp[MAXPATHLEN];
 
-        (void) strcpy(tmp,file);
-        if (stat(strcat(tmp,".0"),&sb) < 0)
-            if (stat(strcat(tmp,COMPRESS_POSTFIX), &sb) < 0)
+        (void)strcpy(tmp, file);
+        if (stat(strcat(tmp, ".0"), &sb) < 0)
+            if (stat(strcat(tmp, COMPRESS_POSTFIX), &sb) < 0)
                 return(-1);
-	*mtime = (int) (timenow - sb.st_mtime + 1800) / 3600;
-	return(0);
+        return( (int) (timenow - sb.st_mtime + 1800) / 3600);
 }
 
 /* Skip Over Blanks */
-char *sob(p)
+char *
+sob(p)
         register char   *p;
 {
         while (p && *p && isspace(*p))
@@ -590,7 +646,8 @@
 }
 
 /* Skip Over Non-Blanks */
-char *son(p)
+char *
+son(p)
         register char   *p;
 {
         while (p && *p && !isspace(*p))
@@ -598,20 +655,20 @@
         return(p);
 }
 
-        
 /* Check if string is actually a number */
-
-int isnumberstr(string)
+int
+isnumberstr(string)
 	char *string;
 {
-        while (*string != '\0') {
+        while (*string) {
             if (!isdigit(*string++))
 		return(0);
         }
         return(1);
 }
 
-void domonitor(log, whom)
+void
+domonitor(log, whom)
 	char *log, *whom;
 {
 	struct stat sb, tsb;
@@ -717,7 +774,8 @@
 		free(rb);
 }
 
-FILE *openmail()
+FILE *
+openmail()
 {
 	char *cmdbuf;
 	FILE *ret;
@@ -733,13 +791,15 @@
 	return(ret);
 }
 
-void closemail(pfp)
+void
+closemail(pfp)
 	FILE *pfp;
 {
 	pclose(pfp);
 }
 
-void child_killer(signum)
+void
+child_killer(signum)
 	int signum;
 {
 	int status;
