Mercurial > hg > freeDiameter
comparison libfdproto/dictionary.c @ 1085:7d7266115a34
Cleaning of the traces in progress
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Fri, 03 May 2013 19:20:56 +0800 |
parents | b3d623f04b6d |
children | 44f3e48dfe27 |
comparison
equal
deleted
inserted
replaced
1084:6b7966ea27fb | 1085:7d7266115a34 |
---|---|
145 | 145 |
146 int dict_count[DICT_TYPE_MAX + 1]; /* Number of objects of each type */ | 146 int dict_count[DICT_TYPE_MAX + 1]; /* Number of objects of each type */ |
147 }; | 147 }; |
148 | 148 |
149 /* Forward declarations of dump functions */ | 149 /* Forward declarations of dump functions */ |
150 static void dump_vendor_data ( void * data ); | 150 static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ); |
151 static void dump_application_data ( void * data ); | 151 static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ); |
152 static void dump_type_data ( void * data ); | 152 static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ); |
153 /* the dump function for enum has a different prototype since it need the datatype */ | 153 /* the dump function for enum has a different prototype since it need the datatype */ |
154 static void dump_avp_data ( void * data ); | 154 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ); |
155 static void dump_command_data ( void * data ); | 155 static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ); |
156 static void dump_rule_data ( void * data ); | 156 static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ); |
157 | 157 |
158 /* Forward declarations of search functions */ | 158 /* Forward declarations of search functions */ |
159 static int search_vendor ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); | 159 static int search_vendor ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); |
160 static int search_application ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); | 160 static int search_application ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); |
161 static int search_type ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); | 161 static int search_type ( struct dictionary * dict, int criteria, const void * what, struct dict_object **result ); |
170 char * name; /* string describing this object, for debug */ | 170 char * name; /* string describing this object, for debug */ |
171 size_t datasize; /* The size of the data structure */ | 171 size_t datasize; /* The size of the data structure */ |
172 int parent; /* 0: never; 1: may; 2: must */ | 172 int parent; /* 0: never; 1: may; 2: must */ |
173 enum dict_object_type parenttype; /* The type of the parent, when relevant */ | 173 enum dict_object_type parenttype; /* The type of the parent, when relevant */ |
174 int eyecatcher; /* A kind of signature for this object */ | 174 int eyecatcher; /* A kind of signature for this object */ |
175 void (*dump_data)(void * data ); /* The function to dump the data section */ | 175 DECLARE_FD_DUMP_PROTOTYPE( (*dump_data), void * data ); /* The function to dump the data section */ |
176 int (*search_fct)(struct dictionary * dict, int criteria, const void * what, struct dict_object **result );; /* The function to search an object of this type */ | 176 int (*search_fct)(struct dictionary * dict, int criteria, const void * what, struct dict_object **result );; /* The function to search an object of this type */ |
177 int haslist[NB_LISTS_PER_OBJ]; /* Tell if this list is used */ | 177 int haslist[NB_LISTS_PER_OBJ]; /* Tell if this list is used */ |
178 } dict_obj_info[] = { { 0, "(error)", 0, 0, 0, 0, NULL, NULL, {0, 0, 0} } | 178 } dict_obj_info[] = { { 0, "(error)", 0, 0, 0, 0, NULL, NULL, {0, 0, 0} } |
179 | 179 |
180 /* type name datasize parent parenttype | 180 /* type name datasize parent parenttype |
1147 /* Dump / debug functions */ | 1147 /* Dump / debug functions */ |
1148 /* */ | 1148 /* */ |
1149 /*******************************************************************************************************/ | 1149 /*******************************************************************************************************/ |
1150 /*******************************************************************************************************/ | 1150 /*******************************************************************************************************/ |
1151 /* The following functions are used to debug the module, and allow to print out the content of the dictionary */ | 1151 /* The following functions are used to debug the module, and allow to print out the content of the dictionary */ |
1152 static void dump_vendor_data ( void * data ) | 1152 static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ) |
1153 { | 1153 { |
1154 struct dict_vendor_data * vendor = (struct dict_vendor_data *)data; | 1154 struct dict_vendor_data * vendor = (struct dict_vendor_data *)data; |
1155 | 1155 |
1156 fd_log_debug("data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name); | 1156 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name); |
1157 } | 1157 } |
1158 static void dump_application_data ( void * data ) | 1158 static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ) |
1159 { | 1159 { |
1160 struct dict_application_data * appli = (struct dict_application_data *) data; | 1160 struct dict_application_data * appli = (struct dict_application_data *) data; |
1161 fd_log_debug("data: %-6u \"%s\"", appli->application_id, appli->application_name); | 1161 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", appli->application_id, appli->application_name); |
1162 } | 1162 } |
1163 static void dump_type_data ( void * data ) | 1163 static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ) |
1164 { | 1164 { |
1165 struct dict_type_data * type = ( struct dict_type_data * ) data; | 1165 struct dict_type_data * type = ( struct dict_type_data * ) data; |
1166 | 1166 |
1167 fd_log_debug("data: %-12s \"%s\"", | 1167 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"", |
1168 type_base_name[type->type_base], | 1168 type_base_name[type->type_base], |
1169 type->type_name); | 1169 type->type_name); |
1170 } | 1170 } |
1171 static void dump_enumval_data ( struct dict_enumval_data * enumval, enum dict_avp_basetype type ) | 1171 static DECLARE_FD_DUMP_PROTOTYPE(dump_enumval_data, struct dict_enumval_data * enumval, enum dict_avp_basetype type ) |
1172 { | 1172 { |
1173 const int LEN_MAX = 20; | 1173 const int LEN_MAX = 20; |
1174 fd_log_debug("data: (%-12s) \"%s\" -> ", type_base_name[type], enumval->enum_name); | 1174 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "data: (%-12s) \"%s\" -> ", type_base_name[type], enumval->enum_name), return NULL); |
1175 switch (type) { | 1175 switch (type) { |
1176 case AVP_TYPE_OCTETSTRING: | 1176 case AVP_TYPE_OCTETSTRING: |
1177 { | 1177 { |
1178 int i, n=LEN_MAX; | 1178 int i, n=LEN_MAX; |
1179 if (enumval->enum_value.os.len < LEN_MAX) | 1179 if (enumval->enum_value.os.len < LEN_MAX) |
1180 n = enumval->enum_value.os.len; | 1180 n = enumval->enum_value.os.len; |
1181 for (i=0; i < n; i++) | 1181 for (i=0; i < n; i++) |
1182 fd_log_debug("0x%2hhX/'%c' ", enumval->enum_value.os.data[i], ASCII(enumval->enum_value.os.data[i])); | 1182 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "0x%2hhX/'%c' ", enumval->enum_value.os.data[i], ASCII(enumval->enum_value.os.data[i])), return NULL); |
1183 if (n == LEN_MAX) | 1183 if (n == LEN_MAX) |
1184 fd_log_debug("..."); | 1184 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "..."), return NULL); |
1185 } | 1185 } |
1186 break; | 1186 break; |
1187 | 1187 |
1188 case AVP_TYPE_INTEGER32: | 1188 case AVP_TYPE_INTEGER32: |
1189 fd_log_debug("%i", enumval->enum_value.i32); | 1189 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%i", enumval->enum_value.i32), return NULL); |
1190 break; | 1190 break; |
1191 | 1191 |
1192 case AVP_TYPE_INTEGER64: | 1192 case AVP_TYPE_INTEGER64: |
1193 fd_log_debug("%"PRId64, enumval->enum_value.i64); | 1193 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRId64, enumval->enum_value.i64), return NULL); |
1194 break; | 1194 break; |
1195 | 1195 |
1196 case AVP_TYPE_UNSIGNED32: | 1196 case AVP_TYPE_UNSIGNED32: |
1197 fd_log_debug("%u", enumval->enum_value.u32); | 1197 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%u", enumval->enum_value.u32), return NULL); |
1198 break; | 1198 break; |
1199 | 1199 |
1200 case AVP_TYPE_UNSIGNED64: | 1200 case AVP_TYPE_UNSIGNED64: |
1201 fd_log_debug("%"PRIu64, enumval->enum_value.u64); | 1201 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRIu64, enumval->enum_value.u64), return NULL); |
1202 break; | 1202 break; |
1203 | 1203 |
1204 case AVP_TYPE_FLOAT32: | 1204 case AVP_TYPE_FLOAT32: |
1205 fd_log_debug("%f", enumval->enum_value.f32); | 1205 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", enumval->enum_value.f32), return NULL); |
1206 break; | 1206 break; |
1207 | 1207 |
1208 case AVP_TYPE_FLOAT64: | 1208 case AVP_TYPE_FLOAT64: |
1209 fd_log_debug("%g", enumval->enum_value.f64); | 1209 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", enumval->enum_value.f64), return NULL); |
1210 break; | 1210 break; |
1211 | 1211 |
1212 default: | 1212 default: |
1213 fd_log_debug("??? (ERROR unknown type %d)", type); | 1213 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "??? (ERROR unknown type %d)", type), return NULL); |
1214 } | 1214 } |
1215 } | 1215 return *buf; |
1216 static void dump_avp_data ( void * data ) | 1216 } |
1217 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ) | |
1217 { | 1218 { |
1218 struct dict_avp_data * avp = (struct dict_avp_data * ) data; | 1219 struct dict_avp_data * avp = (struct dict_avp_data * ) data; |
1219 fd_log_debug("data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"", | 1220 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"", |
1220 DUMP_AVPFL_val(avp->avp_flag_val), | 1221 DUMP_AVPFL_val(avp->avp_flag_val), |
1221 DUMP_AVPFL_val(avp->avp_flag_mask), | 1222 DUMP_AVPFL_val(avp->avp_flag_mask), |
1222 type_base_name[avp->avp_basetype], | 1223 type_base_name[avp->avp_basetype], |
1223 avp->avp_code, | 1224 avp->avp_code, |
1224 avp->avp_name ); | 1225 avp->avp_name ); |
1225 } | 1226 } |
1226 static void dump_command_data ( void * data ) | 1227 static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ) |
1227 { | 1228 { |
1228 struct dict_cmd_data * cmd = (struct dict_cmd_data *) data; | 1229 struct dict_cmd_data * cmd = (struct dict_cmd_data *) data; |
1229 fd_log_debug("data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"", | 1230 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"", |
1230 DUMP_CMDFL_val(cmd->cmd_flag_val), DUMP_CMDFL_val(cmd->cmd_flag_mask), cmd->cmd_code, cmd->cmd_name); | 1231 DUMP_CMDFL_val(cmd->cmd_flag_val), DUMP_CMDFL_val(cmd->cmd_flag_mask), cmd->cmd_code, cmd->cmd_name); |
1231 } | 1232 } |
1232 static void dump_rule_data ( void * data ) | 1233 static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ) |
1233 { | 1234 { |
1234 struct dict_rule_data * rule = (struct dict_rule_data * )data; | 1235 struct dict_rule_data * rule = (struct dict_rule_data * )data; |
1235 fd_log_debug("data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"", | 1236 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"", |
1236 rule->rule_position, | 1237 rule->rule_position, |
1237 rule->rule_order, | 1238 rule->rule_order, |
1238 rule->rule_min, | 1239 rule->rule_min, |
1239 rule->rule_max, | 1240 rule->rule_max, |
1240 rule->rule_avp->data.avp.avp_name); | 1241 rule->rule_avp->data.avp.avp_name); |
1241 } | 1242 } |
1242 | 1243 |
1243 static void dump_object ( struct dict_object * obj, int parents, int depth, int indent ); | 1244 static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ); |
1244 | 1245 |
1245 static void dump_list ( struct fd_list * sentinel, int parents, int depth, int indent ) | 1246 static DECLARE_FD_DUMP_PROTOTYPE(dump_list, struct fd_list * sentinel, int parents, int depth, int indent ) |
1246 { | 1247 { |
1247 struct fd_list * li = sentinel; | 1248 struct fd_list * li = sentinel; |
1248 /* We don't lock here, the caller must have taken the dictionary lock for reading already */ | 1249 /* We don't lock here, the caller must have taken the dictionary lock for reading already */ |
1249 while (li->next != sentinel) | 1250 while (li->next != sentinel) |
1250 { | 1251 { |
1251 li = li->next; | 1252 li = li->next; |
1252 dump_object( _O(li->o), parents, depth, indent ); | 1253 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, _O(li->o), parents, depth, indent ), return NULL); |
1253 } | 1254 } |
1254 } | 1255 } |
1255 | 1256 |
1256 static void dump_object ( struct dict_object * obj, int parents, int depth, int indent ) | 1257 static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ) |
1257 { | 1258 { |
1258 if (obj == NULL) | 1259 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{dictobj}(@%p): ", indent, "", obj), return NULL); |
1259 return; | 1260 |
1260 | 1261 if (!verify_object(obj)) { |
1261 if (parents) | 1262 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL); |
1262 dump_object (obj->parent, parents-1, 0, indent + 1 ); | 1263 return *buf; |
1263 | 1264 } |
1264 fd_log_debug("%*s@%p: %s%s (p:%-9p) ", | 1265 |
1265 indent, | 1266 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ", |
1266 "", | 1267 _OBINFO(obj).name, |
1267 obj, | 1268 obj->parent), return NULL); |
1268 verify_object(obj) ? "" : "INVALID ", | 1269 |
1269 _OBINFO(obj).name, | 1270 if (obj->type == DICT_ENUMVAL) { |
1270 obj->parent); | 1271 CHECK_MALLOC_DO( dump_enumval_data ( FD_DUMP_STD_PARAMS, &obj->data.enumval, obj->parent->data.type.type_base ), return NULL); |
1271 | 1272 } else { |
1272 if (obj->type == DICT_ENUMVAL) | 1273 CHECK_MALLOC_DO( _OBINFO(obj).dump_data(FD_DUMP_STD_PARAMS, &obj->data), return NULL); |
1273 dump_enumval_data ( &obj->data.enumval, obj->parent->data.type.type_base ); | 1274 } |
1274 else | 1275 |
1275 _OBINFO(obj).dump_data(&obj->data); | 1276 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); |
1277 | |
1278 if (parents) { | |
1279 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*sparent:", indent + 1, ""), return NULL); | |
1280 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, obj->parent, parents-1, 0, 0 ), return NULL); | |
1281 } | |
1276 | 1282 |
1277 if (depth) { | 1283 if (depth) { |
1278 int i; | 1284 int i; |
1279 for (i=0; i<NB_LISTS_PER_OBJ; i++) { | 1285 for (i=0; i<NB_LISTS_PER_OBJ; i++) { |
1280 if ((obj->list[i].o == NULL) && (obj->list[i].next != &obj->list[i])) { | 1286 if ((obj->list[i].o == NULL) && (obj->list[i].next != &obj->list[i])) { |
1281 fd_log_debug("%*s>%p: list[%d]:", indent, "", obj, i); | 1287 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*slist[%d]:\n", indent + 1, "", i), return NULL); |
1282 dump_list(&obj->list[i], parents, depth - 1, indent + 2); | 1288 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &obj->list[i], 0, depth - 1, indent + 2), return NULL); |
1283 } | 1289 } |
1284 } | 1290 } |
1285 } | 1291 } |
1286 } | 1292 |
1287 | 1293 return *buf; |
1288 void fd_dict_dump_object(struct dict_object * obj) | 1294 } |
1289 { | 1295 |
1290 fd_log_debug("Dictionary object %p dump:", obj); | 1296 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj) |
1291 dump_object( obj, 1, 2, 2 ); | 1297 { |
1292 } | 1298 size_t o = 0; |
1293 | 1299 |
1294 void fd_dict_dump(struct dictionary * dict) | 1300 if (!offset) |
1301 offset = &o; | |
1302 | |
1303 CHECK_MALLOC_DO( dump_object(FD_DUMP_STD_PARAMS, obj, 1, 2, 0), return NULL); | |
1304 | |
1305 return *buf; | |
1306 } | |
1307 | |
1308 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict) | |
1295 { | 1309 { |
1296 int i; | 1310 int i; |
1297 struct fd_list * li; | 1311 struct fd_list * li; |
1298 | 1312 size_t o = 0; |
1299 CHECK_PARAMS_DO(dict && (dict->dict_eyec == DICT_EYECATCHER), return); | 1313 |
1314 if (!offset) | |
1315 offset = &o; | |
1316 | |
1317 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{dictionary}(@%p): ", dict), return NULL); | |
1318 | |
1319 if ((dict == NULL) || (dict->dict_eyec != DICT_EYECATCHER)) { | |
1320 return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL\n"); | |
1321 } | |
1300 | 1322 |
1301 CHECK_POSIX_DO( pthread_rwlock_rdlock( &dict->dict_lock ), /* ignore */ ); | 1323 CHECK_POSIX_DO( pthread_rwlock_rdlock( &dict->dict_lock ), /* ignore */ ); |
1302 | 1324 |
1303 fd_log_debug("######################################################"); | 1325 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict:%p > vendors, AVPs and related rules}\n", dict), goto error); |
1304 fd_log_debug("###### Dumping vendors, AVPs and related rules #######"); | 1326 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_vendors, 0, 3, 3 ), goto error); |
1305 | |
1306 dump_object( &dict->dict_vendors, 0, 3, 0 ); | |
1307 for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) | 1327 for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) |
1308 dump_object( li->o, 0, 3, 0 ); | 1328 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 3, 3 ), goto error); |
1309 | 1329 |
1310 fd_log_debug("###### Dumping applications #######"); | 1330 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > applications}\n", dict), goto error); |
1311 | 1331 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_applications, 0, 1, 3 ), goto error); |
1312 dump_object( &dict->dict_applications, 0, 1, 0 ); | |
1313 for (li = dict->dict_applications.list[0].next; li != &dict->dict_applications.list[0]; li = li->next) | 1332 for (li = dict->dict_applications.list[0].next; li != &dict->dict_applications.list[0]; li = li->next) |
1314 dump_object( li->o, 0, 1, 0 ); | 1333 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 1, 3 ), goto error); |
1315 | 1334 |
1316 fd_log_debug("###### Dumping types #######"); | 1335 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > types}\n", dict), goto error); |
1317 | 1336 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_types, 0, 2, 3 ), goto error); |
1318 dump_list( &dict->dict_types, 0, 2, 0 ); | 1337 |
1319 | 1338 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > commands}\n", dict), goto error); |
1320 fd_log_debug("###### Dumping commands per name #######"); | 1339 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_cmd_code, 0, 0, 3 ), goto error); |
1321 | 1340 |
1322 dump_list( &dict->dict_cmd_name, 0, 2, 0 ); | 1341 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > statistics}\n", dict), goto error); |
1323 | |
1324 fd_log_debug("###### Dumping commands per code and flags #######"); | |
1325 | |
1326 dump_list( &dict->dict_cmd_code, 0, 0, 0 ); | |
1327 | |
1328 fd_log_debug("###### Statistics #######"); | |
1329 | |
1330 for (i=1; i<=DICT_TYPE_MAX; i++) | 1342 for (i=1; i<=DICT_TYPE_MAX; i++) |
1331 fd_log_debug(" %5d objects of type %s", dict->dict_count[i], dict_obj_info[i].name); | 1343 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " %5d: %s\n", dict->dict_count[i], dict_obj_info[i].name), goto error); |
1332 | 1344 |
1333 fd_log_debug("######################################################"); | 1345 CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); |
1334 | 1346 return *buf; |
1347 error: | |
1335 /* Free the rwlock */ | 1348 /* Free the rwlock */ |
1336 CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); | 1349 CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); |
1350 return NULL; | |
1337 } | 1351 } |
1338 | 1352 |
1339 /**************************** Dump AVP values ********************************/ | 1353 /**************************** Dump AVP values ********************************/ |
1340 | 1354 |
1341 /* Default dump functions */ | 1355 /* Default dump functions */ |
1342 static int dump_val_os(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) | 1356 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_os, union avp_value * value) |
1343 { | 1357 { |
1344 int i; | 1358 int i; |
1345 CHECK_FCT( dump_add_str(outstr, offset, outlen, "<") ); | 1359 |
1360 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<"), return NULL); | |
1346 for (i = 0; i < value->os.len; i++) { | 1361 for (i = 0; i < value->os.len; i++) { |
1347 if (i == 1024) { /* Dump only up to 1024 bytes of the buffer */ | 1362 if (i == 1024) { /* Dump only up to 1024 bytes of the buffer */ |
1348 CHECK_FCT( dump_add_str(outstr, offset, outlen, "[...] (len=%zd)", value->os.len) ); | 1363 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "[...] (len=%zd)", value->os.len), return NULL); |
1349 break; | 1364 break; |
1350 } | 1365 } |
1351 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s%02.2X", (i==0 ? "" : " "), value->os.data[i]) ); | 1366 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s%02hhX", (i==0 ? "" : " "), value->os.data[i]), return NULL); |
1352 } | 1367 } |
1353 CHECK_FCT( dump_add_str(outstr, offset, outlen, ">") ); | 1368 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ">"), return NULL); |
1354 return 0; | 1369 return *buf; |
1355 } | 1370 } |
1356 | 1371 |
1357 static int dump_val_i32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) | 1372 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i32, union avp_value * value) |
1358 { | 1373 { |
1359 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%i (0x%x)", value->i32, value->i32) ); | 1374 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%i (0x%x)", value->i32, value->i32); |
1360 return 0; | 1375 } |
1361 } | 1376 |
1362 | 1377 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i64, union avp_value * value) |
1363 static int dump_val_i64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) | 1378 { |
1364 { | 1379 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRId64 " (0x%" PRIx64 ")", value->i64, value->i64); |
1365 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%lli (0x%llx)", value->i64, value->i64) ); | 1380 } |
1366 return 0; | 1381 |
1367 } | 1382 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u32, union avp_value * value) |
1368 | 1383 { |
1369 static int dump_val_u32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) | 1384 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%u (0x%x)", value->u32, value->u32); |
1370 { | 1385 } |
1371 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%u (0x%x)", value->u32, value->u32) ); | 1386 |
1372 return 0; | 1387 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u64, union avp_value * value) |
1373 } | 1388 { |
1374 | 1389 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRIu64 " (0x%" PRIx64 ")", value->u64, value->u64); |
1375 static int dump_val_u64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) | 1390 } |
1376 { | 1391 |
1377 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%llu (0x%llx)", value->u64, value->u64) ); | 1392 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f32, union avp_value * value) |
1378 return 0; | 1393 { |
1379 } | 1394 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", value->f32); |
1380 | 1395 } |
1381 static int dump_val_f32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) | 1396 |
1382 { | 1397 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f64, union avp_value * value) |
1383 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%f", value->f32) ); | 1398 { |
1384 return 0; | 1399 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", value->f64); |
1385 } | |
1386 | |
1387 static int dump_val_f64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) | |
1388 { | |
1389 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%g", value->f64) ); | |
1390 return 0; | |
1391 } | 1400 } |
1392 | 1401 |
1393 /* Get the dump function for basic dict_avp_basetype */ | 1402 /* Get the dump function for basic dict_avp_basetype */ |
1394 static int (*get_default_dump_val_cb(enum dict_avp_basetype datatype))(union avp_value *, char **, size_t *, size_t *) | 1403 static DECLARE_FD_DUMP_PROTOTYPE((*get_default_dump_val_cb(enum dict_avp_basetype datatype)), union avp_value *) |
1395 { | 1404 { |
1396 switch (datatype) { | 1405 switch (datatype) { |
1397 case AVP_TYPE_OCTETSTRING: | 1406 case AVP_TYPE_OCTETSTRING: |
1398 return &dump_val_os; | 1407 return &dump_val_os; |
1399 | 1408 |
1423 | 1432 |
1424 /* indent inside an object (duplicate from messages.c) */ | 1433 /* indent inside an object (duplicate from messages.c) */ |
1425 #define INOBJHDR "%*s " | 1434 #define INOBJHDR "%*s " |
1426 #define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|" | 1435 #define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|" |
1427 | 1436 |
1437 typedef DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb_t), union avp_value *); | |
1438 | |
1428 /* Formatter for the AVP value dump line */ | 1439 /* Formatter for the AVP value dump line */ |
1429 static int dump_avp_val(union avp_value *avp_value, | 1440 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_val, union avp_value *avp_value, |
1430 int (*def_dump_val_cb)(union avp_value *, char **, size_t *, size_t *), | 1441 dump_val_cb_t def_dump_val_cb, |
1431 char * (*dump_val_cb)(union avp_value *), | 1442 dump_val_cb_t dump_val_cb, |
1432 enum dict_avp_basetype datatype, | 1443 enum dict_avp_basetype datatype, |
1433 char * type_name, | 1444 char * type_name, |
1434 char * const_name, | 1445 char * const_name, |
1435 int indent, | 1446 int indent, |
1436 char **outstr, | |
1437 size_t *offset, | |
1438 size_t *outlen, | |
1439 int header) | 1447 int header) |
1440 { | 1448 { |
1441 if (header) { | 1449 if (header) { |
1442 /* Header for all AVP values dumps: */ | 1450 /* Header for all AVP values dumps: */ |
1443 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "value ", INOBJHDRVAL) ); | 1451 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, INOBJHDR "value ", INOBJHDRVAL), return NULL); |
1444 | 1452 |
1445 /* If the type is provided, write it */ | 1453 /* If the type is provided, write it */ |
1446 if (type_name) { | 1454 if (type_name) { |
1447 CHECK_FCT( dump_add_str(outstr, offset, outlen, "t: '%s' ", type_name) ); | 1455 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "t: '%s' ", type_name), return NULL); |
1448 } | 1456 } |
1449 | 1457 |
1450 /* Always give the base datatype anyway */ | 1458 /* Always give the base datatype anyway */ |
1451 CHECK_FCT( dump_add_str(outstr, offset, outlen, "(%s) ", type_base_name[datatype]) ); | 1459 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(%s) ", type_base_name[datatype]), return NULL); |
1452 | 1460 |
1453 /* Now, the value */ | 1461 /* Now, the value */ |
1454 CHECK_FCT( dump_add_str(outstr, offset, outlen, "v: ") ); | 1462 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "v: "), return NULL); |
1455 } | 1463 } |
1456 if (const_name) { | 1464 if (const_name) { |
1457 CHECK_FCT( dump_add_str(outstr, offset, outlen, "'%s' (", const_name) ); | 1465 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s' (", const_name), return NULL); |
1458 } | 1466 } |
1459 if (dump_val_cb) { | 1467 if (dump_val_cb) { |
1460 char * str; | 1468 CHECK_MALLOC_DO( (*dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), fd_dump_extend( FD_DUMP_STD_PARAMS, "(dump failed)")); |
1461 CHECK_MALLOC_DO( str = (*dump_val_cb)(avp_value), dump_add_str(outstr, offset, outlen, "(dump failed)") ); | |
1462 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s", str) ); | |
1463 free(str); | |
1464 } else { | 1469 } else { |
1465 CHECK_FCT( (*def_dump_val_cb)(avp_value, outstr, offset, outlen) ); | 1470 CHECK_MALLOC_DO( (*def_dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), return NULL); |
1466 } | 1471 } |
1467 if (const_name) { | 1472 if (const_name) { |
1468 CHECK_FCT( dump_add_str(outstr, offset, outlen, ")") ); | 1473 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ")"), return NULL); |
1469 } | 1474 } |
1470 | 1475 |
1471 /* Done! */ | 1476 /* Done! */ |
1472 return 0; | 1477 return *buf; |
1473 } | 1478 } |
1474 | 1479 |
1475 /* Dump the value of an AVP of known type into the returned str */ | 1480 /* Dump the value of an AVP of known type into the returned str */ |
1476 int fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent, char **outstr, size_t *offset, size_t *outlen, int header) | 1481 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_avp_value, union avp_value *avp_value, struct dict_object * model, int indent, int header) |
1477 { | 1482 { |
1478 char * (*dump_val_cb)(union avp_value *avp_value) = NULL; | 1483 DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb), union avp_value *avp_value) = NULL; |
1479 struct dict_object * type = NULL; | 1484 struct dict_object * type = NULL; |
1480 char * type_name = NULL; | 1485 char * type_name = NULL; |
1481 char * const_name = NULL; | 1486 char * const_name = NULL; |
1487 size_t o = 0; | |
1488 | |
1489 if (!offset) | |
1490 offset = &o; | |
1482 | 1491 |
1483 /* Check the parameters are correct */ | 1492 /* Check the parameters are correct */ |
1484 CHECK_PARAMS( avp_value && verify_object(model) && (model->type == DICT_AVP) ); | 1493 CHECK_PARAMS_DO( avp_value && verify_object(model) && (model->type == DICT_AVP), return NULL ); |
1485 | 1494 |
1486 /* Get the type definition of this AVP */ | 1495 /* Get the type definition of this AVP */ |
1487 type = model->parent; | 1496 type = model->parent; |
1488 if (type) { | 1497 if (type) { |
1489 struct dict_enumval_request request; | 1498 struct dict_enumval_request request; |
1499 memset(&request, 0, sizeof(request)); | 1508 memset(&request, 0, sizeof(request)); |
1500 request.type_obj = type; | 1509 request.type_obj = type; |
1501 memcpy(&request.search.enum_value, avp_value, sizeof(union avp_value)); | 1510 memcpy(&request.search.enum_value, avp_value, sizeof(union avp_value)); |
1502 /* bypass checks */ | 1511 /* bypass checks */ |
1503 if ((search_enumval( type->dico, ENUMVAL_BY_STRUCT, &request, &enumval ) == 0) && (enumval)) { | 1512 if ((search_enumval( type->dico, ENUMVAL_BY_STRUCT, &request, &enumval ) == 0) && (enumval)) { |
1504 /* We found a cosntant, get its name */ | 1513 /* We found a constant, get its name */ |
1505 const_name = enumval->data.enumval.enum_name; | 1514 const_name = enumval->data.enumval.enum_name; |
1506 } | 1515 } |
1507 } | 1516 } |
1508 | 1517 |
1509 /* And finally, dump the value */ | 1518 /* And finally, dump the value */ |
1510 CHECK_FCT( dump_avp_val(avp_value, get_default_dump_val_cb(model->data.avp.avp_basetype), dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent, outstr, offset, outlen, header) ); | 1519 CHECK_MALLOC_DO( dump_avp_val(FD_DUMP_STD_PARAMS, avp_value, get_default_dump_val_cb(model->data.avp.avp_basetype), dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent, header), return NULL ); |
1511 return 0; | 1520 return *buf; |
1512 } | 1521 } |
1513 | 1522 |
1514 /*******************************************************************************************************/ | 1523 /*******************************************************************************************************/ |
1515 /*******************************************************************************************************/ | 1524 /*******************************************************************************************************/ |
1516 /* */ | 1525 /* */ |
1571 CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) && data ); | 1580 CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) && data ); |
1572 | 1581 |
1573 /* Check the "parent" parameter */ | 1582 /* Check the "parent" parameter */ |
1574 switch (dict_obj_info[type].parent) { | 1583 switch (dict_obj_info[type].parent) { |
1575 case 0: /* parent is forbidden */ | 1584 case 0: /* parent is forbidden */ |
1576 CHECK_PARAMS( parent == NULL ); | 1585 CHECK_PARAMS_DO( parent == NULL, goto error_param ); |
1577 | 1586 |
1578 case 1: /* parent is optional */ | 1587 case 1: /* parent is optional */ |
1579 if (parent == NULL) | 1588 if (parent == NULL) |
1580 break; | 1589 break; |
1581 | 1590 |
1582 case 2: /* parent is mandatory */ | 1591 case 2: /* parent is mandatory */ |
1583 CHECK_PARAMS( verify_object(parent) ); | 1592 CHECK_PARAMS_DO( verify_object(parent), goto error_param ); |
1584 | 1593 |
1585 if (type == DICT_RULE ) { /* Special case : grouped AVP or Command parents are allowed */ | 1594 if (type == DICT_RULE ) { /* Special case : grouped AVP or Command parents are allowed */ |
1586 CHECK_PARAMS( (parent->type == DICT_COMMAND ) | 1595 CHECK_PARAMS_DO( (parent->type == DICT_COMMAND ) |
1587 || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ) ); | 1596 || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ), goto error_param ); |
1588 } else { | 1597 } else { |
1589 CHECK_PARAMS( parent->type == dict_obj_info[type].parenttype ); | 1598 CHECK_PARAMS_DO( parent->type == dict_obj_info[type].parenttype, goto error_param ); |
1590 } | 1599 } |
1591 } | 1600 } |
1592 | 1601 |
1593 /* For AVP object, we must also check that the "vendor" referenced exists */ | 1602 /* For AVP object, we must also check that the "vendor" referenced exists */ |
1594 if (type == DICT_AVP) { | 1603 if (type == DICT_AVP) { |
1595 CHECK_FCT_DO( fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ), | 1604 CHECK_FCT_DO( fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ), |
1596 { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); return EINVAL; } ); | 1605 { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); goto error_param; } ); |
1597 | 1606 |
1598 /* Also check if a parent is provided, that the type are the same */ | 1607 /* Also check if a parent is provided, that the type are the same */ |
1599 if (parent) { | 1608 if (parent) { |
1600 CHECK_PARAMS( parent->data.type.type_base == ((struct dict_avp_data *)data)->avp_basetype ); | 1609 CHECK_PARAMS_DO( parent->data.type.type_base == ((struct dict_avp_data *)data)->avp_basetype, goto error_param ); |
1601 } | 1610 } |
1602 } | 1611 } |
1603 | 1612 |
1604 /* For RULE object, we must also check that the "avp" referenced exists */ | 1613 /* For RULE object, we must also check that the "avp" referenced exists */ |
1605 if (type == DICT_RULE) { | 1614 if (type == DICT_RULE) { |
1606 CHECK_PARAMS( verify_object(((struct dict_rule_data *)data)->rule_avp) ); | 1615 CHECK_PARAMS_DO( verify_object(((struct dict_rule_data *)data)->rule_avp), goto error_param ); |
1607 CHECK_PARAMS( ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP ); | 1616 CHECK_PARAMS_DO( ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP, goto error_param ); |
1608 } | 1617 } |
1609 | 1618 |
1610 /* For COMMAND object, check that the 'R' flag is fixed */ | 1619 /* For COMMAND object, check that the 'R' flag is fixed */ |
1611 if (type == DICT_COMMAND) { | 1620 if (type == DICT_COMMAND) { |
1612 CHECK_PARAMS( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST ); | 1621 CHECK_PARAMS_DO( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST, goto error_param ); |
1613 } | 1622 } |
1614 | 1623 |
1615 /* We have to check that the new values are not equal to the sentinels */ | 1624 /* We have to check that the new values are not equal to the sentinels */ |
1616 if (type == DICT_VENDOR) { | 1625 if (type == DICT_VENDOR) { |
1617 CHECK_PARAMS( ((struct dict_vendor_data *)data)->vendor_id != 0 ); | 1626 CHECK_PARAMS_DO( ((struct dict_vendor_data *)data)->vendor_id != 0, goto error_param ); |
1618 } | 1627 } |
1619 if (type == DICT_APPLICATION) { | 1628 if (type == DICT_APPLICATION) { |
1620 CHECK_PARAMS( ((struct dict_application_data *)data)->application_id != 0 ); | 1629 CHECK_PARAMS_DO( ((struct dict_application_data *)data)->application_id != 0, goto error_param ); |
1621 } | 1630 } |
1622 | 1631 |
1623 /* Parameters are valid, create the new object */ | 1632 /* Parameters are valid, create the new object */ |
1624 CHECK_MALLOC( new = malloc(sizeof(struct dict_object)) ); | 1633 CHECK_MALLOC( new = malloc(sizeof(struct dict_object)) ); |
1625 | 1634 |
1715 if (ref) | 1724 if (ref) |
1716 *ref = new; | 1725 *ref = new; |
1717 | 1726 |
1718 return 0; | 1727 return 0; |
1719 | 1728 |
1729 error_param: | |
1730 ret = EINVAL; | |
1731 goto all_errors; | |
1732 | |
1720 error_unlock: | 1733 error_unlock: |
1721 CHECK_POSIX_DO( pthread_rwlock_unlock(&dict->dict_lock), /* continue */ ); | 1734 CHECK_POSIX_DO( pthread_rwlock_unlock(&dict->dict_lock), /* continue */ ); |
1722 if (ret == EEXIST) { | 1735 if (ret == EEXIST) { |
1723 /* We have a duplicate key in locref. Check if the pointed object is the same or not */ | 1736 /* We have a duplicate key in locref. Check if the pointed object is the same or not */ |
1724 switch (type) { | 1737 switch (type) { |
1725 case DICT_VENDOR: | 1738 case DICT_VENDOR: |
1726 TRACE_DEBUG(FULL, "Vendor %s already in dictionary", new->data.vendor.vendor_name); | 1739 TRACE_DEBUG(FULL, "Vendor %s already in dictionary", new->data.vendor.vendor_name); |
1727 /* if we are here, it means the two vendors id are identical */ | 1740 /* if we are here, it means the two vendors id are identical */ |
1728 if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len, | 1741 if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len, |
1729 new->data.vendor.vendor_name, new->datastr_len)) { | 1742 new->data.vendor.vendor_name, new->datastr_len)) { |
1730 TRACE_DEBUG(FULL, "Conflicting vendor name"); | 1743 TRACE_DEBUG(INFO, "Conflicting vendor name: %s", new->data.vendor.vendor_name); |
1731 break; | 1744 break; |
1732 } | 1745 } |
1733 /* Otherwise (same name), we consider the function succeeded, since the (same) object is in the dictionary */ | 1746 /* Otherwise (same name), we consider the function succeeded, since the (same) object is in the dictionary */ |
1734 ret = 0; | 1747 ret = 0; |
1735 break; | 1748 break; |
1863 break; | 1876 break; |
1864 } | 1877 } |
1865 ret = 0; | 1878 ret = 0; |
1866 break; | 1879 break; |
1867 } | 1880 } |
1868 if (ret) { | 1881 if (!ret) { |
1869 TRACE_DEBUG(INFO, "An existing object with different non-key data was found: EEXIST"); | |
1870 if (TRACE_BOOL(INFO)) { | |
1871 fd_log_debug("New object to insert:"); | |
1872 dump_object(new, 0, 0, 3); | |
1873 fd_log_debug("Object already in dictionary:"); | |
1874 dump_object(locref, 0, 0 , 3); | |
1875 } | |
1876 } else { | |
1877 TRACE_DEBUG(FULL, "An existing object with the same data was found, ignoring the error..."); | 1882 TRACE_DEBUG(FULL, "An existing object with the same data was found, ignoring the error..."); |
1878 } | 1883 } |
1879 if (ref) | 1884 if (ref) |
1880 *ref = locref; | 1885 *ref = locref; |
1881 } else { | 1886 } |
1882 CHECK_FCT_DO( ret, ); /* log the error */ | 1887 all_errors: |
1883 } | 1888 if (ret != 0) { |
1884 | 1889 char * buf = NULL; |
1890 size_t len = 0; | |
1891 | |
1892 CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, NULL, data) ); | |
1893 TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf); | |
1894 | |
1895 if (ret == EEXIST) { | |
1896 CHECK_MALLOC( dump_object(&buf, &len, NULL, locref, 0, 0, 0) ); | |
1897 TRACE_DEBUG(INFO, "Conflicting entry in the dictionary: %s", buf); | |
1898 } | |
1899 free(buf); | |
1900 } | |
1885 error_free: | 1901 error_free: |
1886 free(new); | 1902 free(new); |
1887 return ret; | 1903 return ret; |
1888 } | 1904 } |
1889 | 1905 |