summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2003-03-02 22:05:17 +0000
committergad <gad@FreeBSD.org>2003-03-02 22:05:17 +0000
commit0b924719849b7e5814e306f2666f4f951f057407 (patch)
tree6406a73ec4566a3ae2d34bf38a1840441e39026f /usr.sbin
parentcd4fafb346eda353b75a3fb1f4ba5b08a8f0e688 (diff)
downloadFreeBSD-src-0b924719849b7e5814e306f2666f4f951f057407.zip
FreeBSD-src-0b924719849b7e5814e306f2666f4f951f057407.tar.gz
Add a command-line option of '-s', which indicates that newsyslog should
not send a signal to any processes. Also add a config-file flag of 'N' or 'n', which indicates that the given logfile has no process which needs a signal when it is rotated. Both of these are based on changes NetBSD has made, although the implementation is somewhat different. PR: bin/36553 (2nd half) Reviewed by: no objections on freebsd-arch Obtained from: NetBSD (in spirit, at least) MFC after: 3 weeks
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/newsyslog/newsyslog.c170
1 files changed, 120 insertions, 50 deletions
diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c
index c0b54cf..136d638 100644
--- a/usr.sbin/newsyslog/newsyslog.c
+++ b/usr.sbin/newsyslog/newsyslog.c
@@ -64,14 +64,19 @@ static const char rcsid[] =
#define dbtob(db) ((unsigned)(db) << UBSHIFT)
#endif
-#define CE_COMPACT 1 /* Compact the achived log files */
-#define CE_BINARY 2 /* Logfile is in binary, don't add */
-#define CE_BZCOMPACT 8 /* Compact the achived log files with bzip2 */
- /* status messages */
-#define CE_TRIMAT 4 /* trim at a specific time */
-#define CE_GLOB 16 /* name of the log is file name pattern */
-#define CE_COMPACTWAIT 32 /* wait till compressing finishes before */
- /* starting the next one */
+/*
+ * Bit-values for the 'flags' parsed from a config-file entry.
+ */
+#define CE_COMPACT 0x0001 /* Compact the achived log files with gzip. */
+#define CE_BZCOMPACT 0x0002 /* Compact the achived log files with bzip2. */
+#define CE_COMPACTWAIT 0x0004 /* wait until compressing one file finishes */
+ /* before starting the next step. */
+#define CE_BINARY 0x0008 /* Logfile is in binary, do not add status */
+ /* messages to logfile(s) when rotating. */
+#define CE_NOSIGNAL 0x0010 /* There is no process to signal when */
+ /* trimming this file. */
+#define CE_TRIMAT 0x0020 /* trim file at a specific time. */
+#define CE_GLOB 0x0040 /* name of the log is file name pattern. */
#define NONE -1
@@ -97,6 +102,7 @@ int archtodir = 0; /* Archive old logfiles to other directory */
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 nosignal; /* Do not send any signals */
int force = 0; /* Force the trim no matter what */
char *archdirname; /* Directory path to old logfiles archive */
const char *conf = _PATH_CONF; /* Configuration file to use */
@@ -117,9 +123,10 @@ static struct conf_entry *init_entry(const char *fname,
struct conf_entry *src_entry);
static void PRS(int argc, char **argv);
static void usage(void);
-static void dotrim(char *log, const char *pid_file, int numdays, int falgs,
- int perm, int owner_uid, int group_gid, int sig, int def_cfg);
-static int log_trim(char *log, int def_cfg);
+static void dotrim(const struct conf_entry *trim_ent, char *log,
+ int numdays, int flags, int perm, int owner_uid,
+ int group_gid, int sig);
+static int log_trim(const char *log, const struct conf_entry *log_ent);
static void compress_log(char *log, int dowait);
static void bzcompress_log(char *log, int dowait);
static int sizefile(char *file);
@@ -131,6 +138,14 @@ static void movefile(char *from, char *to, int perm, int owner_uid,
static void createdir(char *dirpart);
static time_t parseDWM(char *s, char *errline);
+/*
+ * All the following are defined to work on an 'int', in the
+ * range 0 to 255, plus EOF. Define wrappers which can take
+ * values of type 'char', either signed or unsigned.
+ */
+#define isspacech(Anychar) isspace(((int) Anychar) & 255)
+#define tolowerch(Anychar) tolower(((int) Anychar) & 255)
+
int
main(int argc, char **argv)
{
@@ -244,7 +259,6 @@ static void
do_entry(struct conf_entry * ent)
{
int size, modtime;
- const char *pid_file;
if (verbose) {
if (ent->flags & CE_COMPACT)
@@ -292,18 +306,8 @@ do_entry(struct conf_entry * ent)
printf("%s <%d>: trimming\n",
ent->log, ent->numlogs);
}
- if (ent->pid_file) {
- pid_file = ent->pid_file;
- } else {
- /* Only try to notify syslog if we are root */
- if (needroot)
- pid_file = _PATH_SYSLOGPID;
- else
- pid_file = NULL;
- }
- dotrim(ent->log, pid_file, ent->numlogs,
- ent->flags, ent->permissions, ent->uid, ent->gid,
- ent->sig, ent->def_cfg);
+ dotrim(ent, ent->log, ent->numlogs, ent->flags,
+ ent->permissions, ent->uid, ent->gid, ent->sig);
} else {
if (verbose)
printf("--> skipping\n");
@@ -328,29 +332,35 @@ PRS(int argc, char **argv)
if ((p = strchr(hostname, '.'))) {
*p = '\0';
}
- while ((c = getopt(argc, argv, "nrvFf:a:")) != -1)
+
+ /* Parse command line options. */
+ while ((c = getopt(argc, argv, "a:f:nrsvF")) != -1)
switch (c) {
- case 'n':
- noaction++;
- break;
case 'a':
archtodir++;
archdirname = optarg;
break;
+ case 'f':
+ conf = optarg;
+ break;
+ case 'n':
+ noaction++;
+ break;
case 'r':
needroot = 0;
break;
+ case 's':
+ nosignal = 1;
+ break;
case 'v':
verbose++;
break;
- case 'f':
- conf = optarg;
- break;
case 'F':
force++;
break;
default:
usage();
+ /* NOTREACHED */
}
}
@@ -359,7 +369,7 @@ usage(void)
{
fprintf(stderr,
- "usage: newsyslog [-Fnrv] [-f config-file] [-a directory] [ filename ... ]\n");
+ "usage: newsyslog [-Fnrsv] [-f config-file] [-a directory] [ filename ... ]\n");
exit(1);
}
@@ -574,21 +584,42 @@ parse_file(char **files)
*parse = '\0';
}
- while (q && *q && !isspace(*q)) {
- if ((*q == 'Z') || (*q == 'z'))
- working->flags |= CE_COMPACT;
- else if ((*q == 'J') || (*q == 'j'))
- working->flags |= CE_BZCOMPACT;
- else if ((*q == 'B') || (*q == 'b'))
+ for (; q && *q && !isspacech(*q); q++) {
+ switch (tolowerch(*q)) {
+ case 'b':
working->flags |= CE_BINARY;
- else if ((*q == 'G') || (*q == 'c'))
+ break;
+ case 'c':
+ /*
+ * netbsd uses 'c' for "create". We will
+ * temporarily accept it for 'g', because
+ * earlier freebsd versions had a typo
+ * of ('G' || 'c')...
+ */
+ warnx("Assuming 'g' for 'c' in flags for line:\n%s",
+ errline);
+ /* FALLTHROUGH */
+ case 'g':
working->flags |= CE_GLOB;
- else if ((*q == 'W') || (*q == 'w'))
+ break;
+ case 'j':
+ working->flags |= CE_BZCOMPACT;
+ break;
+ case 'n':
+ working->flags |= CE_NOSIGNAL;
+ break;
+ case 'w':
working->flags |= CE_COMPACTWAIT;
- else if (*q != '-')
+ break;
+ case 'z':
+ working->flags |= CE_COMPACT;
+ break;
+ case '-':
+ break;
+ default:
errx(1, "illegal flag in config file -- %c",
*q);
- q++;
+ }
}
if (eol)
@@ -633,7 +664,46 @@ parse_file(char **files)
if (working->sig < 1 || working->sig >= NSIG)
goto err_sig;
}
+
+ /*
+ * Finish figuring out what pid-file to use (if any) in
+ * later processing if this logfile needs to be rotated.
+ */
+ if ((working->flags & CE_NOSIGNAL) == CE_NOSIGNAL) {
+ /*
+ * This config-entry specified 'n' for nosignal,
+ * see if it also specified an explicit pid_file.
+ * This would be a pretty pointless combination.
+ */
+ if (working->pid_file != NULL) {
+ warnx("Ignoring '%s' because flag 'n' was specified in line:\n%s",
+ working->pid_file, errline);
+ free(working->pid_file);
+ working->pid_file = NULL;
+ }
+ } else if (nosignal) {
+ /*
+ * While this entry might usually signal some
+ * process via the pid-file, newsyslog was run
+ * with '-s', so quietly ignore the pid-file.
+ */
+ if (working->pid_file != NULL) {
+ free(working->pid_file);
+ working->pid_file = NULL;
+ }
+ } else if (working->pid_file == NULL) {
+ /*
+ * This entry did not specify the 'n' flag, which
+ * means it should signal syslogd unless it had
+ * specified some other pid-file. But we only
+ * try to notify syslog if we are root
+ */
+ if (needroot)
+ working->pid_file = strdup(_PATH_SYSLOGPID);
+ }
+
free(errline);
+ errline = NULL;
}
(void) fclose(f);
@@ -699,8 +769,8 @@ missing_field(char *p, char *errline)
}
static void
-dotrim(char *log, const char *pid_file, int numdays, int flags, int perm,
- int owner_uid, int group_gid, int sig, int def_cfg)
+dotrim(const struct conf_entry *trim_ent, char *log, int numdays, int flags,
+ int perm, int owner_uid, int group_gid, int sig)
{
char dirpart[MAXPATHLEN], namepart[MAXPATHLEN];
char file1[MAXPATHLEN], file2[MAXPATHLEN];
@@ -817,7 +887,7 @@ dotrim(char *log, const char *pid_file, int numdays, int flags, int perm,
}
if (!noaction && !(flags & CE_BINARY)) {
/* Report the trimming to the old log */
- (void) log_trim(log, def_cfg);
+ (void) log_trim(log, trim_ent);
}
if (!_numdays) {
@@ -851,7 +921,7 @@ dotrim(char *log, const char *pid_file, int numdays, int flags, int perm,
(void) close(fd);
if (!(flags & CE_BINARY)) {
/* Add status message to new log file */
- if (log_trim(tfile, def_cfg))
+ if (log_trim(tfile, trim_ent))
err(1, "can't add status message to log");
}
}
@@ -867,9 +937,9 @@ dotrim(char *log, const char *pid_file, int numdays, int flags, int perm,
pid = 0;
need_notification = notified = 0;
- if (pid_file != NULL) {
+ if (trim_ent->pid_file != NULL) {
need_notification = 1;
- pid = get_pid(pid_file);
+ pid = get_pid(trim_ent->pid_file);
}
if (pid) {
if (noaction) {
@@ -919,7 +989,7 @@ dotrim(char *log, const char *pid_file, int numdays, int flags, int perm,
/* Log the fact that the logs were turned over */
static int
-log_trim(char *log, int def_cfg)
+log_trim(const char *log, const struct conf_entry *log_ent)
{
FILE *f;
const char *xtra;
@@ -927,7 +997,7 @@ log_trim(char *log, int def_cfg)
if ((f = fopen(log, "a")) == NULL)
return (-1);
xtra = "";
- if (def_cfg)
+ if (log_ent->def_cfg)
xtra = " using <default> rule";
fprintf(f, "%s %s newsyslog[%d]: logfile turned over%s\n",
daytime, hostname, (int) getpid(), xtra);
OpenPOWER on IntegriCloud