コード例 #1
0
ファイル: file_unix.c プロジェクト: concurrency/nocc
/*
 *	called to create a directory: does in parts if needed
 *	return 0 on success, non-zero on error
 */
static int unix_mkdirfcn (const char *path, const int perm)
{
	char *ch;
	int err = 0;

	ch = (char *)path;
	for (;;) {
		for (; (*ch != '/') && (*ch != '\0'); ch++);
		/* at next slash or end */
		if (ch > path) {
			/* see if path up to, not including '/' (or end), exists */
			char *tstr = string_ndup (path, (int)(ch - path));

			if (access (tstr, F_OK)) {
				if (errno == ENOENT) {
					/* try and create it */
					err = mkdir (tstr, perm);
					sfree (tstr);
					goto out;
				}
			}

			sfree (tstr);
			if (*ch == '/') {
				ch++;
			}
		} else {
			/* leading slash */
			ch++;
		}
		if (*ch == '\0') {
			break;		/* end */
		}
	}

out:
	return err;
}
コード例 #2
0
ファイル: grok_matchconf.c プロジェクト: ChaosCloud/grok
char *grok_match_reaction_apply_filter(grok_match_t *gm,
                                       char **value, int *value_len,
                                       const char *filter, int filter_len) {
  int offset = 0, len = 0;
  int value_size;
  int ret;
  struct filter *filterobj;

  if (filter_len == 0) {
    return *value;
  }

  *value = string_ndup(*value, *value_len);
  /* we'll use the value_len from the function arguments */
  value_size = *value_len + 1;

  /* skip first char which must be a '|' */
  offset = 1;

  while (offset + len < filter_len) {
    if (filter[offset + len] == '|') {
      /* Apply the filter */
      grok_log(gm->grok, LOG_REACTION, "ApplyFilter code: %.*s",
               len, filter + offset);
      filterobj = string_filter_lookup(filter + offset, len);
      if (filterobj == NULL) {
        grok_log(gm->grok, LOG_REACTION, 
                 "Can't apply filter '%.*s'; it's unknown.",
                 len, filter + offset);
      } else {
        ret = filterobj->func(gm, value, value_len, &value_size);
        if (ret != 0) {
          grok_log(gm->grok, LOG_REACTION,
                   "Applying filter '%.*s' returned error %d for string '%.*s'.",
                   len, filter + offset, *value_len, *value);
        }
      }
      offset += len + 1;
      len = 0;
    }

    len++;
  }

  /* We'll always have one filter left over */
  grok_log(gm->grok, LOG_REACTION, "Filter code: %.*s", len, filter + offset);
  filterobj = string_filter_lookup(filter + offset, len);
  if (filterobj == NULL) {
    grok_log(gm->grok, LOG_REACTION, 
             "Can't apply filter '%.*s'; it's unknown.",
             len, filter + offset);
  } else {
    ret = filterobj->func(gm, value, value_len, &value_size);
    if (ret != 0) {
      grok_log(gm->grok, LOG_REACTION,
               "Applying filter '%.*s' returned error %d for string '%.*s'.",
               len, filter + offset, *value_len, *value);
    }
  }

  return *value;

}
コード例 #3
0
ファイル: grok_matchconf.c プロジェクト: ChaosCloud/grok
char *grok_matchconfig_filter_reaction(const char *str, grok_match_t *gm) {
  char *output;
  int len;
  int size;
  grok_match_t tmp_gm;
  int offset = 0;

  if (gm == NULL) {
    return NULL;
  }

  len = strlen(str);
  size = len + 1;
  output = malloc(size);
  memcpy(output, str, size);

  grok_log(gm->grok, LOG_REACTION,
           "Checking '%.*s'", len - offset, output + offset);
  global_matchconfig_grok.logmask = gm->grok->logmask;
  global_matchconfig_grok.logdepth  = gm->grok->logdepth + 1;
  while (grok_execn(&global_matchconfig_grok, output + offset,
                    len - offset, &tmp_gm) == GROK_OK) {
    grok_log(gm->grok, LOG_REACTION, "Checking '%.*s'",
             len - offset, output + offset);
    const char *name = NULL;
    const char *filter = NULL;
    char *value = NULL;
    char *name_copy;

    int name_len, value_len, filter_len;
    int ret = -1;
    int free_value = 0;
    const struct strmacro *patmacro;

    grok_match_get_named_substring(&tmp_gm, "NAME", &name, &name_len);
    grok_match_get_named_substring(&tmp_gm, "FILTER", &filter, &filter_len);
    grok_log(gm->grok, LOG_REACTION, "Matched something: %.*s", name_len, name);

    /* XXX: We should really make a dispatch table out of this... */
    /* _macro_dispatch_func(char **value, int *value_len) ... */
    /* Let gperf do the hard work for us. */
    patmacro = patname2macro(name, name_len);
    grok_log(gm->grok, LOG_REACTION, "Checking lookup table for '%.*s': %x",
             name_len, name, patmacro);
    if (patmacro != NULL) {
      free_value = 1; /* We malloc stuff to 'value' here */
      switch (patmacro->code) {
        case VALUE_LINE:
          value = strdup(gm->subject);
          value_len = strlen(value);
          ret = 0;
          break;
        case VALUE_START:
          value_len = asprintf(&value, "%d", gm->start);
          ret = 0;
          break;
        case VALUE_END:
          value_len = asprintf(&value, "%d", gm->end);
          ret = 0;
          break;
        case VALUE_LENGTH:
          value_len = asprintf(&value, "%d", gm->end - gm->start);
          ret = 0;
          break;
        case VALUE_MATCH:
          value_len = gm->end - gm->start;
          value = string_ndup(gm->subject + gm->start, value_len);
          ret = 0;
          break;
        case VALUE_JSON_SIMPLE:
        case VALUE_JSON_COMPLEX:
          {
            int value_offset = 0;
            int value_size = 0;
            char *pname;
            const char *pdata;
            int pname_len, pdata_len;

            char *entry = NULL, *tmp = NULL;
            int entry_len = 0, tmp_len = 0, tmp_size = 0;

            value = NULL;
            value_len = 0;

            /* TODO(sissel): use a json generator library? */

            /* Push @FOO values first */
            substr_replace(&tmp, &tmp_len, &tmp_size, 0, 0,
                           gm->subject, strlen(gm->subject));
            filter_jsonencode(gm, &tmp, &tmp_len, &tmp_size);

            if (patmacro->code == VALUE_JSON_SIMPLE) {
              entry_len = asprintf(&entry, 
                                   "\"@LINE\": \"%.*s\", ", tmp_len, tmp);
            } else { /* VALUE_JSON_COMPLEX */
              entry_len = asprintf(&entry, 
                                   "{ \"@LINE\": { "
                                   "\"start\": 0, "
                                   "\"end\": %d, "
                                   "\"value\": \"%.*s\" } }, ",
                                   tmp_len, tmp_len, tmp);
            }
            substr_replace(&value, &value_len, &value_size, value_len, value_len,
                           entry, entry_len);
            free(entry);

            substr_replace(&tmp, &tmp_len, &tmp_size, 0, tmp_len,
                           gm->subject + gm->start, gm->end - gm->start);
            filter_jsonencode(gm, &tmp, &tmp_len, &tmp_size);
            if (patmacro->code == VALUE_JSON_SIMPLE) {
              entry_len = asprintf(&entry, "\"@MATCH\": \"%.*s\", ", tmp_len, tmp);
            } else { /* VALUE_JSON_COMPLEX */
              entry_len = asprintf(&entry, 
                                   "{ \"@MATCH\": { "
                                   "\"start\": %d, "
                                   "\"end\": %d, "
                                   "\"value\": \"%.*s\" } }, ",
                                   gm->start, gm->end, tmp_len, tmp);
            }
            substr_replace(&value, &value_len, &value_size, value_len, value_len,
                           entry, entry_len);
            free(entry);
            //printf("> %.*s\n", value_len, value);

            value_offset += value_len;

            /* For every named capture, put this in our result string:
             * "NAME": "%{NAME|jsonencode}"
             */
            grok_match_walk_init(gm);
            while (grok_match_walk_next(gm, &pname, &pname_len,
                                        &pdata, &pdata_len) == 0) {
              char *entry;
              int entry_len;

              substr_replace(&tmp, &tmp_len, &tmp_size, 0, tmp_len,
                             pdata, pdata_len);
              filter_jsonencode(gm, &tmp, &tmp_len, &tmp_size);

              if (patmacro->code == VALUE_JSON_SIMPLE) {
                entry_len = asprintf(&entry, "\"%.*s\": \"%.*s\", ",
                                     pname_len, pname, tmp_len, tmp);
              } else { /* VALUE_JSON_COMPLEX */ 
                entry_len = asprintf(&entry, 
                                     "{ \"%.*s\": { "
                                     "\"start\": %ld, "
                                     "\"end\": %ld, "
                                     "\"value\": \"%.*s\""
                                     " } }, ",
                                     pname_len, pname, 
                                     pdata - gm->subject, /*start*/
                                     (pdata - gm->subject) + pdata_len, /*end*/
                                     tmp_len, tmp);
              }
              substr_replace(&value, &value_len, &value_size,
                             value_offset, value_offset, entry, entry_len);
              value_offset += entry_len;
              free(entry);
            }
            grok_match_walk_end(gm);

            /* Insert the { at the beginning */
            /* And Replace trailing ", " with " }" */
            if (patmacro->code == VALUE_JSON_SIMPLE) {
              substr_replace(&value, &value_len, &value_size, 0, 0, "{ ", 2); 
              substr_replace(&value, &value_len, &value_size,
                             value_len - 2, value_len, " }", 2);
                             /* TODO(sissel): This could be:
                              * -3, -1, " }", 2); */
            } else { /* VALUE_JSON_COMPLEX */
              substr_replace(&value, &value_len, &value_size, 0, 0, 
                             "{ \"grok\": [ ", 12);
              substr_replace(&value, &value_len, &value_size,
                             value_len - 2, value_len, " ] }", 4);
                             /* TODO(sissel): This could be:
                              * -3, -1, " ] }", 4); */
            }

            char *old = value;
            grok_log(gm->grok, LOG_REACTION, "JSON intermediate: %.*s",
                     value_len, value);
            value = grok_matchconfig_filter_reaction(value, gm);
            free(old);

            ret = 0;
            free(tmp);
          }
          break;
        default:
          grok_log(gm->grok, LOG_REACTION, "Unhandled macro code: '%.*s' (%d)",
                   name_len, name, patmacro->code);
      }
    } else {
      /* XXX: Should just have get_named_substring take a 
       * 'name, name_len' instead */
      name_copy = malloc(name_len + 1);
      memcpy(name_copy, name, name_len);
      name_copy[name_len] = '\0';
      ret = grok_match_get_named_substring(gm, name_copy, (const char **)&value,
                                           &value_len);
      free(name_copy);
    }

    if (ret != 0) {
      offset += tmp_gm.end;
    } else {
      /* replace %{FOO} with the value of foo */
      char *old;
      grok_log(tmp_gm.grok, LOG_REACTION, "Start/end: %d %d", tmp_gm.start, tmp_gm.end);
      grok_log(tmp_gm.grok, LOG_REACTION, "Replacing %.*s",
               (tmp_gm.end - tmp_gm.start), output + tmp_gm.start + offset);

      /* apply the any filters from %{FOO|filter1|filter2...} */
      old = value;

      grok_log(tmp_gm.grok, LOG_REACTION, "Prefilter string: %.*s",
               value_len, value);
      grok_match_reaction_apply_filter(gm, &value, &value_len,
                                       filter, filter_len);
      if (old != value) {
        if (free_value) {
          free(old); /* Free the old value */
        }
        free_value = 1;
      }
      grok_log(gm->grok, LOG_REACTION, "Filter: %.*s", filter_len, filter);

      grok_log(tmp_gm.grok, LOG_REACTION, "Replacing %.*s with %.*s",
               (tmp_gm.end - tmp_gm.start),
               output + tmp_gm.start + offset, value_len, value);
      substr_replace(&output, &len, &size, offset + tmp_gm.start,
                     offset + tmp_gm.end, value, value_len);
      offset += value_len;
      if (free_value) {
        free(value);
      }
    }
  } /* while grok_execn ... */

  return output;
}
コード例 #4
0
ファイル: grokre.c プロジェクト: rdcastro/grok
/* XXX: This method is pretty long; split it up? */
static char *grok_pattern_expand(grok_t *grok) {
  int capture_id = 0; /* Starting capture_id, doesn't really matter what this is */
  int offset = 0; /* string offset; how far we've expanded so far */
  int *capture_vector = NULL;
  int replacement_count = 0; /* count of replacements of %{foo} with a regexp */

  int full_len = -1;
  int full_size = -1;
  char *full_pattern = NULL;
  char capture_id_str[CAPTURE_ID_LEN + 1];

  const char *patname = NULL;

  capture_vector = calloc(3 * g_pattern_num_captures, sizeof(int));
  full_len = grok->pattern_len;
  full_size = full_len;
  full_pattern = calloc(1, full_size + 1);
  memcpy(full_pattern, grok->pattern, full_len + 1);
  grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "start of expand",
           full_len, full_pattern);

  while (pcre_exec(g_pattern_re, NULL, full_pattern, full_len, offset, 
                   0, capture_vector, g_pattern_num_captures * 3) >= 0) {
    int start, end, matchlen;
    const char *pattern_regex;
    int patname_len;
    size_t regexp_len;
    int pattern_regex_needs_free = 0;

    grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "start of loop",
             full_len, full_pattern);

    replacement_count++;
    if (replacement_count > 1000) {
      free(capture_vector);
      free(full_pattern);
      grok->errstr = "Too many replacements have occurred (500), infinite recursion?";
      return NULL;
    }

    start = capture_vector[0];
    end = capture_vector[1];
    matchlen = end - start;
    grok_log(grok, LOG_REGEXPAND, "Pattern length: %d", matchlen);

    pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
                       g_cap_pattern, &patname);
    patname_len = capture_vector[g_cap_pattern * 2 + 1] \
                  - capture_vector[g_cap_pattern * 2];
    grok_log(grok, LOG_REGEXPAND, "Pattern name: %.*s", patname_len, patname);

    grok_pattern_find(grok, patname, patname_len, &pattern_regex, &regexp_len);

    if (pattern_regex == NULL) {
      /* Pattern not found, check if this has an in-line definition */
      int definition_len = capture_vector[g_cap_definition * 2 + 1] 
                           - capture_vector[g_cap_definition * 2];
      if (definition_len > 0) {
        /* We got an in-line definition */
        /* discard const-ness with reckless abandon! */
        pattern_regex = string_ndup(full_pattern + capture_vector[g_cap_definition * 2], definition_len);
        regexp_len = definition_len;
        pattern_regex_needs_free = 1;
        grok_log(grok, LOG_REGEXPAND, "Inline-definition found: %.*s => '%.*s'",
                 patname_len, patname, regexp_len, pattern_regex);
      } else {
        /* If we get here, there's definitely no pattern available for the 
         * current %{thing}, so just leave it unmolested. */
        offset = end;
      }
    }
    
    /* Check for nullness again because there could've been an inline
     * definition found above */
    if (pattern_regex != NULL) {
      int has_predicate = (capture_vector[g_cap_predicate * 2] >= 0);
      const char *longname = NULL;
      const char *subname = NULL;
      grok_capture *gct = calloc(1, sizeof(grok_capture));;

      /* XXX: Change this to not use pcre_get_substring so we can skip a
       * malloc step? */
      pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
                         g_cap_name, &longname);
      pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
                         g_cap_subname, &subname);

      snprintf(capture_id_str, CAPTURE_ID_LEN + 1, CAPTURE_FORMAT, capture_id);

      /* Add this capture to the list of captures */
      gct->id = capture_id;
      gct->name = (char *)longname; /* XXX: CONST PROBLEM */
      gct->name_len = strlen(gct->name);
      gct->subname = (char *)subname;
      gct->subname_len = strlen(gct->subname);
      grok_capture_add(grok, gct);

      //pcre_free_substring(longname);
      //pcre_free_substring(subname);

      /* if a predicate was given, add (?C1) to callout when the match is made,
       * so we can test it further */
      if (has_predicate) {
        int pstart, pend;
        pstart = capture_vector[g_cap_predicate * 2];
        pend = capture_vector[g_cap_predicate * 2 + 1];
        grok_log(grok, LOG_REGEXPAND, "Predicate found in '%.*s'",
                 matchlen, full_pattern + start);
        grok_log(grok, LOG_REGEXPAND, "Predicate is: '%.*s'",
                 pend - pstart, full_pattern + pstart);

        grok_capture_add_predicate(grok, capture_id, full_pattern + pstart,
                                   pend - pstart);
        substr_replace(&full_pattern, &full_len, &full_size,
                       end, 0, "(?C1)", 5);
      }

      /* Replace %{FOO} with (?<>). '5' is strlen("(?<>)") */
      substr_replace(&full_pattern, &full_len, &full_size,
                     start, end, "(?<>)", 5);
      grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "replace with (?<>)",
               full_len, full_pattern);

      /* Insert the capture id into (?<FOO>) */
      substr_replace(&full_pattern, &full_len, &full_size,
                     start + 3, 0,
                     capture_id_str, CAPTURE_ID_LEN);
      grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "add capture id",
               full_len, full_pattern);


      /* Insert the pattern into (?<FOO>pattern) */
      /* 3 = '(?<', 4 = strlen(capture_id_str), 1 = ")" */
      substr_replace(&full_pattern, &full_len, &full_size, 
                     start + 3 + CAPTURE_ID_LEN + 1, 0, 
                     pattern_regex, regexp_len);
      grok_log(grok, LOG_REGEXPAND, ":: Inserted: %.*s", regexp_len,
               pattern_regex);
      grok_log(grok, LOG_REGEXPAND, ":: STR: %.*s", full_len, full_pattern);

      /* Invariant, full_pattern actual len must always be full_len */
      assert(strlen(full_pattern) == full_len);
      
      /* Move offset to the start of the regexp pattern we just injected.
       * This is so when we iterate again, we can process this new pattern
       * to see if the regexp included itself any %{FOO} things */
      offset = start;
      capture_id++;
    }

    if (pattern_regex_needs_free) {
      /* If we need to free,   */
      free(pattern_regex);
    }
    if (patname != NULL) {
      pcre_free_substring(patname);
      patname = NULL;
    }
  } /* while pcre_exec */

  /* Unescape any "\%" strings found */
  offset = 0;
  while (offset < full_len) { /* loop to '< full_len' because we access offset+1 */
    if (full_pattern[offset] == '\\' && full_pattern[offset + 1] == '%') {
      substr_replace(&full_pattern, &full_len, &full_size,
                     offset, offset + 1, "", 0);
    }
    offset++;
  }

  grok_log(grok, LOG_REGEXPAND, "Fully expanded: %.*s", full_len, full_pattern);

  free(capture_vector);
  grok->full_pattern_len = full_len;
  grok->full_pattern = full_pattern;
  return full_pattern;
} /* grok_pattern_expand */