[BACK]Return to newsyslog.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / newsyslog

Diff for /src/usr.bin/newsyslog/newsyslog.c between version 1.9 and 1.10

version 1.9, 1997/04/27 13:48:55 version 1.10, 1997/07/07 22:50:56
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
   
 /*  /*
    * Copyright (c) 1997, Jason Downs.  All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    * 1. Redistributions of source code must retain the above copyright
    *    notice, this list of conditions and the following disclaimer.
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the
    *    documentation and/or other materials provided with the distribution.
    * 3. All advertising materials mentioning features or use of this software
    *    must display the following acknowledgement:
    *      This product includes software developed by Jason Downs for the
    *      OpenBSD system.
    * 4. Neither the name(s) of the author(s) nor the name OpenBSD
    *    may be used to endorse or promote products derived from this software
    *    without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
    * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
    * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    * SUCH DAMAGE.
    */
   
   /*
  * This file contains changes from the Open Software Foundation.   * This file contains changes from the Open Software Foundation.
  */   */
   
Line 44 
Line 76 
 #ifndef COMPRESS_POSTFIX  #ifndef COMPRESS_POSTFIX
 #define COMPRESS_POSTFIX ".Z"  #define COMPRESS_POSTFIX ".Z"
 #endif  #endif
   #ifndef STATS_DIR
   #define STATS_DIR "/etc"
   #endif
   #ifndef SENDMAIL
   #define SENDMAIL "/usr/lib/sendmail"
   #endif
   
 #include <stdio.h>  #include <stdio.h>
 #include <sys/types.h>  #include <sys/types.h>
Line 62 
Line 100 
   
 #define kbytes(size)  (((size) + 1023) >> 10)  #define kbytes(size)  (((size) + 1023) >> 10)
   
 #define CE_COMPACT 1            /* Compact the achived log files */  #define CE_COMPACT      0x01            /* Compact the achived log files */
 #define CE_BINARY 2             /* Logfile is in binary, don't add */  #define CE_BINARY       0x02            /* Logfile is in binary, don't add */
                                 /* status messages */                                          /* status messages */
   #define CE_MONITOR      0x04            /* Monitory for changes */
 #define NONE -1  #define NONE -1
   
 struct conf_entry {  struct conf_entry {
Line 76 
Line 115 
         int     hours;          /* Hours between log trimming */          int     hours;          /* Hours between log trimming */
         int     permissions;    /* File permissions on the log */          int     permissions;    /* File permissions on the log */
         int     flags;          /* Flags (CE_COMPACT & CE_BINARY)  */          int     flags;          /* Flags (CE_COMPACT & CE_BINARY)  */
           char    *whom;          /* Whom to notify if logfile changes */
         struct conf_entry       *next; /* Linked list pointer */          struct conf_entry       *next; /* Linked list pointer */
 };  };
   
Line 83 
Line 123 
 int     verbose = 0;            /* Print out what's going on */  int     verbose = 0;            /* Print out what's going on */
 int     needroot = 1;           /* Root privs are necessary */  int     needroot = 1;           /* Root privs are necessary */
 int     noaction = 0;           /* Don't do anything, just show it */  int     noaction = 0;           /* Don't do anything, just show it */
   int     monitor = 0;            /* Don't do monitoring by default */
 char    *conf = CONF;           /* Configuration file to use */  char    *conf = CONF;           /* Configuration file to use */
 time_t  timenow;  time_t  timenow;
 int     syslog_pid;             /* read in from /etc/syslog.pid */  int     syslog_pid;             /* read in from /etc/syslog.pid */
Line 104 
Line 145 
 int age_old_log __P((char *));  int age_old_log __P((char *));
 char *sob __P((char *));  char *sob __P((char *));
 char *son __P((char *));  char *son __P((char *));
 int isnumber __P((char *));  int isnumberstr __P((char *));
   void domonitor __P((char *, char *));
   FILE *openmail __P((void));
   void closemail __P((FILE *));
   
 int main(argc, argv)  int main(argc, argv)
         int argc;          int argc;
Line 149 
Line 193 
                         printf("size (Kb): %d [%d] ", size, ent->size);                          printf("size (Kb): %d [%d] ", size, ent->size);
                 if (verbose && (ent->hours > 0))                  if (verbose && (ent->hours > 0))
                         printf(" age (hr): %d [%d] ", modtime, ent->hours);                          printf(" age (hr): %d [%d] ", modtime, ent->hours);
                 if (((ent->size > 0) && (size >= ent->size)) ||                  if (monitor && ent->flags & CE_MONITOR)
                           domonitor(ent->log, ent->whom);
                   if (!monitor && ((ent->size > 0) && (size >= ent->size)) ||
                     ((ent->hours > 0) && ((modtime >= ent->hours)                      ((ent->hours > 0) && ((modtime >= ent->hours)
                                         || (modtime < 0)))) {                                          || (modtime < 0)))) {
                         if (verbose)                          if (verbose)
Line 202 
Line 248 
                 *p = '\0';                  *p = '\0';
   
         optind = 1;             /* Start options parsing */          optind = 1;             /* Start options parsing */
         while ((c = getopt(argc,argv,"nrvf:t:")) != -1) {          while ((c = getopt(argc,argv,"nrvmf:t:")) != -1) {
                 switch (c) {                  switch (c) {
                 case 'n':                  case 'n':
                         noaction++; /* This implies needroot as off */                          noaction++; /* This implies needroot as off */
Line 216 
Line 262 
                 case 'f':                  case 'f':
                         conf = optarg;                          conf = optarg;
                         break;                          break;
                   case 'm':
                           monitor++;
                           break;
                 default:                  default:
                         usage();                          usage();
                 }                  }
Line 255 
Line 304 
                 if ((line[0]== '\n') || (line[0] == '#'))                  if ((line[0]== '\n') || (line[0] == '#'))
                         continue;                          continue;
                 errline = strdup(line);                  errline = strdup(line);
                   if (errline == NULL) {
                           (void) fprintf(stderr,"%s: ",progname);
                           perror("strdup()");
                           exit(1);
                   }
                 if (!first) {                  if (!first) {
                         working = (struct conf_entry *) malloc(sizeof(struct conf_entry));                          working = (struct conf_entry *) malloc(sizeof(struct conf_entry));
                           if (working == NULL) {
                                   (void) fprintf(stderr,"%s: ",progname);
                                   perror("malloc()");
                                   exit(1);
                           }
                         first = working;                          first = working;
                 } else {                  } else {
                         working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry));                          working->next = (struct conf_entry *) malloc(sizeof(struct conf_entry));
                           if (working->next == NULL) {
                                   (void) fprintf(stderr,"%s: ",progname);
                                   perror("malloc()");
                                   exit(1);
                           }
                         working = working->next;                          working = working->next;
                 }                  }
   
                 q = parse = missing_field(sob(line),errline);                  q = parse = missing_field(sob(line),errline);
                 *(parse = son(line)) = '\0';                  *(parse = son(line)) = '\0';
                 working->log = strdup(q);                  working->log = strdup(q);
                   if (working->log == NULL) {
                           (void) fprintf(stderr,"%s: ",progname);
                           perror("strdup()");
                           exit(1);
                   }
   
                 q = parse = missing_field(sob(++parse),errline);                  q = parse = missing_field(sob(++parse),errline);
                 *(parse = son(parse)) = '\0';                  *(parse = son(parse)) = '\0';
                 if ((group = strchr(q, '.')) != NULL) {                  if ((group = strchr(q, '.')) != NULL) {
                     *group++ = '\0';                      *group++ = '\0';
                     if (*q) {                      if (*q) {
                         if (!(isnumber(q))) {                          if (!(isnumberstr(q))) {
                             if ((pass = getpwnam(q)) == NULL) {                              if ((pass = getpwnam(q)) == NULL) {
                                 fprintf(stderr,                                  fprintf(stderr,
                                     "Error in config file; unknown user:\n");                                      "Error in config file; unknown user:\n");
Line 287 
Line 356 
   
                     q = group;                      q = group;
                     if (*q) {                      if (*q) {
                         if (!(isnumber(q))) {                          if (!(isnumberstr(q))) {
                             if ((grp = getgrnam(q)) == NULL) {                              if ((grp = getgrnam(q)) == NULL) {
                                 fprintf(stderr,                                  fprintf(stderr,
                                     "Error in config file; unknown group:\n");                                      "Error in config file; unknown group:\n");
Line 344 
Line 413 
                                 working->flags |= CE_COMPACT;                                  working->flags |= CE_COMPACT;
                         else if ((*q == 'B') || (*q == 'b'))                          else if ((*q == 'B') || (*q == 'b'))
                                 working->flags |= CE_BINARY;                                  working->flags |= CE_BINARY;
                           else if ((*q == 'M') || (*q == 'm'))
                                   working->flags |= CE_MONITOR;
                         else {                          else {
                                 fprintf(stderr,                                  fprintf(stderr,
                                         "Illegal flag in config file -- %c\n",                                          "Illegal flag in config file -- %c\n",
Line 352 
Line 423 
                         }                          }
                         q++;                          q++;
                 }                  }
   
                   working->whom = NULL;
                   if (working->flags & CE_MONITOR) {      /* Optional field */
                           q = parse = sob(++parse);
                           *(parse = son(parse)) = '\0';
   
                           working->whom = strdup(q);
                           if (working->log == NULL) {
                                   (void) fprintf(stderr,"%s: ",progname);
                                   perror("strdup()");
                                   exit(1);
                           }
                   }
   
                 free(errline);                  free(errline);
         }          }
Line 560 
Line 644 
   
 /* Check if string is actually a number */  /* Check if string is actually a number */
   
 int isnumber(string)  int isnumberstr(string)
 char *string;          char *string;
 {  {
         while (*string != '\0') {          while (*string != '\0') {
             if (!isdigit(*string++))              if (!isdigit(*string++))
                 return(0);                  return(0);
         }          }
         return(1);          return(1);
   }
   
   void domonitor(log, whom)
           char *log, *whom;
   {
           struct stat sb, tsb;
           char *fname, *flog, *p, *rb = NULL;
           FILE *fp;
           off_t osize;
           int rd;
   
           if (stat(log, &sb) < 0)
                   return;
   
           flog = strdup(log);
           if (flog == NULL) {
                   (void) fprintf(stderr,"%s: ",progname);
                   perror("strdup()");
                   exit(1);
           }
           for (p = flog; *p != '\0'; p++) {
                   if (*p == '/')
                           *p = '_';
           }
           fname = (char *) malloc(strlen(STATS_DIR) + strlen(flog) + 17);
           if (fname == NULL) {
                   (void) fprintf(stderr,"%s: ",progname);
                   perror("malloc()");
                   exit(1);
           }
           sprintf(fname, "%s/newsyslog.%s.size", STATS_DIR, flog);
   
           /* ..if it doesn't exist, simply record the current size. */
           if ((sb.st_size == 0) || stat(fname, &tsb) < 0)
                   goto update;
   
           fp = fopen(fname, "r");
           if (fp == NULL) {
                   (void) fprintf(stderr,"%s: ",progname);
                   perror(fname);
                   goto cleanup;
           }
   #ifdef QUAD_OFF_T
           if (fscanf(fp, "%qd\n", &osize) != 1) {
   #else
           if (fscanf(fp, "%ld\n", &osize) != 1) {
   #endif  /* QUAD_OFF_T */
                   fclose(fp);
                   goto update;
           }
   
           fclose(fp);
   
           /* If the file is smaller, mark the entire thing as changed. */
           if (sb.st_size < osize)
                   osize = 0;
   
           /* Now see if current size is larger. */
           if (sb.st_size > osize) {
                   rb = (char *) malloc(sb.st_size - osize);
                   if (rb == NULL) {
                           (void) fprintf(stderr,"%s: ",progname);
                           perror("malloc()");
                           exit(1);
                   }
   
                   /* Open logfile, seek. */
                   fp = fopen(log, "r");
                   if (fp == NULL) {
                           (void) fprintf(stderr,"%s: ",progname);
                           perror(log);
                           goto cleanup;
                   }
                   fseek(fp, osize, SEEK_SET);
                   rd = fread(rb, 1, sb.st_size - osize, fp);
                   if (rd < 1) {
                           (void) fprintf(stderr,"%s: ",progname);
                           perror("fread()");
                           fclose(fp);
                           goto cleanup;
                   }
   
                   /* Send message. */
                   fclose(fp);
   
                   fp = openmail();
                   if (fp == NULL) {
                           (void) fprintf(stderr,"%s: ",progname);
                           perror("openmail()");
                           goto cleanup;
                   }
                   fprintf(fp, "To: %s\nSubject: LOGFILE NOTIFICATION: %s\n\n\n",
                       whom, log);
                   fwrite(rb, 1, rd, fp);
                   fputs("\n\n", fp);
   
                   closemail(fp);
           }
   update:
           /* Reopen for writing and update file. */
           fp = fopen(fname, "w");
           if (fp == NULL) {
                   (void) fprintf(stderr,"%s: ",progname);
                   perror(fname);
                   goto cleanup;
           }
   #ifdef QUAD_OFF_T
           fprintf(fp, "%qd\n", sb.st_size);
   #else
           fprintf(fp, "%ld\n", sb.st_size);
   #endif  /* QUAD_OFF_T */
           fclose(fp);
   
   cleanup:
           free(flog);
           free(fname);
           if (rb != NULL)
                   free(rb);
   }
   
   FILE *openmail()
   {
           char *cmdbuf;
           FILE *ret;
   
           cmdbuf = (char *) malloc(strlen(SENDMAIL) + 3);
           if (cmdbuf == NULL)
                   return(NULL);
   
           sprintf(cmdbuf, "%s -t", SENDMAIL);
           ret = popen(cmdbuf, "w");
   
           free(cmdbuf);
           return(ret);
   }
   
   void closemail(pfp)
           FILE *pfp;
   {
           pclose(pfp);
 }  }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10