summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic/mboxdriver_cached.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/generic/mboxdriver_cached.c') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/mboxdriver_cached.c90
1 files changed, 87 insertions, 3 deletions
diff --git a/kmicromail/libetpan/generic/mboxdriver_cached.c b/kmicromail/libetpan/generic/mboxdriver_cached.c
index 07871fa..3af7fb9 100644
--- a/kmicromail/libetpan/generic/mboxdriver_cached.c
+++ b/kmicromail/libetpan/generic/mboxdriver_cached.c
@@ -65,48 +65,51 @@ static void mboxdriver_cached_uninitialize(mailsession * session);
65static int mboxdriver_cached_parameters(mailsession * session, 65static int mboxdriver_cached_parameters(mailsession * session,
66 int id, void * value); 66 int id, void * value);
67 67
68static int mboxdriver_cached_connect_path(mailsession * session, char * path); 68static int mboxdriver_cached_connect_path(mailsession * session, char * path);
69 69
70static int mboxdriver_cached_logout(mailsession * session); 70static int mboxdriver_cached_logout(mailsession * session);
71 71
72static int mboxdriver_cached_check_folder(mailsession * session); 72static int mboxdriver_cached_check_folder(mailsession * session);
73 73
74static int mboxdriver_cached_expunge_folder(mailsession * session); 74static int mboxdriver_cached_expunge_folder(mailsession * session);
75 75
76static int mboxdriver_cached_status_folder(mailsession * session, char * mb, 76static int mboxdriver_cached_status_folder(mailsession * session, char * mb,
77 uint32_t * result_messages, uint32_t * result_recent, 77 uint32_t * result_messages, uint32_t * result_recent,
78 uint32_t * result_unseen); 78 uint32_t * result_unseen);
79static int mboxdriver_cached_messages_number(mailsession * session, char * mb, 79static int mboxdriver_cached_messages_number(mailsession * session, char * mb,
80 uint32_t * result); 80 uint32_t * result);
81static int mboxdriver_cached_recent_number(mailsession * session, char * mb, 81static int mboxdriver_cached_recent_number(mailsession * session, char * mb,
82 uint32_t * result); 82 uint32_t * result);
83static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, 83static int mboxdriver_cached_unseen_number(mailsession * session, char * mb,
84 uint32_t * result); 84 uint32_t * result);
85 85
86static int mboxdriver_cached_append_message(mailsession * session, 86static int mboxdriver_cached_append_message(mailsession * session,
87 char * message, size_t size); 87 char * message, size_t size);
88 88
89static int mboxdriver_cached_append_message_flags(mailsession * session,
90 char * message, size_t size, struct mail_flags * flags);
91
89static int 92static int
90mboxdriver_cached_get_messages_list(mailsession * session, 93mboxdriver_cached_get_messages_list(mailsession * session,
91 struct mailmessage_list ** result); 94 struct mailmessage_list ** result);
92 95
93static int 96static int
94mboxdriver_cached_get_envelopes_list(mailsession * session, 97mboxdriver_cached_get_envelopes_list(mailsession * session,
95 struct mailmessage_list * env_list); 98 struct mailmessage_list * env_list);
96 99
97static int mboxdriver_cached_remove_message(mailsession * session, 100static int mboxdriver_cached_remove_message(mailsession * session,
98 uint32_t num); 101 uint32_t num);
99 102
100static int mboxdriver_cached_get_message(mailsession * session, 103static int mboxdriver_cached_get_message(mailsession * session,
101 uint32_t num, mailmessage ** result); 104 uint32_t num, mailmessage ** result);
102 105
103static int mboxdriver_cached_get_message_by_uid(mailsession * session, 106static int mboxdriver_cached_get_message_by_uid(mailsession * session,
104 const char * uid, 107 const char * uid,
105 mailmessage ** result); 108 mailmessage ** result);
106 109
107static mailsession_driver local_mbox_cached_session_driver = { 110static mailsession_driver local_mbox_cached_session_driver = {
108 .sess_name = "mbox-cached", 111 .sess_name = "mbox-cached",
109 112
110 .sess_initialize = mboxdriver_cached_initialize, 113 .sess_initialize = mboxdriver_cached_initialize,
111 .sess_uninitialize = mboxdriver_cached_uninitialize, 114 .sess_uninitialize = mboxdriver_cached_uninitialize,
112 115
@@ -116,48 +119,50 @@ static mailsession_driver local_mbox_cached_session_driver = {
116 .sess_connect_stream = NULL, 119 .sess_connect_stream = NULL,
117 .sess_starttls = NULL, 120 .sess_starttls = NULL,
118 .sess_login = NULL, 121 .sess_login = NULL,
119 .sess_logout = mboxdriver_cached_logout, 122 .sess_logout = mboxdriver_cached_logout,
120 .sess_noop = NULL, 123 .sess_noop = NULL,
121 124
122 .sess_build_folder_name = NULL, 125 .sess_build_folder_name = NULL,
123 .sess_create_folder = NULL, 126 .sess_create_folder = NULL,
124 .sess_delete_folder = NULL, 127 .sess_delete_folder = NULL,
125 .sess_rename_folder = NULL, 128 .sess_rename_folder = NULL,
126 .sess_check_folder = mboxdriver_cached_check_folder, 129 .sess_check_folder = mboxdriver_cached_check_folder,
127 .sess_examine_folder = NULL, 130 .sess_examine_folder = NULL,
128 .sess_select_folder = NULL, 131 .sess_select_folder = NULL,
129 .sess_expunge_folder = mboxdriver_cached_expunge_folder, 132 .sess_expunge_folder = mboxdriver_cached_expunge_folder,
130 .sess_status_folder = mboxdriver_cached_status_folder, 133 .sess_status_folder = mboxdriver_cached_status_folder,
131 .sess_messages_number = mboxdriver_cached_messages_number, 134 .sess_messages_number = mboxdriver_cached_messages_number,
132 .sess_recent_number = mboxdriver_cached_recent_number, 135 .sess_recent_number = mboxdriver_cached_recent_number,
133 .sess_unseen_number = mboxdriver_cached_unseen_number, 136 .sess_unseen_number = mboxdriver_cached_unseen_number,
134 .sess_list_folders = NULL, 137 .sess_list_folders = NULL,
135 .sess_lsub_folders = NULL, 138 .sess_lsub_folders = NULL,
136 .sess_subscribe_folder = NULL, 139 .sess_subscribe_folder = NULL,
137 .sess_unsubscribe_folder = NULL, 140 .sess_unsubscribe_folder = NULL,
138 141
139 .sess_append_message = mboxdriver_cached_append_message, 142 .sess_append_message = mboxdriver_cached_append_message,
143 .sess_append_message_flags = mboxdriver_cached_append_message_flags,
144
140 .sess_copy_message = NULL, 145 .sess_copy_message = NULL,
141 .sess_move_message = NULL, 146 .sess_move_message = NULL,
142 147
143 .sess_get_messages_list = mboxdriver_cached_get_messages_list, 148 .sess_get_messages_list = mboxdriver_cached_get_messages_list,
144 .sess_get_envelopes_list = mboxdriver_cached_get_envelopes_list, 149 .sess_get_envelopes_list = mboxdriver_cached_get_envelopes_list,
145 .sess_remove_message = mboxdriver_cached_remove_message, 150 .sess_remove_message = mboxdriver_cached_remove_message,
146#if 0 151#if 0
147 .sess_search_messages = maildriver_generic_search_messages, 152 .sess_search_messages = maildriver_generic_search_messages,
148#endif 153#endif
149 154
150 .sess_get_message = mboxdriver_cached_get_message, 155 .sess_get_message = mboxdriver_cached_get_message,
151 .sess_get_message_by_uid = mboxdriver_cached_get_message_by_uid, 156 .sess_get_message_by_uid = mboxdriver_cached_get_message_by_uid,
152}; 157};
153 158
154mailsession_driver * mbox_cached_session_driver = 159mailsession_driver * mbox_cached_session_driver =
155&local_mbox_cached_session_driver; 160&local_mbox_cached_session_driver;
156 161
157 162
158#define ENV_NAME "env.db" 163#define ENV_NAME "env.db"
159#define FLAGS_NAME "flags.db" 164#define FLAGS_NAME "flags.db"
160 165
161 166
162 167
163static int mbox_error_to_mail_error(int error) 168static int mbox_error_to_mail_error(int error)
@@ -885,49 +890,126 @@ static int mboxdriver_cached_recent_number(mailsession * session, char * mb,
885 890
886static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, 891static int mboxdriver_cached_unseen_number(mailsession * session, char * mb,
887 uint32_t * result) 892 uint32_t * result)
888{ 893{
889 uint32_t messages; 894 uint32_t messages;
890 uint32_t recent; 895 uint32_t recent;
891 uint32_t unseen; 896 uint32_t unseen;
892 int r; 897 int r;
893 898
894 r = mboxdriver_cached_status_folder(session, mb, 899 r = mboxdriver_cached_status_folder(session, mb,
895 &messages, &recent, &unseen); 900 &messages, &recent, &unseen);
896 if (r != MAIL_NO_ERROR) 901 if (r != MAIL_NO_ERROR)
897 return r; 902 return r;
898 903
899 * result = unseen; 904 * result = unseen;
900 905
901 return MAIL_NO_ERROR; 906 return MAIL_NO_ERROR;
902} 907}
903 908
904/* messages operations */ 909/* messages operations */
905 910
906static int mboxdriver_cached_append_message(mailsession * session, 911static int mboxdriver_cached_append_message(mailsession * session,
907 char * message, size_t size) 912 char * message, size_t size)
908{ 913{
909 return mailsession_append_message(get_ancestor(session), message, size); 914 return mboxdriver_cached_append_message_flags(session,
915 message, size, NULL);
916}
917
918static int mboxdriver_cached_append_message_flags(mailsession * session,
919 char * message, size_t size, struct mail_flags * flags)
920{
921 int r;
922 struct mailmbox_folder * folder;
923 struct mbox_cached_session_state_data * data;
924 unsigned int uid;
925 struct mailmbox_msg_info * msg_info;
926 chashdatum key;
927 chashdatum value;
928 struct mail_cache_db * cache_db_flags;
929 char filename_flags[PATH_MAX];
930 MMAPString * mmapstr;
931 char keyname[PATH_MAX];
932
933 folder = get_mbox_session(session);
934 if (folder == NULL)
935 return MAIL_ERROR_APPEND;
936
937 r = mailmbox_append_message_uid(folder, message, size, &uid);
938
939 switch (r) {
940 case MAILMBOX_ERROR_FILE:
941 return MAIL_ERROR_DISKSPACE;
942 case MAILMBOX_NO_ERROR:
943 break;
944 default:
945 return mboxdriver_mbox_error_to_mail_error(r);
946 }
947
948 /* could store in flags store instead */
949
950 if (flags == NULL)
951 goto exit;
952
953 key.data = &uid;
954 key.len = sizeof(uid);
955 r = chash_get(folder->mb_hash, &key, &value);
956 if (r < 0)
957 goto exit;
958
959 msg_info = value.data;
960
961 data = get_cached_data(session);
962
963 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
964 data->mbox_flags_directory, MAIL_DIR_SEPARATOR, data->mbox_quoted_mb,
965 MAIL_DIR_SEPARATOR, FLAGS_NAME);
966
967 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
968 if (r < 0)
969 goto exit;
970
971 mmapstr = mmap_string_new("");
972 if (mmapstr == NULL)
973 goto close_db_flags;
974
975 snprintf(keyname, PATH_MAX, "%u-%lu", uid,
976 (unsigned long) msg_info->msg_body_len);
977
978 r = mboxdriver_write_cached_flags(cache_db_flags, mmapstr, keyname, flags);
979
980 mmap_string_free(mmapstr);
981 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
982
983 if (r != MAIL_NO_ERROR)
984 goto exit;
985
986 return MAIL_NO_ERROR;
987
988 close_db_flags:
989 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
990 exit:
991 return MAIL_NO_ERROR;
910} 992}
911 993
912static int 994static int
913mboxdriver_cached_get_messages_list(mailsession * session, 995mboxdriver_cached_get_messages_list(mailsession * session,
914 struct mailmessage_list ** result) 996 struct mailmessage_list ** result)
915{ 997{
916 struct mailmbox_folder * folder; 998 struct mailmbox_folder * folder;
917 int res; 999 int res;
918 1000
919 folder = get_mbox_session(session); 1001 folder = get_mbox_session(session);
920 if (folder == NULL) { 1002 if (folder == NULL) {
921 res = MAIL_ERROR_BAD_STATE; 1003 res = MAIL_ERROR_BAD_STATE;
922 goto err; 1004 goto err;
923 } 1005 }
924 1006
925 return mbox_get_uid_messages_list(folder, 1007 return mbox_get_uid_messages_list(folder,
926 session, mbox_cached_message_driver, result); 1008 session, mbox_cached_message_driver, result);
927 1009
928 err: 1010 err:
929 return res; 1011 return res;
930} 1012}
931 1013
932static int 1014static int
933get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, 1015get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
@@ -939,95 +1021,97 @@ get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
939 struct mailimf_fields * fields; 1021 struct mailimf_fields * fields;
940 int res; 1022 int res;
941 struct mailmbox_msg_info * info; 1023 struct mailmbox_msg_info * info;
942 struct mailmbox_folder * folder; 1024 struct mailmbox_folder * folder;
943 chashdatum key; 1025 chashdatum key;
944 chashdatum data; 1026 chashdatum data;
945 1027
946 folder = get_mbox_session(session); 1028 folder = get_mbox_session(session);
947 if (folder == NULL) { 1029 if (folder == NULL) {
948 res = MAIL_ERROR_BAD_STATE; 1030 res = MAIL_ERROR_BAD_STATE;
949 goto err; 1031 goto err;
950 } 1032 }
951 1033
952 key.data = &num; 1034 key.data = &num;
953 key.len = sizeof(num); 1035 key.len = sizeof(num);
954 1036
955 r = chash_get(folder->mb_hash, &key, &data); 1037 r = chash_get(folder->mb_hash, &key, &data);
956 if (r < 0) { 1038 if (r < 0) {
957 res = MAIL_ERROR_MSG_NOT_FOUND; 1039 res = MAIL_ERROR_MSG_NOT_FOUND;
958 goto err; 1040 goto err;
959 } 1041 }
960 1042
961 info = data.data; 1043 info = data.data;
962 1044
963 snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len); 1045 snprintf(keyname, PATH_MAX, "%u-%lu-envelope", num,
1046 (unsigned long) info->msg_body_len);
964 1047
965 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields); 1048 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
966 if (r != MAIL_NO_ERROR) { 1049 if (r != MAIL_NO_ERROR) {
967 res = r; 1050 res = r;
968 goto err; 1051 goto err;
969 } 1052 }
970 1053
971 * result = fields; 1054 * result = fields;
972 1055
973 return MAIL_NO_ERROR; 1056 return MAIL_NO_ERROR;
974 1057
975 err: 1058 err:
976 return res; 1059 return res;
977} 1060}
978 1061
979static int 1062static int
980write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, 1063write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
981 mailsession * session, uint32_t num, 1064 mailsession * session, uint32_t num,
982 struct mailimf_fields * fields) 1065 struct mailimf_fields * fields)
983{ 1066{
984 int r; 1067 int r;
985 char keyname[PATH_MAX]; 1068 char keyname[PATH_MAX];
986 int res; 1069 int res;
987 struct mailmbox_msg_info * info; 1070 struct mailmbox_msg_info * info;
988 struct mailmbox_folder * folder; 1071 struct mailmbox_folder * folder;
989 chashdatum key; 1072 chashdatum key;
990 chashdatum data; 1073 chashdatum data;
991 1074
992 folder = get_mbox_session(session); 1075 folder = get_mbox_session(session);
993 if (folder == NULL) { 1076 if (folder == NULL) {
994 res = MAIL_ERROR_BAD_STATE; 1077 res = MAIL_ERROR_BAD_STATE;
995 goto err; 1078 goto err;
996 } 1079 }
997 1080
998 key.data = &num; 1081 key.data = &num;
999 key.len = sizeof(num); 1082 key.len = sizeof(num);
1000 1083
1001 r = chash_get(folder->mb_hash, &key, &data); 1084 r = chash_get(folder->mb_hash, &key, &data);
1002 if (r < 0) { 1085 if (r < 0) {
1003 res = MAIL_ERROR_MSG_NOT_FOUND; 1086 res = MAIL_ERROR_MSG_NOT_FOUND;
1004 goto err; 1087 goto err;
1005 } 1088 }
1006 1089
1007 info = data.data; 1090 info = data.data;
1008 1091
1009 snprintf(keyname, PATH_MAX, "%u-%u-envelope", num, info->msg_body_len); 1092 snprintf(keyname, PATH_MAX, "%u-%lu-envelope", num,
1093 (unsigned long) info->msg_body_len);
1010 1094
1011 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields); 1095 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
1012 if (r != MAIL_NO_ERROR) { 1096 if (r != MAIL_NO_ERROR) {
1013 res = r; 1097 res = r;
1014 goto err; 1098 goto err;
1015 } 1099 }
1016 1100
1017 return MAIL_NO_ERROR; 1101 return MAIL_NO_ERROR;
1018 1102
1019 err: 1103 err:
1020 return res; 1104 return res;
1021} 1105}
1022 1106
1023static int 1107static int
1024mboxdriver_cached_get_envelopes_list(mailsession * session, 1108mboxdriver_cached_get_envelopes_list(mailsession * session,
1025 struct mailmessage_list * env_list) 1109 struct mailmessage_list * env_list)
1026{ 1110{
1027 int r; 1111 int r;
1028 unsigned int i; 1112 unsigned int i;
1029 struct mbox_cached_session_state_data * cached_data; 1113 struct mbox_cached_session_state_data * cached_data;
1030 char filename_env[PATH_MAX]; 1114 char filename_env[PATH_MAX];
1031 char filename_flags[PATH_MAX]; 1115 char filename_flags[PATH_MAX];
1032 struct mail_cache_db * cache_db_env; 1116 struct mail_cache_db * cache_db_env;
1033 struct mail_cache_db * cache_db_flags; 1117 struct mail_cache_db * cache_db_flags;