Changeset 276


Ignore:
Timestamp:
Mar 22, 2010, 9:00:47 PM (10 years ago)
Author:
katerina
Message:

Fix for bugs in log monitoring (tickets #196, #199), and allow shell command monitoring (ticket #197).

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/docs/Changelog

    r275 r276  
     12.6.4:
     2        * Use data directory as default for logfile checkpoints
     3
    142.6.3:
    25        * Fix bug in mail module, recipients incorrectly flagged
  • trunk/include/sh_log_check.h

    r275 r276  
    7777sh_string * sh_read_shell (sh_string * record, struct sh_logfile * logfile);
    7878
     79/* Parses a shell command reply. */
     80struct sh_logrecord * sh_parse_shell (sh_string * logline, void * fileinfo);
     81
    7982/* Simple line reader.   */
    8083sh_string * sh_default_reader (sh_string * record,
  • trunk/src/sh_log_check.c

    r275 r276  
    88#include <sys/stat.h>
    99#include <fcntl.h>
     10
     11#ifdef HAVE_DIRENT_H
     12#include <dirent.h>
     13#define NAMLEN(dirent) sl_strlen((dirent)->d_name)
     14#else
     15#define dirent direct
     16#define NAMLEN(dirent) (dirent)->d_namlen
     17#ifdef HAVE_SYS_NDIR_H
     18#include <sys/ndir.h>
     19#endif
     20#ifdef HAVE_SYS_DIR_H
     21#include <sys/dir.h>
     22#endif
     23#ifdef HAVE_NDIR_H
     24#include <ndir.h>
     25#endif
     26#endif
    1027
    1128#if !defined(O_NONBLOCK)
     
    5875    {  "PACCT",  sh_read_pacct,   sh_parse_pacct,  NULL },
    5976#endif
    60     {  "SHELL",  sh_read_shell,   sh_parse_generic,  sh_eval_fileinfo_generic },
     77    {  "SHELL",  sh_read_shell,   sh_parse_shell,  NULL },
    6178};
    6279
     
    6986};
    7087
     88static int    do_checkpoint_cleanup = S_FALSE;
     89
    7190static char * save_dir = NULL;
    7291
    73 static void * sh_dummy_path = NULL;
    74 
    75 static char * build_path (struct sh_logfile * record)
    76 {
    77   size_t plen;
    78   int    retval;
    79   char * path = NULL;
    80 
    81   sh_dummy_path = (void *)&path;
     92static const char * get_save_dir(void)
     93{
     94  int retval;
    8295
    8396  if (!save_dir)
    8497    {
    85       save_dir = sh_util_strdup(DEFAULT_PIDDIR);
     98      save_dir = sh_util_strdup(DEFAULT_DATAROOT);
    8699
    87100      SH_MUTEX_LOCK(mutex_thread_nolog);
     
    94107        }
    95108    }
    96 
    97   plen = strlen(save_dir);
    98 
    99   if (SL_TRUE == sl_ok_adds(plen, 130))
    100     {
    101       plen += 130; /* 64 + 64 + 2 */
    102       path = SH_ALLOC(plen);
    103       (void) sl_snprintf(path, plen, "%s/%lu_%lu", save_dir,
    104                          (unsigned long) record->device_id,
    105                          (unsigned long) record->inode);
     109  return save_dir;
     110}
     111
     112static void clean_dir()
     113{
     114  DIR * dir;
     115  struct dirent * entry;
     116
     117  const char * dirpath;
     118
     119  if (S_FALSE == do_checkpoint_cleanup)
     120    return;
     121
     122  dirpath = get_save_dir();
     123
     124  if (dirpath)
     125    {
     126      dir = opendir(dirpath);
     127      if (dir)
     128        {
     129          unsigned long a, b;
     130          int retval;
     131          char c;
     132          size_t dlen = strlen(dirpath) + 1;
     133          time_t now  = time(NULL);
     134
     135          while (NULL != (entry = readdir(dir)))
     136            {
     137              retval = sscanf(entry->d_name, "%lu_%lu%c", &a, &b, &c);
     138
     139              if (2 == retval)
     140                {
     141                  struct stat buf;
     142                  char * path;
     143                  size_t  plen = strlen(entry->d_name) + 1;
     144
     145                  if (SL_TRUE == sl_ok_adds(plen, dlen))
     146                    {
     147                      plen += dlen;
     148                      path = SH_ALLOC(plen);
     149                      (void) sl_snprintf(path, plen, "%s/%s",
     150                                         dirpath,entry->d_name);
     151
     152                      if (0 == retry_lstat(FIL__, __LINE__, path, &buf) &&
     153                          S_ISREG(buf.st_mode))
     154                        {
     155                          if (buf.st_mtime < now &&
     156                              (now - buf.st_mtime) > 2592000) /* 30 days */
     157                            {
     158                              if (0 == tf_trust_check (path, SL_YESPRIV))
     159                                {
     160                                  unlink(path);
     161                                }
     162                            }
     163                        }
     164                    }
     165                }
     166            }
     167          closedir(dir);
     168        }
     169    }
     170}
     171
     172static char * build_path (struct sh_logfile * record)
     173{
     174  size_t plen;
     175  char * path = NULL;
     176  const char * dir = get_save_dir();
     177
     178  if (dir)
     179    {
     180      plen = strlen(dir);
     181
     182      if (SL_TRUE == sl_ok_adds(plen, 130))
     183        {
     184          plen += 130; /* 64 + 64 + 2 */
     185          path = SH_ALLOC(plen);
     186          (void) sl_snprintf(path, plen, "%s/%lu_%lu", dir,
     187                             (unsigned long) record->device_id,
     188                             (unsigned long) record->inode);
     189        }
    106190    }
    107191
     
    113197  char * path;
    114198  FILE * fd;
     199  mode_t mask;
    115200  struct logfile_record save_rec;
    116201
     
    125210        }
    126211
     212      mask = umask(S_IWGRP | S_IWOTH);
    127213      fd = fopen(path, "wb");
     214      (void) umask(mask);
     215
    128216      if (fd)
    129217        {
     
    260348
    261349  thisfile->filename     = filename;
    262   if (strcmp(splits[0], _("SHELL")))
     350  if (0 == strcmp(splits[0], _("SHELL")))
    263351    thisfile->flags        = SH_LOGFILE_NOFILE;
    264352  else
     
    729817}
    730818
     819struct task_entry
     820{
     821  sh_tas_t task;
     822  struct task_entry * next;
     823};
     824
     825static struct task_entry * tasklist = NULL;
     826
     827static struct task_entry * task_find(FILE * fp)
     828{
     829  struct task_entry * entry = tasklist;
     830  while (entry)
     831    {
     832      if (entry->task.pipe == fp)
     833        return (entry);
     834      entry = entry->next;
     835    }
     836  return NULL;
     837}
     838 
     839static void task_remove(struct task_entry * task)
     840{
     841  struct task_entry * entry = tasklist;
     842  struct task_entry * prev  = tasklist;
     843
     844  while (entry)
     845    {
     846      if (entry == task)
     847        {
     848          if (entry == tasklist)
     849            {
     850              tasklist = entry->next;
     851              SH_FREE(entry);
     852              return;
     853            }
     854          else
     855            {
     856              prev->next = entry->next;
     857              SH_FREE(entry);
     858              return;
     859            }
     860        }
     861      prev  = entry;
     862      entry = entry->next;
     863    }
     864  return;
     865}
     866 
     867static void task_add(struct task_entry * entry)
     868{
     869  entry->next = tasklist;
     870  tasklist    = entry;
     871  return;
     872}
     873 
    731874sh_string * sh_command_reader (sh_string * s, struct sh_logfile * logfile)
    732875{
    733   sh_tas_t task;
    734   struct  sigaction  new_act;
    735   struct  sigaction  old_act;
    736 
    737   volatile int         status;
     876  struct task_entry * entry;
     877
     878  struct  sigaction   new_act;
     879  struct  sigaction   old_act;
     880
     881  volatile int        status;
    738882  char * tmp;
    739883
     
    744888      /* ignore SIGPIPE (instead get EPIPE if connection is closed)
    745889       */
     890      memset(&new_act, 0, sizeof(struct  sigaction));
    746891      new_act.sa_handler = SIG_IGN;
    747892      (void) retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
     
    751896      status = (int) sh_string_read(s, logfile->fp, 8192);
    752897
     898      fprintf(stderr, "FIXME: %s\n", sh_string_str(s));
     899
    753900      /* restore old signal handler
    754901       */
     
    757904      if (status <= 0)
    758905        {
    759           sh_ext_pclose (&task);
     906          entry = task_find(logfile->fp);
     907          sh_ext_pclose (&(entry->task));
     908          task_remove(entry);
     909
    760910          logfile->fp = NULL;
    761911          sh_string_destroy(&s);
     
    778928    }
    779929
    780   status = sh_ext_popen_init (&task, logfile->filename);
     930  entry = SH_ALLOC(sizeof(struct task_entry));
     931
     932  status = sh_ext_popen_init (&(entry->task), logfile->filename);
    781933  if (0 == status)
    782934    {
    783       logfile->fp = task.pipe;
     935      task_add(entry);
     936      logfile->fp = entry->task.pipe;
    784937      goto start_read;
    785938    }
    786939  else
    787940    {
     941      SH_FREE(entry);
    788942      SH_MUTEX_LOCK(mutex_thread_nolog);
    789943      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN,
     
    10501204      sh_keep_match();
    10511205      sh_log_mark_check();
     1206      clean_dir();
    10521207    }
    10531208  SH_MUTEX_UNLOCK(mutex_logmon_check);
     
    10831238
    10841239static int sh_logmon_set_active  (const char *str);
     1240static int sh_logmon_set_clean  (const char *str);
    10851241static int sh_logmon_set_interval(const char *str);
    10861242static int sh_logmon_add_watch (const char * str);
     
    11041260    },
    11051261    {
     1262        N_("logmonclean"),
     1263        sh_logmon_set_clean,
     1264    },
     1265    {
    11061266        N_("logmonwatch"),
    11071267        sh_logmon_add_watch,
     
    11701330
    11711331  value = sh_util_flagval(str, &ShLogmonActive);
     1332
     1333  SL_RETURN((value), _("sh_logmon_set_active"));
     1334}
     1335
     1336/* Decide if we're active.
     1337 */
     1338static int sh_logmon_set_clean(const char *str)
     1339{
     1340  int value;
     1341   
     1342  SL_ENTER(_("sh_logmon_set_active"));
     1343
     1344  value = sh_util_flagval(str, &do_checkpoint_cleanup);
    11721345
    11731346  SL_RETURN((value), _("sh_logmon_set_active"));
  • trunk/src/sh_log_evalrule.c

    r272 r276  
    10391039    msg = sh_util_safe_name_keepspace (sh_string_str(record->message));
    10401040  }
    1041   tmp = sh_util_safe_name (record->filename);
     1041  tmp = sh_util_safe_name_keepspace (record->filename);
    10421042  ttt = sh_util_safe_name_keepspace (sh_string_str(record->timestr));
    10431043  sh_error_handle (severity, FIL__, __LINE__, 0, MSG_LOGMON_REP,
     
    10701070
    10711071  SH_MUTEX_LOCK(mutex_thread_nolog);
    1072   tmp = sh_util_safe_name (sh_string_str(path));
     1072  tmp = sh_util_safe_name_keepspace (sh_string_str(path));
    10731073  msg = sh_util_safe_name_keepspace (sh_string_str(message));
    10741074  sh_error_handle (severity, FIL__, __LINE__, 0, MSG_LOGMON_SUM,
  • trunk/src/sh_log_parse_apache.c

    r203 r276  
    390390      record->message   = sh_string_new_from_lchar(sh_string_str(logline),
    391391                                                   sh_string_len(logline));
    392       record->pid       = 0;
     392      record->pid       = PID_INVALID;
    393393
    394394      pcre_free(hstr);
  • trunk/src/sh_nmail.c

    r275 r276  
    966966{
    967967  struct alias * new;
     968  sh_filter_type * p = NULL;
    968969
    969970  while (list)
     
    976977        {
    977978          sh_filter_free(new->mail_filter);
    978           SH_FREE(new->mail_filter);
     979          if (!p || p != new->mail_filter)
     980            {
     981              p = new->mail_filter;
     982              SH_FREE(new->mail_filter);
     983            }
    979984        }
    980985      sh_string_destroy(&(new->recipient));
     
    10071012        {
    10081013          sh_filter_free(item->mail_filter);
    1009           SH_FREE(item->mail_filter);
     1014          /* SH_FREE(item->mail_filter); */
    10101015        }
    10111016      SH_FREE(item);
  • trunk/src/sh_string.c

    r265 r276  
    1717
    1818#include <ctype.h>
     19#include <errno.h>
     20
    1921/* Split array at delim in at most nfields fields.
    2022 * Empty fields are returned as empty (zero-length) strings.
     
    286288}
    287289
     290static char * sh_str_fgets (char *s, int size, FILE *fp)
     291{
     292  char * ret;
     293  do {
     294    clearerr(fp);
     295    ret = fgets(s, size, fp);
     296  } while (ret == NULL && ferror(fp) && errno == EAGAIN);
     297
     298  return ret;
     299}
     300
    288301size_t sh_string_read_int(sh_string * s, FILE * fp, size_t maxlen, char *start)
    289302{
     
    293306  if (start)
    294307    {
    295       int first = fgetc(fp);
     308      int first;
     309
     310      do {
     311        clearerr(fp);
     312        first = fgetc(fp);
     313      } while (first == EOF && ferror(fp) && errno == EAGAIN);
    296314
    297315      if (first == EOF)
     
    313331  /* case 1) EOF or error
    314332   */
    315   if (fgets(s->str, s->siz, fp) == NULL)
     333  if (sh_str_fgets(s->str, s->siz, fp) == NULL)
    316334    {
    317335      sh_string_truncate(s, 0);
     
    348366      }
    349367   
    350     if (fgets(&(s->str[s->len]), (s->siz - s->len), fp) == NULL)
     368    if (sh_str_fgets(&(s->str[s->len]), (s->siz - s->len), fp) == NULL)
    351369      {
    352370        if (ferror(fp))
     
    542560  int    i, curr, last;
    543561
    544 
    545562  for (i = 0; i < ovecnum; ++i)
    546563    {
     
    588605      if (ovector[2*i] >= 0)
    589606        {
    590           curr = i;
     607          curr = 2*i;
    591608          break;
    592609        }
     
    599616      /* First part, until start of first replacement
    600617       */
    601       memcpy(p, s->str, (size_t)ovector[curr]); p += ovector[curr];
    602       memcpy(p, replacement,    rlen);       p += rlen;
    603       *p = '\0'; r->len += (ovector[curr] + rlen);
     618      if (r->siz > (unsigned int)ovector[curr]) {
     619        memcpy(p, s->str, (size_t)ovector[curr]);
     620        p += ovector[curr];
     621        r->len += ovector[curr];
     622      }
     623      if (r->siz > (r->len + rlen)) {
     624        memcpy(p, replacement,    rlen);
     625        p += rlen;
     626        r->len += rlen;
     627      }
     628      *p = '\0';
    604629
    605630      last = curr + 1;
     
    618643              len = (size_t) tlen;
    619644
    620               if (tlen > 0)
     645              if (tlen > 0 && r->siz > (r->len + len))
    621646                {
    622647                  memcpy(p, &(s->str[ovector[last]]), (size_t)len);
    623648                  p += len;
     649                  r->len += len;
    624650                }
    625651             
    626652              /* The replacement */
    627               memcpy(p, replacement, rlen);       
    628               p += rlen;
     653              if (r->siz > (r->len + rlen)) {
     654                memcpy(p, replacement, rlen);       
     655                p += rlen;
     656                r->len += rlen;
     657              }
    629658             
    630659              /* null terminate */
    631               *p = '\0'; r->len += (len + rlen);
     660              *p = '\0';
    632661
    633662              last = curr + 1;
     
    645674            {
    646675              len = (size_t)tlen;
    647               memcpy(p, &(s->str[ovector[2*i -1]]), (size_t)len);
    648               p += len; *p = '\0'; r->len += (len - 1);
     676              if (r->siz >= (r->len + len)) {
     677                memcpy(p, &(s->str[ovector[2*i -1]]), (size_t)len);
     678                p += (len - 1);
     679                r->len += (len - 1);
     680                *p = '\0';
     681              }
    649682            }
    650683        }
Note: See TracChangeset for help on using the changeset viewer.