Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Mar 1997 00:00:16 -0800
From:      jmg@hydrogen.nike.efn.org (John-Mark Gurney)
To:        freebsd-gnats-submit@freebsd.org
Cc:        freebsd-current@freebsd.org (FreeBSD Current)
Subject:   misc/2848 newsyslog only notifies syslogd
Message-ID:  <19970303000016.PF49336@hydrogen.nike.efn.org>

next in thread | raw e-mail | index | archive | help

--+WCv1s2RzB2fBlYC

well... I now have a set of patches that allows you to send a signal to a pid
from a pid file...

attached are the patches as they are actually quite long... if you con't read
mime encoding you can obtain the patches from
http://freefall.cdrom.com/~jmg/newsyslog.patch... it includes patches to the
man page for the new usage information along with minor fixes to the man
page...

all I added is another flag `N' which is just a nop... it it a place holder for
the flags when you don't want to specify any...

I then added two more additional option flag... the first is the pid_file that
you want to read the pid file from.. if this option isn't specified it will
default to the syslog pid file...  these patches also modify newsyslog to
obtain the syslogd pid file from the syslogd sources...

the next is the name or number of the signal...  it can be something like
`sigusr1', or `usr1'... if this option isn't specified it will default to
SIGHUP...

a sample like looks like:
/var/log/testlog   600  2    4    *     N  /tmp/pidfile segv

this will read the pid out of /tmp/pidfile and send it the segv signal when the
log needs to be reopened... 

if people could test this patch out... I would be greatful...  I had to add an
ugly hack to get the parsing to work correctly because it was possible to
"fall" off the end of a string and into other data which would corrupt the
pid_file and signal options...  what really needs to happen is a way to
"detect" end of line and be able to stop parsing... otherwise with the current
implementation it continues past the end of the string...

-- 
John-Mark

gurney_j@efn.org
http://resnet.uoregon.edu/~gurney_j/
Modem/FAX: (541) 683-6954   (FreeBSD Box)

Live in Peace, destroy Micro$oft, support free software, run FreeBSD (unix)

--+WCv1s2RzB2fBlYC
Content-Disposition: attachment; filename=patch

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 <stdio.h>
  #include <stdlib.h>
***************
*** 63,68 ****
--- 69,75 ----
  #include <sys/stat.h>
  #include <sys/param.h>
  #include <sys/wait.h>
+ #include <pathnames.h>
  
  #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;
  }

--+WCv1s2RzB2fBlYC--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19970303000016.PF49336>