diff options
author | gad <gad@FreeBSD.org> | 2004-06-07 01:21:30 +0000 |
---|---|---|
committer | gad <gad@FreeBSD.org> | 2004-06-07 01:21:30 +0000 |
commit | 3e7bce2995cac67f35775e81b4f6bd217fa587e6 (patch) | |
tree | f492174d9ed3e971e21b2e40d03f28c6fa8e8e6b /usr.sbin | |
parent | 4c3fd8116d1815c5e18c8569e354a99c8c7ce1c8 (diff) | |
download | FreeBSD-src-3e7bce2995cac67f35775e81b4f6bd217fa587e6.zip FreeBSD-src-3e7bce2995cac67f35775e81b4f6bd217fa587e6.tar.gz |
A variety of minor changes. Allow users to set a debugging option via
the newsyslog.conf file. Rename one size-related variable, and move
another one from the stack into conf_entry. Add a routine to change
file-attributes (chown, chmod, chflags), instead of having several
places doing the same sequence of system-calls. A few cosmetic/style
changes.
These should not effect any users. Most of these probably look
pointless, but they are the "insignificant parts" of a much larger
update that I'll be committing soon. Doing these as a separate update
should make that update easier to read.
MFC after: 14 days
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/newsyslog/newsyslog.c | 187 |
1 files changed, 120 insertions, 67 deletions
diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c index 7b01b39..3b5a14b 100644 --- a/usr.sbin/newsyslog/newsyslog.c +++ b/usr.sbin/newsyslog/newsyslog.c @@ -80,16 +80,20 @@ __FBSDID("$FreeBSD$"); #define kbytes(size) (((size) + 1023) >> 10) +#define DEFAULT_MARKER "<default>" +#define DEBUG_MARKER "<debug>" + struct conf_entry { char *log; /* Name of the log */ char *pid_file; /* PID file */ char *r_reason; /* The reason this file is being rotated */ int firstcreate; /* Creating log for the first time (-C). */ int rotate; /* Non-zero if this file should be rotated */ + int fsize; /* size found for the log file */ 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 trsize; /* Size cutoff to trigger trimming the log */ int hours; /* Hours between log trimming */ struct ptime_data *trim_at; /* Specific time to do trimming */ int permissions; /* File permissions on the log */ @@ -99,9 +103,12 @@ struct conf_entry { struct conf_entry *next;/* Linked list pointer */ }; -#define DEFAULT_MARKER "<default>" +typedef enum { + FREE_ENT, KEEP_ENT +} fk_entry; int dbg_at_times; /* -D Show details of 'trim_at' code */ +int dbg_new_order; /* -D Try the 'neworder' of doing the work */ int archtodir = 0; /* Archive old logfiles to other directory */ int createlogs; /* Create (non-GLOB) logfiles which do not */ @@ -134,7 +141,10 @@ static char *sob(char *p); static char *son(char *p); static int isnumberstr(const char *); static char *missing_field(char *p, char *errline); -static void do_entry(struct conf_entry * ent); +static void change_attrs(const char *, const struct conf_entry *); +static fk_entry do_entry(struct conf_entry *); +static fk_entry do_rotate(const struct conf_entry *); +static int sizefile(const char *); static void expand_globs(struct conf_entry **work_p, struct conf_entry **glob_p); static void free_clist(struct conf_entry **firstent); @@ -144,11 +154,9 @@ static struct conf_entry *init_entry(const char *fname, static void parse_args(int argc, char **argv); static int parse_doption(const char *doption); static void usage(void); -static void dotrim(const struct conf_entry *ent); static int log_trim(const char *logname, const struct conf_entry *log_ent); static void compress_log(char *logname, int dowait); static void bzcompress_log(char *logname, int dowait); -static int sizefile(char *file); static int age_old_log(char *file); static int send_signal(const struct conf_entry *ent); static void savelog(char *from, char *to); @@ -168,6 +176,7 @@ static void createlog(const struct conf_entry *ent); int main(int argc, char **argv) { + fk_entry free_or_keep; struct conf_entry *p, *q; parse_args(argc, argv); @@ -178,12 +187,18 @@ main(int argc, char **argv) errx(1, "must have root privs"); p = q = get_worklist(argv); + /* + * Rotate all the files which need to be rotated. Note that + * some users have *hundreds* of entries in newsyslog.conf! + */ while (p) { - do_entry(p); + free_or_keep = do_entry(p); p = p->next; - free_entry(q); + if (free_or_keep == FREE_ENT) + free_entry(q); q = p; } + while (wait(NULL) > 0 || errno == EINTR) ; return (0); @@ -212,10 +227,11 @@ init_entry(const char *fname, struct conf_entry *src_entry) tempwork->r_reason = NULL; tempwork->firstcreate = 0; tempwork->rotate = 0; + tempwork->fsize = -1; tempwork->uid = src_entry->uid; tempwork->gid = src_entry->gid; tempwork->numlogs = src_entry->numlogs; - tempwork->size = src_entry->size; + tempwork->trsize = src_entry->trsize; tempwork->hours = src_entry->hours; tempwork->trim_at = NULL; if (src_entry->trim_at != NULL) @@ -230,10 +246,11 @@ init_entry(const char *fname, struct conf_entry *src_entry) tempwork->r_reason = NULL; tempwork->firstcreate = 0; tempwork->rotate = 0; + tempwork->fsize = -1; tempwork->uid = (uid_t)-1; tempwork->gid = (gid_t)-1; tempwork->numlogs = 1; - tempwork->size = -1; + tempwork->trsize = -1; tempwork->hours = -1; tempwork->trim_at = NULL; tempwork->permissions = 0; @@ -296,14 +313,16 @@ free_clist(struct conf_entry **firstent) } } -static void +static fk_entry do_entry(struct conf_entry * ent) { #define REASON_MAX 80 - int size, modtime; + int modtime; + fk_entry free_or_keep; double diffsecs; char temp_reason[REASON_MAX]; + free_or_keep = FREE_ENT; if (verbose) { if (ent->flags & CE_COMPACT) printf("%s <%dZ>: ", ent->log, ent->numlogs); @@ -312,11 +331,11 @@ do_entry(struct conf_entry * ent) else printf("%s <%d>: ", ent->log, ent->numlogs); } - size = sizefile(ent->log); + ent->fsize = sizefile(ent->log); modtime = age_old_log(ent->log); ent->rotate = 0; ent->firstcreate = 0; - if (size < 0) { + if (ent->fsize < 0) { /* * If either the C flag or the -C option was specified, * and if we won't be creating the file, then have the @@ -351,7 +370,7 @@ do_entry(struct conf_entry * ent) printf("--> will trim at %s", ptimeget_ctime(ent->trim_at)); } - return; + return (free_or_keep); } else if (diffsecs >= 3600.0) { /* * trim_at is more than an hour in the past, @@ -366,7 +385,7 @@ do_entry(struct conf_entry * ent) printf("--> will trim at %s", ptimeget_ctime(ent->trim_at)); } - return; + return (free_or_keep); } else if (verbose && noaction && dbg_at_times) { /* * If we are just debugging at-times, then @@ -376,13 +395,13 @@ do_entry(struct conf_entry * ent) */ printf("\n\t--> timematch at %s", ptimeget_ctime(ent->trim_at)); - return; + return (free_or_keep); } else if (verbose && ent->hours <= 0) { printf("--> time is up\n"); } } - if (verbose && (ent->size > 0)) - printf("size (Kb): %d [%d] ", size, ent->size); + if (verbose && (ent->trsize > 0)) + printf("size (Kb): %d [%d] ", ent->fsize, ent->trsize); if (verbose && (ent->hours > 0)) printf(" age (hr): %d [%d] ", modtime, ent->hours); @@ -397,10 +416,10 @@ do_entry(struct conf_entry * ent) } else if (force) { ent->rotate = 1; snprintf(temp_reason, REASON_MAX, " due to -F request"); - } else if ((ent->size > 0) && (size >= ent->size)) { + } else if ((ent->trsize > 0) && (ent->fsize >= ent->trsize)) { ent->rotate = 1; snprintf(temp_reason, REASON_MAX, " due to size>%dK", - ent->size); + ent->trsize); } else if (ent->hours <= 0 && (ent->flags & CE_TRIMAT)) { ent->rotate = 1; } else if ((ent->hours > 0) && ((modtime >= ent->hours) || @@ -427,12 +446,13 @@ do_entry(struct conf_entry * ent) printf("%s <%d>: trimming\n", ent->log, ent->numlogs); } - dotrim(ent); + free_or_keep = do_rotate(ent); } else { if (verbose) printf("--> skipping\n"); } } + return (free_or_keep); #undef REASON_MAX } @@ -662,7 +682,7 @@ parse_doption(const char *doption) return (1); /* successfully parsed */ } - warnx("Unknown -D (debug) option: %s", doption); + warnx("Unknown -D (debug) option: '%s'", doption); return (0); /* failure */ } @@ -734,7 +754,7 @@ get_worklist(char **files) if (defconf == NULL) { defconf = init_entry(DEFAULT_MARKER, NULL); defconf->numlogs = 3; - defconf->size = 50; + defconf->trsize = 50; defconf->permissions = S_IRUSR|S_IWUSR; } @@ -950,10 +970,13 @@ parse_file(FILE *cf, const char *cfname, struct conf_entry **work_p, */ lastglob = lastwork = NULL; + errline = NULL; while (fgets(line, BUFSIZ, cf)) { if ((line[0] == '\n') || (line[0] == '#') || (strlen(line) == 0)) continue; + if (errline != NULL) + free(errline); errline = strdup(line); for (cp = line + 1; *cp != '\0'; cp++) { if (*cp != '#') @@ -974,6 +997,24 @@ parse_file(FILE *cf, const char *cfname, struct conf_entry **work_p, errline); *parse = '\0'; + /* + * Allow people to set debug options via the config file. + * (NOTE: debug optons are undocumented, and may disappear + * at any time, etc). + */ + if (strcasecmp(DEBUG_MARKER, q) == 0) { + q = parse = missing_field(sob(++parse), errline); + parse = son(parse); + if (!*parse) + warnx("debug line specifies no option:\n%s", + errline); + else { + *parse = '\0'; + parse_doption(q); + } + continue; + } + special = 0; working = init_entry(q, NULL); if (strcasecmp(DEFAULT_MARKER, q) == 0) { @@ -1057,13 +1098,13 @@ parse_file(FILE *cf, const char *cfname, struct conf_entry **work_p, errline); *parse = '\0'; if (isdigitch(*q)) - working->size = atoi(q); - else if (strcmp(q,"*") == 0) - working->size = -1; + working->trsize = atoi(q); + else if (strcmp(q, "*") == 0) + working->trsize = -1; else { warnx("Invalid value of '%s' for 'size' in line:\n%s", q, errline); - working->size = -1; + working->trsize = -1; } working->flags = 0; @@ -1266,10 +1307,9 @@ no_trimat: lastwork->next = working; lastwork = working; } - - free(errline); - errline = NULL; } + if (errline != NULL) + free(errline); } static char * @@ -1281,17 +1321,19 @@ missing_field(char *p, char *errline) return (p); } -static void -dotrim(const struct conf_entry *ent) +static fk_entry +do_rotate(const struct conf_entry *ent) { char dirpart[MAXPATHLEN], namepart[MAXPATHLEN]; char file1[MAXPATHLEN], file2[MAXPATHLEN]; char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN]; char jfile1[MAXPATHLEN]; int flags, notified, need_notification, numlogs_c; + fk_entry free_or_keep; struct stat st; flags = ent->flags; + free_or_keep = FREE_ENT; if (archtodir) { char *p; @@ -1377,25 +1419,13 @@ dotrim(const struct conf_entry *ent) continue; } } - if (noaction) { + if (noaction) printf("\tmv %s %s\n", zfile1, zfile2); - printf("\tchmod %o %s\n", ent->permissions, zfile2); - if (ent->uid != (uid_t)-1 || ent->gid != (gid_t)-1) - printf("\tchown %u:%u %s\n", - ent->uid, ent->gid, zfile2); - if (ent->flags & CE_NODUMP) - printf("\tchflags nodump %s\n", zfile2); - } else { - (void) rename(zfile1, zfile2); - if (chmod(zfile2, ent->permissions)) - warn("can't chmod %s", file2); - if (ent->uid != (uid_t)-1 || ent->gid != (gid_t)-1) - if (chown(zfile2, ent->uid, ent->gid)) - warn("can't chown %s", zfile2); - if (ent->flags & CE_NODUMP) - if (chflags(zfile2, UF_NODUMP)) - warn("can't chflags %s NODUMP", zfile2); + else { + /* XXX - Ought to be checking for failure! */ + (void)rename(zfile1, zfile2); } + change_attrs(zfile2, ent); } if (ent->numlogs > 0) { @@ -1410,27 +1440,14 @@ dotrim(const struct conf_entry *ent) printf("\tcp %s %s\n", ent->log, file1); else printf("\tln %s %s\n", ent->log, file1); - printf("\tchmod %o %s\n", ent->permissions, file1); - if (ent->uid != (uid_t)-1 || ent->gid != (gid_t)-1) - printf("\tchown %u:%u %s\n", ent->uid, - ent->gid, file1); - if (ent->flags & CE_NODUMP) - printf("\tchflags nodump %s\n", file1); - } else { + } else { if (!(flags & CE_BINARY)) { /* Report the trimming to the old log */ log_trim(ent->log, ent); } savelog(ent->log, file1); - if (chmod(file1, ent->permissions)) - warn("can't chmod %s", file1); - if (ent->uid != (uid_t)-1 || ent->gid != (gid_t)-1) - if (chown(file1, ent->uid, ent->gid)) - warn("can't chown %s", file1); - if (ent->flags & CE_NODUMP) - if (chflags(file1, UF_NODUMP)) - warn("can't chflags %s NODUMP", file1); } + change_attrs(file1, ent); } /* Create the new log file and move it into place */ @@ -1462,12 +1479,13 @@ dotrim(const struct conf_entry *ent) warnx( "log %s.0 not compressed because daemon(s) not notified", ent->log); - else if (noaction) + else if (noaction) { + printf("\tsleep 10\n"); if (flags & CE_COMPACT) printf("\tgzip %s.0\n", ent->log); else printf("\tbzip2 %s.0\n", ent->log); - else { + } else { if (notified) { if (verbose) printf("small pause to allow daemon(s) to close log\n"); @@ -1492,6 +1510,7 @@ dotrim(const struct conf_entry *ent) } } } + return (free_or_keep); } /* Log the fact that the logs were turned over */ @@ -1566,7 +1585,7 @@ bzcompress_log(char *logname, int dowait) /* Return size in kilobytes of a file */ static int -sizefile(char *file) +sizefile(const char *file) { struct stat sb; @@ -1843,3 +1862,37 @@ createlog(const struct conf_entry *ent) if (fd >= 0) close(fd); } + +static void +change_attrs(const char *fname, const struct conf_entry *ent) +{ + int failed; + + if (noaction) { + printf("\tchmod %o %s\n", ent->permissions, fname); + + if (ent->uid != (uid_t)-1 || ent->gid != (gid_t)-1) + printf("\tchown %u:%u %s\n", + ent->uid, ent->gid, fname); + + if (ent->flags & CE_NODUMP) + printf("\tchflags nodump %s\n", fname); + return; + } + + failed = chmod(fname, ent->permissions); + if (failed) + warn("can't chmod %s", fname); + + if (ent->uid != (uid_t)-1 || ent->gid != (gid_t)-1) { + failed = chown(fname, ent->uid, ent->gid); + if (failed) + warn("can't chown %s", fname); + } + + if (ent->flags & CE_NODUMP) { + failed = chflags(fname, UF_NODUMP); + if (failed) + warn("can't chflags %s NODUMP", fname); + } +} |