static int imap_fetch_envelope(mailmessage * msg_info, struct mailimf_fields ** result) { struct mailimf_fields * fields; int r; struct mail_cache_db * cache_db; MMAPString * mmapstr; char filename[PATH_MAX]; struct imap_cached_session_state_data * data; int res; data = get_cached_session_data(msg_info); if (data->imap_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } snprintf(filename, PATH_MAX, "%s/%s", data->imap_quoted_mb, ENV_NAME); r = mail_cache_db_open_lock(filename, &cache_db); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } r = imapdriver_get_cached_envelope(cache_db, mmapstr, msg_info->msg_session, msg_info, &fields); if ((r != MAIL_ERROR_CACHE_MISS) && (r != MAIL_NO_ERROR)) { res = r; goto close_db; } r = mailmessage_fetch_envelope(get_ancestor(msg_info), &fields); if (r != MAIL_NO_ERROR) { res = r; goto close_db; } r = imapdriver_write_cached_envelope(cache_db, mmapstr, msg_info->msg_session, msg_info, fields); * result = fields; mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename, cache_db); return MAIL_NO_ERROR; close_db: mail_cache_db_close_unlock(filename, cache_db); err: return res; }
static int get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { unsigned int i; char key[PATH_MAX]; int r; struct mail_cache_db * maildb; int res; struct db_session_state_data * data; 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; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields == NULL) { snprintf(key, sizeof(key), "%lu-envelope", (unsigned long) msg->msg_index); r = generic_cache_fields_read(maildb, mmapstr, key, &msg->msg_fields); } if (msg->msg_flags == NULL) { snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg->msg_index); r = generic_cache_flags_read(maildb, mmapstr, key, &msg->msg_flags); } } mmap_string_free(mmapstr); mail_cache_db_close_unlock(data->db_filename, maildb); return MAIL_NO_ERROR; close_db: mail_cache_db_close_unlock(data->db_filename, maildb); err: return res; }
static int prefetch(mailmessage * msg_info) { struct generic_message_t * msg; int res; struct db_msg_data * data; struct db_session_state_data * sess_data; MMAPString * msg_content; struct mail_cache_db * maildb; int r; char key[PATH_MAX]; void * msg_data; size_t msg_data_len; sess_data = get_session_data(msg_info); r = mail_cache_db_open_lock(sess_data->db_filename, &maildb); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } snprintf(key, sizeof(key), "%lu", (unsigned long) msg_info->msg_index); r = mail_cache_db_get(maildb, key, strlen(key), &msg_data, &msg_data_len); if (r < 0) { res = MAIL_ERROR_MSG_NOT_FOUND; goto close_db; } msg_content = mmap_string_new_len(msg_data, msg_data_len); if (msg_content == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } data = malloc(sizeof(* data)); if (data == NULL) { res = MAIL_ERROR_MEMORY; goto free_mmapstr; } data->msg_content = msg_content; msg = msg_info->msg_data; msg->msg_data = data; msg->msg_message = msg_content->str; msg->msg_length = msg_content->len; mail_cache_db_close_unlock(sess_data->db_filename, maildb); return MAIL_NO_ERROR; free_mmapstr: mmap_string_free(msg_content); close_db: mail_cache_db_close_unlock(sess_data->db_filename, maildb); err: return res; }
static int mh_flags_store_process(char * flags_directory, char * quoted_mb, struct mail_flags_store * flags_store) { char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; unsigned int i; int r; int res; if (carray_count(flags_store->fls_tab) == 0) return MAIL_NO_ERROR; if (quoted_mb == NULL) return MAIL_NO_ERROR; snprintf(filename_flags, PATH_MAX, "%s/%s/%s", flags_directory, quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) { mailmessage * msg; msg = carray_get(flags_store->fls_tab, i); r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, msg->msg_uid, msg->msg_flags); } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); mail_flags_store_clear(flags_store); return MAIL_NO_ERROR; close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; }
static int get_flags(mailmessage * msg_info, struct mail_flags ** result) { char key[PATH_MAX]; int r; struct db_session_state_data * sess_data; struct mail_cache_db * maildb; int res; MMAPString * mmapstr; sess_data = get_session_data(msg_info); r = mail_cache_db_open_lock(sess_data->db_filename, &maildb); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg_info->msg_index); mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } r = generic_cache_flags_read(maildb, mmapstr, key, &msg_info->msg_flags); mmap_string_free(mmapstr); if (r != MAIL_NO_ERROR) { msg_info->msg_flags = mail_flags_new_empty(); if (msg_info->msg_flags == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } } mail_cache_db_close_unlock(sess_data->db_filename, maildb); * result = msg_info->msg_flags; return MAIL_NO_ERROR; close_db: mail_cache_db_close_unlock(sess_data->db_filename, maildb); err: return res; }
static int get_message(mailsession * session, uint32_t num, mailmessage ** result) { mailmessage * msg; int r; size_t size; char key[PATH_MAX]; struct db_session_state_data * data; struct mail_cache_db * maildb; int res; data = get_data(session); r = mail_cache_db_open_lock(data->db_filename, &maildb); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } msg = mailmessage_new(); if (msg == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } size = 0; snprintf(key, sizeof(key), "%lu", (unsigned long) num); r = mail_cache_db_get_size(maildb, key, strlen(key), &size); /* ignore error */ r = mailmessage_init(msg, session, db_message_driver, num, size); if (r != MAIL_NO_ERROR) { mailmessage_free(msg); res = r; goto close_db; } mail_cache_db_close_unlock(data->db_filename, maildb); return MAIL_NO_ERROR; close_db: mail_cache_db_close_unlock(data->db_filename, maildb); err: return res; }
static int flags_store_process(mailsession * session) { unsigned int i; MMAPString * mmapstr; int r; int res; struct mail_cache_db * maildb; struct db_session_state_data * data; struct mail_flags_store * flags_store; data = get_data(session); flags_store = data->db_flags_store; if (carray_count(flags_store->fls_tab) == 0) return MAIL_NO_ERROR; mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto err; } r = mail_cache_db_open_lock(data->db_filename, &maildb); if (r < 0) { res = MAIL_ERROR_FILE; goto free_mmapstr; } for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) { mailmessage * msg; char key[PATH_MAX]; msg = carray_get(flags_store->fls_tab, i); snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg->msg_index); r = generic_cache_flags_write(maildb, mmapstr, key, msg->msg_flags); } mail_flags_store_clear(flags_store); mail_cache_db_close_unlock(data->db_filename, maildb); mmap_string_free(mmapstr); return MAIL_NO_ERROR; free_mmapstr: mmap_string_free(mmapstr); err: return res; }
static int mhdriver_cached_expunge_folder(mailsession * session) { struct mailmh_folder * folder; int res; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; struct mh_cached_session_state_data * cached_data; unsigned int i; int r; cached_data = get_cached_data(session); if (cached_data->mh_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } mh_flags_store_process(cached_data->mh_flags_directory, cached_data->mh_quoted_mb, cached_data->mh_flags_store); folder = get_mh_cur_folder(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { struct mailmh_msg_info * mh_info; struct mail_flags * flags; mh_info = carray_get(folder->fl_msgs_tab, i); if (mh_info == NULL) continue; r = mhdriver_get_cached_flags(cache_db_flags, mmapstr, session, mh_info->msg_index, &flags); if (r != MAIL_NO_ERROR) continue; if (flags->fl_flags & MAIL_FLAG_DELETED) { r = mailmh_folder_remove_message(folder, mh_info->msg_index); } mail_flags_free(flags); } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); mailmh_folder_update(folder); return MAIL_NO_ERROR; close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; }
static int mhdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { int r; unsigned int i; char filename_env[PATH_MAX]; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_env; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; int res; struct mh_cached_session_state_data * cached_data; cached_data = get_cached_data(session); if (cached_data->mh_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } mh_flags_store_process(cached_data->mh_flags_directory, cached_data->mh_quoted_mb, cached_data->mh_flags_store); mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto err; } snprintf(filename_env, PATH_MAX, "%s/%s/%s", cached_data->mh_cache_directory, cached_data->mh_quoted_mb, ENV_NAME); r = mail_cache_db_open_lock(filename_env, &cache_db_env); if (r < 0) { res = MAIL_ERROR_FILE; goto free_mmapstr; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto close_db_env; } /* fill with cached */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; struct mailimf_fields * fields; struct mail_flags * flags; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields == NULL) { r = get_cached_envelope(cache_db_env, mmapstr, msg->msg_session, msg->msg_index, &fields); if (r == MAIL_NO_ERROR) { msg->msg_cached = TRUE; msg->msg_fields = fields; } } if (msg->msg_flags == NULL) { r = mhdriver_get_cached_flags(cache_db_flags, mmapstr, session, msg->msg_index, &flags); if (r == MAIL_NO_ERROR) { msg->msg_flags = flags; } } } mail_cache_db_close_unlock(filename_flags, cache_db_flags); mail_cache_db_close_unlock(filename_env, cache_db_env); r = mailsession_get_envelopes_list(get_ancestor(session), env_list); if (r != MAIL_NO_ERROR) { res = r; goto free_mmapstr; } r = mail_cache_db_open_lock(filename_env, &cache_db_env); if (r < 0) { res = MAIL_ERROR_FILE; goto free_mmapstr; } r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto close_db_env; } /* add flags */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_flags == NULL) msg->msg_flags = mail_flags_new_empty(); } /* must write cache */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields != NULL) { if (!msg->msg_cached) { r = write_cached_envelope(cache_db_env, mmapstr, session, msg->msg_index, msg->msg_fields); } } if (msg->msg_flags != NULL) { r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, msg->msg_uid, msg->msg_flags); } } /* flush cache */ maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list); mail_cache_db_close_unlock(filename_flags, cache_db_flags); mail_cache_db_close_unlock(filename_env, cache_db_env); mmap_string_free(mmapstr); return MAIL_NO_ERROR; close_db_env: mail_cache_db_close_unlock(filename_env, cache_db_env); free_mmapstr: mmap_string_free(mmapstr); err: return res; }
static int nntpdriver_cached_get_envelopes_list(mailsession * session, struct mailmessage_list * env_list) { int r; unsigned int i; struct nntp_cached_session_state_data * cached_data; uint32_t first; uint32_t last; struct nntp_session_state_data * ancestor_data; char filename_env[PATH_MAX]; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_env; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; int res; char cache_dir[PATH_MAX]; cached_data = get_cached_data(session); ancestor_data = get_ancestor_data(session); nntp_flags_store_process(cached_data->nntp_flags_directory, ancestor_data->nntp_group_name, cached_data->nntp_flags_store); if (ancestor_data->nntp_group_name == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } /* read articles sequence */ read_article_seq(session, &first, &last); mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto err; } snprintf(filename_env, PATH_MAX, "%s/%s/%s", cached_data->nntp_cache_directory, ancestor_data->nntp_group_name, ENV_NAME); r = mail_cache_db_open_lock(filename_env, &cache_db_env); if (r < 0) { res = MAIL_ERROR_FILE; goto free_mmapstr; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->nntp_flags_directory, ancestor_data->nntp_group_name, FLAGS_NAME); /* fill with cached */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; struct mailimf_fields * fields; msg = carray_get(env_list->msg_tab, i); if ((msg->msg_index < first) || (msg->msg_index > last)) continue; if (msg->msg_fields == NULL) { r = get_cached_envelope(cache_db_env, mmapstr, session, msg->msg_index, &fields); if (r == MAIL_NO_ERROR) { msg->msg_fields = fields; msg->msg_cached = TRUE; } } } mail_cache_db_close_unlock(filename_env, cache_db_env); r = mailsession_get_envelopes_list(get_ancestor(session), env_list); if (r != MAIL_NO_ERROR) { res = r; goto free_mmapstr; } r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto free_mmapstr; } /* add flags */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_flags == NULL) { struct mail_flags * flags; r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr, msg->msg_index, &flags); if (r == MAIL_NO_ERROR) { msg->msg_flags = flags; } else { msg->msg_flags = mail_flags_new_empty(); if (msg->msg_fields == NULL) { msg->msg_flags->fl_flags |= MAIL_FLAG_CANCELLED; mailmessage_check(msg); } } } } mail_cache_db_close_unlock(filename_flags, cache_db_flags); r = mail_cache_db_open_lock(filename_env, &cache_db_env); if (r < 0) { res = MAIL_ERROR_FILE; goto free_mmapstr; } r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto close_db_env; } /* must write cache */ for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) { mailmessage * msg; msg = carray_get(env_list->msg_tab, i); if (msg->msg_fields != NULL) { if (!msg->msg_cached) { r = write_cached_envelope(cache_db_env, mmapstr, session, msg->msg_index, msg->msg_fields); } } if (msg->msg_flags != NULL) { r = nntpdriver_write_cached_flags(cache_db_flags, mmapstr, msg->msg_index, msg->msg_flags); } } first = 0; last = 0; if (carray_count(env_list->msg_tab) > 0) { mailmessage * msg; msg = carray_get(env_list->msg_tab, 0); first = msg->msg_index; msg = carray_get(env_list->msg_tab, carray_count(env_list->msg_tab) - 1); last = msg->msg_index; } /* write articles sequence */ write_article_seq(session, first, last); /* flush cache */ maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list); /* remove cache files */ snprintf(cache_dir, PATH_MAX, "%s/%s", cached_data->nntp_cache_directory, ancestor_data->nntp_group_name); mail_cache_db_close_unlock(filename_flags, cache_db_flags); mail_cache_db_close_unlock(filename_env, cache_db_env); mmap_string_free(mmapstr); maildriver_message_cache_clean_up(cache_dir, env_list, get_uid_from_filename); return MAIL_NO_ERROR; close_db_env: mail_cache_db_close_unlock(filename_env, cache_db_env); free_mmapstr: mmap_string_free(mmapstr); err: return res; }
static int nntpdriver_cached_status_folder(mailsession * session, const char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { int res; struct nntp_cached_session_state_data * cached_data; struct nntp_session_state_data * ancestor_data; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; uint32_t i; int r; uint32_t recent; uint32_t unseen; uint32_t first; uint32_t last; uint32_t count; uint32_t additionnal; r = nntpdriver_cached_select_folder(session, mb); if (r != MAIL_NO_ERROR) { res = r; goto err; } read_article_seq(session, &first, &last); count = 0; recent = 0; unseen = 0; ancestor_data = get_ancestor_data(session); cached_data = get_cached_data(session); if (ancestor_data->nntp_group_name == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } if (ancestor_data->nntp_group_info->grp_first > first) first = ancestor_data->nntp_group_info->grp_first; if (last < first) last = ancestor_data->nntp_group_info->grp_last; snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->nntp_flags_directory, ancestor_data->nntp_group_name, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } for(i = first ; i <= last ; i++) { struct mail_flags * flags; r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr, i, &flags); if (r == MAIL_NO_ERROR) { if ((flags->fl_flags & MAIL_FLAG_CANCELLED) != 0) { mail_flags_free(flags); continue; } count ++; if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) { recent ++; } if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { unseen ++; } mail_flags_free(flags); } } if ((count == 0) && (first != last)) { count = last - first + 1; recent = count; unseen = count; } additionnal = ancestor_data->nntp_group_info->grp_last - last; recent += additionnal; unseen += additionnal; mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); * result_messages = count; * result_recent = recent; * result_unseen = unseen; return MAIL_NO_ERROR; close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; }
static int pop3driver_cached_status_folder(mailsession * session, const char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { int res; struct pop3_cached_session_state_data * cached_data; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; unsigned int i; int r; carray * msg_tab; mailpop3 * pop3; uint32_t recent; uint32_t unseen; recent = 0; unseen = 0; pop3 = get_pop3_session(session); cached_data = get_cached_data(session); pop3_flags_store_process(cached_data->pop3_flags_directory, cached_data->pop3_flags_store); snprintf(filename_flags, PATH_MAX, "%s/%s", cached_data->pop3_flags_directory, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } r = mailpop3_list(pop3, &msg_tab); if (r != MAILPOP3_NO_ERROR) { res = pop3driver_pop3_error_to_mail_error(r); goto free_mmapstr; } for(i = 0 ; i < carray_count(msg_tab) ; i++) { struct mailpop3_msg_info * pop3_info; struct mail_flags * flags; pop3_info = carray_get(msg_tab, i); if (pop3_info == NULL) continue; if (pop3_info->msg_deleted) continue; r = pop3driver_get_cached_flags(cache_db_flags, mmapstr, session, pop3_info->msg_index, &flags); if (r != MAIL_NO_ERROR) { recent ++; unseen ++; continue; } if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) { recent ++; } if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { unseen ++; } mail_flags_free(flags); } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); * result_messages = carray_count(msg_tab) - pop3->pop3_deleted_count; * result_recent = recent; * result_unseen = unseen; return MAIL_NO_ERROR; free_mmapstr: mmap_string_free(mmapstr); close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); 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; }
static int mhdriver_cached_status_folder(mailsession * session, const char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { struct mailmh_folder * folder; int res; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; struct mh_cached_session_state_data * cached_data; unsigned int i; int r; uint32_t count; uint32_t recent; uint32_t unseen; r = mhdriver_cached_select_folder(session, mb); if (r != MAIL_NO_ERROR) { res = r; goto err; } count = 0; recent = 0; unseen = 0; folder = get_mh_cur_folder(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } cached_data = get_cached_data(session); if (cached_data->mh_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->mh_flags_directory, cached_data->mh_quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { struct mailmh_msg_info * mh_info; struct mail_flags * flags; mh_info = carray_get(folder->fl_msgs_tab, i); if (mh_info == NULL) continue; count ++; r = mhdriver_get_cached_flags(cache_db_flags, mmapstr, session, mh_info->msg_index, &flags); if (r != MAIL_NO_ERROR) { recent ++; unseen ++; continue; } if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) { recent ++; } if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { unseen ++; } mail_flags_free(flags); } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); * result_messages = count; * result_recent = recent; * result_unseen = unseen; return MAIL_NO_ERROR; close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; }
static int status_folder(mailsession * session, const char * mb, uint32_t * result_messages, uint32_t * result_recent, uint32_t * result_unseen) { struct mail_cache_db * maildb; char key_value[PATH_MAX]; MMAPString * mmapstr; uint32_t messages; uint32_t recent; uint32_t unseen; struct db_session_state_data * data; int r; int res; carray * msglist; unsigned int i; 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; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto free_list; } messages = 0; recent = 0; unseen = 0; for(i = 0 ; i < carray_count(msglist) ; i ++) { uint32_t num; uint32_t * msg; struct mail_flags * flags; msg = carray_get(msglist, i); num = * msg; free(msg); carray_set(msglist, i, NULL); messages ++; 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_NEW) != 0) { recent ++; } if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) { unseen ++; } mail_flags_free(flags); } } mmap_string_free(mmapstr); carray_free(msglist); mail_cache_db_close_unlock(data->db_filename, maildb); * result_messages = messages; * result_unseen = unseen; * result_recent = recent; return MAIL_NO_ERROR; free_list: for(i = 0 ; i < carray_count(msglist) ; i ++) { uint32_t * msg; msg = carray_get(msglist, i); if (msg != NULL) free(msg); } carray_free(msglist); close_db: mail_cache_db_close_unlock(data->db_filename, maildb); err: return res; }
static int get_messages_list(mailsession * session, struct mailmessage_list ** result) { int r; char key[PATH_MAX]; struct mail_cache_db * maildb; struct db_session_state_data * data; int res; carray * msglist; unsigned int i; carray * msgtab; struct mailmessage_list * driver_msglist; data = get_data(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; } msgtab = carray_new(16); if (msgtab == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } for(i = 0 ; i < carray_count(msglist) ; i ++) { uint32_t msg_num; uint32_t * pmsg_num; mailmessage * msg; size_t size; pmsg_num = carray_get(msglist, i); msg_num = * pmsg_num; free(pmsg_num); carray_set(msglist, i, NULL); snprintf(key, sizeof(key), "%lu", (unsigned long) msg_num); r = mail_cache_db_get_size(maildb, key, strlen(key), &size); if (r < 0) { continue; } msg = mailmessage_new(); if (msg == NULL) { res = MAIL_ERROR_MEMORY; goto free_list; } r = mailmessage_init(msg, session, db_message_driver, msg_num, size); if (r != MAIL_NO_ERROR) { mailmessage_free(msg); res = r; goto free_list; } r = carray_add(msgtab, msg, NULL); if (r < 0) { mailmessage_free(msg); res = MAIL_ERROR_MEMORY; goto free_list; } } carray_free(msglist); driver_msglist = mailmessage_list_new(msgtab); if (driver_msglist == NULL) { res = MAIL_ERROR_MEMORY; goto free_list; } mail_cache_db_close_unlock(data->db_filename, maildb); * result = driver_msglist; return MAIL_NO_ERROR; free_list: for(i = 0 ; i < carray_count(msgtab) ; i ++) { mailmessage * msg; msg = carray_get(msgtab, i); mailmessage_free(msg); } carray_free(msgtab); for(i = 0 ; i < carray_count(msglist) ; i ++) { uint32_t * msg; msg = carray_get(msglist, i); if (msg != NULL) free(msg); } carray_free(msglist); close_db: mail_cache_db_close_unlock(data->db_filename, maildb); err: return res; }
static int append_message_flags(mailsession * session, const char * message, size_t size, struct mail_flags * flags) { carray * msglist; unsigned int i; uint32_t * msg; uint32_t num; char key_value[PATH_MAX]; MMAPString * mmapstr; struct mail_cache_db * maildb; struct db_session_state_data * data; size_t cur_token; struct mailimf_fields * fields; int r; int res; data = get_data(session); r = mail_cache_db_open_lock(data->db_filename, &maildb); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } num = 0; r = db_get_next_msg_number(maildb, &num); if (r != MAIL_NO_ERROR) { res = r; goto err; } r = db_get_message_list(maildb, &msglist); if (r != MAIL_NO_ERROR) { res = r; goto close_db; } msg = malloc(sizeof(* msg)); if (msg == NULL) { res = MAIL_ERROR_MEMORY; goto free_msglist; } * msg = num; r = carray_add(msglist, msg, NULL); if (r < 0) { res = MAIL_ERROR_MEMORY; free(msg); goto free_msglist; } r = db_set_message_list(maildb, msglist); if (r != MAIL_NO_ERROR) { res = r; goto free_msglist; } /* free msglist */ for(i = 0 ; i < carray_count(msglist) ; i ++) { msg = carray_get(msglist, i); free(msg); } carray_free(msglist); snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num); r = mail_cache_db_put(maildb, key_value, strlen(key_value), message, size); if (r < 0) { res = MAIL_ERROR_FILE; goto close_db; } /* write envelope */ cur_token = 0; r = mailimf_envelope_fields_parse(message, size, &cur_token, &fields); if (r != MAILIMF_NO_ERROR) { res = MAIL_ERROR_PARSE; goto close_db; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } cur_token = 0; r = mailimf_cache_fields_write(mmapstr, &cur_token, fields); if (r != MAIL_NO_ERROR) { res = r; mmap_string_free(mmapstr); goto close_db; } snprintf(key_value, sizeof(key_value), "%lu-envelope", (unsigned long) num); r = mail_cache_db_put(maildb, key_value, strlen(key_value), mmapstr->str, mmapstr->len); mmap_string_free(mmapstr); mailimf_fields_free(fields); /* write flags */ if (flags != NULL) { snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num); mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db; } r = generic_cache_flags_write(maildb, mmapstr, key_value, flags); mmap_string_free(mmapstr); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_FILE; goto close_db; } } mail_cache_db_close_unlock(data->db_filename, maildb); return MAIL_NO_ERROR; free_msglist: for(i = 0 ; i < carray_count(msglist) ; i ++) { msg = carray_get(msglist, i); free(msg); } carray_free(msglist); close_db: mail_cache_db_close_unlock(data->db_filename, maildb); err: return res; }
static int mhdriver_cached_append_message_flags(mailsession * session, const char * message, size_t size, struct mail_flags * flags) { int r; struct mailmh_folder * folder; struct mailmh_msg_info * msg_info; chashdatum key; chashdatum value; uint32_t uid; struct mh_cached_session_state_data * data; char filename_flags[PATH_MAX]; struct mail_cache_db * cache_db_flags; MMAPString * mmapstr; char keyname[PATH_MAX]; folder = get_mh_cur_folder(session); if (folder == NULL) return MAIL_ERROR_BAD_STATE; r = mailmh_folder_add_message_uid(folder, message, size, &uid); switch (r) { case MAILMH_ERROR_FILE: return MAIL_ERROR_DISKSPACE; case MAILMH_NO_ERROR: break; default: return mhdriver_mh_error_to_mail_error(r); } if (flags == NULL) goto exit; key.data = &uid; key.len = sizeof(uid); r = chash_get(folder->fl_msgs_hash, &key, &value); if (r < 0) return MAIL_ERROR_CACHE_MISS; msg_info = value.data; data = get_cached_data(session); snprintf(filename_flags, PATH_MAX, "%s/%s/%s", data->mh_flags_directory, data->mh_quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) goto exit; mmapstr = mmap_string_new(""); if (mmapstr == NULL) goto close_db_flags; snprintf(keyname, PATH_MAX, "%u-%lu-%lu-flags", uid, (unsigned long) msg_info->msg_mtime, (unsigned long) msg_info->msg_size); r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, keyname, flags); mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); if (r != MAIL_NO_ERROR) goto exit; return MAIL_NO_ERROR; close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); exit: return MAIL_NO_ERROR; }
static int get_flags(mailmessage * msg_info, struct mail_flags ** result) { struct mail_cache_db * cache_db_flags; chashdatum key; chashdatum value; struct maildir * md; struct mail_flags * flags; struct maildir_cached_session_state_data * data; struct maildir_msg * md_msg; int r; uint32_t driver_flags; char filename_flags[PATH_MAX]; char keyname[PATH_MAX]; MMAPString * mmapstr; if (msg_info->msg_flags != NULL) { * result = msg_info->msg_flags; return MAIL_NO_ERROR; } data = get_cached_session_data(msg_info); flags = mail_flags_store_get(data->md_flags_store, msg_info->msg_index); if (flags != NULL) { msg_info->msg_flags = flags; * result = msg_info->msg_flags; return MAIL_NO_ERROR; } snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s", data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb, MAIL_DIR_SEPARATOR, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) return MAIL_ERROR_FILE; snprintf(keyname, PATH_MAX, "%s-flags", msg_info->msg_uid); mmapstr = mmap_string_new(""); if (mmapstr == NULL) { mail_cache_db_close_unlock(filename_flags, cache_db_flags); return MAIL_ERROR_MEMORY; } r = generic_cache_flags_read(cache_db_flags, mmapstr, keyname, &flags); mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); if (r != MAIL_NO_ERROR) { flags = mail_flags_new_empty(); if (flags == NULL) return MAIL_ERROR_MEMORY; } md = get_maildir_session(msg_info); if (md == NULL) return MAIL_ERROR_BAD_STATE; key.data = msg_info->msg_uid; key.len = (unsigned int) strlen(msg_info->msg_uid); r = chash_get(md->mdir_msg_hash, &key, &value); if (r < 0) return MAIL_ERROR_MSG_NOT_FOUND; md_msg = value.data; driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags); flags->fl_flags = driver_flags; msg_info->msg_flags = flags; * result = msg_info->msg_flags; return MAIL_NO_ERROR; }
static int nntp_get_flags(mailmessage * msg_info, struct mail_flags ** result) { int r; struct mail_flags * flags; struct mail_cache_db * cache_db_flags; char filename_flags[PATH_MAX]; int res; MMAPString * mmapstr; if (msg_info->msg_flags != NULL) { * result = msg_info->msg_flags; return MAIL_NO_ERROR; } flags = mail_flags_store_get(get_cached_session_data(msg_info)->nntp_flags_store, msg_info->msg_index); if (flags == NULL) { struct nntp_cached_session_state_data * cached_data; struct nntp_session_state_data * ancestor_data; cached_data = get_cached_session_data(msg_info); ancestor_data = get_ancestor_session_data(msg_info); if (ancestor_data->nntp_group_name == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->nntp_flags_directory, ancestor_data->nntp_group_name, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr, msg_info->msg_index, &flags); if (r != MAIL_NO_ERROR) { flags = mail_flags_new_empty(); if (flags == NULL) { res = MAIL_ERROR_MEMORY; goto free_mmapstr; } } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); } msg_info->msg_flags = flags; * result = flags; return MAIL_NO_ERROR; free_mmapstr: mmap_string_free(mmapstr); close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; }
static int mbox_get_flags(mailmessage * msg_info, struct mail_flags ** result) { int r; struct mail_flags * flags; struct mail_cache_db * cache_db_flags; char filename_flags[PATH_MAX]; int res; struct mbox_cached_session_state_data * cached_data; MMAPString * mmapstr; struct mailmbox_folder * folder; if (msg_info->msg_flags != NULL) { * result = msg_info->msg_flags; return MAIL_NO_ERROR; } flags = mail_flags_store_get(get_cached_session_data(msg_info)->mbox_flags_store, msg_info->msg_index); if (flags == NULL) { folder = get_mbox_session(msg_info); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } cached_data = get_cached_session_data(msg_info); if (cached_data->mbox_quoted_mb == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } snprintf(filename_flags, PATH_MAX, "%s/%s/%s", cached_data->mbox_flags_directory, cached_data->mbox_quoted_mb, FLAGS_NAME); r = mail_cache_db_open_lock(filename_flags, &cache_db_flags); if (r < 0) { res = MAIL_ERROR_FILE; goto err; } mmapstr = mmap_string_new(""); if (mmapstr == NULL) { res = MAIL_ERROR_MEMORY; goto close_db_flags; } if (msg_info->msg_index > folder->mb_written_uid) { flags = mail_flags_new_empty(); } else { r = mboxdriver_get_cached_flags(cache_db_flags, mmapstr, msg_info->msg_session, msg_info->msg_index, &flags); if (r != MAIL_NO_ERROR) { flags = mail_flags_new_empty(); if (flags == NULL) { res = MAIL_ERROR_MEMORY; goto free_mmapstr; } } } mmap_string_free(mmapstr); mail_cache_db_close_unlock(filename_flags, cache_db_flags); } msg_info->msg_flags = flags; * result = flags; return MAIL_NO_ERROR; free_mmapstr: mmap_string_free(mmapstr); close_db_flags: mail_cache_db_close_unlock(filename_flags, cache_db_flags); err: return res; }