void mailprivacy_unregister(struct mailprivacy * privacy, struct mailprivacy_protocol * protocol) { unsigned int i; for(i = 0 ; i < carray_count(privacy->protocols) ; i ++) { if (carray_get(privacy->protocols, i) == protocol) { carray_delete(privacy->protocols, i); return; } } }
int mail_flags_store_set(struct mail_flags_store * flags_store, mailmessage * msg) { chashdatum key; chashdatum value; unsigned int indx; int res; int r; mailmessage * new_msg; if (msg->msg_flags == NULL) { res = MAIL_NO_ERROR; goto err; } /* duplicate needed message info */ new_msg = mailmessage_build(msg); if (new_msg == NULL) { res = MAIL_ERROR_MEMORY; goto err; } key.data = &new_msg->msg_index; key.len = sizeof(new_msg->msg_index); r = chash_get(flags_store->fls_hash, &key, &value); if (r == 0) { mailmessage * old_msg; indx = * (unsigned int *) value.data; old_msg = carray_get(flags_store->fls_tab, indx); mailmessage_free(old_msg); } else { r = carray_set_size(flags_store->fls_tab, carray_count(flags_store->fls_tab) + 1); if (r != 0) { res = MAIL_ERROR_MEMORY; goto err; } indx = carray_count(flags_store->fls_tab) - 1; } carray_set(flags_store->fls_tab, indx, new_msg); value.data = &indx; value.len = sizeof(indx); r = chash_set(flags_store->fls_hash, &key, &value, NULL); if (r < 0) { carray_delete(flags_store->fls_tab, indx); res = MAIL_ERROR_MEMORY; goto free; } return MAIL_NO_ERROR; free: mailmessage_free(new_msg); err: return res; }
static int expunge_folder(mailsession * session) { int r; char key_value[PATH_MAX]; struct mail_cache_db * maildb; carray * msglist; unsigned int i; struct db_session_state_data * data; int res; chash * msg_table; MMAPString * mmapstr; data = get_data(session); flags_store_process(session); r = mail_cache_db_open_lock(data->db_filename, &maildb); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } r = db_get_message_list(maildb, &msglist); if (r != MAIL_NO_ERROR) { res = r; goto close_db; } msg_table = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); if (msg_table == NULL) { res = MAIL_ERROR_MEMORY; goto free_msglist; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto free_msgtable; } i = 0; while (i < carray_count(msglist)) { uint32_t num; uint32_t * msg; chashdatum key; chashdatum value; struct mail_flags * flags; int deleted; msg = carray_get(msglist, i); num = * msg; deleted = 0; snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num); r = generic_cache_flags_read(maildb, mmapstr, key_value, &flags); if (r == MAIL_NO_ERROR) { if ((flags->fl_flags & MAIL_FLAG_DELETED) != 0) deleted = 1; } if (!deleted) { snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num); key.data = key_value; key.len = strlen(key_value); chash_set(msg_table, &key, &value, NULL); snprintf(key_value, sizeof(key_value), "%lu-envelope", (unsigned long) num); key.data = key_value; key.len = strlen(key_value); chash_set(msg_table, &key, &value, NULL); snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num); key.data = key_value; key.len = strlen(key_value); chash_set(msg_table, &key, &value, NULL); i ++; } else { free(msg); carray_delete(msglist, i); } } mmap_string_free(mmapstr); r = mail_cache_db_clean_up(maildb, msg_table); chash_free(msg_table); r = db_set_message_list(maildb, msglist); for(i = 0 ; i < carray_count(msglist) ; i ++) { uint32_t * msg; msg = carray_get(msglist, i); free(msg); } carray_free(msglist); mail_cache_db_close_unlock(data->db_filename, maildb); return MAIL_NO_ERROR; free_msgtable: chash_free(msg_table); free_msglist: for(i = 0 ; i < carray_count(msglist) ; i ++) { uint32_t * msg; msg = carray_get(msglist, i); free(msg); } close_db: mail_cache_db_close_unlock(data->db_filename, maildb); err: return res; }
int claws_mailmbox_msg_info_update(struct claws_mailmbox_folder * folder, size_t msg_start, size_t msg_start_len, size_t msg_headers, size_t msg_headers_len, size_t msg_body, size_t msg_body_len, size_t msg_size, size_t msg_padding, uint32_t msg_uid) { struct claws_mailmbox_msg_info * info; int res; chashdatum key; chashdatum data; int r; key.data = &msg_uid; key.len = sizeof(msg_uid); r = chash_get(folder->mb_hash, &key, &data); if (r < 0) { unsigned int index; info = claws_mailmbox_msg_info_new(msg_start, msg_start_len, msg_headers, msg_headers_len, msg_body, msg_body_len, msg_size, msg_padding, msg_uid); if (info == NULL) { res = MAILMBOX_ERROR_MEMORY; goto err; } r = carray_add(folder->mb_tab, info, &index); if (r < 0) { claws_mailmbox_msg_info_free(info); res = MAILMBOX_ERROR_MEMORY; goto err; } if (msg_uid != 0) { chashdatum key; chashdatum data; key.data = &msg_uid; key.len = sizeof(msg_uid); data.data = info; data.len = 0; r = chash_set(folder->mb_hash, &key, &data, NULL); if (r < 0) { claws_mailmbox_msg_info_free(info); carray_delete(folder->mb_tab, index); res = MAILMBOX_ERROR_MEMORY; goto err; } } info->msg_index = index; } else { info = data.data; info->msg_start = msg_start; info->msg_start_len = msg_start_len; info->msg_headers = msg_headers; info->msg_headers_len = msg_headers_len; info->msg_body = msg_body; info->msg_body_len = msg_body_len; info->msg_size = msg_size; info->msg_padding = msg_padding; } return MAILMBOX_NO_ERROR; err: return res; }
static int delete_dummy(carray * rootlist, carray * sibling_list, unsigned int cur, unsigned int * pnext) { struct mailmessage_tree * env_tree; int res; int r; unsigned int cur_child; unsigned int next; env_tree = carray_get(sibling_list, cur); cur_child = 0; while (cur_child < carray_count(env_tree->node_children)) { delete_dummy(rootlist, env_tree->node_children, cur_child, &cur_child); } if (env_tree->node_msg == NULL) { if (carray_count(env_tree->node_children) == 0) { /* If it is a dummy message with NO children, delete it. */ mailmessage_tree_free(env_tree); carray_delete(sibling_list, cur); next = cur; } else { /* If it is a dummy message with children, delete it, but promote its children to the current level. */ /* Do not promote the children if doing so would make them children of the root, unless there is only one child. */ cur_child = 0; if ((sibling_list != rootlist) || (carray_count(env_tree->node_children) == 1)) { while (cur_child < carray_count(env_tree->node_children)) { struct mailmessage_tree * child; child = carray_get(env_tree->node_children, cur_child); r = carray_add(sibling_list, child, NULL); if (r < 0) { res = MAIL_ERROR_MEMORY; goto err; } /* set new parent of the children */ child->node_parent = env_tree->node_parent; carray_delete(env_tree->node_children, cur_child); } mailmessage_tree_free(env_tree); carray_delete(sibling_list, cur); next = cur; } else next = cur + 1; } } else next = cur + 1; * pnext = next; return MAIL_NO_ERROR; err: return res; }
static int mail_build_thread_orderedsubject(char * default_from, struct mailmessage_list * env_list, struct mailmessage_tree ** result, int (* comp_func)(struct mailmessage_tree **, struct mailmessage_tree **)) { unsigned int i; carray * rootlist; unsigned int cur; struct mailmessage_tree * root; int res; int r; struct mailmessage_tree * current_thread; root = mailmessage_tree_new(NULL, (time_t) -1, NULL); if (root == NULL) { res = MAIL_ERROR_MEMORY; goto err; } rootlist = root->node_children; /* The ORDEREDSUBJECT threading algorithm is also referred to as "poor man's threading." */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; struct mailmessage_tree * env_tree; char * base_subject; time_t date; msg = carray_get(env_list->msg_tab, i); if (msg == NULL) continue; if (msg->msg_fields != NULL) { date = get_date(msg); env_tree = mailmessage_tree_new(NULL, date, msg); if (env_tree == NULL) { res = MAIL_ERROR_MEMORY; goto free; } /* set parent */ env_tree->node_parent = root; r = carray_add(rootlist, env_tree, NULL); if (r < 0) { mailmessage_tree_free(env_tree); res = MAIL_ERROR_MEMORY; goto free; } r = get_extracted_subject(default_from, env_tree, &base_subject); switch (r) { case MAIL_NO_ERROR: env_tree->node_base_subject = base_subject; break; case MAIL_ERROR_SUBJECT_NOT_FOUND: break; default: res = r; goto free; } } } /* The searched messages are sorted by subject and then by the sent date. */ r = mail_thread_sort(root, tree_subj_time_comp, FALSE); if (r != MAIL_NO_ERROR) { res = r; goto free; } /* The messages are then split into separate threads, with each thread containing messages with the same extracted subject text. */ current_thread = NULL; cur = 0; while (cur < carray_count(rootlist)) { struct mailmessage_tree * cur_env_tree; cur_env_tree = carray_get(rootlist, cur); if (current_thread == NULL) { current_thread = cur_env_tree; cur ++; continue; } if ((cur_env_tree->node_base_subject == NULL) || (current_thread->node_base_subject == NULL)) { current_thread = cur_env_tree; cur ++; continue; } if (strcmp(cur_env_tree->node_base_subject, current_thread->node_base_subject) == 0) { /* set parent */ cur_env_tree->node_parent = current_thread; r = carray_add(current_thread->node_children, cur_env_tree, NULL); if (r < 0) { res = MAIL_ERROR_MEMORY; goto free; } carray_delete(rootlist, cur); } else cur ++; current_thread = cur_env_tree; } /* Finally, the threads are sorted by the sent date of the first message in the thread. Note that each message in a thread is a child (as opposed to a sibling) of the previous message. */ #if 0 if (comp_func != NULL) { r = mail_thread_sort(root, comp_func, FALSE); if (r != MAIL_NO_ERROR) { res = r; goto free; } } #endif if (comp_func == NULL) comp_func = mailthread_tree_timecomp; r = mail_thread_sort(root, comp_func, FALSE); if (r != MAIL_NO_ERROR) { res = r; goto free; } * result = root; return MAIL_NO_ERROR; free: mailmessage_tree_free_recursive(root); err: return res; }