summaryrefslogtreecommitdiffstats
path: root/usr.sbin/newsyslog
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2004-06-07 01:21:30 +0000
committergad <gad@FreeBSD.org>2004-06-07 01:21:30 +0000
commit3e7bce2995cac67f35775e81b4f6bd217fa587e6 (patch)
treef492174d9ed3e971e21b2e40d03f28c6fa8e8e6b /usr.sbin/newsyslog
parent4c3fd8116d1815c5e18c8569e354a99c8c7ce1c8 (diff)
downloadFreeBSD-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/newsyslog')
-rw-r--r--usr.sbin/newsyslog/newsyslog.c187
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);
+ }
+}
OpenPOWER on IntegriCloud