void cfg_dump(Cfg *cfg) { CfgGroup *grp; List *list; List *names; Octstr *name; debug("gwlib.cfg", 0, "Dumping Cfg %p", (void *) cfg); debug("gwlib.cfg", 0, " filename = <%s>", octstr_get_cstr(cfg->filename)); names = dict_keys(cfg->single_groups); while ((name = gwlist_extract_first(names)) != NULL) { grp = cfg_get_single_group(cfg, name); if (grp != NULL) grp_dump(grp); octstr_destroy(name); } gwlist_destroy(names, NULL); names = dict_keys(cfg->multi_groups); while ((name = gwlist_extract_first(names)) != NULL) { list = cfg_get_multi_group(cfg, name); while ((grp = gwlist_extract_first(list)) != NULL) grp_dump(grp); gwlist_destroy(list, NULL); octstr_destroy(name); } gwlist_destroy(names, NULL); debug("gwlib.cfg", 0, "Dump ends."); }
void mms_cfg_destroy(mCfg *cfg) { List *l; int i, n; gw_assert(cfg); for (i = 0, l = dict_keys(cfg->grps), n = gwlist_len(l); i < n; i++) { Octstr *grpname = gwlist_get(l, i); void *val = dict_get(cfg->grps, grpname); if (is_multigroup(grpname)) { /* item is a list. */ List *gl = val; int j, m = gwlist_len(gl); for (j = 0; j < m; j++) mGrp_destroy(gwlist_get(gl, j)); gwlist_destroy(gl, NULL); } else mGrp_destroy(val); } gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy); dict_destroy(cfg->grps); octstr_destroy(cfg->file); if (cfg->xcfg && cfg->cfg_funcs && cfg->cfg_funcs->destroy) cfg->cfg_funcs->destroy(cfg->xcfg); gw_free(cfg); }
/* Test to insert a large number of elements in the dict. */ static void test_readelements(const char *fname) { DICT *dict; char buf[80]; FILE *fp; void *val; const char **keys; int i; /* initialize */ dict=dict_new(); /* read file and insert all entries */ fp=fopen(fname,"r"); assert(fp!=NULL); while (fgets(buf,sizeof(buf),fp)!=NULL) { /* strip newline */ buf[strlen(buf)-1]='\0'; dict_put(dict,buf,&buf); } fclose(fp); /* loop over dictionary contents */ keys=dict_keys(dict); for (i=0;keys[i]!=NULL;i++) { val=dict_get(dict,keys[i]); assert(val==buf); } /* free stuff */ dict_free(dict); free(keys); }
static int do_dump(void) { Octstr *key; Msg *msg; List *sms_list; long l; if (filename == NULL) return 0; /* create a new store-file and save all non-acknowledged * messages into it */ if (open_file(newfile)==-1) return -1; sms_list = dict_keys(sms_dict); for (l=0; l < gwlist_len(sms_list); l++) { key = gwlist_get(sms_list, l); msg = dict_get(sms_dict, key); if (msg != NULL) write_msg(msg); } fflush(file); gwlist_destroy(sms_list, octstr_destroy_item); /* rename old storefile as .bak, and then new as regular file * without .new ending */ return rename_store(); }
/* This tests if it returns the correct list of keys and vals */ U8 Dict_test2(void) { dict_keys(p_dict, &p_list); list_getItem(p_list, 0, &p_tempobj); if (object_isEqual(p_tempobj,(pPmObj_t) p_firstkey)==0) return 0 ; list_getItem(p_list, 1, &p_tempobj); if (object_isEqual(p_tempobj,(pPmObj_t) p_secondkey)==0) return 0 ; list_getItem(p_list, 2, &p_tempobj); if (object_isEqual(p_tempobj,(pPmObj_t) p_thirdkey)==0) return 0 ; //destroy_chunk(p_list); //destroys elements in p_list. Destroys contents the keys! bad dict_vals(p_dict, &p_list); list_getItem(p_list, 0, &p_tempobj); if (object_isEqual(p_tempobj,(pPmObj_t) p_firstval)==0) return 0 ; list_getItem(p_list, 1, &p_tempobj); if (object_isEqual(p_tempobj,(pPmObj_t) p_secondval)==0) return 0 ; list_getItem(p_list, 2, &p_tempobj); if (object_isEqual(p_tempobj,(pPmObj_t) p_thirdval)==0) return 0 ; //NO. Destroys contents. We want to reuse for other tests. //destroy_chunk(p_list); //destroy_chunk(p_tempobj); return 1; }
static void test_dict(void) { Dict *dict = make_dict(); assert_null(dict_get(dict, "abc")); dict_put(dict, "abc", (void *)50); dict_put(dict, "xyz", (void *)70); assert_int(50, (long)dict_get(dict, "abc")); assert_int(70, (long)dict_get(dict, "xyz")); assert_int(2, list_len(dict_keys(dict))); }
static int add_group(Cfg *cfg, CfgGroup *grp) { Octstr *groupname; Octstr *name; List *names; List *list; groupname = cfg_get(grp, octstr_imm("group")); if (groupname == NULL) { error(0, "Group does not contain variable 'group'."); return -1; } set_group_name(grp, groupname); names = dict_keys(grp->vars); while ((name = gwlist_extract_first(names)) != NULL) { int a = is_allowed_in_group(groupname, name); switch (a) { case 0: error(0, "Group '%s' may not contain field '%s'.", octstr_get_cstr(groupname), octstr_get_cstr(name)); octstr_destroy(name); octstr_destroy(groupname); gwlist_destroy(names, octstr_destroy_item); return -1; break; case -1: error(0, "Group '%s' is no valid group identifier.", octstr_get_cstr(groupname)); octstr_destroy(name); octstr_destroy(groupname); gwlist_destroy(names, octstr_destroy_item); return -1; break; default: octstr_destroy(name); break; } } gwlist_destroy(names, NULL); if (is_single_group(groupname)) { dict_put(cfg->single_groups, groupname, grp); } else { list = dict_get(cfg->multi_groups, groupname); if (list == NULL) { list = gwlist_create(); dict_put(cfg->multi_groups, groupname, list); } gwlist_append(list, grp); } octstr_destroy(groupname); return 0; }
void func_dict_keys(void) { cData * args; cList * keys; if (!func_init_1(&args, DICT)) return; keys = dict_keys(DICT1); pop(1); push_list(keys); list_discard(keys); }
void dictExample() { dict_t *d = (dict_t *)malloc(sizeof(dict_t)); char *var; char *key1 = strToHeap("key1"); char *key2 = strToHeap("key2"); char *key3 = strToHeap("key3"); char *value1 = strToHeap("var1"); char *value2 = strToHeap("var2"); char *value3 = strToHeap("var3"); dict_init(d); dict_set(d, key1, value1); dict_set(d, key2, value2); dict_set(d, key3, value3); dict_get(d, "key1", (void **)&var); printf("key1=>%s\n", var); dict_get(d, "key2", (void **)&var); printf("key1=>%s\n", var); dict_get(d, "key3", (void **)&var); printf("key1=>%s\n", var); printf("dict size:%d\n", dict_size(d)); if (1 == dict_del(d, key3)) { key3 = NULL; value3 = NULL; printf("del key3 done\n"); } char **ks = (char **)malloc(dict_size(d)*sizeof(char*)); int i; dict_keys(d, ks); for(i = 0; i < dict_size(d); i++) printf("%s ",*(ks+i) ); printf("\n"); char *k, *v; while(dict_iter(d, &k, (void **)&v)) printf("%s = >%s\n", k, v); dict_reset(d); dict_destory(d); free(d); }
/* Counts the number of elements produced to any deliver threads (live elements) * Used to control how many new queueings to accept. * Each of these may use upto 3 filehandles * - One for the qf * - One for the df file * - Delivery notification file * Does sockets count as filehandles? */ static int mms_queue_live_count() { int i,j,count = 0; static struct Qthread_t *tlist; List *queue_run_thread_groups = dict_keys(tlists); for (i = 0; i < gwlist_len(queue_run_thread_groups); i++) { tlist = dict_get(tlists, gwlist_get(queue_run_thread_groups, i)); for (j = 0; j < number_of_threads; j++) count += gwlist_len(tlist[j].l); } gwlist_destroy(queue_run_thread_groups, octstr_destroy_item); return count; }
/* Simple test that adds a few key/value pairs to the dict and the does most operations. */ static void test_simple(void) { DICT *dict; void *val; static char *value1="value1"; static char *value2="value2"; static char *replace2="replace2"; const char **keys; int i; /* initialize */ dict=dict_new(); /* store some entries */ dict_put(dict,"key1",value1); dict_put(dict,"key2",value2); dict_put(dict,"key3",dict); dict_put(dict,"key2",replace2); /* check dictionary contents */ val=dict_get(dict,"key1"); assert(val==value1); val=dict_get(dict,"key2"); assert(val==replace2); val=dict_get(dict,"key3"); assert(val==dict); val=dict_get(dict,"key4"); assert(val==NULL); val=dict_get(dict,"KEY1"); assert(val==NULL); /* remove a key */ dict_put(dict,"key3",NULL); val=dict_get(dict,"key3"); assert(val==NULL); /* loop over dictionary contents */ keys=dict_keys(dict); for (i=0;keys[i]!=NULL;i++) { val=dict_get(dict,keys[i]); assert(((val==value1)||(val==replace2))); } /* free stuff */ dict_free(dict); free(keys); }
/* Test to insert a large number of elements in the dict. */ static void test_lotsofelements(void) { DICT *dict; char buf[80]; int i,r; void *val; const char **keys; /* initialize */ dict=dict_new(); /* insert a number of entries */ for (i=0;i<1024;i++) { r=1+(int)(10000.0*(rand()/(RAND_MAX+1.0))); sprintf(buf,"test%04d",r); dict_put(dict,buf,&buf); } /* remove a number of entries */ for (i=0;i<100;i++) { r=1+(int)(10000.0*(rand()/(RAND_MAX+1.0))); sprintf(buf,"test%04d",r); dict_put(dict,buf,NULL); } /* add some more entries */ for (i=0;i<1024;i++) { r=1+(int)(10000.0*(rand()/(RAND_MAX+1.0))); sprintf(buf,"test%04d",r); dict_put(dict,buf,&buf); } /* loop over dictionary contents */ keys=dict_keys(dict); for (i=0;keys[i]!=NULL;i++) { val=dict_get(dict,keys[i]); assert(val==buf); } /* free stuff */ dict_free(dict); free(keys); }
void grp_dump(CfgGroup *grp) { List *names; Octstr *name; Octstr *value; if (grp->name == NULL) debug("gwlib.cfg", 0, " dumping group (name not set):"); else debug("gwlib.cfg", 0, " dumping group (%s):", octstr_get_cstr(grp->name)); names = dict_keys(grp->vars); while ((name = gwlist_extract_first(names)) != NULL) { value = cfg_get(grp, name); debug("gwlib.cfg", 0, " <%s> = <%s>", octstr_get_cstr(name), octstr_get_cstr(value)); octstr_destroy(value); octstr_destroy(name); } gwlist_destroy(names, NULL); }
static void test_countelements(int num) { DICT *dict; char buf[80]; int i,r; const char **keys; /* initialize */ dict=dict_new(); /* insert a number of entries */ for (i=0;i<num;i++) { r=1+(int)(10000.0*(rand()/(RAND_MAX+1.0))); sprintf(buf,"%04dx%04d",i,r); dict_put(dict,buf,&buf); } /* loop over dictionary contents */ keys=dict_keys(dict); for (i=0;keys[i]!=NULL;i++); /* we should have num elements */ assert(i==num); /* free stuff */ dict_free(dict); free(keys); }
static void run_smsbox(void *arg) { Boxc *newconn; long sender; Msg *msg; List *keys; Octstr *key; gwlist_add_producer(flow_threads); newconn = arg; newconn->incoming = gwlist_create(); gwlist_add_producer(newconn->incoming); newconn->retry = incoming_sms; newconn->outgoing = outgoing_sms; newconn->sent = dict_create(smsbox_max_pending, NULL); newconn->pending = semaphore_create(smsbox_max_pending); sender = gwthread_create(boxc_sender, newconn); if (sender == -1) { error(0, "Failed to start a new thread, disconnecting client <%s>", octstr_get_cstr(newconn->client_ip)); goto cleanup; } /* * We register newconn in the smsbox_list here but mark newconn as routable * after identification or first message received from smsbox. So we can avoid * a race condition for routable smsboxes (otherwise between startup and * registration we will forward some messages to smsbox). */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_append(smsbox_list, newconn); gw_rwlock_unlock(smsbox_list_rwlock); gwlist_add_producer(newconn->outgoing); boxc_receiver(newconn); gwlist_remove_producer(newconn->outgoing); /* remove us from smsbox routing list */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_delete_equal(smsbox_list, newconn); if (newconn->boxc_id) { dict_remove(smsbox_by_id, newconn->boxc_id); } gw_rwlock_unlock(smsbox_list_rwlock); /* * check if we in the shutdown phase and sms dequeueing thread * has removed the producer already */ if (gwlist_producer_count(newconn->incoming) > 0) gwlist_remove_producer(newconn->incoming); /* check if we are still waiting for ack's and semaphore locked */ if (dict_key_count(newconn->sent) >= smsbox_max_pending) semaphore_up(newconn->pending); /* allow sender to go down */ gwthread_join(sender); /* put not acked msgs into incoming queue */ keys = dict_keys(newconn->sent); while((key = gwlist_extract_first(keys)) != NULL) { msg = dict_remove(newconn->sent, key); gwlist_produce(incoming_sms, msg); octstr_destroy(key); } gw_assert(gwlist_len(keys) == 0); gwlist_destroy(keys, octstr_destroy_item); /* clear our send queue */ while((msg = gwlist_extract_first(newconn->incoming)) != NULL) { gwlist_produce(incoming_sms, msg); } cleanup: gw_assert(gwlist_len(newconn->incoming) == 0); gwlist_destroy(newconn->incoming, NULL); gw_assert(dict_key_count(newconn->sent) == 0); dict_destroy(newconn->sent); semaphore_destroy(newconn->pending); boxc_destroy(newconn); /* wakeup the dequeueing thread */ gwthread_wakeup(sms_dequeue_thread); gwlist_remove_producer(flow_threads); }
static Octstr *store_file_status(int status_type) { char *frmt; Octstr *ret, *key; unsigned long l; struct tm tm; Msg *msg; List *keys; char id[UUID_STR_LEN + 1]; ret = octstr_create(""); /* set the type based header */ if (status_type == BBSTATUS_HTML) { octstr_append_cstr(ret, "<table border=1>\n" "<tr><td>SMS ID</td><td>Type</td><td>Time</td><td>Sender</td><td>Receiver</td>" "<td>SMSC ID</td><td>BOX ID</td><td>UDH</td><td>Message</td>" "</tr>\n"); } else if (status_type == BBSTATUS_TEXT) { octstr_append_cstr(ret, "[SMS ID] [Type] [Time] [Sender] [Receiver] [SMSC ID] [BOX ID] [UDH] [Message]\n"); } /* if there is no store-file, then don't loop in sms_store */ if (filename == NULL) goto finish; keys = dict_keys(sms_dict); for (l = 0; l < gwlist_len(keys); l++) { key = gwlist_get(keys, l); msg = dict_get(sms_dict, key); if (msg == NULL) continue; if (msg_type(msg) == sms) { if (status_type == BBSTATUS_HTML) { frmt = "<tr><td>%s</td><td>%s</td>" "<td>%04d-%02d-%02d %02d:%02d:%02d</td>" "<td>%s</td><td>%s</td><td>%s</td>" "<td>%s</td><td>%s</td><td>%s</td></tr>\n"; } else if (status_type == BBSTATUS_XML) { frmt = "<message>\n\t<id>%s</id>\n\t<type>%s</type>\n\t" "<time>%04d-%02d-%02d %02d:%02d:%02d</time>\n\t" "<sender>%s</sender>\n\t" "<receiver>%s</receiver>\n\t<smsc-id>%s</smsc-id>\n\t" "<box-id>%s</box-id>\n\t" "<udh-data>%s</udh-data>\n\t<msg-data>%s</msg-data>\n\t" "</message>\n"; } else { frmt = "[%s] [%s] [%04d-%02d-%02d %02d:%02d:%02d] [%s] [%s] [%s] [%s] [%s] [%s]\n"; } /* transform the time value */ #if LOG_TIMESTAMP_LOCALTIME tm = gw_localtime(msg->sms.time); #else tm = gw_gmtime(msg->sms.time); #endif if (msg->sms.udhdata) octstr_binary_to_hex(msg->sms.udhdata, 1); if (msg->sms.msgdata && (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2 || (msg->sms.coding == DC_UNDEF && msg->sms.udhdata))) octstr_binary_to_hex(msg->sms.msgdata, 1); uuid_unparse(msg->sms.id, id); octstr_format_append(ret, frmt, id, (msg->sms.sms_type == mo ? "MO" : msg->sms.sms_type == mt_push ? "MT-PUSH" : msg->sms.sms_type == mt_reply ? "MT-REPLY" : msg->sms.sms_type == report_mo ? "DLR-MO" : msg->sms.sms_type == report_mt ? "DLR-MT" : ""), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (msg->sms.sender ? octstr_get_cstr(msg->sms.sender) : ""), (msg->sms.receiver ? octstr_get_cstr(msg->sms.receiver) : ""), (msg->sms.smsc_id ? octstr_get_cstr(msg->sms.smsc_id) : ""), (msg->sms.boxc_id ? octstr_get_cstr(msg->sms.boxc_id) : ""), (msg->sms.udhdata ? octstr_get_cstr(msg->sms.udhdata) : ""), (msg->sms.msgdata ? octstr_get_cstr(msg->sms.msgdata) : "")); if (msg->sms.udhdata) octstr_hex_to_binary(msg->sms.udhdata); if (msg->sms.msgdata && (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2 || (msg->sms.coding == DC_UNDEF && msg->sms.udhdata))) octstr_hex_to_binary(msg->sms.msgdata); } } gwlist_destroy(keys, octstr_destroy_item); finish: /* set the type based footer */ if (status_type == BBSTATUS_HTML) { octstr_append_cstr(ret,"</table>"); } return ret; }
static int store_file_load(void(*receive_msg)(Msg*)) { List *keys; Octstr *store_file, *key; Msg *msg; int retval, msgs; long end, pos; if (filename == NULL) return 0; mutex_lock(file_mutex); if (file != NULL) { fclose(file); file = NULL; } store_file = octstr_read_file(octstr_get_cstr(filename)); if (store_file != NULL) info(0, "Loading store file `%s'", octstr_get_cstr(filename)); else { store_file = octstr_read_file(octstr_get_cstr(newfile)); if (store_file != NULL) info(0, "Loading store file `%s'", octstr_get_cstr(newfile)); else { store_file = octstr_read_file(octstr_get_cstr(bakfile)); if (store_file != NULL) info(0, "Loading store file `%s'", octstr_get_cstr(bakfile)); else { info(0, "Cannot open any store file, starting a new one"); retval = open_file(filename); goto end; } } } info(0, "Store-file size %ld, starting to unpack%s", octstr_len(store_file), octstr_len(store_file) > 10000 ? " (may take awhile)" : ""); pos = 0; msgs = 0; end = octstr_len(store_file); while (pos < end) { if (read_msg(&msg, store_file, &pos) == -1) { error(0, "Garbage at store-file, skipped."); continue; } if (msg_type(msg) == sms) { store_to_dict(msg); msgs++; } else if (msg_type(msg) == ack) { store_to_dict(msg); } else { warning(0, "Strange message in store-file, discarded, " "dump follows:"); msg_dump(msg, 0); } msg_destroy(msg); } octstr_destroy(store_file); info(0, "Retrieved %d messages, non-acknowledged messages: %ld", msgs, dict_key_count(sms_dict)); /* now create a new sms_store out of messages left */ keys = dict_keys(sms_dict); while ((key = gwlist_extract_first(keys)) != NULL) { msg = dict_remove(sms_dict, key); if (store_to_dict(msg) != -1) { receive_msg(msg); } else { error(0, "Found unknown message type in store file."); msg_dump(msg, 0); msg_destroy(msg); } octstr_destroy(key); } gwlist_destroy(keys, octstr_destroy_item); /* Finally, generate new store file out of left messages */ retval = do_dump(); end: mutex_unlock(file_mutex); /* allow using of store */ gwlist_remove_producer(loaded); /* start dumper thread */ if ((cleanup_thread = gwthread_create(store_dumper, NULL))==-1) panic(0, "Failed to create a cleanup thread!"); return retval; }