Esempio n. 1
0
static int
grep_or_recurse(char *filename, BOOL dir_recurse, BOOL show_filenames,
  BOOL only_one_at_top)
{
int rc = 1;
int sep;
FILE *in;

/* If the file is a directory and we are recursing, scan each file within it.
The scanning code is localized so it can be made system-specific. */

if ((sep = isdirectory(filename)) != 0 && dir_recurse)
  {
  char buffer[1024];
  char *nextfile;
  directory_type *dir = opendirectory(filename);

  if (dir == NULL)
    {
    fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", filename,
      strerror(errno));
    return 2;
    }

  while ((nextfile = readdirectory(dir)) != NULL)
    {
    int frc;
    sprintf(buffer, "%.512s%c%.128s", filename, sep, nextfile);
    frc = grep_or_recurse(buffer, dir_recurse, TRUE, FALSE);
    if (frc == 0 && rc == 1) rc = 0;
    }

  closedirectory(dir);
  return rc;
  }

/* If the file is not a directory, or we are not recursing, scan it. If this is
the first and only argument at top level, we don't show the file name (unless
we are only showing the file name). Otherwise, control is via the
show_filenames variable. */

in = fopen(filename, "r");
if (in == NULL)
  {
  fprintf(stderr, "pcregrep: Failed to open %s: %s\n", filename, strerror(errno));
  return 2;
  }

rc = pcregrep(in, (filenames_only || (show_filenames && !only_one_at_top))?
  filename : NULL);
fclose(in);
return rc;
}
Esempio n. 2
0
void dogrep(struct user *user, char *tail)
{
  FILE *fp;
  int i = 1, errptr, opt = 0;
  const char *error;
  char *options, *pattern, *ep;
  char logfile[256];

  /* Check auth level.. */
  if (!CheckAuthLevel(user, 250))
    return;

  options = tail;
  pattern = SeperateWord(tail);

  if (NULL == options) {
    Usage(user, 1);
    return;
  }

  invert = FALSE;
  max_hits = HITS;
  if ('-' == options[0]) {
    while (options[i]) {
      switch (options[i++]) {
      case 'i':
        opt |= PCRE_CASELESS;
        break;
      case 'v':
        invert = TRUE;
        break;
      case 'l':
        if (NULL != pattern) {
          if ((max_hits = (int) strtol(pattern, &ep, 10)) > MAX_HITS)
            max_hits = MAX_HITS;
          if (0 == max_hits)
            max_hits = HITS;
          pattern = SeperateWord(pattern);
        }
        break;
      case 'V':
        NoticeToUser(user, "PCRE version %s", pcre_version());
        break;
      default:
        NoticeToUser(user, "unknown option \"%c\"", options[i - 1]);
        return;
        break;
      }
    }
  } else {
    pattern = options;
  }

  SeperateWord(pattern);

  if (NULL == pattern) {
    Usage(user, 1);
    return;
  }

  if (NULL == (cpattern = pcre_compile(pattern, opt, &error, &errptr, NULL))) {
    NoticeToUser(user, "error in regex at offset %d: %s", errptr, error);
    return;
  }

  hints = pcre_study(cpattern, 0, &error);
  if (NULL != error) {
    NoticeToUser(user, "error while studing regex: %s", error);
    return;
  }

  NoticeToUser(user, "Log entries%smatching \"%s\"", (TRUE == invert) ? " NOT " : " ", pattern);

  count = 0;
  for (i = NUMBEROFLOGFILES; (i >= 0 && count < max_hits); i--) {
    snprintf(logfile, 256, "%s.%i", LOGFILE, i);
    if (NULL == (fp = fopen(logfile, "r"))) {
      NoticeToUser(user, "failed to open: %s (%s)", logfile, strerror(errno));
    } else {
      pcregrep(fp, logfile, user);
      fclose(fp);
    }
  }

  if (cpattern != NULL)
    free(cpattern);
  if (hints != NULL)
    free(hints);

  if (count >= max_hits)
    NoticeToUser(user, "--- More than %d hits, list truncated", max_hits);

  NoticeToUser(user, "--- End of list - %d matc%s", count, (1 == count) ? "h" : "hes");
  NoticeToUser(user, "Done.");
}
Esempio n. 3
0
int
main(int argc, char **argv)
{
int i, j;
int rc = 1;
int options = 0;
int errptr;
const char *error;
BOOL only_one_at_top;

/* Process the options */

for (i = 1; i < argc; i++)
  {
  option_item *op = NULL;
  char *option_data = (char *)"";    /* default to keep compiler happy */
  BOOL longop;
  BOOL longopwasequals = FALSE;

  if (argv[i][0] != '-') break;

  /* If we hit an argument that is just "-", it may be a reference to STDIN,
  but only if we have previously had -f to define the patterns. */

  if (argv[i][1] == 0)
    {
    if (pattern_filename != NULL) break;
      else exit(usage(2));
    }

  /* Handle a long name option, or -- to terminate the options */

  if (argv[i][1] == '-')
    {
    char *arg = argv[i] + 2;
    char *argequals = strchr(arg, '=');

    if (*arg == 0)    /* -- terminates options */
      {
      i++;
      break;                /* out of the options-handling loop */
      }

    longop = TRUE;

    /* Some long options have data that follows after =, for example file=name.
    Some options have variations in the long name spelling: specifically, we
    allow "regexp" because GNU grep allows it, though I personally go along
    with Jeff Friedl in preferring "regex" without the "p". These options are
    entered in the table as "regex(p)". No option is in both these categories,
    fortunately. */

    for (op = optionlist; op->one_char != 0; op++)
      {
      char *opbra = strchr(op->long_name, '(');
      char *equals = strchr(op->long_name, '=');
      if (opbra == NULL)     /* Not a (p) case */
        {
        if (equals == NULL)  /* Not thing=data case */
          {
          if (strcmp(arg, op->long_name) == 0) break;
          }
        else                 /* Special case xxx=data */
          {
          int oplen = equals - op->long_name;
          int arglen = (argequals == NULL)? strlen(arg) : argequals - arg;
          if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0)
            {
            option_data = arg + arglen;
            if (*option_data == '=')
              {
              option_data++;
              longopwasequals = TRUE;
              }
            break;
            }
          }
        }
      else                   /* Special case xxxx(p) */
        {
        char buff1[24];
        char buff2[24];
        int baselen = opbra - op->long_name;
        sprintf(buff1, "%.*s", baselen, op->long_name);
        sprintf(buff2, "%s%.*s", buff1, strlen(op->long_name) - baselen - 2,
          opbra + 1);
        if (strcmp(arg, buff1) == 0 || strcmp(arg, buff2) == 0)
          break;
        }
      }

    if (op->one_char == 0)
      {
      fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]);
      exit(usage(2));
      }
    }

  /* One-char options; many that have no data may be in a single argument; we
  continue till we hit the last one or one that needs data. */

  else
    {
    char *s = argv[i] + 1;
    longop = FALSE;
    while (*s != 0)
      {
      for (op = optionlist; op->one_char != 0; op++)
        { if (*s == op->one_char) break; }
      if (op->one_char == 0)
        {
        fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n",
          *s, argv[i]);
        exit(usage(2));
        }
      if (op->type != OP_NODATA || s[1] == 0)
        {
        option_data = s+1;
        break;
        }
      options = handle_option(*s++, options);
      }
    }

  /* At this point we should have op pointing to a matched option */

  if (op->type == OP_NODATA)
    options = handle_option(op->one_char, options);
  else
    {
    if (*option_data == 0)
      {
      if (i >= argc - 1 || longopwasequals)
        {
        fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]);
        exit(usage(2));
        }
      option_data = argv[++i];
      }

    if (op->type == OP_STRING) *((char **)op->dataptr) = option_data; else
      {
      char *endptr;
      int n = strtoul(option_data, &endptr, 10);
      if (*endptr != 0)
        {
        if (longop)
          fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%s\n",
            option_data, op->long_name);
        else
          fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n",
            option_data, op->one_char);
        exit(usage(2));
        }
      *((int *)op->dataptr) = n;
      }
    }
  }

/* Options have been decoded. If -C was used, its value is used as a default
for -A and -B. */

if (both_context > 0)
  {
  if (after_context == 0) after_context = both_context;
  if (before_context == 0) before_context = both_context;
  }

pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *));
hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *));

if (pattern_list == NULL || hints_list == NULL)
  {
  fprintf(stderr, "pcregrep: malloc failed\n");
  return 2;
  }

/* Compile the regular expression(s). */

if (pattern_filename != NULL)
  {
  FILE *f = fopen(pattern_filename, "r");
  char buffer[MBUFTHIRD + 16];
  char *rdstart;
  int adjust = 0;

  if (f == NULL)
    {
    fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename,
      strerror(errno));
    return 2;
    }

  if (whole_lines)
    {
    strcpy(buffer, "^(?:");
    adjust = 4;
    }
  else if (word_match)
    {
    strcpy(buffer, "\\b");
    adjust = 2;
    }

  rdstart = buffer + adjust;
  while (fgets(rdstart, MBUFTHIRD, f) != NULL)
    {
    char *s = rdstart + (int)strlen(rdstart);
    if (pattern_count >= MAX_PATTERN_COUNT)
      {
      fprintf(stderr, "pcregrep: Too many patterns in file (max %d)\n",
        MAX_PATTERN_COUNT);
      return 2;
      }
    while (s > rdstart && isspace((unsigned char)(s[-1]))) s--;
    if (s == rdstart) continue;
    if (whole_lines) strcpy(s, ")$");
      else if (word_match)strcpy(s, "\\b");
        else *s = 0;
    pattern_list[pattern_count] = pcre_compile(buffer, options, &error,
      &errptr, NULL);
    if (pattern_list[pattern_count++] == NULL)
      {
      fprintf(stderr, "pcregrep: Error in regex number %d at offset %d: %s\n",
        pattern_count, errptr - adjust, error);
      return 2;
      }
    }
  fclose(f);
  }

/* If no file name, a single regex must be given inline. */

else
  {
  char buffer[MBUFTHIRD + 16];
  char *pat;
  int adjust = 0;

  if (i >= argc) return usage(2);

  if (whole_lines)
    {
    sprintf(buffer, "^(?:%.*s)$", MBUFTHIRD, argv[i++]);
    pat = buffer;
    adjust = 4;
    }
  else if (word_match)
    {
    sprintf(buffer, "\\b%.*s\\b", MBUFTHIRD, argv[i++]);
    pat = buffer;
    adjust = 2;
    }
  else pat = argv[i++];

  pattern_list[0] = pcre_compile(pat, options, &error, &errptr, NULL);

  if (pattern_list[0] == NULL)
    {
    fprintf(stderr, "pcregrep: Error in regex at offset %d: %s\n",
      errptr - adjust, error);
    return 2;
    }
  pattern_count++;
  }

/* Study the regular expressions, as we will be running them many times */

for (j = 0; j < pattern_count; j++)
  {
  hints_list[j] = pcre_study(pattern_list[j], 0, &error);
  if (error != NULL)
    {
    char s[16];
    if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j);
    fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error);
    return 2;
    }
  }

/* If there are include or exclude patterns, compile them. */

if (exclude_pattern != NULL)
  {
  exclude_compiled = pcre_compile(exclude_pattern, 0, &error, &errptr, NULL);
  if (exclude_compiled == NULL)
    {
    fprintf(stderr, "pcregrep: Error in 'exclude' regex at offset %d: %s\n",
      errptr, error);
    return 2;
    }
  }

if (include_pattern != NULL)
  {
  include_compiled = pcre_compile(include_pattern, 0, &error, &errptr, NULL);
  if (include_compiled == NULL)
    {
    fprintf(stderr, "pcregrep: Error in 'include' regex at offset %d: %s\n",
      errptr, error);
    return 2;
    }
  }

/* If there are no further arguments, do the business on stdin and exit */

if (i >= argc) return pcregrep(stdin,
  (filenames_only || filenames_nomatch_only)? stdin_name : NULL);

/* Otherwise, work through the remaining arguments as files or directories.
Pass in the fact that there is only one argument at top level - this suppresses
the file name if the argument is not a directory and filenames_only is not set.
*/

only_one_at_top = (i == argc - 1);

for (; i < argc; i++)
  {
  int frc = grep_or_recurse(argv[i], recurse, filenames, only_one_at_top);
  if (frc > 1) rc = frc;
    else if (frc == 0 && rc == 1) rc = 0;
  }

return rc;
}
Esempio n. 4
0
static int
grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL show_filenames,
  BOOL only_one_at_top)
{
int rc = 1;
int sep;
FILE *in;
char *printname;

/* If the file name is "-" we scan stdin */

if (strcmp(pathname, "-") == 0)
  {
  return pcregrep(stdin,
    (filenames_only || filenames_nomatch_only ||
    (show_filenames && !only_one_at_top))?
      stdin_name : NULL);
  }

/* If the file is a directory and we are recursing, scan each file within it,
subject to any include or exclude patterns that were set. The scanning code is
localized so it can be made system-specific. */

if ((sep = isdirectory(pathname)) != 0 && dir_recurse)
  {
  char buffer[1024];
  char *nextfile;
  directory_type *dir = opendirectory(pathname);

  if (dir == NULL)
    {
    if (!silent)
      fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", pathname,
        strerror(errno));
    return 2;
    }

  while ((nextfile = readdirectory(dir)) != NULL)
    {
    int frc, blen;
    sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile);
    blen = strlen(buffer);

    if (exclude_compiled != NULL &&
        pcre_exec(exclude_compiled, NULL, buffer, blen, 0, 0, NULL, 0) >= 0)
      continue;

    if (include_compiled != NULL &&
        pcre_exec(include_compiled, NULL, buffer, blen, 0, 0, NULL, 0) < 0)
      continue;

    frc = grep_or_recurse(buffer, dir_recurse, TRUE, FALSE);
    if (frc > 1) rc = frc;
     else if (frc == 0 && rc == 1) rc = 0;
    }

  closedirectory(dir);
  return rc;
  }

/* If the file is not a directory, or we are not recursing, scan it. If this is
the first and only argument at top level, we don't show the file name (unless
we are only showing the file name). Otherwise, control is via the
show_filenames variable. */

in = fopen(pathname, "r");
if (in == NULL)
  {
  if (!silent)
    fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,
      strerror(errno));
  return 2;
  }

printname =  (filenames_only || filenames_nomatch_only ||
  (show_filenames && !only_one_at_top))? pathname : NULL;

rc = pcregrep(in, printname);

fclose(in);
return rc;
}
Esempio n. 5
0
int
main(int argc, char **argv)
{
int i, j;
int rc = 1;
int options = 0;
int errptr;
const char *error;
BOOL only_one_at_top;

/* Process the options */

for (i = 1; i < argc; i++)
  {
  if (argv[i][0] != '-') break;

  /* Missing options */

  if (argv[i][1] == 0) exit(usage(2));

  /* Long name options */

  if (argv[i][1] == '-')
    {
    option_item *op;

    if (strncmp(argv[i]+2, "file=", 5) == 0)
      {
      pattern_filename = argv[i] + 7;
      continue;
      }

    for (op = optionlist; op->one_char != 0; op++)
      {
      if (strcmp(argv[i]+2, op->long_name) == 0)
        {
        options = handle_option(op->one_char, options);
        break;
        }
      }
    if (op->one_char == 0)
      {
      fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]);
      exit(usage(2));
      }
    }

  /* One-char options */

  else
    {
    char *s = argv[i] + 1;
    while (*s != 0)
      {
      if (*s == 'f')
        {
        pattern_filename = s + 1;
        if (pattern_filename[0] == 0)
          {
          if (i >= argc - 1)
            {
            fprintf(stderr, "pcregrep: File name missing after -f\n");
            exit(usage(2));
            }
          pattern_filename = argv[++i];
          }
        break;
        }
      else options = handle_option(*s++, options);
      }
    }
  }

pattern_list = malloc(MAX_PATTERN_COUNT * sizeof(pcre *));
hints_list = malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *));

if (pattern_list == NULL || hints_list == NULL)
  {
  fprintf(stderr, "pcregrep: malloc failed\n");
  return 2;
  }

/* Compile the regular expression(s). */

if (pattern_filename != NULL)
  {
  FILE *f = fopen(pattern_filename, "r");
  char buffer[BUFSIZ];
  if (f == NULL)
    {
    fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename,
      strerror(errno));
    return 2;
    }
  while (fgets(buffer, sizeof(buffer), f) != NULL)
    {
    char *s = buffer + (int)strlen(buffer);
    if (pattern_count >= MAX_PATTERN_COUNT)
      {
      fprintf(stderr, "pcregrep: Too many patterns in file (max %d)\n",
        MAX_PATTERN_COUNT);
      return 2;
      }
    while (s > buffer && isspace((unsigned char)(s[-1]))) s--;
    if (s == buffer) continue;
    *s = 0;
    pattern_list[pattern_count] = pcre_compile(buffer, options, &error,
      &errptr, NULL);
    if (pattern_list[pattern_count++] == NULL)
      {
      fprintf(stderr, "pcregrep: Error in regex number %d at offset %d: %s\n",
        pattern_count, errptr, error);
      return 2;
      }
    }
  fclose(f);
  }

/* If no file name, a single regex must be given inline */

else
  {
  if (i >= argc) return usage(2);
  pattern_list[0] = pcre_compile(argv[i++], options, &error, &errptr, NULL);
  if (pattern_list[0] == NULL)
    {
    fprintf(stderr, "pcregrep: Error in regex at offset %d: %s\n", errptr,
      error);
    return 2;
    }
  pattern_count++;
  }

/* Study the regular expressions, as we will be running them may times */

for (j = 0; j < pattern_count; j++)
  {
  hints_list[j] = pcre_study(pattern_list[j], 0, &error);
  if (error != NULL)
    {
    char s[16];
    if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j);
    fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error);
    return 2;
    }
  }

/* If there are no further arguments, do the business on stdin and exit */

if (i >= argc) return pcregrep(stdin, NULL);

/* Otherwise, work through the remaining arguments as files or directories.
Pass in the fact that there is only one argument at top level - this suppresses
the file name if the argument is not a directory. */

only_one_at_top = (i == argc - 1);
if (filenames_only) filenames = TRUE;

for (; i < argc; i++)
  {
  int frc = grep_or_recurse(argv[i], recurse, filenames, only_one_at_top);
  if (frc == 0 && rc == 1) rc = 0;
  }

return rc;
}