int callback(struct ee_fieldbucket *fields, char *name,int type,cJSON *item) { struct ee_field *f; struct ee_value *val; char *valstr = NULL; es_str_t *estr; //printf("callback: type %d, name %s\n", type, name); if(type == cJSON_Object || type == cJSON_Array) return 1; // TODO: support! if(type == cJSON_String) { valstr = item->valuestring; } else if(type == cJSON_Number) { valstr = cJSON_print_number(item); } else if(type == cJSON_NULL) { valstr = "-"; } else if(type == cJSON_False) { valstr = "false"; } else if(type == cJSON_True) { valstr = "true"; } //printf("callback: string value %s\n", valstr); estr = es_newStrFromCStr(valstr, strlen(valstr)); val = ee_newValue(fields->ctx); ee_setStrValue(val, estr); f = ee_newFieldFromNV(fields->ctx, name, val); ee_addFieldToBucket(fields, f); if(type == cJSON_Number) free(valstr); return 1; }
/** * Special parser for iptables-like name/value pairs. * The pull multiple fields. Note that once this parser has been selected, * it is very unlikely to be left, as it is *very* generic. This parser is * required because practice shows that already-structured data like iptables * can otherwise not be processed by liblognorm in a meaningful way. * * @param[in] tree current tree to process * @param[in] str string to be matched against (the to-be-normalized data) * @param[in] strLen length of str * @param[in/out] offs start position in input data, on exit first unparsed position * @param[in/out] event handle to event that is being created during normalization * * @return 0 if parser was successfully, something else on error */ static int ln_iptablesParser(struct ln_ptree *tree, const char *str, size_t strLen, size_t *offs, struct json_object *json) { int r; size_t o = *offs; es_str_t *fname; es_str_t *fval; const char *pstr; const char *end; struct json_object *value; ln_dbgprintf(tree->ctx, "%zu enter iptables parser, len %zu", *offs, strLen); if(o == strLen) { r = -1; /* can not be, we have no n/v pairs! */ goto done; } end = str + strLen; pstr = str + o; while(pstr < end) { while(pstr < end && isspace(*pstr)) ++pstr; CHKN(fname = es_newStr(16)); while(pstr < end && !isspace(*pstr) && *pstr != '=') { es_addChar(&fname, *pstr); ++pstr; } if(pstr < end && *pstr == '=') { CHKN(fval = es_newStr(16)); ++pstr; /* error on space */ while(pstr < end && !isspace(*pstr)) { es_addChar(&fval, *pstr); ++pstr; } } else { CHKN(fval = es_newStrFromCStr("[*PRESENT*]", sizeof("[*PRESENT*]")-1)); } char *cn, *cv; CHKN(cn = ln_es_str2cstr(&fname)); CHKN(cv = ln_es_str2cstr(&fval)); if (tree->ctx->debug) { ln_dbgprintf(tree->ctx, "iptables parser extracts %s=%s", cn, cv); } CHKN(value = json_object_new_string(cv)); json_object_object_add(json, cn, value); es_deleteStr(fval); es_deleteStr(fname); } r = 0; *offs = strLen; done: ln_dbgprintf(tree->ctx, "%zu iptables parser returns %d", *offs, r); return r; }
/* returns either a pointer to the value (read only!) or NULL * if either the key could not be found or an error occured. * Note that an estr_t object is returned. The caller is * responsible for freeing it. */ es_str_t * lookupKey_estr(lookup_t *pThis, uchar *key) { lookup_string_tab_etry_t *etry; char *r; es_str_t *estr; pthread_rwlock_rdlock(&pThis->rwlock); etry = bsearch(key, pThis->d.strtab, pThis->nmemb, sizeof(lookup_string_tab_etry_t), bs_arrcmp_strtab); if(etry == NULL) { r = ""; // TODO: use set default } else { r = (char*)etry->val; } estr = es_newStrFromCStr(r, strlen(r)); pthread_rwlock_unlock(&pThis->rwlock); return estr; }