static void remove_storage_ref_info(struct mailengine * engine, struct mailstorage * storage) { chashdatum key; chashdatum data; struct storage_ref_info * ref_info; key.data = &storage; key.len = sizeof(storage); #ifdef LIBETPAN_REENTRANT pthread_mutex_lock(&engine->storage_hash_lock); #endif chash_get(engine->storage_hash, &key, &data); ref_info = data.data; if (ref_info != NULL) { storage_ref_info_free(ref_info); chash_delete(engine->storage_hash, &key, NULL); } #ifdef LIBETPAN_REENTRANT pthread_mutex_unlock(&engine->storage_hash_lock); #endif }
void mailprivacy_smime_encryption_id_list_clear(struct mailprivacy * privacy, mailmessage * msg) { clist * encryption_id_list; clistiter * iter; LOCK(); encryption_id_list = get_list(privacy, msg); if (encryption_id_list != NULL) { chashdatum key; for(iter = clist_begin(encryption_id_list) ; iter != NULL ; iter = clist_next(iter)) { char * str; str = clist_content(iter); free(str); } clist_free(encryption_id_list); key.data = &msg; key.len = sizeof(msg); chash_delete(encryption_id_hash, &key, NULL); if (chash_count(encryption_id_hash) == 0) { chash_free(encryption_id_hash); encryption_id_hash = NULL; } } UNLOCK(); }
static void unregister_message(struct mailprivacy * privacy, mailmessage * msg) { chashdatum key; key.data = &msg; key.len = sizeof(msg); chash_delete(privacy->msg_ref, &key, NULL); }
static void unregister_mime(struct mailprivacy * privacy, struct mailmime * mime) { chashdatum key; key.data = &mime; key.len = sizeof(mime); chash_delete(privacy->mime_ref, &key, NULL); }
static void folder_message_remove(struct folder_ref_info * ref_info, mailmessage * msg) { chashdatum key; struct message_ref_elt * msg_ref; if (msg->msg_uid != NULL) { key.data = msg->msg_uid; key.len = strlen(msg->msg_uid); chash_delete(ref_info->uid_hash, &key, NULL); } msg_ref = folder_info_get_msg_ref(ref_info, msg); message_ref_elt_free(msg_ref); key.data = &msg; key.len = sizeof(msg); chash_delete(ref_info->msg_hash, &key, NULL); }
static void unregister_result_mmapstr(struct mailprivacy * privacy, char * str) { chashdatum key; mmap_string_unref(str); key.data = &str; key.len = sizeof(str); chash_delete(privacy->mmapstr, &key, NULL); }
void stem_cache_delete(struct stem_cache *cache) { unsigned int i; for (i = 0; i < cache->size; i++) { free(cache->arr[i]->src); free(cache->arr[i]->dst); free(cache->arr[i]); } chash_delete(cache->lookup); free(cache->arr); free(cache); }
int mmap_string_unref(char * str) { MMAPString * string; chash * ht; chashdatum key; chashdatum data; int r; if (str == NULL) return -1; MUTEX_LOCK(&mmapstring_lock); ht = mmapstring_hashtable; if (ht == NULL) { MUTEX_UNLOCK(&mmapstring_lock); return -1; } key.data = &str; key.len = sizeof(str); r = chash_get(ht, &key, &data); if (r < 0) string = NULL; else string = data.data; if (string != NULL) { chash_delete(ht, &key, NULL); if (chash_count(ht) == 0) { chash_free(ht); mmapstring_hashtable = NULL; } } MUTEX_UNLOCK(&mmapstring_lock); if (string != NULL) { mmap_string_free(string); return 0; } else return -1; }
static void delete_nntp(Folder *folder, newsnntp *nntp) { chashdatum key; key.data = &folder; key.len = sizeof(folder); chash_delete(session_hash, &key, NULL); key.data = &nntp; key.len = sizeof(nntp); if (nntp && nntp->nntp_stream) { /* we don't want libetpan to logout */ mailstream_close(nntp->nntp_stream); nntp->nntp_stream = NULL; } debug_print("removing newsnntp %p\n", nntp); newsnntp_free(nntp); }
void mail_flags_store_clear(struct mail_flags_store * flags_store) { unsigned int i; for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) { chashdatum key; mailmessage * msg; msg = carray_get(flags_store->fls_tab, i); key.data = &msg->msg_index; key.len = sizeof(msg->msg_index); chash_delete(flags_store->fls_hash, &key, NULL); mailmessage_free(msg); } carray_set_size(flags_store->fls_tab, 0); }
static int folder_message_add(struct folder_ref_info * ref_info, mailmessage * msg) { chashdatum key; chashdatum data; struct message_ref_elt * msg_ref; int r; msg_ref = message_ref_elt_new(ref_info->folder, msg); if (msg_ref == NULL) goto err; key.data = &msg; key.len = sizeof(msg); data.data = msg_ref; data.len = 0; r = chash_set(ref_info->msg_hash, &key, &data, NULL); if (r < 0) goto free_msg_ref; if (msg->msg_uid != NULL) { key.data = msg->msg_uid; key.len = strlen(msg->msg_uid); data.data = msg; data.len = 0; r = chash_set(ref_info->uid_hash, &key, &data, NULL); if (r < 0) goto remove_msg_ref; } return MAIL_NO_ERROR; remove_msg_ref: key.data = &msg; key.len = sizeof(msg); chash_delete(ref_info->msg_hash, &key, NULL); free_msg_ref: message_ref_elt_free(msg_ref); err: return MAIL_ERROR_MEMORY; }
/* WARNING: This does not sync!!! */ void remove_element(cache_t *c, struct ce_t *o, int locked) { if(!o) return; if(o->dirty) panic(PANIC_NOSYNC, "tried to remove non-sync'd element"); if(!locked) rwlock_acquire(c->rwl, RWL_WRITER); if(o->dirty) set_dirty(c, o, 0); assert(c->count); sub_atomic(&c->count, 1); ll_remove(&c->primary_ll, o->list_node); if(c->hash) chash_delete(c->hash, o->id, o->key); if(o->data) kfree(o->data); rwlock_destroy(o->rwl); kfree(o); if(!locked) rwlock_release(c->rwl, RWL_WRITER); }
void nntp_done(Folder * folder) { struct etpan_thread * thread; chashdatum key; chashdatum value; int r; key.data = &folder; key.len = sizeof(folder); r = chash_get(nntp_hash, &key, &value); if (r < 0) return; thread = value.data; etpan_thread_unbind(thread); chash_delete(nntp_hash, &key, NULL); debug_print("remove thread"); }
int mailmh_folder_remove_message(struct mailmh_folder * folder, uint32_t indx) { char * filename; struct mailmh_msg_info * msg_info; int res; int r; chashdatum key; chashdatum data; r = mailmh_folder_get_message_filename(folder, indx, &filename); if (filename == NULL) { res = r; goto err; } if (unlink(filename) == -1) { res = MAILMH_ERROR_FILE; goto free; } key.data = &indx; key.len = sizeof(indx); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r == 0) { msg_info = data.data; carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); chash_delete(folder->fl_msgs_hash, &key, NULL); } return MAILMH_NO_ERROR; free: free(filename); err: return res; }
static void storage_folder_remove_ref(struct storage_ref_info * ref_info, struct mailfolder * folder) { struct folder_ref_info * folder_ref; chashdatum key; chashdatum value; int r; key.data = &folder; key.len = sizeof(folder); r = chash_get(ref_info->folder_ref_info, &key, &value); if (r < 0) return; folder_ref = value.data; if (folder_ref == NULL) return; folder_ref_info_free(folder_ref); chash_delete(ref_info->folder_ref_info, &key, &value); }
int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) { struct mailmh_folder * parent; chashdatum key; chashdatum data; int r; parent = folder->fl_parent; key.data = folder->fl_filename; key.len = strlen(folder->fl_filename); r = chash_get(parent->fl_subfolders_hash, &key, &data); if (r < 0) return MAILMH_ERROR_FOLDER; chash_delete(parent->fl_subfolders_hash, &key, NULL); carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); mailmh_folder_free(folder); return MAILMH_NO_ERROR; }
int mailmh_folder_update(struct mailmh_folder * folder) { DIR * d; struct dirent * ent; struct stat buf; char * mh_seq; char filename[PATH_MAX]; int res; int r; uint32_t max_index; unsigned int i; if (stat(folder->fl_filename, &buf) == -1) { res = MAILMH_ERROR_FOLDER; goto err; } if (folder->fl_mtime == buf.st_mtime) { res = MAILMH_NO_ERROR; goto err; } folder->fl_mtime = buf.st_mtime; d = opendir(folder->fl_filename); if (d == NULL) { res = MAILMH_ERROR_FOLDER; goto err; } max_index = 0; /* clear the message list */ for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { struct mailmh_msg_info * msg_info; chashdatum key; msg_info = carray_get(folder->fl_msgs_tab, i); if (msg_info == NULL) continue; key.data = &msg_info->msg_index; key.len = sizeof(msg_info->msg_index); chash_delete(folder->fl_msgs_hash, &key, NULL); mailmh_msg_info_free(msg_info); } carray_set_size(folder->fl_msgs_tab, 0); do { uint32_t indx; ent = readdir(d); if (ent != NULL) { snprintf(filename, PATH_MAX, "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); if (stat(filename, &buf) == -1) continue; if (S_ISREG(buf.st_mode)) { indx = strtoul(ent->d_name, NULL, 10); if (indx != 0) { struct mailmh_msg_info * msg_info; unsigned int array_index; chashdatum key; chashdatum data; msg_info = mailmh_msg_info_new(indx, buf.st_size, buf.st_mtime); if (msg_info == NULL) { res = MAILMH_ERROR_MEMORY; goto closedir; } r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); if (r < 0) { mailmh_msg_info_free(msg_info); res = MAILMH_ERROR_MEMORY; goto closedir; } msg_info->msg_array_index = array_index; if (indx > max_index) max_index = indx; key.data = &msg_info->msg_index; key.len = sizeof(msg_info->msg_index); data.data = msg_info; data.len = 0; r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); if (r < 0) { carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); mailmh_msg_info_free(msg_info); res = MAILMH_ERROR_MEMORY; goto closedir; } } } else if (S_ISDIR(buf.st_mode)) { struct mailmh_folder * subfolder; unsigned int array_index; chashdatum key; chashdatum data; if (ent->d_name[0] == '.') { if (ent->d_name[1] == 0) continue; if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) continue; } key.data = ent->d_name; key.len = strlen(ent->d_name); r = chash_get(folder->fl_subfolders_hash, &key, &data); if (r < 0) { subfolder = mailmh_folder_new(folder, ent->d_name); if (subfolder == NULL) { res = MAILMH_ERROR_MEMORY; goto closedir; } r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); if (r < 0) { mailmh_folder_free(subfolder); res = MAILMH_ERROR_MEMORY; goto closedir; } subfolder->fl_array_index = array_index; key.data = subfolder->fl_filename; key.len = strlen(subfolder->fl_filename); data.data = subfolder; data.len = 0; r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); if (r < 0) { carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); mailmh_folder_free(subfolder); res = MAILMH_ERROR_MEMORY; goto closedir; } } } } } while (ent != NULL); folder->fl_max_index = max_index; mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); if (mh_seq == NULL) { res = MAILMH_ERROR_MEMORY; goto closedir; } strcpy(mh_seq, folder->fl_filename); strcat(mh_seq, MAIL_DIR_SEPARATOR_S); strcat(mh_seq, ".mh_sequences"); if (stat(mh_seq, &buf) == -1) { int fd; fd = creat(mh_seq, S_IRUSR | S_IWUSR); if (fd != -1) close(fd); } free(mh_seq); closedir(d); return MAILMH_NO_ERROR; closedir: closedir(d); err: return res; }
int test_file(FILE *fp, int argc, char **argv) { char buf[65535 + 1]; char *pos; unsigned int strategy = 0; /* what bucketing strategy we're using */ void *ptr = NULL; unsigned int bucketsize = 0; struct params params = {0}; struct chash *hash = NULL; char name[256]; if (!parse_params(argc, argv, ¶ms)) { fprintf(stderr, "failed to parse params\n"); return 0; } while (fgets((char *) buf, 65535, fp)) { str_rtrim(buf); pos = (char *) str_ltrim(buf); if (!str_casecmp(pos, "new")) { /* creating a new bucket */ unsigned int size = -1; if (ptr) { chash_delete(hash); free(ptr); } /* read parameters */ if ((fscanf(fp, "%255s %u %u", name, &strategy, &size) == 3) && (size <= 65535) && (bucketsize = size) && (ptr = malloc(size)) && (hash = chash_ptr_new(1, 2.0, /* some fn pointer casting dodginess */ (unsigned int (*)(const void *)) str_len, (int (*)(const void *, const void *)) str_cmp)) && (bucket_new(ptr, bucketsize, strategy))) { /* succeeded, do nothing */ if (params.verbose) { printf("%s: new bucket with size %u strategy %u\n", name, size, strategy); } } else { fprintf(stderr, "%s: failed to create bucket\n", name); return 0; } } else if (!str_casecmp(pos, "add")) { /* adding a term to the bucket */ void *ret; unsigned int veclen, succeed, len; int toobig; if (!ptr) { return 0; } /* read parameters */ if ((fscanf(fp, "%65535s %u %u", buf, &veclen, &succeed) == 3) && (veclen <= 65535)) { len = str_len(buf); if ((((ret = bucket_alloc(ptr, bucketsize, strategy, buf, len, veclen, &toobig, NULL)) && succeed) || (!ret && !succeed))) { /* do nothing */ if (params.verbose) { printf("%s: added term '%s'\n", name, buf); } } else if (succeed) { fprintf(stderr, "%s: failed to add '%s' to bucket\n", name, buf); return 0; } else if (!succeed) { fprintf(stderr, "%s: add '%s' succeeded but shouldn't " "have\n", name, buf); return 0; } } else { fprintf(stderr, "%s: failed to add\n", name); return 0; } } else if (!str_casecmp(pos, "ls")) { /* matching stuff in the bucket */ unsigned int numterms, i, len, veclen, veclen2, state; void *addr; struct chash *tmphash; const char *term; void **tmpptr, *tmp; if (!ptr) { return 0; } if (!(tmphash = chash_ptr_new(1, 2.0, /* some fn pointer casting dodginess */ (unsigned int (*)(const void *)) str_len, (int (*)(const void *, const void *)) str_cmp))) { fprintf(stderr, "%s: failed to init hashtable\n", name); return 0; } /* first, fill hashtable with all terms from bucket */ state = 0; while ((term = bucket_next_term(ptr, bucketsize, strategy, &state, &len, &addr, &veclen))) { if (!((term = str_ndup(term, len)) && (chash_ptr_ptr_insert(tmphash, term, (void*) term) == CHASH_OK))) { fprintf(stderr, "%s: failed to init hashtable\n", name); return 0; } } /* now, take terms from file, comparing them with hashtable * entries */ if (fscanf(fp, "%u", &numterms)) { for (i = 0; i < numterms; i++) { if (fscanf(fp, "%65535s %u ", buf, &veclen)) { if (params.verbose) { printf("%s: ls checking %s\n", name, buf); } if ((addr = bucket_find(ptr, bucketsize, strategy, buf, str_len(buf), &veclen2, NULL)) /* remove it from hashtable */ && chash_ptr_ptr_find(tmphash, buf, &tmpptr) == CHASH_OK && chash_ptr_ptr_remove(tmphash, *tmpptr, &tmp) == CHASH_OK && (free(tmp), 1) && (veclen <= 65535) && (veclen2 == veclen) && fread(buf, veclen, 1, fp) && ((buf[veclen] = '\0'), 1) && (!params.verbose || printf("%s: ls check read '%s'\n", name, buf)) && !memcmp(buf, addr, veclen)) { /* do nothing */ } else { unsigned int j; fprintf(stderr, "%s: ls failed cmp '%s' with '", name, buf); for (j = 0; j < veclen; j++) { putc(((char *) addr)[j], stderr); } fprintf(stderr, "'\n"); return 0; } } else { fprintf(stderr, "%s: ls failed\n", name); return 0; } } if (chash_size(tmphash)) { fprintf(stderr, "%s: ls failed\n", name); return 0; } } else { fprintf(stderr, "%s: ls failed\n", name); return 0; } chash_delete(tmphash); if (params.verbose) { printf("%s: matched all (%u) entries\n", name, numterms); } } else if (!str_casecmp(pos, "set")) { /* setting the vector for a term in the bucket */ unsigned int veclen, reallen; void *addr; if (!ptr) { return 0; } /* read parameters */ if ((fscanf(fp, "%65535s %u ", buf, &veclen) == 2) && (veclen <= 65535)) { addr = bucket_find(ptr, bucketsize, strategy, buf, str_len(buf), &reallen, NULL); if (addr && (reallen == veclen) && fread(addr, 1, veclen, fp)) { /* do nothing */ if (params.verbose) { unsigned int j; printf("%s: set term '%s' to '", name, buf); for (j = 0; j < reallen; j++) { putc(((char *) addr)[j], stdout); } printf("'\n"); } } else { fprintf(stderr, "%s: failed to set!\n", name); return 0; } } else { fprintf(stderr, "%s: failed to set\n", name); return 0; } } else if (!str_casecmp(pos, "realloc")) { /* reallocating a term in the bucket */ unsigned int veclen, succeed; int toobig; if (!ptr) { return 0; } /* read parameters */ if ((fscanf(fp, "%65535s %u %u", buf, &veclen, &succeed) == 3) && (veclen <= 65535)) { if (!bucket_realloc(ptr, bucketsize, strategy, buf, str_len(buf), veclen, &toobig)) { fprintf(stderr, "%s: failed to realloc!\n", name); return 0; } } else { fprintf(stderr, "%s: failed to realloc\n", name); return 0; } if (params.verbose) { printf("%s: realloc'd term '%s'\n", name, buf); } } else if (!str_casecmp(pos, "rm")) { /* removing something from the bucket */ unsigned int succeed; if (!ptr) { return 0; } if (fscanf(fp, "%65535s %u", buf, &succeed) == 2) { if (succeed) { if (!(bucket_remove(ptr, bucketsize, strategy, buf, str_len(buf)))) { fprintf(stderr, "%s: failed to rm '%s'\n", name, buf); return 0; } else if (params.verbose) { printf("%s: rm term '%s'\n", name, buf); } } else if (succeed) { fprintf(stderr, "%s: failed to rm\n", name); return 0; } } else { fprintf(stderr, "%s: failed to rm\n", name); return 0; } } else if (!str_casecmp(pos, "print")) { /* printing out the bucket contents */ unsigned int state = 0, len, veclen; const char *term; char format[100]; void *addr; if (!ptr) { printf("can't print, no bucket\n"); } else { do { term = bucket_next_term(ptr, bucketsize, strategy, &state, &len, &addr, &veclen); } while (term && memcpy(buf, term, len) && ((buf[len] = '\0') || 1) && snprintf(format, 100, "%%.%us (%%u): '%%.%us' (%%u) " "(off %%u)\n", len, veclen) && printf(format, term, len, (char*) addr, veclen, ((char *) addr) - (char *) ptr)); if (!state) { printf("(empty)\n"); } printf("%u entries, %u data, %u string, %u overhead, %u free\n", bucket_entries(ptr, bucketsize, strategy), bucket_utilised(ptr, bucketsize, strategy), bucket_string(ptr, bucketsize, strategy), bucket_overhead(ptr, bucketsize, strategy), bucket_unused(ptr, bucketsize, strategy)); } } else if (!str_casecmp(pos, "match")) { unsigned int veclen, veclen2; void *addr; if (fscanf(fp, "%65535s %u ", buf, &veclen)) { if ((addr = bucket_find(ptr, bucketsize, strategy, buf, str_len(buf), &veclen2, NULL)) && (veclen <= 65535) && (veclen2 >= veclen) && (!params.verbose || printf("%s: match on '%s' ", name, buf)) && fread(buf, veclen, 1, fp) && !memcmp(buf, addr, veclen)) { if (params.verbose) { printf("content succeeded\n"); } } else { fprintf(stderr, "%s: match failed (%s vs %s)\n", name, buf, (char *) addr); return 0; } } else { fprintf(stderr, "%s: match failed\n", name); return 0; } } else if ((*pos != '#') && str_len(pos)) { fprintf(stderr, "%s: unknown command '%s'\n", name, pos); return 0; } } if (ptr) { chash_delete(hash); free(ptr); } return 1; }