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)
This commit is contained in:
Garance A Drosehn 2003-03-02 23:23:11 +00:00
parent 03d031626d
commit 9fb022b6d6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=111772

View File

@ -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);