#include "Maat_table.h" #include "map_str2int.h" #include "Maat_utils.h" #include "cJSON.h" #include #include #include #include #include int read_expr_table_info(const char* line, struct Maat_table_desc* table, MESA_htable_handle string2int_map) { int j=0,ret[4]={0}; char table_type[16],src_charset[256],dst_charset[256],merge[4],quick_str_scan[32]={0}; char *token=NULL,*sub_token=NULL,*saveptr; struct expr_table_desc* p=&(table->expr); sscanf(line,"%d\t%s\t%s\t%s\t%s\t%s\t%d\t%s",&(table->table_id) ,table->table_name[0] ,table_type ,src_charset ,dst_charset ,merge ,&(p->cross_cache_size) ,quick_str_scan); memset(ret,0,sizeof(ret)); ret[0]=map_str2int(string2int_map,str_tolower(table_type),(int*)&(table->table_type)); ret[1]=map_str2int(string2int_map,str_tolower(src_charset),(int*)&(p->src_charset)); ret[2]=map_str2int(string2int_map,str_tolower(merge),&(p->do_charset_merge)); if(strlen(quick_str_scan)>0) { ret[3]=map_str2int(string2int_map,str_tolower(quick_str_scan),&(p->quick_expr_switch)); } memset(quick_str_scan,0,sizeof(quick_str_scan)); for(j=0;j<4;j++) { if(ret[j]<0) { return -1; } } j=0; for (token = dst_charset; ; token= NULL) { sub_token= strtok_r(token,"/", &saveptr); if (sub_token == NULL) break; ret[3]=map_str2int(string2int_map,str_tolower(sub_token),(int*)&(p->dst_charset[j])); if(ret[3]>0) { if(p->dst_charset[j]==p->src_charset) { p->src_charset_in_dst=TRUE; } j++; } else { return -1; } } return 0; } int read_virtual_table_info(const char* line, struct Maat_table_desc* table, MESA_htable_handle string2int_map) { int ret=0; char table_type[16]; ret=sscanf(line, "%d\t%s\t%s\t%s", &(table->table_id), table->table_name[0], table_type, table->virtual_table.real_table_name); if(ret!=4) { return -1; } ret=map_str2int(string2int_map,str_tolower(table_type),(int*)&(table->table_type)); if(ret<0) { return -1; } return 0; } Maat_table_desc* table_info_new(void) { struct Maat_table_desc*p=ALLOC(struct Maat_table_desc, 1); p->conj_cnt=1; return p; } void table_info_free(struct Maat_table_desc*p) { free(p); return; } int _read_integer_arrary(char* string, int *array, int size) { char *token=NULL,*sub_token=NULL,*saveptr; int i=0; for (token = string, i=0; iplugin); copy_line=_maat_strdup(line); ret=get_column_pos(copy_line, COLUMN_PLUGIN_DESCR_JSON, &offset, &len); if(i<0) { goto error_out; } if(offset+lenvalid_flag_column)); if(ret==0||ret==EOF) { plugin_desc->valid_flag_column=-1; } free(copy_line); return 0; } json=cJSON_Parse(plug_info); if(!json) { goto error_out; } tmp=cJSON_GetObjectItem(json, "key"); if(tmp!=NULL) { assert(tmp->type==cJSON_Number); plugin_desc->key_column=tmp->valueint; } tmp=cJSON_GetObjectItem(json, "valid"); if(tmp!=NULL) { assert(tmp->type==cJSON_Number); plugin_desc->valid_flag_column=tmp->valueint; } tmp=cJSON_GetObjectItem(json, "tag"); if(tmp!=NULL) { assert(tmp->type==cJSON_Number); plugin_desc->rule_tag_column=tmp->valueint; } tmp=cJSON_GetObjectItem(json, "estimate_size"); if(tmp!=NULL) { assert(tmp->type==cJSON_Number); plugin_desc->estimate_size=tmp->valueint; } tmp=cJSON_GetObjectItem(json, "foreign"); if(tmp!=NULL) { if(tmp->type==cJSON_String) { plugin_desc->n_foreign=_read_integer_arrary(tmp->valuestring, plugin_desc->foreign_columns, MAX_FOREIGN_CLMN_NUM); } else if(tmp->type==cJSON_Array) { plugin_desc->n_foreign= cJSON_GetArraySize(tmp); for(i=0;in_foreign; i++) { array_item=cJSON_GetArrayItem(tmp, i); assert(array_item->type==cJSON_Number); plugin_desc->foreign_columns[i]=array_item->valueint; } } } cJSON_Delete(json); free(copy_line); return 0; error_out: free(copy_line); return -1; } int Maat_table_read_table_info(struct Maat_table_desc** p_table_info, size_t n_table, const char* table_info_path, void* logger) { FILE*fp=NULL; char line[MAX_TABLE_LINE_SIZE]; int i=0,ret=0,table_cnt=0; char table_type_str[16]={0},not_care[1024]={0}, tmp_str[32]={0}; MESA_htable_handle string2int_map=NULL;; struct Maat_table_desc*p=NULL; struct Maat_table_desc*conj_table=NULL; fp=fopen(table_info_path,"r"); if(fp==NULL) { fprintf(stderr,"Maat read table info %s error.\n",table_info_path); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s failed: %s.\n", table_info_path, strerror(errno)); return 0; } string2int_map=map_create(); map_register(string2int_map,"expr", TABLE_TYPE_EXPR); map_register(string2int_map,"ip", TABLE_TYPE_IP); map_register(string2int_map,"ip_plus", TABLE_TYPE_IP_PLUS); map_register(string2int_map,"compile", TABLE_TYPE_COMPILE); map_register(string2int_map,"plugin", TABLE_TYPE_PLUGIN); map_register(string2int_map,"intval", TABLE_TYPE_INTERVAL); map_register(string2int_map,"digest", TABLE_TYPE_DIGEST); map_register(string2int_map,"expr_plus", TABLE_TYPE_EXPR_PLUS); map_register(string2int_map,"group", TABLE_TYPE_GROUP); map_register(string2int_map,"similar", TABLE_TYPE_SIMILARITY); map_register(string2int_map,"virtual", TABLE_TYPE_VIRTUAL); map_register(string2int_map,"quickoff", 0); map_register(string2int_map,"quickon", 1); map_register(string2int_map,"escape", USER_REGION_ENCODE_ESCAPE); // map_register(string2int_map,"base64",USER_REGION_ENCODE_BASE64); //NOT supported yet const char** charset_name_list=charset_get_all_name(); for(i=0;i0) { map_register(string2int_map, charset_name_list[i], i); } else { break; } } map_register(string2int_map,"yes", 1); map_register(string2int_map,"no", 0); i=0; while(NULL!=fgets(line,sizeof(line),fp)) { i++; if(line[0]=='#'||line[0]==' '||line[0]=='\t'||strlen(line)<4) { continue; } p=table_info_new(); ret=sscanf(line,"%d\t%s\t%s\t%[a-z0-9\t ]",&(p->table_id) ,p->table_name[0] ,table_type_str ,not_care); if(ret<3) { MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error: not enough column.",table_info_path,i); continue; } ret=map_str2int(string2int_map,str_tolower(table_type_str),(int*)&(p->table_type)); if(ret<0) { MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error:invalid table type.",table_info_path,i); goto invalid_table; } switch(p->table_type) { case TABLE_TYPE_EXPR: case TABLE_TYPE_EXPR_PLUS: ret=read_expr_table_info(line, p, string2int_map); if(ret<0) { fprintf(stderr,"Maat read table info %s line %d error:illegal column.\n",table_info_path,i); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error:illegal column.",table_info_path,i); goto invalid_table; } break; case TABLE_TYPE_PLUGIN: ret=read_plugin_table_description(line, p); if(ret<0) { fprintf(stderr,"Maat read table info %s line %d error:illegal plugin info.\n",table_info_path,i); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error:illegal plugin info.",table_info_path,i); goto invalid_table; } break; case TABLE_TYPE_VIRTUAL: ret=read_virtual_table_info(line, p, string2int_map); if(ret<0) { fprintf(stderr,"Maat read table info %s line %d error:illegal virtual info.\n",table_info_path,i); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error:illegal virtual info.",table_info_path,i); goto invalid_table; } break; case TABLE_TYPE_COMPILE: ret=sscanf(not_care,"%[a-z0-9]",tmp_str); if(ret>0) { ret=map_str2int(string2int_map,str_tolower(tmp_str),(int*)&(p->compile.user_region_encoding)); } if(ret!=1) { p->compile.user_region_encoding=USER_REGION_ENCODE_NONE; } default: break; } if((unsigned int)p->table_id>=n_table) { fprintf(stderr,"Maat read table info %s:%d error: table id %uh > %zu.\n",table_info_path,i,p->table_id,n_table); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error: table id %uh > %d.\n",table_info_path,i,p->table_id,n_table); goto invalid_table; } if(p_table_info[p->table_id]!=NULL)//duplicate table_id,means conjunction table; { conj_table=p_table_info[p->table_id]; if(conj_table->conj_cnt==MAX_CONJUNCTION_TABLE_NUM) { MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, "Maat read table info %s line %d error:reach tableid %d conjunction upper limit." ,table_info_path,i,p->table_id); goto invalid_table; } memcpy(conj_table->table_name[conj_table->conj_cnt],p->table_name[0],MAX_TABLE_NAME_LEN); conj_table->conj_cnt++; MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_module, "Maat read table info %s:%d:conjunction %s with %s (id=%d,total=%d)." ,table_info_path,i,p->table_name[0] ,conj_table->table_name[0],conj_table->table_id,conj_table->conj_cnt); //use goto to free the conjunctioned table_info goto invalid_table; } p_table_info[p->table_id]=p; table_cnt++; continue; invalid_table: table_info_free(p); p=NULL; } fclose(fp); map_destroy(string2int_map); return table_cnt; } MESA_htable_handle Maat_table_build(struct Maat_table_desc** p_table_info, size_t n_table, char* compile_tn, size_t n_ctn, char* group_tn, size_t n_gtn, void* logger) { MESA_htable_handle map_tablename2id=map_create(); size_t i=0; int j=0, ret=0; for(i=0;itable_type) { case TABLE_TYPE_GROUP: strncpy(group_tn, p_table_info[i]->table_name[0], n_gtn); break; case TABLE_TYPE_COMPILE: strncpy(compile_tn, p_table_info[i]->table_name[0], n_ctn); break; case TABLE_TYPE_VIRTUAL: ret=map_str2int(map_tablename2id, p_table_info[i]->virtual_table.real_table_name, &(p_table_info[i]->virtual_table.real_table_id)); if(ret<0) { MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, "Undefined real table %s, virtual table %s of table id %d.", p_table_info[i]->virtual_table.real_table_name, p_table_info[i]->table_name[j], p_table_info[i]->table_id); goto failed; } break; default: break; } for(j=0; jconj_cnt; j++) { ret=map_register(map_tablename2id, p_table_info[i]->table_name[j], p_table_info[i]->table_id); if(ret<0) { MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, "Duplicate table %s of table id %d", p_table_info[i]->table_name[j], p_table_info[i]->table_id); continue; } } } return map_tablename2id; failed: map_destroy(map_tablename2id); return NULL; } void Maat_table_clear(struct Maat_table_desc** p_table_info, size_t n_table) { size_t i=0; for(i=0;i