Obtained from: NetBSD
imported the newsyslog command from NetBSD - it make the "rotation" of the logfiles much simpler (it is currently done by "hand" in the /etc/[daily,weekly,monthly] scripts) - now it will be done by invoking newsyslog every hour which is very customizable via a /etc/newsyslog.conf file
This commit is contained in:
parent
d021b6c07a
commit
abf212be33
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/NetBSD/dist/; revision=13244
15
usr.sbin/newsyslog/Makefile
Normal file
15
usr.sbin/newsyslog/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
# $Id: Makefile,v 1.6 1994/12/22 12:30:26 cgd Exp $
|
||||
|
||||
PROG= newsyslog
|
||||
|
||||
CFLAGS+= -DOSF
|
||||
CFLAGS+= -DCONF=\"/etc/newsyslog.conf\"
|
||||
CFLAGS+= -DPIDFILE=\"/var/run/syslog.pid\"
|
||||
CFLAGS+= -DCOMPRESS=\"/usr/bin/gzip\"
|
||||
CFLAGS+= -DCOMPRESS_POSTFIX=\".gz\"
|
||||
|
||||
BINOWN= root
|
||||
|
||||
MAN8= newsyslog.8
|
||||
|
||||
.include <bsd.prog.mk>
|
168
usr.sbin/newsyslog/newsyslog.8
Normal file
168
usr.sbin/newsyslog/newsyslog.8
Normal file
@ -0,0 +1,168 @@
|
||||
.TH NEWSYSLOG 8 "January 12, 1989" "Project Athena"
|
||||
.ns
|
||||
.\" This file contains changes from the Open Software Foundation.
|
||||
.\"
|
||||
.\" from: @(#)newsyslog.8
|
||||
.\" $Id: newsyslog.8,v 1.6 1995/01/06 19:20:20 jtc Exp $
|
||||
.\"
|
||||
.\" Copyright 1988, 1989 by the Massachusetts Institute of Technology
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software
|
||||
.\" and its documentation for any purpose and without fee is
|
||||
.\" hereby granted, provided that the above copyright notice
|
||||
.\" appear in all copies and that both that copyright notice and
|
||||
.\" this permission notice appear in supporting documentation,
|
||||
.\" and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
|
||||
.\" used in advertising or publicity pertaining to distribution
|
||||
.\" of the software without specific, written prior permission.
|
||||
.\" M.I.T. and the M.I.T. S.I.P.B. make no representations about
|
||||
.\" the suitability of this software for any purpose. It is
|
||||
.\" provided "as is" without express or implied warranty.
|
||||
.\"
|
||||
.sp
|
||||
.SH NAME
|
||||
newsyslog \- maintain system log files to manageable sizes
|
||||
.SH SYNOPSIS
|
||||
.B /usr/bin/newsyslog
|
||||
[
|
||||
.B \-vnr
|
||||
] [
|
||||
.B \-f
|
||||
.I configuration file
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.I Newsyslog
|
||||
is a program that should be scheduled to run periodically by
|
||||
.IR crontab .
|
||||
When it is executed it archives log files if necessary. If a log file
|
||||
is determined to require archiving,
|
||||
.I newsyslog
|
||||
rearranges the files so that ``logfile'' is empty, ``logfile.0'' has
|
||||
the last period's logs in it, ``logfile.1'' has the next to last
|
||||
period's logs in it, and so on, up to a user-specified number of
|
||||
archived logs. Optionally the archived logs can be compressed to save
|
||||
space.
|
||||
.PP
|
||||
A log can be archived because of two reasons. The log file can have
|
||||
grown bigger than a preset size in kilobytes, or a preset number of
|
||||
hours may have elapsed since the last log archive. The granularity of
|
||||
.I newsyslog
|
||||
is dependent on how often it is scheduled to run in crontab. Since
|
||||
the program is quite fast, it may be scheduled to run every hour
|
||||
without any ill effects.
|
||||
.PP
|
||||
When starting up,
|
||||
.I newsyslog
|
||||
reads in a configuration file to determine which logs should be looked
|
||||
at. By default, this configuration file is
|
||||
.IR /etc/newsyslog.conf .
|
||||
Each line of the file contains information about a particular log file
|
||||
that should be handled by
|
||||
.IR newsyslog .
|
||||
Each line has five mandatory fields and two optional fields, with a
|
||||
whitespace separating each field. Blank lines or lines beginning with
|
||||
``#'' are ignored. The fields of the configuration file are as
|
||||
follows:
|
||||
.br
|
||||
logfile name
|
||||
.br
|
||||
owner.group of archives (optional)
|
||||
.br
|
||||
mode of logfile & archives
|
||||
.br
|
||||
number of archives
|
||||
.br
|
||||
size of archives
|
||||
.br
|
||||
archive interval
|
||||
.br
|
||||
flags (optional)
|
||||
.PP
|
||||
The
|
||||
.I logfile name
|
||||
entry is the name of the system log file to be archived.
|
||||
.PP
|
||||
The optional
|
||||
.I owner.group
|
||||
entry specifies an ownership and group for the archive file.
|
||||
The "." is essential, even if the
|
||||
.I owner
|
||||
or
|
||||
.I group
|
||||
field is left blank. The
|
||||
fields may be numeric, or a name which is looked up in
|
||||
.I /etc/passwd
|
||||
or
|
||||
.IR /etc/group .
|
||||
.PP
|
||||
The
|
||||
.I number of archives
|
||||
entry specifies the number of archives to be kept besides the log file
|
||||
itself.
|
||||
.PP
|
||||
When the size of the logfile reaches
|
||||
.I size of
|
||||
.IR archives ,
|
||||
the logfile becomes trimmed as described above. If this field is
|
||||
replaced by a ``*'', then the size of the logfile is not taken into
|
||||
account when determining when to trim the log file.
|
||||
.PP
|
||||
The
|
||||
.I number of hours
|
||||
entry specifies the time separation between the trimming of the log
|
||||
file. If this field is replaced by a ``*'', then the number of hours
|
||||
since the last time the log was trimmed will not be taken into
|
||||
consideration.
|
||||
.PP
|
||||
The
|
||||
.I flags
|
||||
field specifies if the archives should have any special processing
|
||||
done to the archived log files. The ``Z'' flag will make the archive
|
||||
files compressed to save space using /usr/bin/gzip. The ``B'' flag
|
||||
means that the file is a binary file, and so the ascii message which
|
||||
.I newsyslog
|
||||
inserts to indicate the fact that the logs have been turned over
|
||||
should not be included.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
The following options can be used with newsyslog:
|
||||
.TP
|
||||
.B \-f \fIconfig-file
|
||||
instructs newsyslog to use
|
||||
.I config-file
|
||||
instead of /etc/newsyslog.conf for its configuration file.
|
||||
.TP
|
||||
.B \-v
|
||||
places
|
||||
.I newsyslog
|
||||
in verbose mode. In this mode it will print out each log and its
|
||||
reasons for either trimming that log or skipping it.
|
||||
.TP
|
||||
.B \-n
|
||||
causes
|
||||
.I newsyslog
|
||||
not to trim the logs, but to print out what it would do if this option
|
||||
were not specified.
|
||||
.TP
|
||||
.B \-r
|
||||
removes the restriction that
|
||||
.I newsyslog
|
||||
must be running as root. Of course,
|
||||
.I newsyslog
|
||||
will not be able to send a HUP signal to
|
||||
.IR syslogd ,
|
||||
so this option should only be used in debugging.
|
||||
.SH FILES
|
||||
/etc/newsyslog.conf
|
||||
.SH BUGS
|
||||
Doesn't yet automatically read the logs to find security breaches.
|
||||
|
||||
|
||||
.SH AUTHOR
|
||||
Theodore Ts'o, MIT Project Athena
|
||||
.br
|
||||
Copyright 1987, Massachusetts Institute of Technology
|
||||
.SH "SEE ALSO"
|
||||
syslogd(8), syslog(3), gzip(1)
|
||||
.ns
|
||||
.sp
|
568
usr.sbin/newsyslog/newsyslog.c
Normal file
568
usr.sbin/newsyslog/newsyslog.c
Normal file
@ -0,0 +1,568 @@
|
||||
/*
|
||||
* This file contains changes from the Open Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1988, 1989 by the Massachusetts Institute of Technology
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is
|
||||
hereby granted, provided that the above copyright notice
|
||||
appear in all copies and that both that copyright notice and
|
||||
this permission notice appear in supporting documentation,
|
||||
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific, written prior permission.
|
||||
M.I.T. and the M.I.T. S.I.P.B. make no representations about
|
||||
the suitability of this software for any purpose. It is
|
||||
provided "as is" without express or implied warranty.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* newsyslog - roll over selected logs at the appropriate time,
|
||||
* keeping the a specified number of backup files around.
|
||||
*
|
||||
* $Source: /a/cvsroot/src/usr.bin/newsyslog/newsyslog.c,v $
|
||||
* $Author: jtc $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: newsyslog.c,v 1.9 1995/01/21 21:53:46 jtc Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef CONF
|
||||
#define CONF "/etc/athena/newsyslog.conf" /* Configuration file */
|
||||
#endif
|
||||
#ifndef PIDFILE
|
||||
#define PIDFILE "/etc/syslog.pid"
|
||||
#endif
|
||||
#ifndef COMPRESS
|
||||
#define COMPRESS "/usr/ucb/compress" /* File compression program */
|
||||
#endif
|
||||
#ifndef COMPRESS_POSTFIX
|
||||
#define COMPRESS_POSTFIX ".Z"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define kbytes(size) (((size) + 1023) >> 10)
|
||||
#ifdef _IBMR2
|
||||
/* Calculates (db * DEV_BSIZE) */
|
||||
#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 */
|
||||
/* status messages */
|
||||
#define NONE -1
|
||||
|
||||
struct conf_entry {
|
||||
char *log; /* Name of the log */
|
||||
int uid; /* Owner of log */
|
||||
int gid; /* Group of log */
|
||||
int numlogs; /* Number of logs to keep */
|
||||
int size; /* Size cutoff to trigger trimming the log */
|
||||
int hours; /* Hours between log trimming */
|
||||
int permissions; /* File permissions on the log */
|
||||
int flags; /* Flags (CE_COMPACT & CE_BINARY) */
|
||||
struct conf_entry *next; /* Linked list pointer */
|
||||
};
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
extern char *malloc();
|
||||
extern uid_t getuid(),geteuid();
|
||||
extern time_t time();
|
||||
|
||||
char *progname; /* contains argv[0] */
|
||||
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 */
|
||||
char *conf = CONF; /* Configuration file to use */
|
||||
time_t timenow;
|
||||
int syslog_pid; /* read in from /etc/syslog.pid */
|
||||
#define MIN_PID 3
|
||||
#define MAX_PID 65534
|
||||
char hostname[64]; /* hostname */
|
||||
char *daytime; /* timenow in human readable form */
|
||||
|
||||
|
||||
struct conf_entry *parse_file();
|
||||
char *sob(), *son(), *strdup(), *missing_field();
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct conf_entry *p, *q;
|
||||
|
||||
PRS(argc,argv);
|
||||
if (needroot && getuid() && geteuid()) {
|
||||
fprintf(stderr,"%s: must have root privs\n",progname);
|
||||
exit(1);
|
||||
}
|
||||
p = q = parse_file();
|
||||
while (p) {
|
||||
do_entry(p);
|
||||
p=p->next;
|
||||
free((char *) q);
|
||||
q=p;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
do_entry(ent)
|
||||
struct conf_entry *ent;
|
||||
|
||||
{
|
||||
int size, modtime;
|
||||
|
||||
if (verbose) {
|
||||
if (ent->flags & CE_COMPACT)
|
||||
printf("%s <%dZ>: ",ent->log,ent->numlogs);
|
||||
else
|
||||
printf("%s <%d>: ",ent->log,ent->numlogs);
|
||||
}
|
||||
size = sizefile(ent->log);
|
||||
modtime = age_old_log(ent->log);
|
||||
if (size < 0) {
|
||||
if (verbose)
|
||||
printf("does not exist.\n");
|
||||
} else {
|
||||
if (verbose && (ent->size > 0))
|
||||
printf("size (Kb): %d [%d] ", size, ent->size);
|
||||
if (verbose && (ent->hours > 0))
|
||||
printf(" age (hr): %d [%d] ", modtime, ent->hours);
|
||||
if (((ent->size > 0) && (size >= ent->size)) ||
|
||||
((ent->hours > 0) && ((modtime >= ent->hours)
|
||||
|| (modtime < 0)))) {
|
||||
if (verbose)
|
||||
printf("--> trimming log....\n");
|
||||
if (noaction && !verbose) {
|
||||
if (ent->flags & CE_COMPACT)
|
||||
printf("%s <%dZ>: trimming",
|
||||
ent->log,ent->numlogs);
|
||||
else
|
||||
printf("%s <%d>: trimming",
|
||||
ent->log,ent->numlogs);
|
||||
}
|
||||
dotrim(ent->log, ent->numlogs, ent->flags,
|
||||
ent->permissions, ent->uid, ent->gid);
|
||||
} else {
|
||||
if (verbose)
|
||||
printf("--> skipping\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRS(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
FILE *f;
|
||||
char line[BUFSIZ];
|
||||
char *p;
|
||||
|
||||
progname = argv[0];
|
||||
timenow = time((time_t *) 0);
|
||||
daytime = ctime(&timenow) + 4;
|
||||
daytime[16] = '\0';
|
||||
|
||||
/* Let's find the pid of syslogd */
|
||||
syslog_pid = 0;
|
||||
f = fopen(PIDFILE,"r");
|
||||
if (f && fgets(line,BUFSIZ,f))
|
||||
syslog_pid = atoi(line);
|
||||
if (f)
|
||||
(void)fclose(f);
|
||||
|
||||
/* Let's get our hostname */
|
||||
(void) gethostname(hostname, sizeof(hostname));
|
||||
|
||||
/* Truncate domain */
|
||||
if (p = strchr(hostname, '.')) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
optind = 1; /* Start options parsing */
|
||||
while ((c=getopt(argc,argv,"nrvf:t:")) != EOF)
|
||||
switch (c) {
|
||||
case 'n':
|
||||
noaction++; /* This implies needroot as off */
|
||||
/* fall through */
|
||||
case 'r':
|
||||
needroot = 0;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'f':
|
||||
conf = optarg;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s <-nrv> <-f config-file>\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Parse a configuration file and return a linked list of all the logs
|
||||
* to process
|
||||
*/
|
||||
struct conf_entry *parse_file()
|
||||
{
|
||||
FILE *f;
|
||||
char line[BUFSIZ], *parse, *q;
|
||||
char *errline, *group;
|
||||
struct conf_entry *first = NULL;
|
||||
struct conf_entry *working;
|
||||
struct passwd *pass;
|
||||
struct group *grp;
|
||||
|
||||
if (strcmp(conf,"-"))
|
||||
f = fopen(conf,"r");
|
||||
else
|
||||
f = stdin;
|
||||
if (!f) {
|
||||
(void) fprintf(stderr,"%s: ",progname);
|
||||
perror(conf);
|
||||
exit(1);
|
||||
}
|
||||
while (fgets(line,BUFSIZ,f)) {
|
||||
if ((line[0]== '\n') || (line[0] == '#'))
|
||||
continue;
|
||||
errline = strdup(line);
|
||||
if (!first) {
|
||||
working = (struct conf_entry *) malloc(sizeof(struct conf_entry));
|
||||
first = working;
|
||||
} else {
|
||||
working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry));
|
||||
working = working->next;
|
||||
}
|
||||
|
||||
q = parse = missing_field(sob(line),errline);
|
||||
*(parse = son(line)) = '\0';
|
||||
working->log = strdup(q);
|
||||
|
||||
q = parse = missing_field(sob(++parse),errline);
|
||||
*(parse = son(parse)) = '\0';
|
||||
if ((group = strchr(q, '.')) != NULL) {
|
||||
*group++ = '\0';
|
||||
if (*q) {
|
||||
if (!(isnumber(*q))) {
|
||||
if ((pass = getpwnam(q)) == NULL) {
|
||||
fprintf(stderr,
|
||||
"Error in config file; unknown user:\n");
|
||||
fputs(errline,stderr);
|
||||
exit(1);
|
||||
}
|
||||
working->uid = pass->pw_uid;
|
||||
} else
|
||||
working->uid = atoi(q);
|
||||
} else
|
||||
working->uid = NONE;
|
||||
|
||||
q = group;
|
||||
if (*q) {
|
||||
if (!(isnumber(*q))) {
|
||||
if ((grp = getgrnam(q)) == NULL) {
|
||||
fprintf(stderr,
|
||||
"Error in config file; unknown group:\n");
|
||||
fputs(errline,stderr);
|
||||
exit(1);
|
||||
}
|
||||
working->gid = grp->gr_gid;
|
||||
} else
|
||||
working->gid = atoi(q);
|
||||
} else
|
||||
working->gid = NONE;
|
||||
|
||||
q = parse = missing_field(sob(++parse),errline);
|
||||
*(parse = son(parse)) = '\0';
|
||||
}
|
||||
else
|
||||
working->uid = working->gid = NONE;
|
||||
|
||||
if (!sscanf(q,"%o",&working->permissions)) {
|
||||
fprintf(stderr,
|
||||
"Error in config file; bad permissions:\n");
|
||||
fputs(errline,stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
q = parse = missing_field(sob(++parse),errline);
|
||||
*(parse = son(parse)) = '\0';
|
||||
if (!sscanf(q,"%d",&working->numlogs)) {
|
||||
fprintf(stderr,
|
||||
"Error in config file; bad number:\n");
|
||||
fputs(errline,stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
q = parse = missing_field(sob(++parse),errline);
|
||||
*(parse = son(parse)) = '\0';
|
||||
if (isdigit(*q))
|
||||
working->size = atoi(q);
|
||||
else
|
||||
working->size = -1;
|
||||
|
||||
q = parse = missing_field(sob(++parse),errline);
|
||||
*(parse = son(parse)) = '\0';
|
||||
if (isdigit(*q))
|
||||
working->hours = atoi(q);
|
||||
else
|
||||
working->hours = -1;
|
||||
|
||||
q = parse = sob(++parse); /* Optional field */
|
||||
*(parse = son(parse)) = '\0';
|
||||
working->flags = 0;
|
||||
while (q && *q && !isspace(*q)) {
|
||||
if ((*q == 'Z') || (*q == 'z'))
|
||||
working->flags |= CE_COMPACT;
|
||||
else if ((*q == 'B') || (*q == 'b'))
|
||||
working->flags |= CE_BINARY;
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Illegal flag in config file -- %c\n",
|
||||
*q);
|
||||
exit(1);
|
||||
}
|
||||
q++;
|
||||
}
|
||||
|
||||
free(errline);
|
||||
}
|
||||
if (working)
|
||||
working->next = (struct conf_entry *) NULL;
|
||||
(void) fclose(f);
|
||||
return(first);
|
||||
}
|
||||
|
||||
char *missing_field(p,errline)
|
||||
char *p,*errline;
|
||||
{
|
||||
if (!p || !*p) {
|
||||
fprintf(stderr,"Missing field in config file:\n");
|
||||
fputs(errline,stderr);
|
||||
exit(1);
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
|
||||
dotrim(log,numdays,flags,perm,owner_uid,group_gid)
|
||||
char *log;
|
||||
int numdays;
|
||||
int flags;
|
||||
int perm;
|
||||
int owner_uid;
|
||||
int group_gid;
|
||||
{
|
||||
char file1[128], file2[128];
|
||||
char zfile1[128], zfile2[128];
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
#ifdef _IBMR2
|
||||
/* AIX 3.1 has a broken fchown- if the owner_uid is -1, it will actually */
|
||||
/* change it to be owned by uid -1, instead of leaving it as is, as it is */
|
||||
/* supposed to. */
|
||||
if (owner_uid == -1)
|
||||
owner_uid = geteuid();
|
||||
#endif
|
||||
|
||||
/* Remove oldest log */
|
||||
(void) sprintf(file1,"%s.%d",log,numdays);
|
||||
(void) strcpy(zfile1, file1);
|
||||
(void) strcat(zfile1, COMPRESS_POSTFIX);
|
||||
|
||||
if (noaction) {
|
||||
printf("rm -f %s\n", file1);
|
||||
printf("rm -f %s\n", zfile1);
|
||||
} else {
|
||||
(void) unlink(file1);
|
||||
(void) unlink(zfile1);
|
||||
}
|
||||
|
||||
/* Move down log files */
|
||||
while (numdays--) {
|
||||
(void) strcpy(file2,file1);
|
||||
(void) sprintf(file1,"%s.%d",log,numdays);
|
||||
(void) strcpy(zfile1, file1);
|
||||
(void) strcpy(zfile2, file2);
|
||||
if (lstat(file1, &st)) {
|
||||
(void) strcat(zfile1, COMPRESS_POSTFIX);
|
||||
(void) strcat(zfile2, COMPRESS_POSTFIX);
|
||||
if (lstat(zfile1, &st)) continue;
|
||||
}
|
||||
if (noaction) {
|
||||
printf("mv %s %s\n",zfile1,zfile2);
|
||||
printf("chmod %o %s\n", perm, zfile2);
|
||||
printf("chown %d.%d %s\n",
|
||||
owner_uid, group_gid, zfile2);
|
||||
} else {
|
||||
(void) rename(zfile1, zfile2);
|
||||
(void) chmod(zfile2, perm);
|
||||
(void) chown(zfile2, owner_uid, group_gid);
|
||||
}
|
||||
}
|
||||
if (!noaction && !(flags & CE_BINARY))
|
||||
(void) log_trim(log); /* Report the trimming to the old log */
|
||||
|
||||
if (noaction)
|
||||
printf("mv %s to %s\n",log,file1);
|
||||
else
|
||||
(void) rename(log,file1);
|
||||
if (noaction)
|
||||
printf("Start new log...");
|
||||
else {
|
||||
fd = creat(log,perm);
|
||||
if (fd < 0) {
|
||||
perror("can't start new log");
|
||||
exit(1);
|
||||
}
|
||||
if (fchown(fd, owner_uid, group_gid)) {
|
||||
perror("can't chmod new log file");
|
||||
exit(1);
|
||||
}
|
||||
(void) close(fd);
|
||||
if (!(flags & CE_BINARY))
|
||||
if (log_trim(log)) { /* Add status message */
|
||||
perror("can't add status message to log");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (noaction)
|
||||
printf("chmod %o %s...",perm,log);
|
||||
else
|
||||
(void) chmod(log,perm);
|
||||
if (noaction)
|
||||
printf("kill -HUP %d (syslogd)\n",syslog_pid);
|
||||
else
|
||||
if (syslog_pid < MIN_PID || syslog_pid > MAX_PID) {
|
||||
fprintf(stderr,"%s: preposterous process number: %d\n",
|
||||
progname, syslog_pid);
|
||||
} else if (kill(syslog_pid,SIGHUP)) {
|
||||
fprintf(stderr,"%s: ",progname);
|
||||
perror("warning - could not restart syslogd");
|
||||
}
|
||||
if (flags & CE_COMPACT) {
|
||||
if (noaction)
|
||||
printf("Compress %s.0\n",log);
|
||||
else
|
||||
compress_log(log);
|
||||
}
|
||||
}
|
||||
|
||||
/* Log the fact that the logs were turned over */
|
||||
log_trim(log)
|
||||
char *log;
|
||||
{
|
||||
FILE *f;
|
||||
if ((f = fopen(log,"a")) == NULL)
|
||||
return(-1);
|
||||
fprintf(f,"%s %s newsyslog[%d]: logfile turned over\n",
|
||||
daytime, hostname, getpid());
|
||||
if (fclose(f) == EOF) {
|
||||
perror("log_trim: fclose:");
|
||||
exit(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Fork of /usr/ucb/compress to compress the old log file */
|
||||
compress_log(log)
|
||||
char *log;
|
||||
{
|
||||
int pid;
|
||||
char tmp[128];
|
||||
|
||||
pid = fork();
|
||||
(void) sprintf(tmp,"%s.0",log);
|
||||
if (pid < 0) {
|
||||
fprintf(stderr,"%s: ",progname);
|
||||
perror("fork");
|
||||
exit(1);
|
||||
} else if (!pid) {
|
||||
(void) execl(COMPRESS,"compress","-f",tmp,0);
|
||||
fprintf(stderr,"%s: ",progname);
|
||||
perror(COMPRESS);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return size in kilobytes of a file */
|
||||
int sizefile(file)
|
||||
char *file;
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat(file,&sb) < 0)
|
||||
return(-1);
|
||||
return(kbytes(dbtob(sb.st_blocks)));
|
||||
}
|
||||
|
||||
/* Return the age of old log file (file.0) */
|
||||
int age_old_log(file)
|
||||
char *file;
|
||||
{
|
||||
struct stat sb;
|
||||
char tmp[MAXPATHLEN+3];
|
||||
|
||||
(void) strcpy(tmp,file);
|
||||
if (stat(strcat(tmp,".0"),&sb) < 0)
|
||||
if (stat(strcat(tmp,COMPRESS_POSTFIX), &sb) < 0)
|
||||
return(-1);
|
||||
return( (int) (timenow - sb.st_mtime + 1800) / 3600);
|
||||
}
|
||||
|
||||
|
||||
#ifndef OSF
|
||||
/* Duplicate a string using malloc */
|
||||
|
||||
char *strdup(strp)
|
||||
register char *strp;
|
||||
{
|
||||
register char *cp;
|
||||
|
||||
if ((cp = malloc((unsigned) strlen(strp) + 1)) == NULL)
|
||||
abort();
|
||||
return(strcpy (cp, strp));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Skip Over Blanks */
|
||||
char *sob(p)
|
||||
register char *p;
|
||||
{
|
||||
while (p && *p && isspace(*p))
|
||||
p++;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Skip Over Non-Blanks */
|
||||
char *son(p)
|
||||
register char *p;
|
||||
{
|
||||
while (p && *p && !isspace(*p))
|
||||
p++;
|
||||
return(p);
|
||||
}
|
Loading…
Reference in New Issue
Block a user