summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2003-03-02 23:23:11 +0000
committergad <gad@FreeBSD.org>2003-03-02 23:23:11 +0000
commit6133e17fe01863494a188956c48aac643dfa7736 (patch)
tree2cdf1ac6763c6d2b219f1f616300e98b6fe30718
parentf9ac94177616b8fff27d42a447cd6a28ffa950c6 (diff)
downloadFreeBSD-src-6133e17fe01863494a188956c48aac643dfa7736.zip
FreeBSD-src-6133e17fe01863494a188956c48aac643dfa7736.tar.gz
Add a command-line option of '-R somename', which indicates that newsyslog
should rotate all files given on the command, even if they don't seem to need to be rotated. This would be used by some other command that decides the given log file(s) should be rotated, but wants the "how" of that rotation to be determined by entries to newsyslog. Wes expects to change syslogd to take advantage of this. Man page will be updated after we're sure this is all working the way we want it to. Reviewed by: no objections on freebsd-arch MFC after: 3 weeks MFC addendum: (or after the code-freeze of 4.x is lifted)
-rw-r--r--usr.sbin/newsyslog/newsyslog.c86
1 files changed, 77 insertions, 9 deletions
diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c
index 136d638..09d828c 100644
--- a/usr.sbin/newsyslog/newsyslog.c
+++ b/usr.sbin/newsyslog/newsyslog.c
@@ -83,6 +83,8 @@ static const char rcsid[] =
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 rotate; /* Non-zero if this file should be rotated */
int uid; /* Owner of log */
int gid; /* Group of log */
int numlogs; /* Number of logs to keep */
@@ -104,6 +106,11 @@ 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 */
+int rotatereq = 0; /* -R = Always rotate the file(s) as given */
+ /* on the command (this also requires */
+ /* that a list of files *are* given on */
+ /* the run command). */
+char *requestor; /* The name given on a -R request */
char *archdirname; /* Directory path to old logfiles archive */
const char *conf = _PATH_CONF; /* Configuration file to use */
time_t timenow;
@@ -143,6 +150,7 @@ static time_t parseDWM(char *s, char *errline);
* range 0 to 255, plus EOF. Define wrappers which can take
* values of type 'char', either signed or unsigned.
*/
+#define isprintch(Anychar) isprint(((int) Anychar) & 255)
#define isspacech(Anychar) isspace(((int) Anychar) & 255)
#define tolowerch(Anychar) tolower(((int) Anychar) & 255)
@@ -204,6 +212,8 @@ init_entry(const char *fname, struct conf_entry *src_entry)
tempwork->pid_file = NULL;
if (src_entry->pid_file)
tempwork->pid_file = strdup(src_entry->pid_file);
+ tempwork->r_reason = NULL;
+ tempwork->rotate = 0;
tempwork->uid = src_entry->uid;
tempwork->gid = src_entry->gid;
tempwork->numlogs = src_entry->numlogs;
@@ -217,6 +227,8 @@ init_entry(const char *fname, struct conf_entry *src_entry)
} else {
/* Initialize as a "do-nothing" entry */
tempwork->pid_file = NULL;
+ tempwork->r_reason = NULL;
+ tempwork->rotate = 0;
tempwork->uid = NONE;
tempwork->gid = NONE;
tempwork->numlogs = 1;
@@ -252,13 +264,20 @@ free_entry(struct conf_entry *ent)
ent->pid_file = NULL;
}
+ if (ent->r_reason != NULL) {
+ free(ent->r_reason);
+ ent->r_reason = NULL;
+ }
+
free(ent);
}
static void
do_entry(struct conf_entry * ent)
{
+#define REASON_MAX 80
int size, modtime;
+ char temp_reason[REASON_MAX];
if (verbose) {
if (ent->flags & CE_COMPACT)
@@ -270,11 +289,12 @@ do_entry(struct conf_entry * ent)
}
size = sizefile(ent->log);
modtime = age_old_log(ent->log);
+ ent->rotate = 0;
if (size < 0) {
if (verbose)
printf("does not exist.\n");
} else {
- if (ent->flags & CE_TRIMAT && !force) {
+ if (ent->flags & CE_TRIMAT && !force && !rotatereq) {
if (timenow < ent->trim_at
|| difftime(timenow, ent->trim_at) >= 60 * 60) {
if (verbose)
@@ -289,10 +309,35 @@ do_entry(struct conf_entry * ent)
printf("size (Kb): %d [%d] ", size, ent->size);
if (verbose && (ent->hours > 0))
printf(" age (hr): %d [%d] ", modtime, ent->hours);
- if (force || ((ent->size > 0) && (size >= ent->size)) ||
- (ent->hours <= 0 && (ent->flags & CE_TRIMAT)) ||
- ((ent->hours > 0) && ((modtime >= ent->hours)
- || (modtime < 0)))) {
+
+ /*
+ * Figure out if this logfile needs to be rotated.
+ */
+ temp_reason[0] = '\0';
+ if (rotatereq) {
+ ent->rotate = 1;
+ snprintf(temp_reason, REASON_MAX, " due to -R from %s",
+ requestor);
+ } else if (force) {
+ ent->rotate = 1;
+ snprintf(temp_reason, REASON_MAX, " due to -F request");
+ } else if ((ent->size > 0) && (size >= ent->size)) {
+ ent->rotate = 1;
+ snprintf(temp_reason, REASON_MAX, " due to size>%dK",
+ ent->size);
+ } else if (ent->hours <= 0 && (ent->flags & CE_TRIMAT)) {
+ ent->rotate = 1;
+ } else if ((ent->hours > 0) && ((modtime >= ent->hours) ||
+ (modtime < 0))) {
+ ent->rotate = 1;
+ }
+
+ /*
+ * If the file needs to be rotated, then rotate it.
+ */
+ if (ent->rotate) {
+ if (temp_reason[0] != '\0')
+ ent->r_reason = strdup(temp_reason);
if (verbose)
printf("--> trimming log....\n");
if (noaction && !verbose) {
@@ -313,6 +358,7 @@ do_entry(struct conf_entry * ent)
printf("--> skipping\n");
}
}
+#undef REASON_MAX
}
static void
@@ -334,7 +380,7 @@ PRS(int argc, char **argv)
}
/* Parse command line options. */
- while ((c = getopt(argc, argv, "a:f:nrsvF")) != -1)
+ while ((c = getopt(argc, argv, "a:f:nrsvFR:")) != -1)
switch (c) {
case 'a':
archtodir++;
@@ -358,10 +404,27 @@ PRS(int argc, char **argv)
case 'F':
force++;
break;
+ case 'R':
+ rotatereq++;
+ requestor = strdup(optarg);
+ break;
default:
usage();
/* NOTREACHED */
}
+
+ if (rotatereq) {
+ if (optind == argc) {
+ warnx("At least one filename must be given when -R is specified.");
+ usage();
+ /* NOTREACHED */
+ }
+ /* Make sure "requestor" value is safe for a syslog message. */
+ for (p = requestor; *p != '\0'; p++) {
+ if (!isprintch(*p) && (*p != '\t'))
+ *p = '.';
+ }
+ }
}
static void
@@ -369,7 +432,8 @@ usage(void)
{
fprintf(stderr,
- "usage: newsyslog [-Fnrsv] [-f config-file] [-a directory] [ filename ... ]\n");
+ "usage: newsyslog [-Fnrsv] [-a directory] [-f config-file]\n"
+ " [ [-R requestor] filename ... ]\n");
exit(1);
}
@@ -999,8 +1063,12 @@ log_trim(const char *log, const struct conf_entry *log_ent)
xtra = "";
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);
+ if (log_ent->r_reason != NULL)
+ fprintf(f, "%s %s newsyslog[%d]: logfile turned over%s%s\n",
+ daytime, hostname, (int) getpid(), log_ent->r_reason, xtra);
+ else
+ fprintf(f, "%s %s newsyslog[%d]: logfile turned over%s\n",
+ daytime, hostname, (int) getpid(), xtra);
if (fclose(f) == EOF)
err(1, "log_trim: fclose:");
return (0);
OpenPOWER on IntegriCloud