Index: Makefile =================================================================== RCS file: /usr/cvs/src/usr.sbin/newsyslog/Makefile,v retrieving revision 1.4 diff -c -r1.4 Makefile *** Makefile 1997/02/22 16:08:24 1.4 --- Makefile 1997/03/03 07:43:53 *************** *** 8,13 **** --- 8,14 ---- CFLAGS+= -DCOMPRESS_PATH=\"/usr/bin/gzip\" CFLAGS+= -DCOMPRESS_PROG=\"gzip\" CFLAGS+= -DCOMPRESS_POSTFIX=\".gz\" + CFLAGS+= -I${.CURDIR}/../syslogd BINOWN= root Index: newsyslog.8 =================================================================== RCS file: /usr/cvs/src/usr.sbin/newsyslog/newsyslog.8,v retrieving revision 1.5 diff -c -r1.5 newsyslog.8 *** newsyslog.8 1997/02/28 07:33:37 1.5 --- newsyslog.8 1997/03/03 06:57:48 *************** *** 17,44 **** .\" the suitability of this software for any purpose. It is .\" provided "as is" without express or implied warranty. .\" ! .Dd "January 12, 1989" .Dt NEWSYSLOG 8 .Os .Sh NAME .Nm newsyslog .Nd maintain system log files to manageable sizes .Sh SYNOPSIS ! .Nm newsyslog .Op Fl rnv .Op Fl f Ar config_file .Sh DESCRIPTION ! .Nm Newsyslog is a program that should be scheduled to run periodically by .Xr cron 8 . When it is executed it archives log files if necessary. If a log file is determined to require archiving, ! .Nm 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 --- 17,48 ---- .\" the suitability of this software for any purpose. It is .\" provided "as is" without express or implied warranty. .\" ! .Dd January 12, 1989 .Dt NEWSYSLOG 8 .Os .Sh NAME .Nm newsyslog .Nd maintain system log files to manageable sizes .Sh SYNOPSIS ! .Nm .Op Fl rnv .Op Fl f Ar config_file .Sh DESCRIPTION ! .Nm is a program that should be scheduled to run periodically by .Xr cron 8 . When it is executed it archives log files if necessary. If a log file is determined to require archiving, ! .Nm ! rearranges the files so that ! .Dq Pa logfile ! is empty, ! .Dq Pa logfile.0 ! has the last period's logs in it, ! .Dq Pa 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 *************** *** 50,73 **** without any ill effects. .Pp When starting up, ! .Nm newsyslog reads in a configuration file to determine which logs should be looked at. By default, this configuration file is .Pa /etc/newsyslog.conf . Each line of the file contains information about a particular log file that should be handled by ! .Nm 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: .Pp .Bl -tag -width logfile_namexxxx .It Ar logfile_name Name of the system log file to be archived. .It Ar owner.group Specifies the owner and group for the archive file. ! The "." is essential, even if the .Ar owner or .Ar group --- 54,79 ---- without any ill effects. .Pp When starting up, ! .Nm reads in a configuration file to determine which logs should be looked at. By default, this configuration file is .Pa /etc/newsyslog.conf . Each line of the file contains information about a particular log file that should be handled by ! .Nm Ns . ! Each line has five mandatory fields and four optional fields, with a whitespace separating each field. Blank lines or lines beginning with ! .Dq # ! are ignored. The fields of the configuration file are as follows: .Pp .Bl -tag -width logfile_namexxxx .It Ar logfile_name Name of the system log file to be archived. .It Ar owner.group Specifies the owner and group for the archive file. ! The ! .Dq \&. ! is essential, even if the .Ar owner or .Ar group *************** *** 75,92 **** present in .Pa /etc/passwd or ! .Pa /etc/group. .It Ar mode Specifies the mode of the log file and archives. .It Ar count ! Specifies the number of archive files to be kept ! besides the log file itself. .It Ar size When the size of the log file reaches .Ar size , the log file will be trimmed as described above. If this field is replaced by a ! .Ar * , then the size of the log file is not taken into account when determining when to trim the log file. of archives --- 81,97 ---- present in .Pa /etc/passwd or ! .Pa /etc/group . .It Ar mode Specifies the mode of the log file and archives. .It Ar count ! Specifies the number of archive files to be kept besides the log file itself. .It Ar size When the size of the log file reaches .Ar size , the log file will be trimmed as described above. If this field is replaced by a ! .Dq * , then the size of the log file is not taken into account when determining when to trim the log file. of archives *************** *** 95,101 **** .Ar interval hours have passed, the log file will be trimmed. If this field is replaced by a ! .Ar * , then the number of hours since the last time the log was trimmed will not be taken into consideration. .It Ar flags --- 100,106 ---- .Ar interval hours have passed, the log file will be trimmed. If this field is replaced by a ! .Dq * , then the number of hours since the last time the log was trimmed will not be taken into consideration. .It Ar flags *************** *** 113,118 **** --- 118,143 ---- .Nm inserts to indicate the fact that the logs have been turned over should not be included. + The + .Ar N + flag means no flags are specified. This is used so that you can specify + the next option when you don't want to compress or mark the log as binary. + .It Ar pid_file + The + .Ar pid_file + is the file that the process id is to be read out of. The process id is then + sent a signal to tell the process to reopen it's log file. If + .Ar pid_file + is not specified it will default to + .Pa /var/run/syslog.pid + .It Ar signal + The + .Ar signal + is the name or number of the signal to be sent to the process id. + If + .Ar signal + is not specified it will default to + .Dv SIGHUP . .El .Sh OPTIONS The following options can be used with newsyslog: *************** *** 154,160 **** Theodore Ts'o, MIT Project Athena .Pp Copyright 1987, Massachusetts Institute of Technology ! .Sh "SEE ALSO" .Xr gzip 1 , .Xr syslog 3 , .Xr syslogd 8 --- 179,185 ---- Theodore Ts'o, MIT Project Athena .Pp Copyright 1987, Massachusetts Institute of Technology ! .Sh SEE ALSO .Xr gzip 1 , .Xr syslog 3 , .Xr syslogd 8 Index: newsyslog.c =================================================================== RCS file: /usr/cvs/src/usr.sbin/newsyslog/newsyslog.c,v retrieving revision 1.9 diff -c -r1.9 newsyslog.c *** newsyslog.c 1997/02/22 16:08:26 1.9 --- newsyslog.c 1997/03/03 07:42:39 *************** *** 36,42 **** #define CONF "/etc/athena/newsyslog.conf" /* Configuration file */ #endif #ifndef PIDFILE ! #define PIDFILE "/etc/syslog.pid" #endif #ifndef COMPRESS_PATH #define COMPRESS_PATH "/usr/ucb/compress" /* File compression program */ --- 36,42 ---- #define CONF "/etc/athena/newsyslog.conf" /* Configuration file */ #endif #ifndef PIDFILE ! #define PIDFILE _PATH_LOGPID #endif #ifndef COMPRESS_PATH #define COMPRESS_PATH "/usr/ucb/compress" /* File compression program */ *************** *** 47,52 **** --- 47,58 ---- #ifndef COMPRESS_POSTFIX #define COMPRESS_POSTFIX ".Z" #endif + #ifndef DEFAULT_SIGNAL + #define DEFAULT_SIGNAL SIGHUP + #endif + #ifndef SIGNAL_PREFIX + #define SIGNAL_PREFIX "sig" + #endif #include #include *************** *** 63,68 **** --- 69,75 ---- #include #include #include + #include #define kbytes(size) (((size) + 1023) >> 10) #ifdef _IBMR2 *************** *** 84,89 **** --- 91,99 ---- int hours; /* Hours between log trimming */ int permissions; /* File permissions on the log */ int flags; /* Flags (CE_COMPACT & CE_BINARY) */ + char *pid_file; /* PID file of program to HUP */ + int pid; /* PID from file */ + int signal; /* signal to deliever to process */ struct conf_entry *next; /* Linked list pointer */ }; *************** *** 93,99 **** 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 30000 /* was 65534, see /usr/include/sys/proc.h */ char hostname[MAXHOSTNAMELEN+1]; /* hostname */ --- 103,108 ---- *************** *** 110,120 **** static void do_entry(struct conf_entry *ent); static void PRS(int argc,char **argv); static void usage(); ! static void dotrim(char *log,int numdays,int falgs,int perm, int owner_uid,int group_gid); static int log_trim(char *log); static void compress_log(char *log); static int sizefile(char *file); static int age_old_log(char *file); int main(argc,argv) int argc; --- 119,131 ---- static void do_entry(struct conf_entry *ent); static void PRS(int argc,char **argv); static void usage(); ! static void dotrim(char *log,int numdays,int falgs,int perm, int owner_uid,int group_gid, int pid, char *pid_file, int sig); static int log_trim(char *log); static void compress_log(char *log); static int sizefile(char *file); static int age_old_log(char *file); + static int get_pid(char *file); + static char *strtoupper(const char *str); int main(argc,argv) int argc; *************** *** 137,142 **** --- 148,171 ---- return(0); } + static int get_pid(char *file) + { + char line[13]; + FILE *f; + + f = fopen(file,"r"); + if (f && fgets(line,sizeof(line), f)) { + if(f) + (void)fclose(f); + return atoi(line); + } + + if (f) + (void)fclose(f); + + return 0; + } + static void do_entry(ent) struct conf_entry *ent; *************** *** 173,179 **** ent->log,ent->numlogs); } dotrim(ent->log, ent->numlogs, ent->flags, ! ent->permissions, ent->uid, ent->gid); } else { if (verbose) printf("--> skipping\n"); --- 202,209 ---- ent->log,ent->numlogs); } dotrim(ent->log, ent->numlogs, ent->flags, ! ent->permissions, ent->uid, ent->gid, ent->pid, ! ent->pid_file, ent->signal); } else { if (verbose) printf("--> skipping\n"); *************** *** 186,193 **** char **argv; { int c; - FILE *f; - char line[BUFSIZ]; char *p; progname = argv[0]; --- 216,221 ---- *************** *** 195,208 **** daytime = ctime(&timenow) + 4; daytime[15] = '\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)); --- 223,228 ---- *************** *** 257,263 **** f = stdin; if (!f) err(1, "%s", conf); ! while (fgets(line,BUFSIZ,f)) { if ((line[0]== '\n') || (line[0] == '#')) continue; errline = strdup(line); --- 277,283 ---- f = stdin; if (!f) err(1, "%s", conf); ! while (memset(line, 0, BUFSIZ), fgets(line,BUFSIZ-5,f)) { if ((line[0]== '\n') || (line[0] == '#')) continue; errline = strdup(line); *************** *** 340,350 **** working->flags |= CE_COMPACT; else if ((*q == 'B') || (*q == 'b')) working->flags |= CE_BINARY; ! else errx(1, "Illegal flag in config file -- %c", *q); q++; } free(errline); } if (working) --- 360,415 ---- working->flags |= CE_COMPACT; else if ((*q == 'B') || (*q == 'b')) working->flags |= CE_BINARY; ! else if ((*q == 'N') || (*q == 'n')) { ! /* nop */ ! } else errx(1, "Illegal flag in config file -- %c", *q); q++; } + + q = parse = sob(++parse); /* Optional field */ + *(parse = son(parse)) = '\0'; + if(q && *q) + working->pid_file=strdup(q); + else + working->pid_file=NULL; + if(working->pid_file == NULL) + working->pid_file=strdup(PIDFILE); + + if((working->pid=get_pid(working->pid_file)) == 0) + errx(1, "can't read pid out of file %s", + working->pid_file); + + q = parse = sob(++parse); /* Optional field */ + *(parse = son(parse)) = '\0'; + if (q && *q) { + if(isdigit(*q)) { + /* they provided a decimal signal number */ + working->signal = atoi(q); + if (working->signal <= 0 || + working->signal >= NSIG) + errx(1, "signal %d is invalid in config line: %s", + working->signal, errline); + } else { + /* search for a matching signal name */ + int i; + if(!strncasecmp(q, SIGNAL_PREFIX, + sizeof(SIGNAL_PREFIX)-1)) + q += sizeof(SIGNAL_PREFIX)-1; + for (i=1; i < NSIG && + strcasecmp(q, sys_signame[i]); i++); + if(i == NSIG) + errx(1, "could not find signal %s, on line: %s", + q, errline); + else + working->signal = i; + } + } else { + /* no signal provided, use default */ + working->signal = DEFAULT_SIGNAL; + } + free(errline); } if (working) *************** *** 361,373 **** return(p); } ! static void 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 [MAXPATHLEN+1], file2 [MAXPATHLEN+1]; char zfile1[MAXPATHLEN+1], zfile2[MAXPATHLEN+1]; --- 426,441 ---- return(p); } ! static void dotrim(log,numdays,flags,perm,owner_uid,group_gid,pid,pid_file,sig) char *log; int numdays; int flags; int perm; int owner_uid; int group_gid; + int pid; + char *pid_file; + int sig; { char file1 [MAXPATHLEN+1], file2 [MAXPATHLEN+1]; char zfile1[MAXPATHLEN+1], zfile2[MAXPATHLEN+1]; *************** *** 451,463 **** 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) { ! warnx("preposterous process number: %d", syslog_pid); ! } else if (kill(syslog_pid,SIGHUP)) ! warn("could not restart syslogd"); if (flags & CE_COMPACT) { if (noaction) printf("Compress %s.0\n",log); --- 519,532 ---- printf("chmod %o %s...",perm,log); else (void) chmod(log,perm); ! if (noaction) { ! printf("kill -%s %d (%s)\n", strtoupper(sys_signame[sig]), ! pid, pid_file); ! } else ! if (pid < MIN_PID || pid > MAX_PID) { ! warnx("preposterous process number %d from %s", pid, pid_file); ! } else if (kill(pid,sig)) ! warn("could not restart pid %d from %s", pid, pid_file); if (flags & CE_COMPACT) { if (noaction) printf("Compress %s.0\n",log); *************** *** 553,556 **** --- 622,642 ---- while (p && *p && !isspace(*p)) p++; return(p); + } + + static char *strtoupper(str) + register const char *str; + { + static char *buf; + register int i; + + if(buf) + free(buf); + + buf=malloc(strlen(str)+1); + + i=0; + while((buf[i++]=toupper(str[i])) != '\0'); + + return buf; }