static int mhdriver_rename_folder(mailsession * session, const char * mb, const char * new_name) { struct mailmh_folder * src_folder; struct mailmh_folder * dst_folder; const char * name; struct mailmh * mh; int r; r = get_parent(session, new_name, &dst_folder, &name); if (r != MAIL_NO_ERROR) return r; mh = get_mh_session(session); if (mh == NULL) return MAIL_ERROR_BAD_STATE; src_folder = mailmh_folder_find(mh->mh_main, mb); if (src_folder == NULL) return MAIL_ERROR_FOLDER_NOT_FOUND; if (get_mh_cur_folder(session) == src_folder) get_data(session)->mh_cur_folder = NULL; r = mailmh_folder_rename_subfolder(src_folder, dst_folder, name); return mhdriver_mh_error_to_mail_error(r); }
static int mhdriver_remove_message(mailsession * session, uint32_t num) { int r; struct mailmh_folder * folder; folder = get_mh_cur_folder(session); if (folder == NULL) return MAIL_ERROR_DELETE; r = mailmh_folder_remove_message(folder, num); return mhdriver_mh_error_to_mail_error(r); }
static int mhdriver_cached_get_message_by_uid(mailsession * session, const char * uid, mailmessage ** result) { uint32_t indx; char *p; struct mailmh_msg_info * mh_msg_info; struct mailmh_folder * folder; time_t mtime; char * mtime_p; chashdatum key; chashdatum data; int r; if (uid == NULL) return MAIL_ERROR_INVAL; indx = strtoul(uid, &p, 10); if (p == uid || * p != '-') return MAIL_ERROR_INVAL; folder = get_mh_cur_folder(session); mh_msg_info = NULL; key.data = &indx; key.len = sizeof(indx); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r < 0) return MAIL_ERROR_MSG_NOT_FOUND; mh_msg_info = data.data; mtime_p = p + 1; mtime = strtoul(mtime_p, &p, 10); if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) { size_t size; char *size_p; size_p = p + 1; size = strtoul(size_p, &p, 10); if ((* p == '\0') && (size == mh_msg_info->msg_size)) return mhdriver_cached_get_message(session, indx, result); } else if (*p != '-') { return MAIL_ERROR_INVAL; } return MAIL_ERROR_MSG_NOT_FOUND; }
static int mhdriver_copy_message(mailsession * session, uint32_t num, const char * mb) { int fd; int r; struct mailmh_folder * folder; struct mailmh * mh; int res; mh = get_mh_session(session); if (mh == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } folder = get_mh_cur_folder(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } r = mailmh_folder_get_message_fd(folder, num, O_RDONLY, &fd); if (r != MAIL_NO_ERROR) { res = r; goto err; } folder = mailmh_folder_find(mh->mh_main, mb); if (folder == NULL) { res = MAIL_ERROR_FOLDER_NOT_FOUND; goto close; } r = mailmh_folder_add_message_file(folder, fd); if (r != MAIL_NO_ERROR) { res = MAIL_ERROR_COPY; goto close; } close(fd); return MAIL_NO_ERROR; close: close(fd); err: return res; }
static int mhdriver_get_messages_list(mailsession * session, struct mailmessage_list ** result) { struct mailmh_folder * folder; int res; folder = get_mh_cur_folder(session); if (folder == NULL) { res = MAIL_ERROR_BAD_STATE; goto err; } mailmh_folder_update(folder); return mh_get_messages_list(folder, session, mh_message_driver, result); err: return res; }
static int mhdriver_append_message(mailsession * session, const char * message, size_t size) { int r; struct mailmh_folder * folder; folder = get_mh_cur_folder(session); if (folder == NULL) return MAIL_ERROR_BAD_STATE; r = mailmh_folder_add_message(folder, message, size); switch (r) { case MAILMH_ERROR_FILE: return MAIL_ERROR_DISKSPACE; default: return mhdriver_mh_error_to_mail_error(r); } }
static int mhdriver_delete_folder(mailsession * session, const char * mb) { int r; struct mailmh_folder * folder; struct mailmh * mh; mh = get_mh_session(session); if (mh == NULL) return MAIL_ERROR_BAD_STATE; folder = mailmh_folder_find(mh->mh_main, mb); if (folder == NULL) return MAIL_ERROR_FOLDER_NOT_FOUND; if (get_mh_cur_folder(session) == folder) get_data(session)->mh_cur_folder = NULL; r = mailmh_folder_remove_subfolder(folder); return mhdriver_mh_error_to_mail_error(r); }
static int mh_initialize(mailmessage * msg_info) { struct generic_message_t * msg; int r; char * uid; char static_uid[PATH_MAX]; struct mailmh_msg_info * mh_msg_info; chashdatum key; chashdatum data; struct mailmh_folder * folder; folder = get_mh_cur_folder(msg_info); key.data = &msg_info->msg_index; key.len = sizeof(msg_info->msg_index); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r < 0) return MAIL_ERROR_INVAL; mh_msg_info = data.data; snprintf(static_uid, PATH_MAX, "%u-%lu-%lu", msg_info->msg_index, mh_msg_info->msg_mtime, (unsigned long) mh_msg_info->msg_size); uid = strdup(static_uid); if (uid == NULL) return MAIL_ERROR_MEMORY; r = mailmessage_generic_initialize(msg_info); if (r != MAIL_NO_ERROR) { free(uid); return r; } msg = msg_info->msg_data; msg->msg_prefetch = mh_prefetch; msg->msg_prefetch_free = mh_prefetch_free; msg_info->msg_uid = uid; return MAIL_NO_ERROR; }
static int get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, mailsession * session, uint32_t num, struct mailimf_fields ** result) { int r; char keyname[PATH_MAX]; struct mailimf_fields * fields; int res; struct mailmh_folder * folder; struct mailmh_msg_info * msg_info; chashdatum key; chashdatum data; folder = get_mh_cur_folder(session); key.data = # key.len = sizeof(num); r = chash_get(folder->fl_msgs_hash, &key, &data); if (r < 0) return MAIL_ERROR_CACHE_MISS; msg_info = data.data; snprintf(keyname, PATH_MAX, "%u-%lu-%lu-envelope", num, (unsigned long) msg_info->msg_mtime, (unsigned long) msg_info->msg_size); r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields); if (r != MAIL_NO_ERROR) { res = r; goto err; } * result = fields; return MAIL_NO_ERROR; err: return res; }
static int mhdriver_messages_number(mailsession * session, const char * mb, uint32_t * result) { struct mailmh_folder * folder; uint32_t count; struct mailmh * mh; unsigned int i; mh = get_mh_session(session); if (mh == NULL) return MAIL_ERROR_BAD_STATE; if (mb != NULL) { folder = mailmh_folder_find(mh->mh_main, mb); if (folder == NULL) return MAIL_ERROR_FOLDER_NOT_FOUND; } else { folder = get_mh_cur_folder(session); if (folder == NULL) return MAIL_ERROR_BAD_STATE; } mailmh_folder_update(folder); count = 0; for (i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { struct mailmh_msg_info * msg_info; msg_info = carray_get(folder->fl_msgs_tab, i); if (msg_info != NULL) count ++; } * result = count; return MAIL_NO_ERROR; }
static int mhdriver_move_message(mailsession * session, uint32_t num, const char * mb) { int r; struct mailmh_folder * src_folder; struct mailmh_folder * dest_folder; struct mailmh * mh; mh = get_mh_session(session); if (mh == NULL) return MAIL_ERROR_BAD_STATE; src_folder = get_mh_cur_folder(session); if (src_folder == NULL) return MAIL_ERROR_BAD_STATE; dest_folder = mailmh_folder_find(mh->mh_main, mb); if (dest_folder == NULL) return MAIL_ERROR_FOLDER_NOT_FOUND; r = mailmh_folder_move_message(dest_folder, src_folder, num); return mhdriver_mh_error_to_mail_error(r); }
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 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 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; }