=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/newsyslog/newsyslog.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- src/usr.bin/newsyslog/newsyslog.c 2000/06/30 16:00:19 1.34 +++ src/usr.bin/newsyslog/newsyslog.c 2001/01/12 16:24:06 1.35 @@ -1,4 +1,4 @@ -/* $OpenBSD: newsyslog.c,v 1.34 2000/06/30 16:00:19 millert Exp $ */ +/* $OpenBSD: newsyslog.c,v 1.35 2001/01/12 16:24:06 deraadt Exp $ */ /* * Copyright (c) 1999 Todd C. Miller @@ -88,7 +88,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: newsyslog.c,v 1.34 2000/06/30 16:00:19 millert Exp $"; +static char rcsid[] = "$OpenBSD: newsyslog.c,v 1.35 2001/01/12 16:24:06 deraadt Exp $"; #endif /* not lint */ #ifndef CONF @@ -132,21 +132,21 @@ /* status messages */ #define CE_MONITOR 0x08 /* Monitory for changes */ #define NONE -1 - + struct conf_entry { - char *log; /* Name of the 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 */ - int permissions; /* File permissions on the log */ + char *log; /* Name of the 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 */ + int permissions; /* File permissions on the log */ int signal; /* Signal to send (defaults to SIGHUP) */ - int flags; /* Flags (CE_COMPACT & CE_BINARY) */ + int flags; /* Flags (CE_COMPACT & CE_BINARY) */ char *whom; /* Whom to notify if logfile changes */ char *pidfile; /* Path to file containg pid to signal */ char *runcmd; /* Command to run instead of sending a signal */ - struct conf_entry *next; /* Linked list pointer */ + struct conf_entry *next; /* Linked list pointer */ }; struct pidinfo { @@ -154,15 +154,15 @@ int signal; }; -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 */ +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 */ int monitormode = 0; /* Don't do monitoring by default */ -char *conf = CONF; /* Configuration file to use */ +char *conf = CONF; /* Configuration file to use */ time_t timenow; #define MIN_PID 4 char hostname[MAXHOSTNAMELEN]; /* hostname */ -char *daytime; /* timenow in human readable form */ +char *daytime; /* timenow in human readable form */ void do_entry __P((struct conf_entry *)); @@ -187,17 +187,17 @@ int main(argc, argv) - int argc; - char **argv; + int argc; + char **argv; { - struct conf_entry *p, *q; + struct conf_entry *p, *q; struct pidinfo *pidlist, *pl; int status, listlen; - - PRS(argc, argv); - if (needroot && getuid() && geteuid()) + + PRS(argc, argv); + if (needroot && getuid() && geteuid()) errx(1, "You must be root."); - p = q = parse_file(&listlen); + p = q = parse_file(&listlen); signal(SIGCHLD, child_killer); pidlist = (struct pidinfo *)calloc(sizeof(struct pidinfo), listlen + 1); @@ -205,10 +205,10 @@ err(1, "calloc"); /* Step 1, rotate all log files */ - while (q) { - do_entry(q); - q = q->next; - } + while (q) { + do_entry(q); + q = q->next; + } /* Step 2, make a list of unique pid files */ for (q = p, pl = pidlist; q; ) { @@ -232,8 +232,8 @@ pl++; } } - q = q->next; - } + q = q->next; + } /* Step 3, send a signal or run a command */ for (pl = pidlist; pl->file; pl++) { @@ -246,56 +246,56 @@ sleep(5); /* Step 4, compress the log.0 file if configured to do so and free */ - while (p) { + while (p) { if ((p->flags & CE_COMPACT) && (p->flags & CE_ROTATED)) compress_log(p->log); q = p; - p = p->next; - free(q); - } + p = p->next; + free(q); + } /* Wait for children to finish, then exit */ while (waitpid(-1, &status, 0) != -1) ; - exit(0); + exit(0); } void do_entry(ent) - struct conf_entry *ent; - + struct conf_entry *ent; + { int modtime, size; if (verbose) printf("%s <%d%s>: ", ent->log, ent->numlogs, (ent->flags & CE_COMPACT) ? "Z" : ""); - size = sizefile(ent->log); - modtime = age_old_log(ent->log); - if (size < 0) { - if (verbose) - printf("does not exist.\n"); - } else { - if (verbose && (ent->size > 0)) - printf("size (Kb): %d [%d] ", size, ent->size); - if (verbose && (ent->hours > 0)) - printf(" age (hr): %d [%d] ", modtime, ent->hours); + size = sizefile(ent->log); + modtime = age_old_log(ent->log); + if (size < 0) { + if (verbose) + printf("does not exist.\n"); + } else { + if (verbose && (ent->size > 0)) + printf("size (Kb): %d [%d] ", size, ent->size); + if (verbose && (ent->hours > 0)) + printf(" age (hr): %d [%d] ", modtime, ent->hours); if (monitormode && ent->flags & CE_MONITOR) domonitor(ent->log, ent->whom); - if (!monitormode && (((ent->size > 0) && (size >= ent->size)) || - ((ent->hours > 0) && ((modtime >= ent->hours) - || (modtime < 0))))) { - if (verbose) - printf("--> trimming log....\n"); + if (!monitormode && (((ent->size > 0) && (size >= ent->size)) || + ((ent->hours > 0) && ((modtime >= ent->hours) + || (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); + dotrim(ent->log, ent->numlogs, ent->flags, + ent->permissions, ent->uid, ent->gid); ent->flags |= CE_ROTATED; - } else if (verbose) + } else if (verbose) printf("--> skipping\n"); - } + } } /* Run the specified command */ @@ -317,10 +317,10 @@ int signal; { FILE *f; - char line[BUFSIZ]; + char line[BUFSIZ]; pid_t pid = 0; - if ((f = fopen(pidfile, "r")) == NULL) { + if ((f = fopen(pidfile, "r")) == NULL) { warn("can't open %s", pidfile); return; } @@ -329,8 +329,8 @@ pid = atoi(line); (void)fclose(f); - if (noaction) - (void)printf("kill -%s %d\n", sys_signame[signal], pid); + if (noaction) + (void)printf("kill -%s %d\n", sys_signame[signal], pid); else if (pid == 0) warnx("empty pid file: %s", pidfile); else if (pid < MIN_PID) @@ -342,46 +342,46 @@ void PRS(argc, argv) - int argc; - char **argv; + int argc; + char **argv; { - int c; + int c; char *p; - timenow = time(NULL); - daytime = ctime(&timenow) + 4; - daytime[15] = '\0'; + timenow = time(NULL); + daytime = ctime(&timenow) + 4; + daytime[15] = '\0'; - /* Let's get our hostname */ - (void)gethostname(hostname, sizeof(hostname)); + /* Let's get our hostname */ + (void)gethostname(hostname, sizeof(hostname)); /* Truncate domain */ p = strchr(hostname, '.'); if (p) *p = '\0'; - optind = 1; /* Start options parsing */ - while ((c = getopt(argc, argv, "nrvmf:t:")) != -1) { - switch (c) { - case 'n': - noaction++; /* This implies needroot as off */ - /* fall through */ - case 'r': - needroot = 0; - break; - case 'v': - verbose++; - break; - case 'f': - conf = optarg; - break; + optind = 1; /* Start options parsing */ + while ((c = getopt(argc, argv, "nrvmf:t:")) != -1) { + switch (c) { + case 'n': + noaction++; /* This implies needroot as off */ + /* fall through */ + case 'r': + needroot = 0; + break; + case 'v': + verbose++; + break; + case 'f': + conf = optarg; + break; case 'm': monitormode++; break; - default: - usage(); - } - } + default: + usage(); + } + } } void @@ -401,49 +401,49 @@ parse_file(nentries) int *nentries; { - FILE *f; - char line[BUFSIZ], *parse, *q; - char *errline, *group, *tmp; - struct conf_entry *first = NULL; - struct conf_entry *working; - struct passwd *pass; - struct group *grp; + FILE *f; + char line[BUFSIZ], *parse, *q; + char *errline, *group, *tmp; + struct conf_entry *first = NULL; + struct conf_entry *working = NULL; + struct passwd *pass; + struct group *grp; - if (strcmp(conf, "-") == 0) - f = stdin; + if (strcmp(conf, "-") == 0) + f = stdin; else { - if ((f = fopen(conf, "r")) == NULL) + if ((f = fopen(conf, "r")) == NULL) err(1, "can't open %s", conf); } *nentries = 0; - while (fgets(line, sizeof(line), f)) { - if ((line[0] == '\n') || (line[0] == '#')) - continue; - errline = strdup(line); + while (fgets(line, sizeof(line), f)) { + if ((line[0] == '\n') || (line[0] == '#')) + continue; + errline = strdup(line); if (errline == NULL) err(1, "strdup"); (*nentries)++; - if (!first) { - working = (struct conf_entry *) malloc(sizeof(struct conf_entry)); + if (!first) { + working = (struct conf_entry *) malloc(sizeof(struct conf_entry)); if (working == NULL) err(1, "malloc"); - first = working; - } else { - working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry)); + first = working; + } else { + working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry)); if (working->next == NULL) err(1, "malloc"); - working = working->next; - } + working = working->next; + } - q = parse = missing_field(sob(line), errline); - *(parse = son(line)) = '\0'; - working->log = strdup(q); + 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); - *(parse = son(parse)) = '\0'; + q = parse = missing_field(sob(++parse), errline); + *(parse = son(parse)) = '\0'; if ((group = strchr(q, '.')) != NULL) { *group++ = '\0'; if (*q) { @@ -472,30 +472,30 @@ } 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); - *(parse = son(parse)) = '\0'; - if (!sscanf(q, "%d", &working->numlogs) || working->numlogs < 0) + q = parse = missing_field(sob(++parse), errline); + *(parse = son(parse)) = '\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); - *(parse = son(parse)) = '\0'; - if (isdigit(*q)) - working->size = atoi(q); - else - working->size = -1; - - q = parse = missing_field(sob(++parse), errline); - *(parse = son(parse)) = '\0'; - if (isdigit(*q)) - working->hours = atoi(q); - else - working->hours = -1; + 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); + *(parse = son(parse)) = '\0'; + if (isdigit(*q)) + working->hours = atoi(q); + else + working->hours = -1; - working->flags = 0; - q = sob(++parse); /* Optional field */ + working->flags = 0; + q = sob(++parse); /* Optional field */ if (*q == 'Z' || *q == 'z' || *q == 'B' || *q == 'b' || *q == 'M' || *q == 'm') { *(parse = son(q)) = '\0'; @@ -571,99 +571,101 @@ 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); - return(first); + + if (tmp) + free(tmp); + free(errline); + } + if (working) + working->next = NULL; + (void)fclose(f); + return(first); } char * missing_field(p, errline) - char *p; + char *p; char *errline; { - if (!p || !*p) { + if (!p || !*p) { warnx("Missing field in config file line:"); - fputs(errline, stderr); - exit(1); - } - return(p); + fputs(errline, stderr); + exit(1); + } + return(p); } void dotrim(log, numdays, flags, perm, owner_uid, group_gid) - char *log; - int numdays; - int flags; - int perm; - uid_t owner_uid; - gid_t group_gid; + char *log; + int numdays; + int flags; + int perm; + uid_t owner_uid; + gid_t group_gid; { - char file1[MAXPATHLEN], file2[MAXPATHLEN]; - char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN]; - int fd; - struct stat st; + char file1[MAXPATHLEN], file2[MAXPATHLEN]; + char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN]; + int fd; + struct stat st; int days = numdays; - /* 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 %s\n", file1, zfile1); - } else { - (void)unlink(file1); - (void)unlink(zfile1); - } + /* Remove oldest log (may not exist) */ + (void)snprintf(file1, sizeof file1, "%s.%d", log, numdays); + (void)snprintf(zfile1, sizeof zfile1, "%s.%d%s", log, numdays, + COMPRESS_POSTFIX); - /* 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); - if (lstat(file1, &st)) { - (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("chmod %o %s\n", perm, zfile2); - printf("chown %d:%d %s\n", - owner_uid, group_gid, zfile2); - } else { - if (rename(zfile1, zfile2)) + if (noaction) { + printf("rm -f %s %s\n", file1, zfile1); + } else { + (void)unlink(file1); + (void)unlink(zfile1); + } + + /* Move down log files */ + while (numdays--) { + (void)strlcpy(file2, file1, sizeof file2); + (void)snprintf(file1, sizeof file1, "%s.%d", log, numdays); + (void)strlcpy(zfile1, file1, sizeof zfile1); + (void)strlcpy(zfile2, file2, sizeof zfile2); + if (lstat(file1, &st)) { + (void)strlcat(zfile1, COMPRESS_POSTFIX, sizeof zfile1); + (void)strlcat(zfile2, COMPRESS_POSTFIX, sizeof zfile2); + if (lstat(zfile1, &st)) + continue; + } + if (noaction) { + printf("mv %s %s\n", zfile1, zfile2); + printf("chmod %o %s\n", perm, zfile2); + printf("chown %d:%d %s\n", + owner_uid, group_gid, zfile2); + } else { + if (rename(zfile1, zfile2)) warn("can't mv %s to %s", zfile1, zfile2); - if (chmod(zfile2, perm)) + if (chmod(zfile2, perm)) warn("can't chmod %s", zfile2); - if (chown(zfile2, owner_uid, group_gid)) + 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 */ + } + } + if (!noaction && !(flags & CE_BINARY)) + (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) + 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)) + if (fchown(fd, owner_uid, group_gid)) err(1, "can't chown '%s' log file", file2); - if (fchmod(fd, perm)) + if (fchmod(fd, perm)) err(1, "can't chmod '%s' log file", file2); - (void)close(fd); + (void)close(fd); /* Add status message */ - if (!(flags & CE_BINARY) && log_trim(file2)) + if (!(flags & CE_BINARY) && log_trim(file2)) err(1, "can't add status message to log '%s'", file2); - } + } if (days == 0) { if (noaction) @@ -672,8 +674,8 @@ warn("can't rm %s", log); } else { if (noaction) - printf("mv %s to %s\n", log, file1); - else if (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); } @@ -689,26 +691,26 @@ log_trim(log) char *log; { - FILE *f; + FILE *f; - if ((f = fopen(log, "a")) == NULL) - return(-1); - (void)fprintf(f, "%s %s newsyslog[%d]: logfile turned over\n", + if ((f = fopen(log, "a")) == NULL) + return(-1); + (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); + 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) - char *log; + char *log; { - pid_t pid; + pid_t pid; char *base; - char tmp[MAXPATHLEN]; - + char tmp[MAXPATHLEN]; + if ((base = strrchr(COMPRESS, '/')) == NULL) base = COMPRESS; else @@ -717,62 +719,65 @@ printf("%s %s.0\n", base, log); return; } - pid = fork(); - (void)sprintf(tmp, "%s.0", log); - if (pid < 0) { + pid = fork(); + (void)snprintf(tmp, sizeof tmp, "%s.0", log); + if (pid < 0) { err(1, "fork"); - } else if (!pid) { - (void)execl(COMPRESS, base, "-f", tmp, 0); + } else if (!pid) { + (void)execl(COMPRESS, base, "-f", tmp, 0); warn(COMPRESS); _exit(1); - } + } } /* Return size in kilobytes of a file */ int sizefile(file) - char *file; + char *file; { - struct stat sb; + struct stat sb; - if (stat(file, &sb) < 0) - return(-1); - return(sb.st_blocks / (1024.0 / DEV_BSIZE)); + if (stat(file, &sb) < 0) + return(-1); + return(sb.st_blocks / (1024.0 / DEV_BSIZE)); } /* Return the age (in hours) of old log file (file.0), or -1 if none */ int age_old_log(file) - char *file; + char *file; { - struct stat sb; - char tmp[MAXPATHLEN]; + 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) - return(-1); - return( (int) (timenow - sb.st_mtime + 1800) / 3600); + (void)strlcpy(tmp, file, sizeof tmp); + strlcat(tmp, ".0", sizeof tmp); + if (stat(tmp, &sb) < 0) { + strlcat(tmp, COMPRESS_POSTFIX, sizeof tmp); + if (stat(tmp, &sb) < 0) + return(-1); + } + return( (int) (timenow - sb.st_mtime + 1800) / 3600); } /* Skip Over Blanks */ char * sob(p) - register char *p; + register char *p; { - while (p && *p && isspace(*p)) - p++; - return(p); + while (p && *p && isspace(*p)) + p++; + return(p); } /* Skip Over Non-Blanks */ char * son(p) - register char *p; + register char *p; { - while (p && *p && !isspace(*p)) - p++; - return(p); + while (p && *p && !isspace(*p)) + p++; + return(p); } /* Check if string is actually a number */ @@ -780,11 +785,11 @@ isnumberstr(string) char *string; { - while (*string) { - if (!isdigit(*string++)) - return(0); - } - return(1); + while (*string) { + if (!isdigit(*string++)) + return(0); + } + return(1); } void @@ -792,7 +797,7 @@ char *log, *whom; { struct stat sb, tsb; - char *fname, *flog, *p, *rb = NULL; + char fname[MAXPATHLEN], *flog, *p, *rb = NULL; FILE *fp; off_t osize; int rd; @@ -808,12 +813,9 @@ if (*p == '/') *p = '_'; } - fname = (char *) malloc(sizeof(STATS_DIR) + strlen(flog) + 16); - if (fname == NULL) - err(1, "malloc"); + snprintf(fname, sizeof fname, "%s/newsyslog.%s.size", + STATS_DIR, flog); - sprintf(fname, "%s/newsyslog.%s.size", STATS_DIR, flog); - /* ..if it doesn't exist, simply record the current size. */ if ((sb.st_size == 0) || stat(fname, &tsb) < 0) goto update; @@ -889,7 +891,6 @@ cleanup: free(flog); - free(fname); if (rb != NULL) free(rb); } @@ -897,18 +898,16 @@ FILE * openmail() { - char *cmdbuf; + char *cmdbuf = NULL; FILE *ret; - cmdbuf = (char *) malloc(sizeof(SENDMAIL) + 3); - if (cmdbuf == NULL) - return(NULL); - - sprintf(cmdbuf, "%s -t", SENDMAIL); - ret = popen(cmdbuf, "w"); - - free(cmdbuf); - return(ret); + asprintf(&cmdbuf, "%s -t", SENDMAIL); + if (cmdbuf) { + ret = popen(cmdbuf, "w"); + free(cmdbuf); + return (ret); + } + return (NULL); } void