Began use git manage source code since MAAT_FRAME_VERSION_1_2_20150724.
This commit is contained in:
3130
src/entry/Maat_rule.cpp
Normal file
3130
src/entry/Maat_rule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
288
src/entry/Maat_rule_internal.h
Normal file
288
src/entry/Maat_rule_internal.h
Normal file
@@ -0,0 +1,288 @@
|
||||
#include "Maat_rule.h"
|
||||
|
||||
#include <MESA/MESA_htable.h>
|
||||
#include <MESA/MESA_list_queue.h>
|
||||
#include "dynamic_array.h"
|
||||
#include "UniversalBoolMatch.h"
|
||||
#include "rulescan.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <iconv.h>
|
||||
|
||||
#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 411)
|
||||
#define atomic_inc(x) __sync_add_and_fetch((x),1)
|
||||
#define atomic_dec(x) __sync_sub_and_fetch((x),1)
|
||||
#define atomic_add(x,y) __sync_add_and_fetch((x),(y))
|
||||
#define atomic_sub(x,y) __sync_sub_and_fetch((x),(y))
|
||||
typedef int atomic_t;
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
#define atomic_read(x) __sync_add_and_fetch((x),0)
|
||||
#define atomic_set(x,y) __sync_lock_test_and_set((x),y)
|
||||
#else
|
||||
#include <alsa/iatomic.h>
|
||||
#endif
|
||||
#define CPU_CACHE_ALIGMENT 64
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define MAX_TABLE_NUM 256
|
||||
#define MAX_CHARSET_NUM 6
|
||||
#define MAX_TABLE_NAME_LEN 256
|
||||
#define MAX_TABLE_LINE_SIZE (1024*4)
|
||||
#define MAX_EXPR_KEYLEN 1024
|
||||
#define MAX_PLUGING_NUM 32
|
||||
|
||||
#define MAX_SCANNER_HIT_NUM 64
|
||||
|
||||
#define MAX_GROUP_CACHE 128
|
||||
|
||||
#define MAX_FAILED_NUM 128
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
typedef void* rule_scanner_t;
|
||||
enum MAAT_TABLE_TYPE
|
||||
{
|
||||
TABLE_TYPE_EXPR=0,
|
||||
TABLE_TYPE_IP,
|
||||
TABLE_TYPE_COMPILE,
|
||||
TABLE_TYPE_PLUGIN,
|
||||
TABLE_TYPE_INTVAL,
|
||||
TABLE_TYPE_GROUP
|
||||
|
||||
};
|
||||
enum MAAT_EXPR_TYPE
|
||||
{
|
||||
EXPR_TYPE_STRING=0,
|
||||
EXPR_TYPE_AND,
|
||||
EXPR_TYPE_REGEX,
|
||||
EXPR_TYPE_OFFSET
|
||||
};
|
||||
enum MAAT_MATCH_METHOD
|
||||
{
|
||||
MATCH_METHOD_SUB=0,
|
||||
MATCH_METHOD_RIGHT,
|
||||
MATCH_METHOD_LEFT,
|
||||
MATCH_METHOD_FULL
|
||||
};
|
||||
struct db_str_rule_t
|
||||
{
|
||||
int region_id;
|
||||
int group_id;
|
||||
char keywords[MAX_EXPR_KEYLEN];
|
||||
enum MAAT_EXPR_TYPE expr_type;
|
||||
enum MAAT_MATCH_METHOD match_method;
|
||||
int is_hexbin;
|
||||
int is_case_sensitive;
|
||||
int is_valid;
|
||||
|
||||
};
|
||||
struct db_ip_rule_t
|
||||
{
|
||||
int region_id;
|
||||
int group_id;
|
||||
int addr_type;
|
||||
union
|
||||
{
|
||||
//ip address use network order
|
||||
//port use host order
|
||||
ipv4_rule_t ipv4_rule;
|
||||
ipv6_rule_t ipv6_rule;
|
||||
};
|
||||
int is_valid;
|
||||
};
|
||||
struct db_intval_rule_t
|
||||
{
|
||||
int region_id;
|
||||
int group_id;
|
||||
interval_rule_t intval;
|
||||
int is_valid;
|
||||
};
|
||||
struct _head_Maat_rule_t
|
||||
{
|
||||
int config_id;
|
||||
int service_id;
|
||||
char do_log;
|
||||
char do_blacklist;
|
||||
char action;
|
||||
char resevered;
|
||||
int serv_def_len;
|
||||
};
|
||||
struct db_compile_rule_t
|
||||
{
|
||||
// Maat_rule_t m_rule_head;
|
||||
struct _head_Maat_rule_t m_rule_head;// fix len of Maat_rule_t
|
||||
char* service_defined;
|
||||
long long effective_range;
|
||||
int is_valid;
|
||||
int declare_grp_num;
|
||||
};
|
||||
struct db_group_rule_t
|
||||
{
|
||||
int group_id;
|
||||
int compile_id;
|
||||
int is_valid;
|
||||
};
|
||||
struct op_expr_t
|
||||
{
|
||||
boolean_expr_t* p_expr;
|
||||
scan_rule_t* p_rules[MAAT_MAX_EXPR_ITEM_NUM];
|
||||
};
|
||||
|
||||
struct _Maat_region_rule_t
|
||||
{
|
||||
int region_id;
|
||||
int expr_id;
|
||||
enum MAAT_TABLE_TYPE region_type;
|
||||
};
|
||||
struct _Maat_group_rule_t
|
||||
{
|
||||
int group_id;
|
||||
int region_boundary;
|
||||
int region_cnt;
|
||||
int ref_cnt;
|
||||
dynamic_array_t *region_rules;
|
||||
void* compile_shortcut;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
struct _Maat_compile_rule_t
|
||||
{
|
||||
struct db_compile_rule_t *db_c_rule;
|
||||
dynamic_array_t *groups;
|
||||
int group_cnt;
|
||||
int compile_id;//equal to db_c_rule->m_rule.config_id
|
||||
pthread_rwlock_t rwlock;//reading compile rule is safe in update thread, rwlock lock called when delete or scan thread read
|
||||
};
|
||||
struct _compile_result_t
|
||||
{
|
||||
int compile_id;
|
||||
universal_bool_expr_t group_set;
|
||||
};
|
||||
struct _callback_plugin
|
||||
{
|
||||
Maat_start_callback_t *start;
|
||||
Maat_update_callback_t *update;
|
||||
Maat_finish_callback_t *finish;
|
||||
void* u_para;
|
||||
};
|
||||
|
||||
struct _plugin_table_info
|
||||
{
|
||||
int cb_plug_cnt;
|
||||
struct _callback_plugin cb_plug[MAX_PLUGING_NUM];
|
||||
dynamic_array_t *cache_lines;
|
||||
int line_num;
|
||||
long cache_size;
|
||||
};
|
||||
struct _Maat_table_info_t
|
||||
{
|
||||
unsigned short table_id;
|
||||
char table_name[MAX_TABLE_NAME_LEN];
|
||||
enum MAAT_TABLE_TYPE table_type;
|
||||
enum MAAT_CHARSET src_charset;
|
||||
enum MAAT_CHARSET dst_charset[MAX_CHARSET_NUM];
|
||||
int src_charset_in_dst;
|
||||
int do_charset_merge;
|
||||
int cfg_num;
|
||||
int cross_cache_size;
|
||||
int expr_rule_cnt; //expr_type=0,1,3
|
||||
int regex_rule_cnt; //expr_type=2
|
||||
struct _plugin_table_info *cb_info;
|
||||
};
|
||||
struct _scan_status_t
|
||||
{
|
||||
struct _Maat_feather_t* feather;
|
||||
int thread_num;
|
||||
int cur_hit_cnt;
|
||||
int hit_group_cnt;
|
||||
int hit_group_size;
|
||||
unsigned int cur_hit_id[MAX_SCANNER_HIT_NUM];
|
||||
unsigned int *hitted_group_id;
|
||||
};
|
||||
enum maat_garbage_type
|
||||
{
|
||||
GARBAGE_SCANNER=0,
|
||||
GARBAGE_GROUP_RULE,
|
||||
GARBAGE_COMPILE_RULE,
|
||||
GARBAGE_BOOL_MATCHER
|
||||
};
|
||||
struct iconv_handle_t
|
||||
{
|
||||
int is_initialized;
|
||||
iconv_t cd;
|
||||
};
|
||||
struct _stream_para_t
|
||||
{
|
||||
struct _Maat_feather_t* feather;
|
||||
int version;
|
||||
int thread_num;
|
||||
int max_cross_size;
|
||||
int caching_size;
|
||||
unsigned short table_id;
|
||||
char do_merge;
|
||||
char do_expr:4;
|
||||
char do_regex:4;
|
||||
char* last_cache;
|
||||
char* scan_buff;
|
||||
void* rs_stream_para;
|
||||
long acc_scan_len;
|
||||
|
||||
};
|
||||
struct _Maat_scanner_t
|
||||
{
|
||||
int version;
|
||||
time_t last_update_time;
|
||||
int *ref_cnt; //optimized for cache_alignment 64
|
||||
rule_scanner_t region;
|
||||
MESA_htable_handle region_hash;
|
||||
MESA_htable_handle group_hash;
|
||||
MESA_htable_handle compile_hash;
|
||||
unsigned int cfg_num;
|
||||
unsigned int exprid_generator;
|
||||
MESA_lqueue_head region_update_q;
|
||||
void * expr_compiler;
|
||||
scan_result_t *region_rslt_buff;
|
||||
MESA_lqueue_head tomb_ref;//reference of feather->garbage_q
|
||||
int max_thread_num;
|
||||
iconv_t iconv_handle[MAX_CHARSET_NUM][MAX_CHARSET_NUM];//iconv_handle[to][from]
|
||||
};
|
||||
struct _Maat_feather_t
|
||||
{
|
||||
struct _Maat_scanner_t *scanner;
|
||||
struct _Maat_scanner_t *update_tmp_scanner;
|
||||
MESA_lqueue_head garbage_q;
|
||||
int table_cnt;
|
||||
struct _Maat_table_info_t *p_table_info[MAX_TABLE_NUM];
|
||||
MESA_htable_handle map_tablename2id;
|
||||
void* logger;
|
||||
int maat_version;
|
||||
int scan_thread_num;
|
||||
char inc_dir[MAX_TABLE_NAME_LEN];
|
||||
char full_dir[MAX_TABLE_NAME_LEN];
|
||||
int GROUP_MODE_ON;
|
||||
int still_working;
|
||||
int scan_interval_ms;
|
||||
int effect_interval_ms;
|
||||
};
|
||||
struct _maat_garbage_t
|
||||
{
|
||||
enum maat_garbage_type type;
|
||||
time_t create_time;
|
||||
int ok_times;
|
||||
union
|
||||
{
|
||||
struct _Maat_scanner_t* scanner;
|
||||
struct _Maat_group_rule_t* group_rule;
|
||||
struct _Maat_compile_rule_t* compile_rule;
|
||||
void* bool_matcher;
|
||||
void * raw;
|
||||
};
|
||||
};
|
||||
void garbage_bagging(enum maat_garbage_type type,void *p,MESA_lqueue_head garbage_q);
|
||||
void garbage_bury(MESA_lqueue_head garbage_q,void *logger);
|
||||
37
src/entry/Makefile
Normal file
37
src/entry/Makefile
Normal file
@@ -0,0 +1,37 @@
|
||||
#opt: OPTFLAGS = -O2
|
||||
#export OPTFLAGS
|
||||
|
||||
CC = g++
|
||||
CCC = g++
|
||||
CFLAGS = -Wall -g -fPIC
|
||||
CFLAGS += $(OPTFLAGS)
|
||||
LDFLAGS = -lMESA_handle_logger -lMESA_htable -lpthread
|
||||
MAILLIB = ../lib
|
||||
|
||||
G_H_DIR =../inc_internal
|
||||
H_DIR =-I$(G_H_DIR) -I../../inc
|
||||
LIBMAAT = libmaatframe.a
|
||||
LIBMAAT_SO = libmaatframe.so
|
||||
|
||||
OBJS=config_monitor.o Maat_rule.o UniversalBoolMatch.o dynamic_array.o cJSON.o json2iris.o map_str2int.o
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) -I. $(H_DIR) $<
|
||||
|
||||
.cpp.o:
|
||||
$(CCC) -c $(CFLAGS) -I. $(H_DIR) $<
|
||||
|
||||
all: $(LIBMAAT) $(LIBMAAT_SO)
|
||||
|
||||
$(LIBMAAT_SO): $(OBJS)
|
||||
$(CCC) -o $(LIBMAAT_SO) -shared $(OBJS) $(LDFLAGS)
|
||||
cp $(LIBMAAT_SO) ../../lib/
|
||||
$(LIBMAAT): $(OBJS)
|
||||
echo making dynamic lib ...
|
||||
ar cqs $(LIBMAAT) $(OBJS)
|
||||
cp $(LIBMAAT) ../../lib/
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(LIBMAAT) *~
|
||||
|
||||
opt:
|
||||
$(MAKE) all
|
||||
259
src/entry/UniversalBoolMatch.cpp
Normal file
259
src/entry/UniversalBoolMatch.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
#include "UniversalBoolMatch.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const unsigned int MAX_ARRAY_SIZE=65536;
|
||||
|
||||
struct thread_local_data_t
|
||||
{
|
||||
unsigned int mapped_ids[MAX_ARRAY_SIZE];
|
||||
unsigned int used_cells[MAX_ARRAY_SIZE];
|
||||
unsigned char * bitmap;
|
||||
unsigned int * matched_bitmap;
|
||||
};
|
||||
|
||||
struct boolexpr_matcher_t
|
||||
{
|
||||
unsigned int max_thread_num;
|
||||
unsigned int bool_expr_num;
|
||||
unsigned int multi_expr_num;
|
||||
void ** bool_expr_ids;
|
||||
unsigned char * multi_expr_size;
|
||||
unsigned int bool_item_id_num;
|
||||
unsigned int min_item_id;
|
||||
unsigned int max_item_id;
|
||||
unsigned int * bool_item_ids;
|
||||
unsigned int * mapped_ptr;
|
||||
unsigned int * mapped_ids;
|
||||
unsigned int theta;
|
||||
unsigned int L[65537];
|
||||
thread_local_data_t * thread_data;
|
||||
};
|
||||
|
||||
void * boolexpr_initialize(universal_bool_expr_t * bool_exprs, unsigned int bool_expr_num, unsigned int max_thread_num, unsigned int * mem_size)
|
||||
{
|
||||
if(bool_exprs==NULL || bool_expr_num==0 || max_thread_num==0) return NULL;
|
||||
|
||||
for(unsigned int i=0; i<bool_expr_num; i++)
|
||||
{
|
||||
if(bool_exprs[i].bool_item_num==0 || bool_exprs[i].bool_item_num>MAX_ITEMS_PER_BOOL_EXPR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int I=-1, J=(int)bool_expr_num;
|
||||
while(I<J)
|
||||
{
|
||||
I++;
|
||||
while(I<J && bool_exprs[I].bool_item_num>1) I++;
|
||||
if(I==J) break;
|
||||
J--;
|
||||
while(J>I && bool_exprs[J].bool_item_num==1) J--;
|
||||
if(J==I) break;
|
||||
swap(bool_exprs[I], bool_exprs[J]);
|
||||
}
|
||||
|
||||
for(int k=0; k<(int)bool_expr_num; k++)
|
||||
{
|
||||
if((k<I && bool_exprs[k].bool_item_num==1) || (k>=I && bool_exprs[k].bool_item_num>1))
|
||||
{
|
||||
printf("[%s:%d]: fatal error!\n", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int mem_bytes=0;
|
||||
|
||||
boolexpr_matcher_t * matcher=new boolexpr_matcher_t;
|
||||
mem_bytes+=sizeof(boolexpr_matcher_t);
|
||||
|
||||
matcher->max_thread_num=max_thread_num;
|
||||
matcher->bool_expr_num=bool_expr_num;
|
||||
matcher->multi_expr_num=I;
|
||||
|
||||
matcher->bool_expr_ids=new void *[bool_expr_num];
|
||||
mem_bytes+=bool_expr_num*sizeof(void *);
|
||||
|
||||
matcher->multi_expr_size=new unsigned char[matcher->multi_expr_num+1];
|
||||
mem_bytes+=(matcher->multi_expr_num+1)*sizeof(unsigned char);
|
||||
|
||||
matcher->thread_data=new thread_local_data_t[max_thread_num];
|
||||
mem_bytes+=max_thread_num*sizeof(thread_local_data_t);
|
||||
|
||||
for(unsigned int i=0; i<max_thread_num; i++)
|
||||
{
|
||||
matcher->thread_data[i].bitmap=new unsigned char[matcher->multi_expr_num+1];
|
||||
mem_bytes+=(matcher->multi_expr_num+1)*sizeof(unsigned char);
|
||||
|
||||
unsigned int size=(bool_expr_num-matcher->multi_expr_num);
|
||||
size=(size>>5)+1;
|
||||
matcher->thread_data[i].matched_bitmap=new unsigned int[size];
|
||||
mem_bytes+=size*sizeof(unsigned int);
|
||||
}
|
||||
|
||||
map< unsigned int, vector<unsigned int> > M;
|
||||
unsigned int count=0;
|
||||
for(unsigned int i=0; i<bool_expr_num; i++)
|
||||
{
|
||||
matcher->bool_expr_ids[i] =bool_exprs[i].bool_expr_id;
|
||||
if(i<matcher->multi_expr_num)
|
||||
{
|
||||
matcher->multi_expr_size[i]=bool_exprs[i].bool_item_num;
|
||||
}
|
||||
count+=bool_exprs[i].bool_item_num;
|
||||
for(unsigned int j=0; j<bool_exprs[i].bool_item_num; j++)
|
||||
{
|
||||
M[bool_exprs[i].bool_item_ids[j]].push_back((i<<3)|j);
|
||||
}
|
||||
}
|
||||
|
||||
matcher->bool_item_id_num=(unsigned int)M.size();
|
||||
matcher->bool_item_ids=new unsigned int[M.size()];
|
||||
matcher->mapped_ptr =new unsigned int[M.size()+1];
|
||||
matcher->mapped_ids =new unsigned int[count];
|
||||
mem_bytes+=(2*(unsigned int)M.size()+1+count)*sizeof(unsigned int);
|
||||
|
||||
matcher->mapped_ptr[0]=0;
|
||||
map< unsigned int, vector<unsigned int> >::const_iterator it=M.begin();
|
||||
for(unsigned int k=0; k<M.size(); ++k, ++it)
|
||||
{
|
||||
matcher->bool_item_ids[k]=it->first;
|
||||
copy(it->second.begin(), it->second.end(), matcher->mapped_ids+matcher->mapped_ptr[k]);
|
||||
matcher->mapped_ptr[k+1]=matcher->mapped_ptr[k]+(unsigned int)it->second.size();
|
||||
}
|
||||
|
||||
matcher->min_item_id=matcher->bool_item_ids[0];
|
||||
matcher->max_item_id=matcher->bool_item_ids[M.size()-1];
|
||||
for(unsigned int k=0; k<M.size(); ++k)
|
||||
{
|
||||
matcher->bool_item_ids[k]-=matcher->min_item_id;
|
||||
}
|
||||
|
||||
unsigned long long ONE=1;
|
||||
unsigned int theta=0;
|
||||
while((ONE<<(theta+16))<=matcher->bool_item_ids[M.size()-1]) theta++;
|
||||
matcher->theta=theta;
|
||||
|
||||
matcher->L[0]=0;
|
||||
for(unsigned int i=1; i<65536; i++)
|
||||
{
|
||||
matcher->L[i]=(unsigned int)(lower_bound(matcher->bool_item_ids, matcher->bool_item_ids+M.size(), i*(1U<<theta))-matcher->bool_item_ids);
|
||||
}
|
||||
matcher->L[65536]=(unsigned int)M.size();
|
||||
|
||||
M.clear();
|
||||
|
||||
*mem_size=mem_bytes;
|
||||
return matcher;
|
||||
}
|
||||
|
||||
int boolexpr_match(void * instance, unsigned int thread_id, unsigned int * item_ids, unsigned int item_num, void ** result, unsigned int size)
|
||||
{
|
||||
if(instance==NULL) return -1;
|
||||
|
||||
boolexpr_matcher_t * matcher=(boolexpr_matcher_t *)instance;
|
||||
if(thread_id>=matcher->max_thread_num) return -1;
|
||||
|
||||
unsigned int * mapped_ids=matcher->thread_data[thread_id].mapped_ids;
|
||||
unsigned int ids_num=0;
|
||||
for(unsigned int i=0; i<item_num; i++)
|
||||
{
|
||||
if(item_ids[i]<matcher->min_item_id || item_ids[i]>matcher->max_item_id) continue;
|
||||
|
||||
unsigned int id=item_ids[i]-matcher->min_item_id;
|
||||
unsigned int k=id>>matcher->theta;
|
||||
|
||||
int l=matcher->L[k], h=(int)matcher->L[k+1]-1;
|
||||
if(h<l) continue;
|
||||
while(l<=h)
|
||||
{
|
||||
int m=(l+h)/2;
|
||||
if(id<matcher->bool_item_ids[m]) h=m-1;
|
||||
else l=m+1;
|
||||
}
|
||||
if(h<(int)matcher->L[k] || matcher->bool_item_ids[h]!=id) continue;
|
||||
|
||||
for(unsigned int j=matcher->mapped_ptr[h]; j<matcher->mapped_ptr[h+1]; j++)
|
||||
{
|
||||
if(ids_num==MAX_ARRAY_SIZE) return -1;
|
||||
mapped_ids[ids_num++]=matcher->mapped_ids[j];
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int * used_cells=matcher->thread_data[thread_id].used_cells;
|
||||
unsigned int used_num=0;
|
||||
for(unsigned int i=0; i<ids_num; i++)
|
||||
{
|
||||
if(used_num==MAX_ARRAY_SIZE) return -1;
|
||||
used_cells[used_num++]=(mapped_ids[i]>>3);
|
||||
}
|
||||
|
||||
unsigned char * bitmap=matcher->thread_data[thread_id].bitmap;
|
||||
unsigned int * matched_bitmap=matcher->thread_data[thread_id].matched_bitmap;
|
||||
for(unsigned int i=0; i<used_num; i++)
|
||||
{
|
||||
if(used_cells[i]<matcher->multi_expr_num)
|
||||
{
|
||||
bitmap[used_cells[i]]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int j=used_cells[i]-matcher->multi_expr_num;
|
||||
matched_bitmap[j>>5]&=~(1U<<(j&31));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int r=0;
|
||||
|
||||
for(unsigned int i=0; i<ids_num; i++)
|
||||
{
|
||||
unsigned int x=(mapped_ids[i]>>3);
|
||||
if(x<matcher->multi_expr_num)
|
||||
{
|
||||
unsigned int y=(mapped_ids[i]&7);
|
||||
if((bitmap[x]&(1U<<y))==0)
|
||||
{
|
||||
bitmap[x]|=(1U<<y);
|
||||
if(bitmap[x]==(1U<<matcher->multi_expr_size[x])-1)
|
||||
{
|
||||
if(r<size) result[r++]=matcher->bool_expr_ids[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int j=x-matcher->multi_expr_num;
|
||||
if((matched_bitmap[j>>5]&(1U<<(j&31)))==0)
|
||||
{
|
||||
if(r<size) result[r++]=matcher->bool_expr_ids[x];
|
||||
matched_bitmap[j>>5]|=(1U<<(j&31));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void boolexpr_destroy(void * instance)
|
||||
{
|
||||
if(instance!=NULL)
|
||||
{
|
||||
boolexpr_matcher_t * matcher=(boolexpr_matcher_t *)instance;
|
||||
delete [] matcher->bool_expr_ids;
|
||||
delete [] matcher->multi_expr_size;
|
||||
delete [] matcher->bool_item_ids;
|
||||
delete [] matcher->mapped_ptr;
|
||||
delete [] matcher->mapped_ids;
|
||||
for(unsigned int i=0; i<matcher->max_thread_num; i++)
|
||||
{
|
||||
delete [] matcher->thread_data[i].bitmap;
|
||||
}
|
||||
delete [] matcher->thread_data;
|
||||
delete matcher;
|
||||
}
|
||||
}
|
||||
46
src/entry/UniversalBoolMatch.h
Normal file
46
src/entry/UniversalBoolMatch.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2014
|
||||
* String Algorithms Research Group
|
||||
* Institute of Information Engineering, Chinese Academy of Sciences (IIE-CAS)
|
||||
* National Engineering Laboratory for Information Security Technologies (NELIST)
|
||||
* All rights reserved
|
||||
*
|
||||
* Written by: LIU YANBING (liuyanbing@iie.ac.cn)
|
||||
* Last modification: 2014-12-09
|
||||
*
|
||||
* This code is the exclusive and proprietary property of IIE-CAS and NELIST.
|
||||
* Usage for direct or indirect commercial advantage is not allowed without
|
||||
* written permission from the authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef H_UNIVERSAL_BOOL_MATCH_H
|
||||
#define H_UNIVERSAL_BOOL_MATCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define MAX_ITEMS_PER_BOOL_EXPR 8
|
||||
|
||||
typedef struct _universal_bool_expr_t
|
||||
{
|
||||
void * bool_expr_id;
|
||||
unsigned int bool_item_num;
|
||||
unsigned int bool_item_ids[MAX_ITEMS_PER_BOOL_EXPR];
|
||||
}universal_bool_expr_t;
|
||||
|
||||
/*ע<>⣺<EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ûύ<C3BB><E1BDBB>bool_exprs<72><73>Ԫ<EFBFBD>ص<EFBFBD>λ<EFBFBD><CEBB>*/
|
||||
void * boolexpr_initialize(universal_bool_expr_t * bool_exprs, unsigned int bool_expr_num, unsigned int max_thread_num, unsigned int * mem_size);
|
||||
|
||||
int boolexpr_match(void * instance, unsigned int thread_id, unsigned int * item_ids, unsigned int item_num, void ** result, unsigned int size);
|
||||
|
||||
void boolexpr_destroy(void * instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
596
src/entry/cJSON.c
Normal file
596
src/entry/cJSON.c
Normal file
@@ -0,0 +1,596 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* cJSON */
|
||||
/* JSON parser in C. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *ep;
|
||||
|
||||
const char *cJSON_GetErrorPtr(void) {return ep;}
|
||||
|
||||
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||
{
|
||||
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
|
||||
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
|
||||
}
|
||||
|
||||
static void *(*cJSON_malloc)(size_t sz) = malloc;
|
||||
static void (*cJSON_free)(void *ptr) = free;
|
||||
|
||||
static char* cJSON_strdup(const char* str)
|
||||
{
|
||||
size_t len;
|
||||
char* copy;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if (!(copy = (char*)cJSON_malloc(len))) return 0;
|
||||
memcpy(copy,str,len);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
{
|
||||
if (!hooks) { /* Reset hooks */
|
||||
cJSON_malloc = malloc;
|
||||
cJSON_free = free;
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
|
||||
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
|
||||
}
|
||||
|
||||
/* Internal constructor. */
|
||||
static cJSON *cJSON_New_Item(void)
|
||||
{
|
||||
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
|
||||
if (node) memset(node,0,sizeof(cJSON));
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Delete a cJSON structure. */
|
||||
void cJSON_Delete(cJSON *c)
|
||||
{
|
||||
cJSON *next;
|
||||
while (c)
|
||||
{
|
||||
next=c->next;
|
||||
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
|
||||
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
|
||||
if (c->string) cJSON_free(c->string);
|
||||
cJSON_free(c);
|
||||
c=next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
static const char *parse_number(cJSON *item,const char *num)
|
||||
{
|
||||
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
|
||||
|
||||
if (*num=='-') sign=-1,num++; /* Has sign? */
|
||||
if (*num=='0') num++; /* is zero */
|
||||
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
|
||||
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
|
||||
if (*num=='e' || *num=='E') /* Exponent? */
|
||||
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
|
||||
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
|
||||
}
|
||||
|
||||
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
|
||||
|
||||
item->valuedouble=n;
|
||||
item->valueint=(int)n;
|
||||
item->type=cJSON_Number;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static char *print_number(cJSON *item)
|
||||
{
|
||||
char *str;
|
||||
double d=item->valuedouble;
|
||||
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
|
||||
{
|
||||
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
|
||||
if (str) sprintf(str,"%d",item->valueint);
|
||||
}
|
||||
else
|
||||
{
|
||||
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
|
||||
if (str)
|
||||
{
|
||||
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
|
||||
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
|
||||
else sprintf(str,"%f",d);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static unsigned parse_hex4(const char *str)
|
||||
{
|
||||
unsigned h=0;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Parse the input text into an unescaped cstring, and populate item. */
|
||||
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
static const char *parse_string(cJSON *item,const char *str)
|
||||
{
|
||||
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
|
||||
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
||||
|
||||
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
|
||||
if (!out) return 0;
|
||||
|
||||
ptr=str+1;ptr2=out;
|
||||
while (*ptr!='\"' && *ptr)
|
||||
{
|
||||
if (*ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case 'b': *ptr2++='\b'; break;
|
||||
case 'f': *ptr2++='\f'; break;
|
||||
case 'n': *ptr2++='\n'; break;
|
||||
case 'r': *ptr2++='\r'; break;
|
||||
case 't': *ptr2++='\t'; break;
|
||||
case 'u': /* transcode utf16 to utf8. */
|
||||
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
|
||||
|
||||
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
|
||||
|
||||
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
|
||||
{
|
||||
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
|
||||
uc2=parse_hex4(ptr+3);ptr+=6;
|
||||
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
|
||||
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
|
||||
}
|
||||
|
||||
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
|
||||
|
||||
switch (len) {
|
||||
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
||||
}
|
||||
ptr2+=len;
|
||||
break;
|
||||
default: *ptr2++=*ptr; break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*ptr2=0;
|
||||
if (*ptr=='\"') ptr++;
|
||||
item->valuestring=out;
|
||||
item->type=cJSON_String;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Render the cstring provided to an escaped version that can be printed. */
|
||||
static char *print_string_ptr(const char *str)
|
||||
{
|
||||
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
|
||||
|
||||
if (!str) return cJSON_strdup("");
|
||||
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
|
||||
|
||||
out=(char*)cJSON_malloc(len+3);
|
||||
if (!out) return 0;
|
||||
|
||||
ptr2=out;ptr=str;
|
||||
*ptr2++='\"';
|
||||
while (*ptr)
|
||||
{
|
||||
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
*ptr2++='\\';
|
||||
switch (token=*ptr++)
|
||||
{
|
||||
case '\\': *ptr2++='\\'; break;
|
||||
case '\"': *ptr2++='\"'; break;
|
||||
case '\b': *ptr2++='b'; break;
|
||||
case '\f': *ptr2++='f'; break;
|
||||
case '\n': *ptr2++='n'; break;
|
||||
case '\r': *ptr2++='r'; break;
|
||||
case '\t': *ptr2++='t'; break;
|
||||
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2++='\"';*ptr2++=0;
|
||||
return out;
|
||||
}
|
||||
/* Invote print_string_ptr (which is useful) on an item. */
|
||||
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
|
||||
|
||||
/* Predeclare these prototypes. */
|
||||
static const char *parse_value(cJSON *item,const char *value);
|
||||
static char *print_value(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_array(cJSON *item,const char *value);
|
||||
static char *print_array(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_object(cJSON *item,const char *value);
|
||||
static char *print_object(cJSON *item,int depth,int fmt);
|
||||
|
||||
/* Utility to jump whitespace and cr/lf */
|
||||
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
|
||||
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
|
||||
{
|
||||
const char *end=0;
|
||||
cJSON *c=cJSON_New_Item();
|
||||
ep=0;
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
end=parse_value(c,skip(value));
|
||||
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
|
||||
|
||||
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
|
||||
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
|
||||
if (return_parse_end) *return_parse_end=end;
|
||||
return c;
|
||||
}
|
||||
/* Default options for cJSON_Parse */
|
||||
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
|
||||
|
||||
/* Render a cJSON item/entity/structure to text. */
|
||||
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
|
||||
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char *parse_value(cJSON *item,const char *value)
|
||||
{
|
||||
if (!value) return 0; /* Fail on null. */
|
||||
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
|
||||
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
|
||||
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
|
||||
if (*value=='\"') { return parse_string(item,value); }
|
||||
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
|
||||
if (*value=='[') { return parse_array(item,value); }
|
||||
if (*value=='{') { return parse_object(item,value); }
|
||||
|
||||
ep=value;return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Render a value to text. */
|
||||
static char *print_value(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char *out=0;
|
||||
if (!item) return 0;
|
||||
switch ((item->type)&255)
|
||||
{
|
||||
case cJSON_NULL: out=cJSON_strdup("null"); break;
|
||||
case cJSON_False: out=cJSON_strdup("false");break;
|
||||
case cJSON_True: out=cJSON_strdup("true"); break;
|
||||
case cJSON_Number: out=print_number(item);break;
|
||||
case cJSON_String: out=print_string(item);break;
|
||||
case cJSON_Array: out=print_array(item,depth,fmt);break;
|
||||
case cJSON_Object: out=print_object(item,depth,fmt);break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char *parse_array(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='[') {ep=value;return 0;} /* not an array! */
|
||||
|
||||
item->type=cJSON_Array;
|
||||
value=skip(value+1);
|
||||
if (*value==']') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0; /* memory fail */
|
||||
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_value(child,skip(value+1)));
|
||||
if (!value) return 0; /* memory fail */
|
||||
}
|
||||
|
||||
if (*value==']') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an array to text */
|
||||
static char *print_array(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries;
|
||||
char *out=0,*ptr,*ret;int len=5;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,i=0,fail=0;
|
||||
|
||||
/* How many entries in the array? */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle numentries==0 */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(3);
|
||||
if (out) strcpy(out,"[]");
|
||||
return out;
|
||||
}
|
||||
/* Allocate an array to hold the values for each */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
memset(entries,0,numentries*sizeof(char*));
|
||||
/* Retrieve all the results: */
|
||||
child=item->child;
|
||||
while (child && !fail)
|
||||
{
|
||||
ret=print_value(child,depth+1,fmt);
|
||||
entries[i++]=ret;
|
||||
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* If we didn't fail, try to malloc the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
/* If that fails, we fail. */
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure. */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
|
||||
cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output array. */
|
||||
*out='[';
|
||||
ptr=out+1;*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
|
||||
cJSON_free(entries[i]);
|
||||
}
|
||||
cJSON_free(entries);
|
||||
*ptr++=']';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char *parse_object(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='{') {ep=value;return 0;} /* not an object! */
|
||||
|
||||
item->type=cJSON_Object;
|
||||
value=skip(value+1);
|
||||
if (*value=='}') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0;
|
||||
value=skip(parse_string(child,skip(value)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_string(child,skip(value+1)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value=='}') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an object to text. */
|
||||
static char *print_object(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries=0,**names=0;
|
||||
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,fail=0;
|
||||
/* Count the number of entries. */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle empty object case */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(fmt?depth+4:3);
|
||||
if (!out) return 0;
|
||||
ptr=out;*ptr++='{';
|
||||
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
/* Allocate space for the names and the objects */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
names=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!names) {cJSON_free(entries);return 0;}
|
||||
memset(entries,0,sizeof(char*)*numentries);
|
||||
memset(names,0,sizeof(char*)*numentries);
|
||||
|
||||
/* Collect all the results into our arrays: */
|
||||
child=item->child;depth++;if (fmt) len+=depth;
|
||||
while (child)
|
||||
{
|
||||
names[i]=str=print_string_ptr(child->string);
|
||||
entries[i++]=ret=print_value(child,depth,fmt);
|
||||
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* Try to allocate the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output: */
|
||||
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
|
||||
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
|
||||
*ptr++=':';if (fmt) *ptr++='\t';
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) *ptr++=',';
|
||||
if (fmt) *ptr++='\n';*ptr=0;
|
||||
cJSON_free(names[i]);cJSON_free(entries[i]);
|
||||
}
|
||||
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Get Array size/item / object item. */
|
||||
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
|
||||
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
|
||||
|
||||
/* Utility for array list handling. */
|
||||
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
|
||||
/* Utility for handling references. */
|
||||
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
|
||||
|
||||
/* Add item to array/object. */
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
|
||||
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
|
||||
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
|
||||
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
|
||||
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
|
||||
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
|
||||
|
||||
/* Replace array/object items with new ones. */
|
||||
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
|
||||
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
|
||||
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
|
||||
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
|
||||
|
||||
/* Create basic types: */
|
||||
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
|
||||
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
|
||||
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
|
||||
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
|
||||
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
|
||||
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
|
||||
|
||||
/* Create Arrays: */
|
||||
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
|
||||
/* Duplication */
|
||||
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
|
||||
{
|
||||
cJSON *newitem,*cptr,*nptr=0,*newchild;
|
||||
/* Bail on bad ptr */
|
||||
if (!item) return 0;
|
||||
/* Create new item */
|
||||
newitem=cJSON_New_Item();
|
||||
if (!newitem) return 0;
|
||||
/* Copy over all vars */
|
||||
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
|
||||
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
|
||||
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
|
||||
/* If non-recursive, then we're done! */
|
||||
if (!recurse) return newitem;
|
||||
/* Walk the ->next chain for the child. */
|
||||
cptr=item->child;
|
||||
while (cptr)
|
||||
{
|
||||
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
|
||||
if (!newchild) {cJSON_Delete(newitem);return 0;}
|
||||
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
|
||||
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
|
||||
cptr=cptr->next;
|
||||
}
|
||||
return newitem;
|
||||
}
|
||||
|
||||
void cJSON_Minify(char *json)
|
||||
{
|
||||
char *into=json;
|
||||
while (*json)
|
||||
{
|
||||
if (*json==' ') json++;
|
||||
else if (*json=='\t') json++; // Whitespace characters.
|
||||
else if (*json=='\r') json++;
|
||||
else if (*json=='\n') json++;
|
||||
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
|
||||
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
|
||||
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
|
||||
else *into++=*json++; // All other characters.
|
||||
}
|
||||
*into=0; // and null-terminate.
|
||||
}
|
||||
143
src/entry/cJSON.h
Normal file
143
src/entry/cJSON.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
|
||||
|
||||
extern void cJSON_Minify(char *json);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
321
src/entry/config_monitor.cpp
Normal file
321
src/entry/config_monitor.cpp
Normal file
@@ -0,0 +1,321 @@
|
||||
#include "MESA_handle_logger.h"
|
||||
#include "config_monitor.h"
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
const char* module_config_monitor="CONFIG_MONITOR";
|
||||
|
||||
#define CM_UPDATE_TYPE_ERR -1
|
||||
#define CM_UPDATE_TYPE_NONE 0
|
||||
|
||||
#define CM_MAX_TABLE_NUM 256
|
||||
#define MAX_CONFIG_FN_LEN 256
|
||||
#define MAX_CONFIG_LINE 1024*4
|
||||
//#define USING_DICTATOR 1
|
||||
extern "C" void __real_free(void*p);
|
||||
struct cm_table_info_t
|
||||
{
|
||||
char table_name[MAX_CONFIG_FN_LEN];
|
||||
char cfg_path[MAX_CONFIG_FN_LEN];
|
||||
int cfg_num;
|
||||
};
|
||||
//replacement of glibc scandir, to adapt dictator malloc wrap
|
||||
#define ENLARGE_STEP 1024
|
||||
int my_scandir(const char *dir, struct dirent ***namelist,
|
||||
int(*filter)(const struct dirent *),
|
||||
int(*compar)(const void *, const void *))
|
||||
{
|
||||
DIR * od;
|
||||
int n = 0;
|
||||
int DIR_ENT_SIZE=ENLARGE_STEP;
|
||||
struct dirent ** list = NULL;
|
||||
struct dirent * p;
|
||||
struct dirent entry,*result;
|
||||
|
||||
if((dir == NULL) || (namelist == NULL))
|
||||
return -1;
|
||||
|
||||
od = opendir(dir);
|
||||
if(od == NULL)
|
||||
return -1;
|
||||
|
||||
list = (struct dirent **)malloc(DIR_ENT_SIZE*sizeof(struct dirent *));
|
||||
|
||||
|
||||
while(0==readdir_r(od,&entry,&result))
|
||||
{
|
||||
if(result==NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if( filter && !filter(&entry))
|
||||
continue;
|
||||
|
||||
p = (struct dirent *)malloc(sizeof(struct dirent));
|
||||
memcpy((void *)p,(void *)(&entry),sizeof(struct dirent));
|
||||
list[n] = p;
|
||||
|
||||
n++;
|
||||
if(n >= DIR_ENT_SIZE)
|
||||
{
|
||||
DIR_ENT_SIZE+=ENLARGE_STEP;
|
||||
list=(struct dirent **)realloc((void*)list,DIR_ENT_SIZE*sizeof(struct dirent *));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
closedir(od);
|
||||
|
||||
*namelist = list;
|
||||
|
||||
if(compar)
|
||||
qsort((void *)*namelist,n,sizeof(struct dirent *),compar);
|
||||
|
||||
return n;
|
||||
|
||||
}
|
||||
int filter_fn(const struct dirent * ent)
|
||||
{
|
||||
if(ent->d_type != DT_REG)
|
||||
return 0;
|
||||
|
||||
return (strncmp(ent->d_name,"full_config_index",strlen("full_config_index")) == 0||
|
||||
strncmp(ent->d_name,"inc_config_index",strlen("inc_config_index")) == 0);
|
||||
}
|
||||
int get_new_idx_path(unsigned int current_version,const char*file_dir,void* logger,char*** idx_path,int*idx_num)
|
||||
{
|
||||
struct dirent **namelist;
|
||||
int n=0,i=0,sscanf_ret;
|
||||
|
||||
char update_str[32]={0};
|
||||
unsigned int latest_ful_version=0,latest_inc_version=0;
|
||||
unsigned int config_seq=0;
|
||||
int *inc_file_idx;
|
||||
int full_file_idx=0,inc_idx_num=0,path_len=0;
|
||||
|
||||
int update_type=CM_UPDATE_TYPE_NONE;
|
||||
|
||||
|
||||
n = my_scandir(file_dir, &namelist, filter_fn, (int (*)(const void*, const void*))alphasort);
|
||||
if (n < 0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"scan dir error");
|
||||
update_type=CM_UPDATE_TYPE_ERR;
|
||||
return update_type;
|
||||
}
|
||||
inc_file_idx=(int*)calloc(sizeof(int),n);
|
||||
inc_idx_num=0;
|
||||
for(i=0;i<n;i++)
|
||||
{
|
||||
config_seq=0;
|
||||
if((strcmp(namelist[i]->d_name, ".") == 0) || (strcmp(namelist[i]->d_name, "..") == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(strlen(namelist[i]->d_name)>32)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor
|
||||
,"config file %s filename too long,should like full_config_index.0000000001"
|
||||
,namelist[i]->d_name);
|
||||
continue;
|
||||
}
|
||||
sscanf_ret=sscanf(namelist[i]->d_name,"%[a-zA-Z]_config_index.%u",update_str,&config_seq);
|
||||
if(sscanf_ret!=2)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor
|
||||
,"config file %s filename error,should like full_config_index.0000000001"
|
||||
,namelist[i]->d_name);
|
||||
continue;
|
||||
}
|
||||
if(strncasecmp(update_str,"full",strlen(update_str))==0)
|
||||
{
|
||||
if(config_seq>latest_ful_version)
|
||||
{
|
||||
latest_ful_version=config_seq;
|
||||
full_file_idx=i;
|
||||
}
|
||||
}
|
||||
else if(strncasecmp(update_str,"inc",strlen(update_str))==0)
|
||||
{
|
||||
if(config_seq>current_version)
|
||||
{
|
||||
inc_file_idx[inc_idx_num]=i;
|
||||
inc_idx_num++;
|
||||
if(config_seq>latest_inc_version)
|
||||
{
|
||||
latest_inc_version=config_seq;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor
|
||||
,"config file %s,not full or inc config"
|
||||
,namelist[i]->d_name);
|
||||
}
|
||||
}
|
||||
//full update
|
||||
if(latest_ful_version>current_version)
|
||||
{
|
||||
*idx_path=(char**)malloc(sizeof(char**));
|
||||
path_len=strlen(file_dir)+strlen(namelist[full_file_idx]->d_name)+1+1;
|
||||
(*idx_path)[0]=(char*)malloc(path_len);
|
||||
snprintf((*idx_path)[0],path_len,"%s/%s",file_dir,namelist[full_file_idx]->d_name);
|
||||
*idx_num=1;
|
||||
update_type=CM_UPDATE_TYPE_FULL;
|
||||
}
|
||||
//inc update,it's possible that do inc after full update in this function,but we'll process it at next call.
|
||||
else if(latest_inc_version>current_version)
|
||||
{
|
||||
|
||||
*idx_path=(char**)malloc(sizeof(char**)*inc_idx_num);
|
||||
for(i=0;i<inc_idx_num;i++)
|
||||
{
|
||||
path_len=strlen(file_dir)+strlen(namelist[inc_file_idx[i]]->d_name)+1+1;
|
||||
(*idx_path)[i]=(char*)malloc(path_len);
|
||||
snprintf((*idx_path)[i],path_len,"%s/%s",file_dir,namelist[inc_file_idx[i]]->d_name);
|
||||
|
||||
}
|
||||
*idx_num=inc_idx_num;
|
||||
update_type=CM_UPDATE_TYPE_INC;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
update_type=CM_UPDATE_TYPE_NONE;
|
||||
}
|
||||
free(inc_file_idx);
|
||||
for(i=0;i<n;i++)
|
||||
{
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
|
||||
return update_type;
|
||||
}
|
||||
int cm_read_cfg_index_file(const char* path,struct cm_table_info_t* idx,int size,void* logger)
|
||||
{
|
||||
FILE* fp=NULL;
|
||||
fp=fopen(path,"r");
|
||||
int ret=0,i=0;
|
||||
while(!feof(fp))
|
||||
{
|
||||
ret=fscanf(fp,"%s\t%d\t%s",idx[i].table_name
|
||||
,&(idx[i].cfg_num)
|
||||
,idx[i].cfg_path);
|
||||
if(ret==3&&idx[i].cfg_num>0)//jump over empty line
|
||||
{
|
||||
i++;
|
||||
}
|
||||
if(i==size)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor ,"Too much lines in %s",path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return i;
|
||||
}
|
||||
|
||||
int cm_read_table_file(struct cm_table_info_t* index,
|
||||
void (*update)(const char*,const char*,void*),
|
||||
void* u_para,
|
||||
void* logger)
|
||||
{
|
||||
int cfg_num=0,i=0;
|
||||
char line[MAX_CONFIG_LINE]={0},*ret_str=NULL;
|
||||
FILE*fp=fopen(index->cfg_path,"r");
|
||||
if(fp==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"update error,open %s failed.",index->cfg_path);
|
||||
return -1;
|
||||
}
|
||||
fscanf(fp,"%d\n",&cfg_num);
|
||||
if(cfg_num!=index->cfg_num)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor ,"file %s config num not matched",index->cfg_path);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
for(i=0;i<cfg_num;i++)
|
||||
{
|
||||
line[sizeof(line)-1]='\0';
|
||||
ret_str=fgets(line,sizeof(line),fp);
|
||||
if(ret_str==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor ,
|
||||
"update error,file %s line_num %d less than claimed %d",
|
||||
index->cfg_path,i,cfg_num);
|
||||
break;
|
||||
}
|
||||
if(line[sizeof(line)-1]!='\0')
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor ,
|
||||
"update error,line size more than %u at of file %s:%d",
|
||||
sizeof(line),index->cfg_path,i);
|
||||
continue;
|
||||
}
|
||||
update(index->table_name,line,u_para);
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
const char* path2filename(const char*path)
|
||||
{
|
||||
int i=0;
|
||||
for(i=strlen(path);i>0;i--)
|
||||
{
|
||||
if(path[i]=='/')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path+i+1;
|
||||
}
|
||||
void config_monitor_traverse(unsigned int version,const char*idx_dir,
|
||||
void (*start)(unsigned int ,int ,void*),
|
||||
void (*update)(const char* ,const char*,void* ),
|
||||
void (*finish)(void*),
|
||||
void* u_para,
|
||||
void* logger)
|
||||
{
|
||||
|
||||
int update_type=CM_UPDATE_TYPE_NONE;
|
||||
unsigned int new_version=0;
|
||||
char**idx_path_array=NULL;
|
||||
const char* table_filename=NULL;
|
||||
char str_not_care[256]={0};
|
||||
int idx_num=0,table_num=0,i=0,j=0;
|
||||
struct cm_table_info_t table_array[CM_MAX_TABLE_NUM];
|
||||
update_type=get_new_idx_path(version, idx_dir,logger, &idx_path_array, &idx_num);
|
||||
if(update_type==CM_UPDATE_TYPE_FULL||update_type==CM_UPDATE_TYPE_INC)
|
||||
{
|
||||
|
||||
for(i=0;i<idx_num;i++)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_INFO,module_config_monitor ,
|
||||
"load %s",idx_path_array[i]);
|
||||
table_num=cm_read_cfg_index_file(idx_path_array[i],table_array, CM_MAX_TABLE_NUM,logger);
|
||||
table_filename=path2filename(idx_path_array[i]);
|
||||
sscanf(table_filename,"%[a-zA-Z]_config_index.%u",str_not_care,&new_version);
|
||||
start(new_version,update_type,u_para);
|
||||
for(j=0;j<table_num;j++)
|
||||
{
|
||||
cm_read_table_file(table_array+j,update,u_para,logger);
|
||||
}
|
||||
finish(u_para);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(i=0;i<idx_num;i++)
|
||||
{
|
||||
free(idx_path_array[i]);
|
||||
}
|
||||
free(idx_path_array);//free null is OK
|
||||
return;
|
||||
}
|
||||
|
||||
14
src/entry/config_monitor.h
Normal file
14
src/entry/config_monitor.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __CONFIG_MONITOR_H_INCLUDE_
|
||||
#define __CONFIG_MONITOR_H_INCLUDE_
|
||||
|
||||
#define CM_UPDATE_TYPE_FULL 1
|
||||
#define CM_UPDATE_TYPE_INC 2
|
||||
|
||||
void config_monitor_traverse(unsigned int version,const char*idx_dir,
|
||||
void (*start)(unsigned int ,int ,void*),//vesion,CM_UPDATE_TYPE_*,u_para
|
||||
void (*update)(const char* ,const char*,void* ),//table name ,line ,u_para
|
||||
void (*finish)(void*),//u_para
|
||||
void* u_para,
|
||||
void* logger);
|
||||
#endif
|
||||
|
||||
53
src/entry/dynamic_array.cpp
Normal file
53
src/entry/dynamic_array.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include"dynamic_array.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
int dynamic_array_VERSION_20141202=0;
|
||||
struct dynamic_array_t* dynamic_array_create(int size,int step)
|
||||
{
|
||||
struct dynamic_array_t* d_array=(struct dynamic_array_t*)calloc(sizeof(struct dynamic_array_t),1);
|
||||
d_array->array=(void**)calloc(sizeof(void*),size);
|
||||
d_array->size=size;
|
||||
d_array->enlarge_step=step;
|
||||
return d_array;
|
||||
}
|
||||
void dynamic_array_destroy(struct dynamic_array_t* d_array,void (* free_data)(void *))
|
||||
{
|
||||
int i;
|
||||
if(free_data!=NULL)
|
||||
{
|
||||
for(i=0;i<d_array->size;i++)
|
||||
{
|
||||
free_data(d_array->array[i]);
|
||||
}
|
||||
}
|
||||
free(d_array->array);
|
||||
free(d_array);
|
||||
}
|
||||
void* dynamic_array_read(struct dynamic_array_t* d_array,int i)
|
||||
{
|
||||
if(i<d_array->size)
|
||||
{
|
||||
return d_array->array[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
void dynamic_array_write(struct dynamic_array_t* d_array,int i,void* data)
|
||||
{
|
||||
int new_size=0;
|
||||
if(i<d_array->size)
|
||||
{
|
||||
d_array->array[i]=data;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_size=i+d_array->enlarge_step;
|
||||
d_array->array=(void**)realloc(d_array->array,new_size*sizeof(void*));
|
||||
memset(d_array->array+d_array->size,0,(new_size-d_array->size)*sizeof(void*));
|
||||
d_array->size=new_size;
|
||||
d_array->array[i]=data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
13
src/entry/dynamic_array.h
Normal file
13
src/entry/dynamic_array.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef _DYNAMIC_ARRAY_H_INCLUDE_
|
||||
#define _DYNAMIC_ARRAY_H_INCLUDE_
|
||||
struct dynamic_array_t
|
||||
{
|
||||
void ** array;
|
||||
int size;
|
||||
int enlarge_step;
|
||||
};
|
||||
struct dynamic_array_t* dynamic_array_create(int size,int step);
|
||||
void dynamic_array_destroy(struct dynamic_array_t* d_array,void (* free_data)(void *));
|
||||
void* dynamic_array_read(struct dynamic_array_t* d_array,int i);
|
||||
void dynamic_array_write(struct dynamic_array_t* d_array,int i,void* data);
|
||||
#endif //_DYNAMIC_ARRAY_H_INCLUDE_
|
||||
919
src/entry/json2iris.cpp
Normal file
919
src/entry/json2iris.cpp
Normal file
@@ -0,0 +1,919 @@
|
||||
|
||||
#include <MESA/MESA_handle_logger.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <MESA/MESA_htable.h>
|
||||
#include "cJSON.h"
|
||||
#include "map_str2int.h"
|
||||
#include "Maat_rule_internal.h"
|
||||
const char* maat_json="maat json";
|
||||
const int json_version=1;
|
||||
#define MAX_PATH_LINE 256
|
||||
#define MAX_COLUMN_NUM 32
|
||||
struct group_info_t
|
||||
{
|
||||
int group_id;
|
||||
};
|
||||
struct iris_table_t
|
||||
{
|
||||
char table_name[MAX_PATH_LINE];
|
||||
char table_path[MAX_PATH_LINE];
|
||||
int line_count;
|
||||
};
|
||||
struct iris_description_t
|
||||
{
|
||||
int group_cnt;
|
||||
int region_cnt;
|
||||
|
||||
char tmp_iris_dir[MAX_PATH_LINE];
|
||||
char tmp_iris_index_dir[MAX_PATH_LINE];
|
||||
char index_path[MAX_PATH_LINE];
|
||||
|
||||
struct iris_table_t group_table;
|
||||
struct iris_table_t compile_table;
|
||||
MESA_htable_handle group_name_map;
|
||||
MESA_htable_handle iris_table_map;
|
||||
MESA_htable_handle str2int_map;
|
||||
|
||||
};
|
||||
struct traslate_command_t
|
||||
{
|
||||
const char* json_string;
|
||||
char* json_value;
|
||||
int json_type;
|
||||
int str2int_flag;
|
||||
int empty_allowed;
|
||||
const char* default_string;
|
||||
int default_int;
|
||||
};
|
||||
int set_iris_descriptor(const char* json_file,cJSON *json,struct iris_description_t *iris_cfg,void * logger)
|
||||
{
|
||||
cJSON* j=NULL;
|
||||
char* table_name=NULL;
|
||||
memset(iris_cfg,0,sizeof(struct iris_description_t));
|
||||
snprintf(iris_cfg->tmp_iris_dir,sizeof(iris_cfg->tmp_iris_dir),"%s_iris_tmp",json_file);
|
||||
snprintf(iris_cfg->tmp_iris_index_dir,sizeof(iris_cfg->tmp_iris_index_dir),"%s_iris_tmp/index",json_file);
|
||||
snprintf(iris_cfg->index_path,sizeof(iris_cfg->index_path),"%s/full_config_index.%010d",iris_cfg->tmp_iris_index_dir,json_version);
|
||||
|
||||
j=cJSON_GetObjectItem(json, "compile_table");
|
||||
if(j==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile_table not defined.");
|
||||
return -1;
|
||||
}
|
||||
table_name=j->valuestring;
|
||||
memcpy(iris_cfg->compile_table.table_name,table_name,strlen(table_name));
|
||||
snprintf(iris_cfg->compile_table.table_path,sizeof(iris_cfg->compile_table.table_path),
|
||||
"%s/%s.local",iris_cfg->tmp_iris_dir,iris_cfg->compile_table.table_name);
|
||||
j=cJSON_GetObjectItem(json, "group_table");
|
||||
if(j==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"group_table not defined.");
|
||||
return -1;
|
||||
}
|
||||
table_name=j->valuestring;
|
||||
memcpy(iris_cfg->group_table.table_name,table_name,strlen(table_name));
|
||||
snprintf(iris_cfg->group_table.table_path,sizeof(iris_cfg->group_table.table_name),
|
||||
"%s/%s.local",iris_cfg->tmp_iris_dir,iris_cfg->group_table.table_name);
|
||||
|
||||
MESA_htable_create_args_t hargs;
|
||||
memset(&hargs,0,sizeof(hargs));
|
||||
hargs.thread_safe=1;
|
||||
hargs.hash_slot_size = 1024;
|
||||
hargs.max_elem_num = 0;
|
||||
hargs.eliminate_type = HASH_ELIMINATE_ALGO_LRU;
|
||||
hargs.expire_time = 0;
|
||||
hargs.key_comp = NULL;
|
||||
hargs.key2index = NULL;
|
||||
hargs.recursive = 0;
|
||||
hargs.data_free = free;
|
||||
hargs.data_expire_with_condition = NULL;
|
||||
|
||||
iris_cfg->group_name_map=MESA_htable_create(&hargs, sizeof(hargs));
|
||||
MESA_htable_print_crtl(iris_cfg->group_name_map, 0);
|
||||
|
||||
iris_cfg->iris_table_map=MESA_htable_create(&hargs, sizeof(hargs));
|
||||
MESA_htable_print_crtl(iris_cfg->iris_table_map, 0);
|
||||
|
||||
iris_cfg->str2int_map=map_create();
|
||||
|
||||
map_register(iris_cfg->str2int_map, "yes",1);
|
||||
map_register(iris_cfg->str2int_map, "no",0);
|
||||
|
||||
map_register(iris_cfg->str2int_map, "ip",TABLE_TYPE_IP);
|
||||
map_register(iris_cfg->str2int_map, "string",TABLE_TYPE_EXPR);
|
||||
map_register(iris_cfg->str2int_map, "intval",TABLE_TYPE_INTVAL);
|
||||
|
||||
map_register(iris_cfg->str2int_map, "ipv4",4);
|
||||
map_register(iris_cfg->str2int_map, "ipv6",6);
|
||||
|
||||
map_register(iris_cfg->str2int_map, "double",0);
|
||||
map_register(iris_cfg->str2int_map, "single",1);
|
||||
|
||||
map_register(iris_cfg->str2int_map, "none",0);
|
||||
map_register(iris_cfg->str2int_map, "and",1);
|
||||
map_register(iris_cfg->str2int_map, "regex",2);
|
||||
map_register(iris_cfg->str2int_map, "offset",3);
|
||||
|
||||
map_register(iris_cfg->str2int_map, "sub",0);
|
||||
map_register(iris_cfg->str2int_map, "right",1);
|
||||
map_register(iris_cfg->str2int_map, "left",2);
|
||||
map_register(iris_cfg->str2int_map, "complete",3);
|
||||
|
||||
map_register(iris_cfg->str2int_map, "uncase plain",0);
|
||||
map_register(iris_cfg->str2int_map, "hexbin",1);
|
||||
map_register(iris_cfg->str2int_map, "case plain",2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
void clear_iris_descriptor(struct iris_description_t *iris_cfg)
|
||||
{
|
||||
if(iris_cfg->group_name_map!=NULL)
|
||||
{
|
||||
MESA_htable_destroy(iris_cfg->group_name_map, NULL);
|
||||
}
|
||||
if(iris_cfg->iris_table_map!=NULL)
|
||||
{
|
||||
MESA_htable_destroy(iris_cfg->iris_table_map, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
int create_tmp_dir(struct iris_description_t *p)
|
||||
{
|
||||
|
||||
|
||||
if((access(p->tmp_iris_dir,F_OK))<0)
|
||||
{
|
||||
if((mkdir(p->tmp_iris_dir, 0777)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if((access(p->tmp_iris_index_dir,F_OK))<0)
|
||||
{
|
||||
if((mkdir(p->tmp_iris_index_dir, 0777)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int set_file_rulenum(const char* path,int rulenum,void* logger)
|
||||
{
|
||||
FILE* fp=NULL;
|
||||
if(rulenum==0)
|
||||
{
|
||||
fp=fopen(path,"w");
|
||||
}
|
||||
else
|
||||
{
|
||||
fp=fopen(path,"r+");
|
||||
}
|
||||
if(fp==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"fopen %s failed %s at set rule num.",path,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fprintf(fp,"%010d\n",rulenum);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
int direct_write_rule(cJSON* json,MESA_htable_handle str2int,struct traslate_command_t*cmd,int cmd_cnt,const char* path,void* logger)
|
||||
{
|
||||
int i=0,ret=-1;
|
||||
cJSON* item=NULL;
|
||||
cJSON dummy;
|
||||
char *p=NULL;
|
||||
int int_value=0;
|
||||
FILE* fp=NULL;
|
||||
for(i=0;i<cmd_cnt;i++)
|
||||
{
|
||||
item=cJSON_GetObjectItem(json,cmd[i].json_string);
|
||||
if(item==NULL&&cmd[i].empty_allowed==1)
|
||||
{
|
||||
dummy.valuestring=(char*)cmd[i].default_string;
|
||||
dummy.valueint=cmd[i].default_int;
|
||||
dummy.type=cmd[i].json_type;
|
||||
|
||||
item=&dummy;
|
||||
}
|
||||
if(item==NULL||item->type!=cmd[i].json_type)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"%s not defined or wrong format.",cmd[i].json_string);
|
||||
goto error_out;
|
||||
}
|
||||
if(cmd[i].str2int_flag==1)
|
||||
{
|
||||
p=item->valuestring;
|
||||
ret=map_str2int(str2int, p, &int_value);
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"%s's value %s is not valid format.",cmd[i].json_string,p);
|
||||
free(p);
|
||||
goto error_out;
|
||||
}
|
||||
cmd[i].json_value=(char*)malloc(21);/* 2^64+1 can be represented in 21 chars. */
|
||||
snprintf(cmd[i].json_value,21,"%d",int_value);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(item->type)
|
||||
{
|
||||
case cJSON_Number:
|
||||
cmd[i].json_value=cJSON_Print(item);
|
||||
break;
|
||||
case cJSON_String:
|
||||
cmd[i].json_value=(char*)calloc(strlen(item->valuestring)+1,1);
|
||||
memcpy(cmd[i].json_value,item->valuestring,strlen(item->valuestring));
|
||||
break;
|
||||
default://impossible ,already checked
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fp=fopen(path,"a");
|
||||
if(fp==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"fopen %s error %s.",path,strerror(errno));
|
||||
goto error_out;
|
||||
}
|
||||
for(i=0;i<cmd_cnt;i++)
|
||||
{
|
||||
fprintf(fp,"%s\t",cmd[i].json_value);
|
||||
}
|
||||
fprintf(fp,"\n");
|
||||
fclose(fp);
|
||||
|
||||
for(i=0;i<cmd_cnt;i++)
|
||||
{
|
||||
if(cmd[i].json_value!=NULL)
|
||||
{
|
||||
free(cmd[i].json_value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
error_out:
|
||||
for(i=0;i<cmd_cnt;i++)
|
||||
{
|
||||
if(cmd[i].json_value!=NULL)
|
||||
{
|
||||
free(cmd[i].json_value);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int write_ip_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger)
|
||||
{
|
||||
struct traslate_command_t json_cmd[MAX_COLUMN_NUM];
|
||||
int cmd_cnt=0;
|
||||
memset(json_cmd,0,sizeof(json_cmd));
|
||||
|
||||
json_cmd[cmd_cnt].json_string="region_id";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="group_id";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="addr_type";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].str2int_flag=1;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="src_ip";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="0.0.0.0";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="mask_src_ip";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="255.255.255.255";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="src_port";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="0";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="mask_src_port";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="65535";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="dst_ip";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="0.0.0.0";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="mask_dst_ip";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="255.255.255.255";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="dst_port";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="0";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="mask_dst_port";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="65535";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="protocol";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_int=0;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="direction";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].str2int_flag=1;
|
||||
json_cmd[cmd_cnt].empty_allowed=1;
|
||||
json_cmd[cmd_cnt].default_string="double";
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="is_valid";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger);
|
||||
}
|
||||
int write_expr_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger)
|
||||
{
|
||||
struct traslate_command_t json_cmd[MAX_COLUMN_NUM];
|
||||
int cmd_cnt=0;
|
||||
memset(json_cmd,0,sizeof(json_cmd));
|
||||
|
||||
json_cmd[cmd_cnt].json_string="region_id";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="group_id";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="keywords";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="expr_type";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].str2int_flag=1;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="match_method";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].str2int_flag=1;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="format";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
json_cmd[cmd_cnt].str2int_flag=1;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="is_valid";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger);
|
||||
|
||||
}
|
||||
int write_intval_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger)
|
||||
{
|
||||
struct traslate_command_t json_cmd[MAX_COLUMN_NUM];
|
||||
int cmd_cnt=0;
|
||||
memset(json_cmd,0,sizeof(json_cmd));
|
||||
|
||||
json_cmd[cmd_cnt].json_string="region_id";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="group_id";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="low_boundary";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="up_boundary";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
json_cmd[cmd_cnt].json_string="is_valid";
|
||||
json_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger);
|
||||
|
||||
}
|
||||
struct iris_table_t* query_table_info(iris_description_t* p_iris,const char* table_name)
|
||||
{
|
||||
struct iris_table_t* table_info=NULL;
|
||||
table_info=(struct iris_table_t*)MESA_htable_search(p_iris->iris_table_map, (const unsigned char*)table_name,strlen(table_name));
|
||||
if(table_info==NULL)
|
||||
{
|
||||
table_info=(struct iris_table_t*)calloc(sizeof(struct iris_table_t),1);
|
||||
table_info->line_count=0;
|
||||
memcpy(table_info->table_name,table_name,MIN(sizeof(table_info->table_name)-1, strlen(table_name)));
|
||||
snprintf(table_info->table_path,sizeof(table_info->table_path),"%s/%s.local",p_iris->tmp_iris_dir,table_info->table_name);
|
||||
MESA_htable_add(p_iris->iris_table_map,(const unsigned char*)table_info->table_name,strlen(table_info->table_name),table_info);
|
||||
}
|
||||
return table_info;
|
||||
}
|
||||
int write_plugin_table(cJSON* plug_table_json,int sequence,iris_description_t* p_iris,void* logger)
|
||||
{
|
||||
cJSON* item=NULL,*table_content=NULL,*each_line=NULL;
|
||||
struct iris_table_t* table_info=NULL;
|
||||
const char* table_name=NULL,*line_content=NULL;
|
||||
int ret=0,i=0,line_cnt=0;
|
||||
FILE*fp=NULL;
|
||||
|
||||
item=cJSON_GetObjectItem(plug_table_json,"table_name");
|
||||
if(item==NULL||item->type!=cJSON_String)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"The %d plugin_table's table_name not defined or format error.",sequence);
|
||||
return -1;
|
||||
}
|
||||
table_name= item->valuestring;
|
||||
table_info=query_table_info(p_iris, table_name);
|
||||
table_content=cJSON_GetObjectItem(plug_table_json,"table_content");
|
||||
if(table_content==NULL||table_content->type!=cJSON_Array)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"%d plugin_table's table_content not defined or format error."
|
||||
,sequence);
|
||||
return -1;
|
||||
}
|
||||
line_cnt=cJSON_GetArraySize(table_content);
|
||||
if(table_info->line_count==0)
|
||||
{
|
||||
ret=set_file_rulenum(table_info->table_path,0,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fp=fopen(table_info->table_path,"a");
|
||||
if(fp==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"fopen %s error %s.",table_info->table_path,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i=0;i<line_cnt;i++)
|
||||
{
|
||||
each_line=cJSON_GetArrayItem(table_content,i);
|
||||
if(each_line==NULL||each_line->type!=cJSON_String)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"plugin_table %s's line %d format error.",table_info->table_name,i+1);
|
||||
continue;
|
||||
}
|
||||
line_content=each_line->valuestring;
|
||||
fprintf(fp,"%s\n",line_content);
|
||||
table_info->line_count++;
|
||||
}
|
||||
fclose(fp);
|
||||
set_file_rulenum(table_info->table_path,table_info->line_count,logger);
|
||||
return 0;
|
||||
}
|
||||
int write_region_rule(cJSON* region_json,int compile_id,int group_id,iris_description_t* p_iris,void* logger)
|
||||
{
|
||||
cJSON* item=NULL,*table_content=NULL;
|
||||
int ret=0;
|
||||
int region_id=0;
|
||||
const char* table_name=NULL,*table_type_str=NULL;
|
||||
enum MAAT_TABLE_TYPE table_type=TABLE_TYPE_EXPR;
|
||||
struct iris_table_t* table_info=NULL;
|
||||
|
||||
item=cJSON_GetObjectItem(region_json,"table_name");
|
||||
if(item==NULL||item->type!=cJSON_String)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d's region table_name not defined or format error.",compile_id);
|
||||
return -1;
|
||||
}
|
||||
table_name=item->valuestring;
|
||||
table_info=query_table_info( p_iris, table_name);
|
||||
item=cJSON_GetObjectItem(region_json,"table_type");
|
||||
if(item==NULL||item->type!=cJSON_String)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d table name %s's table_type not defined or format error."
|
||||
,compile_id,table_name);
|
||||
return -1;
|
||||
}
|
||||
table_type_str=item->valuestring;
|
||||
ret=map_str2int(p_iris->str2int_map,table_type_str,(int*)&(table_type));
|
||||
if(ret!=1)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d table name %s's table_type %s invalid."
|
||||
,compile_id,table_name,table_type_str);
|
||||
return -1;
|
||||
}
|
||||
table_content=cJSON_GetObjectItem(region_json,"table_content");
|
||||
if(table_content==NULL||table_content->type!=cJSON_Object)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d table name %s's table_content not defined or format error."
|
||||
,compile_id,table_name);
|
||||
return -1;
|
||||
}
|
||||
if(table_info->line_count==0)
|
||||
{
|
||||
ret=set_file_rulenum(table_info->table_path,0,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
region_id=p_iris->region_cnt++;
|
||||
cJSON_AddNumberToObject(table_content, "region_id", region_id);
|
||||
cJSON_AddNumberToObject(table_content, "group_id", group_id);
|
||||
cJSON_AddNumberToObject(table_content, "is_valid", 1);
|
||||
|
||||
switch(table_type)
|
||||
{
|
||||
case TABLE_TYPE_EXPR:
|
||||
ret=write_expr_rule(table_content, p_iris, table_info->table_path, logger);
|
||||
break;
|
||||
case TABLE_TYPE_IP:
|
||||
ret=write_ip_rule(table_content, p_iris, table_info->table_path, logger);
|
||||
break;
|
||||
case TABLE_TYPE_INTVAL:
|
||||
ret=write_intval_rule(table_content, p_iris, table_info->table_path, logger);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
if(ret>=0)
|
||||
{
|
||||
table_info->line_count++;
|
||||
set_file_rulenum(table_info->table_path,table_info->line_count,logger);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int write_compile_rule(cJSON *compile,struct iris_description_t *p_iris,void * logger)
|
||||
{
|
||||
int compile_id=-1,cmd_cnt=0,ret=-1;
|
||||
cJSON* item=NULL;
|
||||
struct traslate_command_t compile_cmd[MAX_COLUMN_NUM];
|
||||
memset(compile_cmd,0,sizeof(compile_cmd));
|
||||
compile_cmd[cmd_cnt].json_string="compile_id";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
compile_cmd[cmd_cnt].json_string="service";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
compile_cmd[cmd_cnt].json_string="action";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
compile_cmd[cmd_cnt].json_string="do_blacklist";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
compile_cmd[cmd_cnt].json_string="do_log";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
compile_cmd[cmd_cnt].json_string="effective_rage";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_Number;
|
||||
cmd_cnt++;
|
||||
|
||||
compile_cmd[cmd_cnt].json_string="user_region";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
cmd_cnt++;
|
||||
|
||||
compile_cmd[cmd_cnt].json_string="is_valid";
|
||||
compile_cmd[cmd_cnt].json_type=cJSON_String;
|
||||
compile_cmd[cmd_cnt].str2int_flag=1;
|
||||
cmd_cnt++;
|
||||
|
||||
|
||||
if(p_iris->compile_table.line_count==0)
|
||||
{
|
||||
ret=set_file_rulenum(p_iris->compile_table.table_path, 0,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ret=direct_write_rule(compile, p_iris->str2int_map,compile_cmd,cmd_cnt, p_iris->compile_table.table_path,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
item=cJSON_GetObjectItem(compile,"compile_id");
|
||||
if(item->type!=cJSON_Number)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile_id format not number.");
|
||||
return -1;
|
||||
}
|
||||
compile_id=item->valueint;
|
||||
p_iris->compile_table.line_count++;
|
||||
set_file_rulenum(p_iris->compile_table.table_path,p_iris->compile_table.line_count,logger);
|
||||
return compile_id;
|
||||
}
|
||||
int write_group_rule(int compile_id ,int group_id,struct iris_description_t *p_iris,void * logger)
|
||||
{
|
||||
FILE*fp=NULL;
|
||||
int ret=0;
|
||||
|
||||
if(p_iris->group_table.line_count==0)
|
||||
{
|
||||
ret=set_file_rulenum(p_iris->group_table.table_path,0,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fp=fopen(p_iris->group_table.table_path,"a");
|
||||
if(fp==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"fopen %s error %s.",p_iris->group_table.table_path,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fprintf(fp,"%d\t%d\t1\n",group_id,compile_id);
|
||||
fclose(fp);
|
||||
p_iris->group_table.line_count++;
|
||||
ret=set_file_rulenum(p_iris->group_table.table_path,p_iris->group_table.line_count,logger);
|
||||
return 0;
|
||||
}
|
||||
void table_idx_write_cb(const uchar * key, uint size, void * data, void * user)
|
||||
{
|
||||
struct iris_table_t* p_table=(struct iris_table_t*)data;
|
||||
FILE* fp=(FILE*)user;
|
||||
fprintf(fp,"%s\t%d\t%s\n",p_table->table_name,p_table->line_count,p_table->table_path);
|
||||
}
|
||||
int write_index_file(struct iris_description_t *p_iris,void* logger)
|
||||
{
|
||||
FILE*fp=NULL;
|
||||
fp=fopen(p_iris->index_path,"w");
|
||||
if(fp==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"index file %s fopen error %s.",p_iris->index_path,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fprintf(fp,"%s\t%d\t%s\n",p_iris->compile_table.table_name
|
||||
,p_iris->compile_table.line_count
|
||||
,p_iris->compile_table.table_path);
|
||||
fprintf(fp,"%s\t%d\t%s\n",p_iris->group_table.table_name
|
||||
,p_iris->group_table.line_count
|
||||
,p_iris->group_table.table_path);
|
||||
MESA_htable_iterate(p_iris->iris_table_map, table_idx_write_cb, fp);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
int write_iris(cJSON *json,struct iris_description_t *p_iris,void* logger)
|
||||
{
|
||||
int i=0,j=0,k=0;
|
||||
int compile_id=-1,compile_cnt=0,group_cnt=0,region_cnt=0,plug_table_cnt=0;
|
||||
int ret=0;
|
||||
cJSON *c_rules=NULL,*g_rules=NULL,*r_rules=NULL,*item=NULL,*plug_tables=NULL;
|
||||
cJSON *compile_rule=NULL,*group_rule=NULL,*region_rule=NULL,*each_plug_table=NULL;
|
||||
const char* group_name=NULL;
|
||||
struct group_info_t *group_info=NULL;
|
||||
plug_tables=cJSON_GetObjectItem(json,"plugin_table");
|
||||
if(NULL!=plug_tables)
|
||||
{
|
||||
plug_table_cnt=cJSON_GetArraySize(plug_tables);
|
||||
for(i=0;i<plug_table_cnt;i++)
|
||||
{
|
||||
each_plug_table=cJSON_GetArrayItem(plug_tables,i);
|
||||
write_plugin_table(each_plug_table, i, p_iris, logger);
|
||||
}
|
||||
}
|
||||
c_rules=cJSON_GetObjectItem(json,"rules");
|
||||
if(c_rules==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"have no rules.");
|
||||
return -1;
|
||||
|
||||
}
|
||||
compile_cnt=cJSON_GetArraySize(c_rules);
|
||||
if(compile_cnt<=0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"have no rules.");
|
||||
return -1;
|
||||
}
|
||||
for(i=0;i<compile_cnt;i++)
|
||||
{
|
||||
compile_rule=cJSON_GetArrayItem(c_rules,i);
|
||||
compile_id=write_compile_rule(compile_rule,p_iris, logger);
|
||||
if(compile_id<0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"In %d compile rule.",i);
|
||||
return -1;
|
||||
}
|
||||
g_rules=cJSON_GetObjectItem(compile_rule,"groups");
|
||||
if(g_rules==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d have no group.",compile_id);
|
||||
return -1;
|
||||
}
|
||||
group_cnt=cJSON_GetArraySize(g_rules);
|
||||
if(group_cnt<=0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d have no groups.",compile_id);
|
||||
return -1;
|
||||
}
|
||||
for(j=0;j<group_cnt;j++)
|
||||
{
|
||||
group_rule=cJSON_GetArrayItem(g_rules,j);
|
||||
item=cJSON_GetObjectItem(group_rule,"group_name");
|
||||
if(item==NULL||item->type!=cJSON_String)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d's group has no name.",compile_id);
|
||||
return -1;
|
||||
}
|
||||
group_name=item->valuestring;
|
||||
group_info=(struct group_info_t*)MESA_htable_search(p_iris->group_name_map, (const unsigned char*)group_name, strlen(group_name));
|
||||
if(group_info!=NULL)//exist group name ,region already read
|
||||
{
|
||||
ret=write_group_rule(compile_id, group_info->group_id, p_iris, logger);
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d write group error.",compile_id);
|
||||
return -1;
|
||||
}
|
||||
r_rules=cJSON_GetObjectItem(group_rule,"regions");
|
||||
if(r_rules!=NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_json,
|
||||
"compile rule %d's %s declared in previous compile rule, regions NOT take effect."
|
||||
,compile_id,group_name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
group_info=(struct group_info_t*)malloc(sizeof(struct group_info_t));
|
||||
group_info->group_id=p_iris->group_cnt++;
|
||||
MESA_htable_add(p_iris->group_name_map,(const unsigned char*)group_name, strlen(group_name),group_info);
|
||||
|
||||
r_rules=cJSON_GetObjectItem(group_rule,"regions");
|
||||
if(r_rules==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d's %s has no region.",compile_id,group_name);
|
||||
return -1;
|
||||
}
|
||||
region_cnt=cJSON_GetArraySize(r_rules);
|
||||
if(region_cnt<=0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d's %s has no region.",compile_id,group_name);
|
||||
return -1;
|
||||
}
|
||||
for(k=0;k<region_cnt;k++)
|
||||
{
|
||||
region_rule=cJSON_GetArrayItem(r_rules,k);
|
||||
ret=write_region_rule(region_rule, compile_id, group_info->group_id, p_iris, logger);
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d write region error.",compile_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ret=write_group_rule(compile_id, group_info->group_id, p_iris, logger);
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"compile rule %d write group error.",compile_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
ret=write_index_file(p_iris,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int json2iris(const char* json_file,char* iris_dir_buf,int buf_len,void* logger)
|
||||
{
|
||||
FILE* json_fp=NULL;
|
||||
cJSON *json=NULL;
|
||||
struct stat fstat_buf;
|
||||
int ret=-1;
|
||||
char* json_buff=NULL;
|
||||
unsigned long json_file_size=0,read_size=0;
|
||||
struct iris_description_t iris_cfg;
|
||||
memset(&iris_cfg,0,sizeof(iris_cfg));
|
||||
ret=stat(json_file, &fstat_buf);
|
||||
if(ret!=0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"fstat file %s error.",json_file);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
json_fp=fopen(json_file,"r");
|
||||
if(json_fp==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"fopen file %s error %s.",json_file,strerror(errno));
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
|
||||
json_file_size=fstat_buf.st_size;
|
||||
json_buff=(char*)calloc(1,json_file_size);
|
||||
read_size=fread(json_buff,1,json_file_size,json_fp);
|
||||
if(read_size!=json_file_size)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"fread file %s error.",json_file);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
|
||||
json=cJSON_Parse(json_buff);
|
||||
if (!json)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,"Error before: %-200.200s",cJSON_GetErrorPtr());
|
||||
goto error_out;
|
||||
}
|
||||
ret=set_iris_descriptor(json_file,json, &iris_cfg,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
goto error_out;
|
||||
}
|
||||
ret=create_tmp_dir(&iris_cfg);
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json,
|
||||
"create tmp folder %s error",iris_cfg.tmp_iris_dir);
|
||||
goto error_out;
|
||||
}
|
||||
ret=write_iris(json,&iris_cfg,logger);
|
||||
if(ret<0)
|
||||
{
|
||||
goto error_out;
|
||||
}
|
||||
memcpy(iris_dir_buf,iris_cfg.tmp_iris_index_dir,MIN(strlen(iris_cfg.tmp_iris_index_dir)+1,(unsigned int)buf_len));
|
||||
|
||||
cJSON_Delete(json);
|
||||
fclose(json_fp);
|
||||
free(json_buff);
|
||||
clear_iris_descriptor(&iris_cfg);
|
||||
return 0;
|
||||
|
||||
|
||||
error_out:
|
||||
cJSON_Delete(json);
|
||||
if(json_fp!=NULL)
|
||||
{
|
||||
fclose(json_fp);
|
||||
}
|
||||
free(json_buff);
|
||||
clear_iris_descriptor(&iris_cfg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
2
src/entry/json2iris.h
Normal file
2
src/entry/json2iris.h
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
int json2iris(const char* json_file,char* iris_dir_buf,int buf_len,void* logger);
|
||||
55
src/entry/map_str2int.cpp
Normal file
55
src/entry/map_str2int.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <MESA/MESA_htable.h>
|
||||
void map_tmp_free(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
MESA_htable_handle map_create(void)
|
||||
{
|
||||
MESA_htable_handle string2int_map;
|
||||
MESA_htable_create_args_t hargs;
|
||||
memset(&hargs,0,sizeof(hargs));
|
||||
hargs.thread_safe=1;
|
||||
hargs.hash_slot_size = 1024*1024;
|
||||
hargs.max_elem_num = 0;
|
||||
hargs.eliminate_type = HASH_ELIMINATE_ALGO_LRU;
|
||||
hargs.expire_time = 0;
|
||||
hargs.key_comp = NULL;
|
||||
hargs.key2index = NULL;
|
||||
hargs.recursive = 0;
|
||||
hargs.data_free = map_tmp_free;
|
||||
hargs.data_expire_with_condition = NULL;
|
||||
string2int_map=MESA_htable_create(&hargs, sizeof(hargs));
|
||||
MESA_htable_print_crtl(string2int_map, 0);
|
||||
return string2int_map;
|
||||
}
|
||||
void map_destroy(MESA_htable_handle p)
|
||||
{
|
||||
MESA_htable_destroy(p,NULL);
|
||||
return;
|
||||
}
|
||||
int map_register(MESA_htable_handle handle,const char* string,int value)
|
||||
{
|
||||
unsigned int size=strlen(string);
|
||||
unsigned char *key=(unsigned char *)string;
|
||||
int *data=(int*)malloc(sizeof(int));
|
||||
int ret=0;
|
||||
*data=value;
|
||||
ret=MESA_htable_add(handle,key,size,data);
|
||||
return ret;
|
||||
}
|
||||
int map_str2int(MESA_htable_handle handle,const char* string,int* value)
|
||||
{
|
||||
int *data=NULL;
|
||||
unsigned int size=strlen(string);
|
||||
data=(int*)MESA_htable_search(handle,(unsigned char*)string,size);
|
||||
if(data!=NULL)
|
||||
{
|
||||
*value=*data;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
8
src/entry/map_str2int.h
Normal file
8
src/entry/map_str2int.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __MAP_STR2INT_H_INCLUDE_
|
||||
#define __MAP_STR2INT_H_INCLUDE_
|
||||
MESA_htable_handle map_create(void);
|
||||
void map_destroy(MESA_htable_handle p);
|
||||
int map_register(MESA_htable_handle handle,const char* string,int value);
|
||||
int map_str2int(MESA_htable_handle handle,const char* string,int* value);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user