void SVSNickChange(struct userNode* user, const char *new_nick) { char *old_nick; unsigned int nn; /* don't do anything if there's no change */ old_nick = user->nick; if (!strncmp(new_nick, old_nick, NICKLEN)) return; /* remove old entry from clients dictionary */ dict_remove(clients, old_nick); #if !defined(WITH_PROTOCOL_P10) /* Remove from uplink's clients dict */ dict_remove(user->uplink->users, old_nick); #endif /* and reinsert */ user->nick = strdup(new_nick); dict_insert(clients, user->nick, user); #if !defined(WITH_PROTOCOL_P10) dict_insert(user->uplink->users, user->nick, user); #endif /* Make callbacks for nick changes. Do this with new nick in * place because that is slightly more useful. */ for (nn=0; (nn<ncf2_used) && !user->dead; nn++) ncf2_list[nn](user, old_nick, ncf2_list_extra[nn]); user->timestamp = now; free(old_nick); }
/* * Remove msg from sent queue. * Return 0 if message should be deleted from store and 1 if not (e.g. tmp nack) */ static void boxc_sent_pop(Boxc *conn, Msg *m, Msg **orig) { Octstr *os; char id[UUID_STR_LEN + 1]; Msg *msg; if (conn->is_wap || !conn->sent || !m || (msg_type(m) != ack && msg_type(m) != sms)) return; if (orig != NULL) *orig = NULL; uuid_unparse((msg_type(m) == sms ? m->sms.id : m->ack.id), id); os = octstr_create(id); msg = dict_remove(conn->sent, os); octstr_destroy(os); if (!msg) { error(0, "BOXC: Got ack for nonexistend message!"); msg_dump(m, 0); return; } semaphore_up(conn->pending); if (orig == NULL) msg_destroy(msg); else *orig = msg; }
static void flow_destructor(void *arg) { struct flow *flow = arg; struct call *call = flow->call; info("flowmgr(%p): call(%p): flow(%p -- %s) destructor\n", call->fm, call, flow, flow->flowid); flow->cp = mem_deref(flow->cp); call_remove_conf_part(call, flow); delete_flow(flow); list_unlink(&flow->le); release_mediaflow(flow); flow->flowid = mem_deref(flow->flowid); flow->remoteid = mem_deref(flow->remoteid); if (flow->userflow) { userflow_set_flow(flow->userflow, NULL); dict_remove(call->users, flow->userflow->userid); flow->userflow = mem_deref(flow->userflow); } list_flush(&flow->pendingl); }
static void DelChannel(struct chanNode *channel) { unsigned int n; verify(channel); dict_remove(channels, channel->name); if (channel->members.used || channel->locks) { log_module(MAIN_LOG, LOG_ERROR, "Warning: deleting channel %s with %d users and %d locks remaining.", channel->name, channel->members.used, channel->locks); } /* go through all channel members and delete them from the channel */ for (n=channel->members.used; n>0; ) DelChannelUser(channel->members.list[--n]->user, channel, NULL, 1); /* delete all channel bans */ for (n=channel->banlist.used; n>0; ) free(channel->banlist.list[--n]); channel->banlist.used = 0; /* delete all channel exempts */ for (n=channel->exemptlist.used; n>0; ) free(channel->exemptlist.list[--n]); channel->exemptlist.used = 0; for (n=0; n<dcf_used; n++) dcf_list[n](channel, dcf_list_extra[n]); modeList_clean(&channel->members); banList_clean(&channel->banlist); exemptList_clean(&channel->exemptlist); free(channel); }
void proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp) { debug(DEBUG_FUNCTION, "proc_remove_breakpoint(pid=%d, %s@%p)", proc->pid, breakpoint_name(bp), bp->addr); check_leader(proc); struct breakpoint *removed = dict_remove(proc->breakpoints, bp->addr); assert(removed == bp); }
void call_remove_flow(struct call *call, const char *flowid) { if (!call) return; dict_remove(call->flows, flowid); call_mestab_check(call); }
static void qserver_destroy_fd(struct io_fd *fd) { struct qserverClient *client; client = fd->data; assert(client->fd == fd); dict_remove(qserver_dict, client->user->nick); DelUser(client->user, NULL, 0, "client disconnected"); qserver_clients[client->id] = NULL; free(client); }
int main(void) { dict *d = dict_new(); assert( dict_value(d, "a") == NULL ); assert( dict_remove(d, "a") == 0 ); assert( dict_set(d, "a", "01") == 1 ); assert( strcmp(dict_value(d, "a"), "01") == 0 ); assert( dict_set(d, "a", "10") == 0 ); assert( strcmp(dict_value(d, "a"), "10") == 0 ); assert( dict_remove(d, "b") == 0 ); assert( dict_remove(d, "a") == 1 ); assert( dict_value(d, "a") == NULL); d = dict_free(d); return EXIT_SUCCESS; }
extern ini_t *ini_unset(ini_t * self, char *section, char *var) { dict_t *vars; assert(self && section && var); strlower(section); strlower(var); if (!(vars = dict_get(self->sections, section))) return self; dict_remove(vars, var, free); return self; }
void call_purge_users(struct call *call) { struct userflow *uf; if (!call) return; do { uf = dict_apply(call->users, purge_handler, call); if (uf) { info("flowmgr: %s purging user: (%p)%s\n", __func__, uf, uf->userid); dict_remove(call->users, uf->userid); } } while (uf != NULL); }
void mm_platform_unregisterMedia(struct dict *sounds, const char *name) { struct sound *snd; struct jni_env jni_env; info("mm_platform_android: unregisterMedia: name=%s\n", name); snd = dict_lookup(sounds, name); if (!snd) return; if(jni_attach(&jni_env)){ error("mm: %s jni_attach failed\n", __FUNCTION__); return; } (*jni_env.env)->DeleteGlobalRef(jni_env.env, (jobject)snd->arg); dict_remove(sounds, name); jni_detach(&jni_env); }
static void call_destructor(void *arg) { struct call *call = arg; struct le *le; info("flowmgr(%p): call(%p): dtor\n", call->fm, call); le = call->rrl.head; while (le) { struct rr_resp *rr = le->data; le = le->next; rr_cancel(rr); } list_flush(&call->ghostl); list_flush(&call->conf_parts); dict_flush(call->users); mem_deref(call->users); if (call->fm) dict_remove(call->fm->calls, call->convid); if (call->flows) { struct dict *flows = call->flows; call->flows = NULL; mem_deref(flows); } mem_deref(call->convid); mem_deref(call->sessid); call->fm = NULL; list_unlink(&call->post_le); }
static int store_to_dict(Msg *msg) { Msg *copy; Octstr *uuid_os; char id[UUID_STR_LEN + 1]; /* always set msg id and timestamp */ if (msg_type(msg) == sms && uuid_is_null(msg->sms.id)) uuid_generate(msg->sms.id); if (msg_type(msg) == sms && msg->sms.time == MSG_PARAM_UNDEFINED) time(&msg->sms.time); if (msg_type(msg) == sms) { copy = msg_duplicate(msg); uuid_unparse(copy->sms.id, id); uuid_os = octstr_create(id); dict_put(sms_dict, uuid_os, copy); octstr_destroy(uuid_os); last_dict_mod = time(NULL); } else if (msg_type(msg) == ack) { uuid_unparse(msg->ack.id, id); uuid_os = octstr_create(id); copy = dict_remove(sms_dict, uuid_os); octstr_destroy(uuid_os); if (copy == NULL) { warning(0, "bb_store: get ACK of message not found " "from store, strange?"); } else { msg_destroy(copy); last_dict_mod = time(NULL); } } else return -1; return 0; }
void test_basic(dict *dct, const struct key_info *keys, const unsigned nkeys, const struct closest_lookup_info *cl_infos, unsigned n_cl_infos) { dict_itor *itor = dict_itor_new(dct); CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_TRUE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NULL(*datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j <= i; ++j) test_search(dct, itor, keys[j].key, keys[j].value); for (unsigned j = i + 1; j < nkeys; ++j) test_search(dct, itor, keys[j].key, NULL); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); if (dct->_vtable->insert == (dict_insert_func)hashtable_insert || dct->_vtable->insert == (dict_insert_func)hashtable2_insert) { /* Verify that hashtable_resize works as expected. */ dict *clone = dict_clone(dct, NULL); CU_ASSERT_TRUE(dict_verify(dct)); if (dct->_vtable->insert == (dict_insert_func)hashtable_insert) { CU_ASSERT_TRUE(hashtable_resize(dict_private(clone), 3)); } else { CU_ASSERT_TRUE(hashtable2_resize(dict_private(clone), 3)); } CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j < nkeys; ++j) test_search(clone, NULL, keys[j].key, keys[j].value); dict_free(clone); } if (dct->_vtable->clone) { dict *clone = dict_clone(dct, NULL); CU_ASSERT_PTR_NOT_NULL(clone); CU_ASSERT_TRUE(dict_verify(clone)); CU_ASSERT_EQUAL(dict_count(clone), nkeys); for (unsigned i = 0; i < nkeys; ++i) { test_search(clone, itor, keys[i].key, keys[i].value); } for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_TRUE(dict_remove(clone, keys[i].key)); } dict_free(clone); } for (unsigned i = 0; i < nkeys; ++i) test_search(dct, itor, keys[i].key, keys[i].value); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_FALSE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_EQUAL(*datum_location, keys[i].value); CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_PTR_NOT_NULL(itor); char *last_key = NULL; unsigned n = 0; for (dict_itor_first(itor); dict_itor_valid(itor); dict_itor_next(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); CU_ASSERT_PTR_NOT_NULL(*dict_itor_data(itor)); char *key = dict_itor_key(itor); bool key_matched = false; for (unsigned i = 0; i < nkeys; ++i) { if (keys[i].key == key) { CU_ASSERT_EQUAL(*dict_itor_data(itor), keys[i].value); key_matched = true; break; } } CU_ASSERT_TRUE(key_matched); if (dct->_vtable->insert != (dict_insert_func)hashtable_insert && dct->_vtable->insert != (dict_insert_func)hashtable2_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) < 0); } last_key = dict_itor_key(itor); } ++n; } CU_ASSERT_EQUAL(n, nkeys); last_key = NULL; n = 0; for (dict_itor_last(itor); dict_itor_valid(itor); dict_itor_prev(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); CU_ASSERT_PTR_NOT_NULL(*dict_itor_data(itor)); char *key = dict_itor_key(itor); bool key_matched = false; for (unsigned i = 0; i < nkeys; ++i) { if (keys[i].key == key) { CU_ASSERT_EQUAL(*dict_itor_data(itor), keys[i].value); key_matched = true; break; } } CU_ASSERT_TRUE(key_matched); if (dct->_vtable->insert != (dict_insert_func)hashtable_insert && dct->_vtable->insert != (dict_insert_func)hashtable2_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) > 0); } last_key = dict_itor_key(itor); } ++n; } CU_ASSERT_EQUAL(n, nkeys); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_FALSE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NOT_NULL(*datum_location); *datum_location = keys[i].alt; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) test_search(dct, itor, keys[i].key, keys[i].alt); for (unsigned i = 0; i < nkeys; ++i) { test_search(dct, itor, keys[i].key, keys[i].alt); CU_ASSERT_TRUE(dict_remove(dct, keys[i].key)); CU_ASSERT_TRUE(dict_verify(dct)); CU_ASSERT_EQUAL(dict_remove(dct, keys[i].key), false); for (unsigned j = 0; j <= i; ++j) { test_search(dct, itor, keys[j].key, NULL); } for (unsigned j = i + 1; j < nkeys; ++j) { test_search(dct, itor, keys[j].key, keys[j].alt); } } for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_TRUE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NULL(*datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_clear(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_TRUE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NULL(*datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } test_closest_lookup(dct, cl_infos, n_cl_infos); dict_itor_free(itor); CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_free(dct), nkeys); }
void test_basic(dict *dct, const struct key_info *keys, const unsigned nkeys) { CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_TRUE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j <= i; ++j) CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), keys[j].value); for (unsigned j = i + 1; j < nkeys; ++j) CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), NULL); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); if (dct->_vtable->insert == (dict_insert_func)hashtable_insert) { /* Verify that hashtable_resize works as expected. */ dict *clone = dict_clone(dct, NULL); CU_ASSERT_TRUE(dict_verify(dct)); CU_ASSERT_TRUE(hashtable_resize(dict_private(clone), 3)); CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j < nkeys; ++j) CU_ASSERT_EQUAL(dict_search(clone, keys[j].key), keys[j].value); dict_free(clone); } if (dct->_vtable->clone) { dict *clone = dict_clone(dct, NULL); CU_ASSERT_PTR_NOT_NULL(clone); CU_ASSERT_TRUE(dict_verify(clone)); CU_ASSERT_EQUAL(dict_count(clone), nkeys); for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_EQUAL(dict_search(clone, keys[i].key), keys[i].value); } for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_TRUE(dict_remove(clone, keys[i].key)); } dict_free(clone); } for (unsigned i = 0; i < nkeys; ++i) CU_ASSERT_EQUAL(dict_search(dct, keys[i].key), keys[i].value); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_FALSE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_EQUAL(*datum_location, keys[i].value); CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); dict_itor *itor = dict_itor_new(dct); CU_ASSERT_PTR_NOT_NULL(itor); char *last_key = NULL; unsigned n = 0; for (dict_itor_first(itor); dict_itor_valid(itor); dict_itor_next(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); ++n; if (dct->_vtable->insert != (dict_insert_func)hashtable_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) < 0); } last_key = dict_itor_key(itor); } } CU_ASSERT_EQUAL(n, nkeys); last_key = NULL; n = 0; for (dict_itor_last(itor); dict_itor_valid(itor); dict_itor_prev(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); ++n; if (dct->_vtable->insert != (dict_insert_func)hashtable_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) > 0); } last_key = dict_itor_key(itor); } } CU_ASSERT_EQUAL(n, nkeys); dict_itor_free(itor); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_FALSE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].alt; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) CU_ASSERT_EQUAL(dict_search(dct, keys[i].key), keys[i].alt); for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_EQUAL(dict_search(dct, keys[i].key), keys[i].alt); CU_ASSERT_TRUE(dict_remove(dct, keys[i].key)); CU_ASSERT_TRUE(dict_verify(dct)); CU_ASSERT_EQUAL(dict_remove(dct, keys[i].key), false); for (unsigned j = 0; j <= i; ++j) { CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), NULL); } for (unsigned j = i + 1; j < nkeys; ++j) { CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), keys[j].alt); } } for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_TRUE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_clear(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_TRUE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_free(dct), nkeys); }
int main(int argc, char **argv) { bool shuffle_keys = true; if (argc != 3) { fprintf(stderr, "usage: %s [type] [input]\n", appname); fprintf(stderr, "type: specifies the dictionary type:\n"); fprintf(stderr, " h: height-balanced tree\n"); fprintf(stderr, " p: path-reduction tree\n"); fprintf(stderr, " r: red-black tree\n"); fprintf(stderr, " t: treap\n"); fprintf(stderr, " s: splay tree\n"); fprintf(stderr, " w: weight-balanced tree\n"); fprintf(stderr, " S: skiplist\n"); fprintf(stderr, " H: hashtable\n"); fprintf(stderr, " 2: hashtable 2\n"); fprintf(stderr, "input: text file consisting of newline-separated keys\n"); exit(EXIT_FAILURE); } srand(0xdeadbeef); dict_malloc_func = xmalloc; const char type = argv[1][0]; const char *container_name = NULL; dict *dct = create_dictionary(type, &container_name); if (!dct) quit("can't create container"); ASSERT(dict_verify(dct)); ASSERT(comp_count == 0); ASSERT(hash_count == 0); const size_t malloced_save = malloced; FILE *fp = fopen(argv[2], "r"); if (fp == NULL) quit("cant open file '%s': %s", argv[2], strerror(errno)); size_t nwords = 0; char buf[512]; while (fgets(buf, sizeof(buf), fp)) ++nwords; if (!nwords) quit("nothing read from file"); char **words = xmalloc(sizeof(*words) * nwords); rewind(fp); size_t words_read = 0; while (words_read < nwords && fgets(buf, sizeof(buf), fp)) { strtok(buf, "\n"); words[words_read++] = xstrdup(buf); } fclose(fp); if (words_read < nwords) quit("Only read %zu/%zu words!", words_read, nwords); printf("Loaded %zu keys from %s.\n", nwords, argv[2]); malloced = malloced_save; size_t total_comp = 0, total_hash = 0, total_rotations = 0; struct rusage start, end; struct timeval total = { 0, 0 }; timer_start(&start); for (unsigned i = 0; i < nwords; i++) { dict_insert_result result = dict_insert(dct, words[i]); if (!result.inserted) quit("insert #%d failed for '%s'", i, words[i]); ASSERT(result.datum_ptr != NULL); ASSERT(*result.datum_ptr == NULL); *result.datum_ptr = words[i]; } timer_end(&start, &end, &total); printf(" %s container: %.02fkB\n", container_name, malloced_save * 1e-3); printf(" %s memory: %.02fkB\n", container_name, malloced * 1e-3); printf(" %s insert: %6.03fs %9zu cmp (%.02f/insert)", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, comp_count / (double) nwords); if (hash_count) printf(" %9zu hash", hash_count); printf("\n"); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; if (dict_is_sorted(dct) && type != 'S') { tree_base *tree = dict_private(dct); printf(" min path length: %zu\n", tree_min_path_length(tree)); printf(" max path length: %zu\n", tree_max_path_length(tree)); printf(" tot path length: %zu\n", tree_total_path_length(tree)); printf("insert rotations: %zu\n", tree->rotation_count); total_rotations += tree->rotation_count; tree->rotation_count = 0; } else if (type == 'S') { size_t counts[16] = { 0 }; size_t num_counts = skiplist_link_count_histogram(dict_private(dct), counts, sizeof(counts) / sizeof(counts[0])); size_t count_sum = 0; for (size_t i = 0; i <= num_counts; ++i) { printf("skiplist %zu-node(s): %zu\n", i, counts[i]); count_sum += counts[i]; } ASSERT(count_sum == nwords); } ASSERT(dict_verify(dct)); comp_count = hash_count = 0; /* Ignore comparisons/hashes incurred by dict_verify() */ size_t n = dict_count(dct); if (n != nwords) quit("bad count (%u - should be %u)!", n, nwords); dict_itor *itor = dict_itor_new(dct); timer_start(&start); n = 0; ASSERT(dict_itor_first(itor)); do { ASSERT(dict_itor_valid(itor)); ASSERT(dict_itor_key(itor) == *dict_itor_datum(itor)); ++n; } while (dict_itor_next(itor)); timer_end(&start, &end, &total); printf(" %s fwd iterate: %6.03fs\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6); if (n != nwords) warn("Fwd iteration returned %u items - should be %u", n, nwords); ASSERT(dict_verify(dct)); comp_count = hash_count = 0; /* Ignore comparisons/hashes incurred by dict_verify() */ timer_start(&start); n = 0; ASSERT(dict_itor_last(itor)); do { ASSERT(dict_itor_valid(itor)); ASSERT(dict_itor_key(itor) == *dict_itor_datum(itor)); ++n; } while (dict_itor_prev(itor)); timer_end(&start, &end, &total); printf(" %s rev iterate: %6.03fs\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6); if (n != nwords) warn("Rev iteration returned %u items - should be %u", n, nwords); dict_itor_free(itor); if (shuffle_keys) shuffle(words, nwords); ASSERT(dict_verify(dct)); comp_count = hash_count = 0; /* Ignore comparisons/hashes incurred by dict_verify() */ timer_start(&start); for (unsigned i = 0; i < nwords; i++) { void **p = dict_search(dct, words[i]); if (!p) quit("lookup failed for '%s'", buf); if (*p != words[i]) quit("bad data for '%s', got '%s' instead", words[i], *(char **)p); } timer_end(&start, &end, &total); printf(" %s good search: %6.03fs %9zu cmp (%.02f/search)", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, comp_count / (double) nwords); if (hash_count) printf(" %9zu hash", hash_count); printf("\n"); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; if (type != 'H' && type != '2' && type != 'S') { tree_base *tree = dict_private(dct); printf("search rotations: %zu\n", tree->rotation_count); total_rotations += tree->rotation_count; tree->rotation_count = 0; } ASSERT(dict_verify(dct)); comp_count = hash_count = 0; /* Ignore comparisons/hashes incurred by dict_verify() */ timer_start(&start); for (unsigned i = 0; i < nwords; i++) { unsigned rv = dict_rand() % strlen(words[i]); words[i][rv]++; dict_search(dct, words[i]); words[i][rv]--; } timer_end(&start, &end, &total); printf(" %s bad search: %6.03fs %9zu cmp (%.02f/search)", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, comp_count / (double) nwords); if (hash_count) printf(" %9zu hash", hash_count); printf("\n"); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; ASSERT(dict_verify(dct)); comp_count = hash_count = 0; /* Ignore comparisons/hashes incurred by dict_verify() */ if (shuffle_keys) shuffle(words, nwords); timer_start(&start); for (unsigned i = 0; i < nwords; i++) { dict_remove_result result = dict_remove(dct, words[i]); if (!result.removed) quit("removing #%d '%s' failed!\n", i, words[i]); ASSERT(result.key == words[i]); ASSERT(result.datum == words[i]); } timer_end(&start, &end, &total); printf(" %s remove: %6.03fs %9zu cmp (%.2f/remove)", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, comp_count / (double)nwords); if (hash_count) printf(" %9zu hash", hash_count); printf("\n"); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; if (type != 'H' && type != '2' && type != 'S') { tree_base *tree = dict_private(dct); printf("remove rotations: %zu\n", tree->rotation_count); total_rotations += tree->rotation_count; tree->rotation_count = 0; } ASSERT(dict_verify(dct)); comp_count = hash_count = 0; /* Ignore comparisons/hashes incurred by dict_verify() */ if ((n = dict_count(dct)) != 0) quit("error - count not zero (%u)!", n); dict_free(dct, key_str_free); printf(" %s total: %6.03fs %9zu cmp", container_name, (total.tv_sec * 1000000 + total.tv_usec) * 1e-6, total_comp); if (total_hash) printf(" %9zu hash", total_hash); printf("\n"); if (type != 'H' && type != '2' && type != 'S') { printf(" total rotations: %zu\n", total_rotations); } FREE(words); exit(EXIT_SUCCESS); }
int main(void) { char *option = NULL, *word = NULL, *def = NULL, *filename = NULL; bool exit = false; dict_t dict = NULL,copy = NULL; dict = dict_empty(); do { option = print_menu(); switch (*option) { case ADD: printf("\tPlease enter the word to add to the dict: "); word = readline_from_stdin(); if (!dict_exists(dict, word)) { printf("\tPlease enter the definition: "); def = readline_from_stdin(); dict_add(dict,word,def); printf("\t-> The word and definition were added.\n"); free(def); def = NULL; } else { printf("\t-> The word %s already exists.\n", word); } assert(dict_exists(dict,word)); free(word); word = NULL; break; case COPY: copy = dict_copy(dict); printf("\t-> The dictionary was duplicated. Showing the duplicated dict:\n"); printf("{\n"); dict_dump(copy, stdout); printf("\n}\n"); copy = dict_destroy(copy); break; case DELETE: printf("\tPlease enter the word to delete from the dict: "); word = readline_from_stdin(); if(dict_exists(dict,word)) { dict = dict_remove(dict,word); printf("\t-> The word was successfully removed.\n"); } else { printf("\t-> The word %s does not exist.\n", word); } assert(!dict_exists(dict, word)); free(word); word = NULL; break; case DUMP: printf("\tPlease enter the filename to dump the dict to: "); filename = readline_from_stdin(); dict_to_file(dict,filename); printf("\t-> The dictionary was successfully dumped.\n"); free(filename); filename = NULL; break; case EMPTY: dict = dict_destroy(dict); dict = dict_empty(); printf("\t-> The dictionary was successfully emptied.\n"); break; case EXIT: printf("\t-> Exiting.\n"); exit = true; break; case LOAD: printf("\tPlease enter the filename to load the dict from: "); filename = readline_from_stdin(); copy = dict_from_file(filename); if (copy == NULL) { printf("Can not load dict from filename %s\n", filename); } else { dict = dict_destroy(dict); dict = copy; printf("\t-> The dictionary was successfully loaded.\n"); } free(filename); filename = NULL; break; case SEARCH: printf("\tPlease enter the word to search in the dict: "); word = readline_from_stdin(); if(dict_exists(dict,word)) { def = dict_search(dict,word); printf("\t-> The definition for \"%s\" is \"%s\".\n", word, def); free(def); def = NULL; } else { printf("\t-> The word \"%s\" does not exist in the dict.\n", word); } free(word); word = NULL; break; case SHOW: printf("{\n"); dict_dump(dict, stdout); printf("\n}\n"); break; case SIZE: printf("\t-> The size is %u.\n", dict_length(dict)); break; default: printf("\n\"%c\" is invalid. Please choose a valid option.\n\n", *option); } free(option); option = NULL; } while (!exit); dict = dict_destroy(dict); return (0); }
int main(int argc, char **argv) { if (argc != 3) { fprintf(stderr, "usage: %s [type] [input]\n", appname); fprintf(stderr, "type: specifies the dictionary type:\n"); fprintf(stderr, " h: height-balanced tree\n"); fprintf(stderr, " p: path-reduction tree\n"); fprintf(stderr, " r: red-black tree\n"); fprintf(stderr, " t: treap\n"); fprintf(stderr, " s: splay tree\n"); fprintf(stderr, " w: weight-balanced tree\n"); fprintf(stderr, " S: skiplist\n"); fprintf(stderr, " H: hashtable\n"); fprintf(stderr, " 2: hashtable 2\n"); fprintf(stderr, "input: text file consisting of newline-separated keys\n"); exit(EXIT_FAILURE); } srand(0xdeadbeef); dict_malloc_func = xmalloc; const char type = argv[1][0]; const char *container_name = NULL; dict *dct = create_dictionary(type, &container_name); if (!dct) quit("can't create container"); ASSERT(dict_verify(dct)); const size_t malloced_save = malloced; FILE *fp = fopen(argv[2], "r"); if (fp == NULL) quit("cant open file '%s': %s", argv[2], strerror(errno)); unsigned nwords = 0; char buf[512]; while (fgets(buf, sizeof(buf), fp)) ++nwords; if (!nwords) quit("nothing read from file"); char **words = xmalloc(sizeof(*words) * nwords); rewind(fp); for (unsigned i = 0; i < nwords && fgets(buf, sizeof(buf), fp); i++) { strtok(buf, "\n"); words[i] = xstrdup(buf); } fclose(fp); malloced = malloced_save; size_t total_comp = 0, total_hash = 0, total_rotations = 0; struct rusage start, end; struct timeval total = { 0, 0 }; timer_start(&start); for (unsigned i = 0; i < nwords; i++) { bool inserted = false; void **datum_location = dict_insert(dct, words[i], &inserted); if (!inserted) quit("insert #%d failed for '%s'", i, words[i]); ASSERT(datum_location != NULL); ASSERT(*datum_location == NULL); *datum_location = words[i]; } timer_end(&start, &end, &total); printf(" %s container: %.02fkB\n", container_name, malloced_save * 1e-3); printf(" %s memory: %.02fkB\n", container_name, malloced * 1e-3); printf(" %s insert: %6.03f s (%9zu cmp, %9zu hash)\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, hash_count); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; if (type != 'H' && type != '2' && type != 'S') { tree_base *tree = dict_private(dct); printf("insert rotations: %zu\n", tree->rotation_count); total_rotations += tree->rotation_count; tree->rotation_count = 0; } ASSERT(dict_verify(dct)); unsigned n = dict_count(dct); if (n != nwords) quit("bad count (%u - should be %u)!", n, nwords); dict_itor *itor = dict_itor_new(dct); timer_start(&start); n = 0; ASSERT(dict_itor_first(itor)); do { ASSERT(dict_itor_valid(itor)); ASSERT(dict_itor_key(itor) == *dict_itor_data(itor)); ++n; } while (dict_itor_next(itor)); timer_end(&start, &end, &total); printf(" %s fwd iterate: %6.03f s\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6); if (n != nwords) warn("Fwd iteration returned %u items - should be %u", n, nwords); timer_start(&start); n = 0; ASSERT(dict_itor_last(itor)); do { ASSERT(dict_itor_valid(itor)); ASSERT(dict_itor_key(itor) == *dict_itor_data(itor)); ++n; } while (dict_itor_prev(itor)); timer_end(&start, &end, &total); printf(" %s rev iterate: %6.03f s\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6); if (n != nwords) warn("Rev iteration returned %u items - should be %u", n, nwords); dict_itor_free(itor); /* shuffle(words, nwords); */ timer_start(&start); for (unsigned i = 0; i < nwords; i++) { char *p = dict_search(dct, words[i]); if (!p) quit("lookup failed for '%s'", buf); if (p != words[i]) quit("bad data for '%s', got '%s' instead", words[i], p); } timer_end(&start, &end, &total); printf(" %s good search: %6.03f s (%9zu cmp, %9zu hash)\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, hash_count); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; if (type != 'H' && type != '2' && type != 'S') { tree_base *tree = dict_private(dct); printf("search rotations: %zu\n", tree->rotation_count); total_rotations += tree->rotation_count; tree->rotation_count = 0; } timer_start(&start); for (unsigned i = 0; i < nwords; i++) { int rv = rand() % strlen(words[i]); words[i][rv]++; dict_search(dct, words[i]); words[i][rv]--; } timer_end(&start, &end, &total); printf(" %s bad search: %6.03f s (%9zu cmp, %9zu hash)\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, hash_count); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; /* shuffle(words, nwords); */ timer_start(&start); for (unsigned i = 0; i < nwords; i++) { if (!dict_remove(dct, words[i])) quit("removing #%d '%s' failed!\n", i, words[i]); } timer_end(&start, &end, &total); printf(" %s remove: %6.03f s (%9zu cmp, %9zu hash)\n", container_name, (end.ru_utime.tv_sec * 1000000 + end.ru_utime.tv_usec) * 1e-6, comp_count, hash_count); total_comp += comp_count; comp_count = 0; total_hash += hash_count; hash_count = 0; if (type != 'H' && type != '2' && type != 'S') { tree_base *tree = dict_private(dct); printf("remove rotations: %zu\n", tree->rotation_count); total_rotations += tree->rotation_count; tree->rotation_count = 0; } ASSERT(dict_verify(dct)); if ((n = dict_count(dct)) != 0) quit("error - count not zero (%u)!", n); dict_free(dct); printf(" %s total: %6.03f s (%9zu cmp, %9zu hash)\n", container_name, (total.tv_sec * 1000000 + total.tv_usec) * 1e-6, total_comp, total_hash); if (type != 'H' && type != '2' && type != 'S') { printf(" total rotations: %zu\n", total_rotations); } FREE(words); exit(EXIT_SUCCESS); }
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 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; }
static void boxc_receiver(void *arg) { Boxc *conn = arg; Msg *msg, *mack; /* remove messages from socket until it is closed */ while (bb_status != BB_DEAD && conn->alive) { gwlist_consume(suspended); /* block here if suspended */ msg = read_from_box(conn); if (msg == NULL) { /* garbage/connection lost */ conn->alive = 0; break; } /* we don't accept new messages in shutdown phase */ if ((bb_status == BB_SHUTDOWN || bb_status == BB_DEAD) && msg_type(msg) == sms) { mack = msg_create(ack); uuid_copy(mack->ack.id, msg->sms.id); mack->ack.time = msg->sms.time; mack->ack.nack = ack_failed_tmp; msg_destroy(msg); send_msg(conn, mack); msg_destroy(mack); continue; } if (msg_type(msg) == sms && conn->is_wap == 0) { debug("bb.boxc", 0, "boxc_receiver: sms received"); /* deliver message to queue */ deliver_sms_to_queue(msg, conn); if (conn->routable == 0) { conn->routable = 1; /* wakeup the dequeue thread */ gwthread_wakeup(sms_dequeue_thread); } } else if (msg_type(msg) == wdp_datagram && conn->is_wap) { debug("bb.boxc", 0, "boxc_receiver: got wdp from wapbox"); /* XXX we should block these in SHUTDOWN phase too, but we need ack/nack msgs implemented first. */ gwlist_produce(conn->outgoing, msg); } else if (msg_type(msg) == sms && conn->is_wap) { debug("bb.boxc", 0, "boxc_receiver: got sms from wapbox"); /* should be a WAP push message, so tried it the same way */ deliver_sms_to_queue(msg, conn); if (conn->routable == 0) { conn->routable = 1; /* wakeup the dequeue thread */ gwthread_wakeup(sms_dequeue_thread); } } else { if (msg_type(msg) == heartbeat) { if (msg->heartbeat.load != conn->load) debug("bb.boxc", 0, "boxc_receiver: heartbeat with " "load value %ld received", msg->heartbeat.load); conn->load = msg->heartbeat.load; } else if (msg_type(msg) == ack) { if (msg->ack.nack == ack_failed_tmp) { Msg *orig; boxc_sent_pop(conn, msg, &orig); if (orig != NULL) /* retry this message */ gwlist_append(conn->retry, orig); } else { boxc_sent_pop(conn, msg, NULL); store_save(msg); } debug("bb.boxc", 0, "boxc_receiver: got ack"); } /* if this is an identification message from an smsbox instance */ else if (msg_type(msg) == admin && msg->admin.command == cmd_identify) { /* * any smsbox sends this command even if boxc_id is NULL, * but we will only consider real identified boxes */ if (msg->admin.boxc_id != NULL) { /* and add the boxc_id into conn for boxc_status() output */ if (conn->boxc_id != NULL) { dict_remove(smsbox_by_id, msg->admin.boxc_id); octstr_destroy(conn->boxc_id); } conn->boxc_id = msg->admin.boxc_id; msg->admin.boxc_id = NULL; /* add this identified smsbox to the dictionary */ /* XXX check for equal boxc_id in Dict, otherwise we overwrite it */ dict_put(smsbox_by_id, conn->boxc_id, conn); debug("bb.boxc", 0, "boxc_receiver: got boxc_id <%s> from <%s>", octstr_get_cstr(conn->boxc_id), octstr_get_cstr(conn->client_ip)); } conn->routable = 1; /* wakeup the dequeue thread */ gwthread_wakeup(sms_dequeue_thread); } else warning(0, "boxc_receiver: unknown msg received from <%s>, " "ignored", octstr_get_cstr(conn->client_ip)); msg_destroy(msg); } } }
/* * Updates the internal RADIUS mapping tables. Returns 1 if the * mapping has been processes and the PDU should be proxied to the * remote RADIUS server, otherwise if it is a duplicate returns 0. */ static int update_tables(RADIUS_PDU *pdu) { Octstr *client_ip, *msisdn; Octstr *type, *session_id; int ret = 0; Octstr *rm_item; client_ip = msisdn = type = session_id = NULL; /* only add if we have a Accounting-Request PDU */ if (pdu->type == 0x04) { /* check if we have a START or STOP event */ type = dict_get(pdu->attr, octstr_imm("Acct-Status-Type")); /* get the sesion id */ session_id = dict_get(pdu->attr, octstr_imm("Acct-Session-Id")); /* grep the needed data */ client_ip = dict_get(pdu->attr, octstr_imm("Framed-IP-Address")); msisdn = dict_get(pdu->attr, octstr_imm("Calling-Station-Id")); /* we can't add mapping without both components */ if (client_ip == NULL || msisdn == NULL) { warning(0, "RADIUS: NAS did either not send 'Framed-IP-Address' or/and " "'Calling-Station-Id', dropping mapping but will forward."); /* anyway forward the packet to remote RADIUS server */ return 1; } if (octstr_compare(type, octstr_imm("1")) == 0 && session_id && msisdn) { /* session START */ if (dict_get(radius_table, client_ip) == NULL && dict_get(session_table, session_id) == NULL) { Octstr *put_msisdn = octstr_duplicate(msisdn); Octstr *put_client_ip = octstr_duplicate(client_ip); Octstr *put_session_id = octstr_duplicate(session_id); Octstr *old_session_id, *old_client_ip; /* ok, this is a new session. If it contains an IP that is still * in the session/client tables then remove the old session from the * two tables session/client */ if ((old_session_id = dict_get(client_table, client_ip)) != NULL && (old_client_ip = dict_get(session_table, old_session_id)) != NULL && octstr_compare(old_session_id, session_id) != 0) { rm_item = dict_remove(client_table, client_ip); octstr_destroy(rm_item); rm_item = dict_remove(session_table, old_session_id); octstr_destroy(rm_item); octstr_destroy(old_session_id); octstr_destroy(old_client_ip); } /* insert both, new client IP and session to mapping tables */ dict_put(radius_table, client_ip, put_msisdn); dict_put(session_table, session_id, put_client_ip); dict_put(client_table, client_ip, put_session_id); info(0, "RADIUS: Mapping `%s <-> %s' for session id <%s> added.", octstr_get_cstr(client_ip), octstr_get_cstr(msisdn), octstr_get_cstr(session_id)); ret = 1; } else { warning(0, "RADIUS: Duplicate mapping `%s <-> %s' for session " "id <%s> received, ignoring.", octstr_get_cstr(client_ip), octstr_get_cstr(msisdn), octstr_get_cstr(session_id)); } } else if (octstr_compare(type, octstr_imm("2")) == 0) { /* session STOP */ Octstr *comp_client_ip; if ((msisdn = dict_get(radius_table, client_ip)) != NULL && (comp_client_ip = dict_get(session_table, session_id)) != NULL && octstr_compare(client_ip, comp_client_ip) == 0) { dict_remove(radius_table, client_ip); rm_item = dict_remove(client_table, client_ip); octstr_destroy(rm_item); dict_remove(session_table, session_id); info(0, "RADIUS: Mapping `%s <-> %s' for session id <%s> removed.", octstr_get_cstr(client_ip), octstr_get_cstr(msisdn), octstr_get_cstr(session_id)); octstr_destroy(msisdn); octstr_destroy(comp_client_ip); ret = 1; } else { warning(0, "RADIUS: Could not find mapping for `%s' session " "id <%s>, ignoring.", octstr_get_cstr(client_ip), octstr_get_cstr(session_id)); } } else { error(0, "RADIUS: unknown Acct-Status-Type `%s' received, ignoring.", octstr_get_cstr(type)); } } return ret; }
int main(int argc, char **argv) { char buf[512], *p, *ptr, *ptr2; int rv; dict *dct; if (argc != 2) quit("usage: %s [type]", appname); srand((unsigned)time(NULL)); dict_malloc_func = xmalloc; ++argv; switch (argv[0][0]) { case 'h': dct = hb_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'p': dct = pr_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'r': dct = rb_dict_new((dict_compare_func)strcmp, key_val_free); break; case 't': dct = tr_dict_new((dict_compare_func)strcmp, NULL, key_val_free); break; case 's': dct = sp_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'w': dct = wb_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'H': dct = hashtable_dict_new((dict_compare_func)strcmp, dict_str_hash, key_val_free, HSIZE); break; default: quit("type must be one of h, p, r, t, s, w, or H"); } if (!dct) quit("can't create container"); for (;;) { printf("> "); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) break; if ((p = strchr(buf, '\n')) != NULL) *p = 0; for (p = buf; isspace(*p); p++) /* void */; strcpy(buf, p); ptr2 = (ptr = strtok(buf, " ") ? strtok(NULL, " ") : NULL) ? strtok(NULL, " ") : NULL; if (*buf == 0) continue; if (strcmp(buf, "insert") == 0) { if (!ptr2) { printf("usage: insert <key> <data>\n"); continue; } void **datum_location; if (dict_insert(dct, xstrdup(ptr), &datum_location)) { *datum_location = xstrdup(ptr2); printf("inserted '%s': '%s'\n", ptr, *datum_location); } else { printf("key '%s' already in dict: '%s'\n", ptr, *datum_location); } } else if (strcmp(buf, "search") == 0) { if (ptr2) { printf("usage: search <key>\n"); continue; } ptr2 = dict_search(dct, ptr); if (ptr2) printf("found '%s': '%s'\n", ptr, ptr2); else printf("key '%s' not in dict!\n", ptr); } else if (strcmp(buf, "remove") == 0) { if (!ptr || ptr2) { printf("usage: remove <key>\n"); continue; } rv = dict_remove(dct, ptr); if (rv == 0) printf("removed '%s' from dict\n", ptr); else printf("key '%s' not in dict!\n", ptr); } else if (strcmp(buf, "show") == 0) { if (ptr) { printf("usage: show\n"); continue; } dict_itor *itor = dict_itor_new(dct); dict_itor_first(itor); for (; dict_itor_valid(itor); dict_itor_next(itor)) printf("'%s': '%s'\n", (char *)dict_itor_key(itor), (char *)dict_itor_data(itor)); dict_itor_free(itor); } else if (strcmp(buf, "reverse") == 0) { if (ptr) { printf("usage: reverse\n"); continue; } dict_itor *itor = dict_itor_new(dct); dict_itor_last(itor); for (; dict_itor_valid(itor); dict_itor_prev(itor)) printf("'%s': '%s'\n", (char *)dict_itor_key(itor), (char *)dict_itor_data(itor)); dict_itor_free(itor); } else if (strcmp(buf, "clear") == 0) { if (ptr) { printf("usage: clear\n"); continue; } dict_clear(dct); } else if (strcmp(buf, "count") == 0) { if (ptr) { printf("usage: count\n"); continue; } printf("count = %zu\n", dict_count(dct)); } else if (strcmp(buf, "quit") == 0) { break; } else { printf("Usage summary:\n"); printf(" insert <key> <data>\n"); printf(" search <key>\n"); printf(" remove <key>\n"); printf(" clear\n"); printf(" count\n"); printf(" show\n"); printf(" reverse\n"); printf(" quit\n"); } } dict_free(dct); exit(0); }
static void del_track_user(const char *nick) { dict_remove(track_db, nick); }