summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic/mhdriver_cached.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/generic/mhdriver_cached.c') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/mhdriver_cached.c93
1 files changed, 88 insertions, 5 deletions
diff --git a/kmicromail/libetpan/generic/mhdriver_cached.c b/kmicromail/libetpan/generic/mhdriver_cached.c
index 5c35089..04aa523 100644
--- a/kmicromail/libetpan/generic/mhdriver_cached.c
+++ b/kmicromail/libetpan/generic/mhdriver_cached.c
@@ -87,48 +87,50 @@ static int mhdriver_cached_expunge_folder(mailsession * session);
87static int mhdriver_cached_status_folder(mailsession * session, char * mb, 87static int mhdriver_cached_status_folder(mailsession * session, char * mb,
88 uint32_t * result_messages, uint32_t * result_recent, 88 uint32_t * result_messages, uint32_t * result_recent,
89 uint32_t * result_unseen); 89 uint32_t * result_unseen);
90 90
91static int mhdriver_cached_messages_number(mailsession * session, char * mb, 91static int mhdriver_cached_messages_number(mailsession * session, char * mb,
92 uint32_t * result); 92 uint32_t * result);
93static int mhdriver_cached_recent_number(mailsession * session, char * mb, 93static int mhdriver_cached_recent_number(mailsession * session, char * mb,
94 uint32_t * result); 94 uint32_t * result);
95static int mhdriver_cached_unseen_number(mailsession * session, char * mb, 95static int mhdriver_cached_unseen_number(mailsession * session, char * mb,
96 uint32_t * result); 96 uint32_t * result);
97 97
98static int mhdriver_cached_list_folders(mailsession * session, char * mb, 98static int mhdriver_cached_list_folders(mailsession * session, char * mb,
99 struct mail_list ** result); 99 struct mail_list ** result);
100 100
101static int mhdriver_cached_lsub_folders(mailsession * session, char * mb, 101static int mhdriver_cached_lsub_folders(mailsession * session, char * mb,
102 struct mail_list ** result); 102 struct mail_list ** result);
103 103
104static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb); 104static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb);
105 105
106static int mhdriver_cached_unsubscribe_folder(mailsession * session, 106static int mhdriver_cached_unsubscribe_folder(mailsession * session,
107 char * mb); 107 char * mb);
108 108
109static int mhdriver_cached_append_message(mailsession * session, 109static int mhdriver_cached_append_message(mailsession * session,
110 char * message, size_t size); 110 char * message, size_t size);
111static int mhdriver_cached_append_message_flags(mailsession * session,
112 char * message, size_t size, struct mail_flags * flags);
111static int mhdriver_cached_copy_message(mailsession * session, 113static int mhdriver_cached_copy_message(mailsession * session,
112 uint32_t num, char * mb); 114 uint32_t num, char * mb);
113 115
114static int mhdriver_cached_remove_message(mailsession * session, 116static int mhdriver_cached_remove_message(mailsession * session,
115 uint32_t num); 117 uint32_t num);
116 118
117static int mhdriver_cached_move_message(mailsession * session, 119static int mhdriver_cached_move_message(mailsession * session,
118 uint32_t num, char * mb); 120 uint32_t num, char * mb);
119 121
120static int 122static int
121mhdriver_cached_get_messages_list(mailsession * session, 123mhdriver_cached_get_messages_list(mailsession * session,
122 struct mailmessage_list ** result); 124 struct mailmessage_list ** result);
123 125
124static int 126static int
125mhdriver_cached_get_envelopes_list(mailsession * session, 127mhdriver_cached_get_envelopes_list(mailsession * session,
126 struct mailmessage_list * env_list); 128 struct mailmessage_list * env_list);
127 129
128static int mhdriver_cached_get_message(mailsession * session, 130static int mhdriver_cached_get_message(mailsession * session,
129 uint32_t num, mailmessage ** result); 131 uint32_t num, mailmessage ** result);
130 132
131static int mhdriver_cached_get_message_by_uid(mailsession * session, 133static int mhdriver_cached_get_message_by_uid(mailsession * session,
132 const char * uid, 134 const char * uid,
133 mailmessage ** result); 135 mailmessage ** result);
134 136
@@ -144,48 +146,49 @@ static mailsession_driver local_mh_cached_session_driver = {
144 .sess_connect_path = mhdriver_cached_connect_path, 146 .sess_connect_path = mhdriver_cached_connect_path,
145 .sess_starttls = NULL, 147 .sess_starttls = NULL,
146 .sess_login = NULL, 148 .sess_login = NULL,
147 .sess_logout = mhdriver_cached_logout, 149 .sess_logout = mhdriver_cached_logout,
148 .sess_noop = NULL, 150 .sess_noop = NULL,
149 151
150 .sess_build_folder_name = mhdriver_cached_build_folder_name, 152 .sess_build_folder_name = mhdriver_cached_build_folder_name,
151 .sess_create_folder = mhdriver_cached_create_folder, 153 .sess_create_folder = mhdriver_cached_create_folder,
152 .sess_delete_folder = mhdriver_cached_delete_folder, 154 .sess_delete_folder = mhdriver_cached_delete_folder,
153 .sess_rename_folder = mhdriver_cached_rename_folder, 155 .sess_rename_folder = mhdriver_cached_rename_folder,
154 .sess_check_folder = mhdriver_cached_check_folder, 156 .sess_check_folder = mhdriver_cached_check_folder,
155 .sess_examine_folder = NULL, 157 .sess_examine_folder = NULL,
156 .sess_select_folder = mhdriver_cached_select_folder, 158 .sess_select_folder = mhdriver_cached_select_folder,
157 .sess_expunge_folder = mhdriver_cached_expunge_folder, 159 .sess_expunge_folder = mhdriver_cached_expunge_folder,
158 .sess_status_folder = mhdriver_cached_status_folder, 160 .sess_status_folder = mhdriver_cached_status_folder,
159 .sess_messages_number = mhdriver_cached_messages_number, 161 .sess_messages_number = mhdriver_cached_messages_number,
160 .sess_recent_number = mhdriver_cached_recent_number, 162 .sess_recent_number = mhdriver_cached_recent_number,
161 .sess_unseen_number = mhdriver_cached_unseen_number, 163 .sess_unseen_number = mhdriver_cached_unseen_number,
162 .sess_list_folders = mhdriver_cached_list_folders, 164 .sess_list_folders = mhdriver_cached_list_folders,
163 .sess_lsub_folders = mhdriver_cached_lsub_folders, 165 .sess_lsub_folders = mhdriver_cached_lsub_folders,
164 .sess_subscribe_folder = mhdriver_cached_subscribe_folder, 166 .sess_subscribe_folder = mhdriver_cached_subscribe_folder,
165 .sess_unsubscribe_folder = mhdriver_cached_unsubscribe_folder, 167 .sess_unsubscribe_folder = mhdriver_cached_unsubscribe_folder,
166 168
167 .sess_append_message = mhdriver_cached_append_message, 169 .sess_append_message = mhdriver_cached_append_message,
170 .sess_append_message_flags = mhdriver_cached_append_message_flags,
168 .sess_copy_message = mhdriver_cached_copy_message, 171 .sess_copy_message = mhdriver_cached_copy_message,
169 .sess_move_message = mhdriver_cached_move_message, 172 .sess_move_message = mhdriver_cached_move_message,
170 173
171 .sess_get_messages_list = mhdriver_cached_get_messages_list, 174 .sess_get_messages_list = mhdriver_cached_get_messages_list,
172 .sess_get_envelopes_list = mhdriver_cached_get_envelopes_list, 175 .sess_get_envelopes_list = mhdriver_cached_get_envelopes_list,
173 .sess_remove_message = mhdriver_cached_remove_message, 176 .sess_remove_message = mhdriver_cached_remove_message,
174#if 0 177#if 0
175 .sess_search_messages = maildriver_generic_search_messages, 178 .sess_search_messages = maildriver_generic_search_messages,
176#endif 179#endif
177 180
178 .sess_get_message = mhdriver_cached_get_message, 181 .sess_get_message = mhdriver_cached_get_message,
179 .sess_get_message_by_uid = mhdriver_cached_get_message_by_uid, 182 .sess_get_message_by_uid = mhdriver_cached_get_message_by_uid,
180}; 183};
181 184
182mailsession_driver * mh_cached_session_driver = 185mailsession_driver * mh_cached_session_driver =
183&local_mh_cached_session_driver; 186&local_mh_cached_session_driver;
184 187
185#define ENV_NAME "env.db" 188#define ENV_NAME "env.db"
186#define FLAGS_NAME "flags.db" 189#define FLAGS_NAME "flags.db"
187 190
188 191
189static inline struct mh_cached_session_state_data * 192static inline struct mh_cached_session_state_data *
190get_cached_data(mailsession * session) 193get_cached_data(mailsession * session)
191{ 194{
@@ -862,49 +865,127 @@ static int mhdriver_cached_list_folders(mailsession * session, char * mb,
862} 865}
863 866
864static int mhdriver_cached_lsub_folders(mailsession * session, char * mb, 867static int mhdriver_cached_lsub_folders(mailsession * session, char * mb,
865 struct mail_list ** result) 868 struct mail_list ** result)
866{ 869{
867 return mailsession_lsub_folders(get_ancestor(session), mb, result); 870 return mailsession_lsub_folders(get_ancestor(session), mb, result);
868} 871}
869 872
870static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb) 873static int mhdriver_cached_subscribe_folder(mailsession * session, char * mb)
871{ 874{
872 return mailsession_subscribe_folder(get_ancestor(session), mb); 875 return mailsession_subscribe_folder(get_ancestor(session), mb);
873} 876}
874 877
875static int mhdriver_cached_unsubscribe_folder(mailsession * session, 878static int mhdriver_cached_unsubscribe_folder(mailsession * session,
876 char * mb) 879 char * mb)
877{ 880{
878 return mailsession_unsubscribe_folder(get_ancestor(session), mb); 881 return mailsession_unsubscribe_folder(get_ancestor(session), mb);
879} 882}
880 883
881/* messages operations */ 884/* messages operations */
882 885
883static int mhdriver_cached_append_message(mailsession * session, 886static int mhdriver_cached_append_message(mailsession * session,
884 char * message, size_t size) 887 char * message, size_t size)
885{ 888{
886 return mailsession_append_message(get_ancestor(session), message, size); 889 return mhdriver_cached_append_message_flags(session,
890 message, size, NULL);
891}
892
893static int mhdriver_cached_append_message_flags(mailsession * session,
894 char * message, size_t size, struct mail_flags * flags)
895{
896 int r;
897 struct mailmh_folder * folder;
898 struct mailmh_msg_info * msg_info;
899 chashdatum key;
900 chashdatum value;
901 uint32_t uid;
902 struct mh_cached_session_state_data * data;
903 char filename_flags[PATH_MAX];
904 struct mail_cache_db * cache_db_flags;
905 MMAPString * mmapstr;
906 char keyname[PATH_MAX];
907
908 folder = get_mh_cur_folder(session);
909 if (folder == NULL)
910 return MAIL_ERROR_BAD_STATE;
911
912 r = mailmh_folder_add_message_uid(folder,
913 message, size, &uid);
914
915 switch (r) {
916 case MAILMH_ERROR_FILE:
917 return MAIL_ERROR_DISKSPACE;
918
919 case MAILMH_NO_ERROR:
920 break;
921
922 default:
923 return mhdriver_mh_error_to_mail_error(r);
924 }
925
926 if (flags == NULL)
927 goto exit;
928
929 key.data = &uid;
930 key.len = sizeof(uid);
931 r = chash_get(folder->fl_msgs_hash, &key, &value);
932 if (r < 0)
933 return MAIL_ERROR_CACHE_MISS;
934
935 msg_info = value.data;
936
937 data = get_cached_data(session);
938
939 snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
940 data->mh_flags_directory, data->mh_quoted_mb, FLAGS_NAME);
941
942 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
943 if (r < 0)
944 goto exit;
945
946 mmapstr = mmap_string_new("");
947 if (mmapstr == NULL)
948 goto close_db_flags;
949
950 snprintf(keyname, PATH_MAX, "%u-%lu-%lu-flags",
951 uid, (unsigned long) msg_info->msg_mtime,
952 (unsigned long) msg_info->msg_size);
953
954 r = mhdriver_write_cached_flags(cache_db_flags, mmapstr, keyname, flags);
955
956 mmap_string_free(mmapstr);
957 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
958
959 if (r != MAIL_NO_ERROR)
960 goto exit;
961
962 return MAIL_NO_ERROR;
963
964 close_db_flags:
965 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
966 exit:
967 return MAIL_NO_ERROR;
887} 968}
888 969
889static int mhdriver_cached_copy_message(mailsession * session, 970static int mhdriver_cached_copy_message(mailsession * session,
890 uint32_t num, char * mb) 971 uint32_t num, char * mb)
891{ 972{
892 return mailsession_copy_message(get_ancestor(session), num, mb); 973 return mailsession_copy_message(get_ancestor(session), num, mb);
893} 974}
894 975
895static int mhdriver_cached_remove_message(mailsession * session, uint32_t num) 976static int mhdriver_cached_remove_message(mailsession * session, uint32_t num)
896{ 977{
897 return mailsession_remove_message(get_ancestor(session), num); 978 return mailsession_remove_message(get_ancestor(session), num);
898} 979}
899 980
900static int mhdriver_cached_move_message(mailsession * session, 981static int mhdriver_cached_move_message(mailsession * session,
901 uint32_t num, char * mb) 982 uint32_t num, char * mb)
902{ 983{
903 return mailsession_move_message(get_ancestor(session), num, mb); 984 return mailsession_move_message(get_ancestor(session), num, mb);
904} 985}
905 986
906static int 987static int
907mhdriver_cached_get_messages_list(mailsession * session, 988mhdriver_cached_get_messages_list(mailsession * session,
908 struct mailmessage_list ** result) 989 struct mailmessage_list ** result)
909{ 990{
910 struct mailmh_folder * folder; 991 struct mailmh_folder * folder;
@@ -932,95 +1013,97 @@ get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
932{ 1013{
933 int r; 1014 int r;
934 char keyname[PATH_MAX]; 1015 char keyname[PATH_MAX];
935 struct mailimf_fields * fields; 1016 struct mailimf_fields * fields;
936 int res; 1017 int res;
937 struct mailmh_folder * folder; 1018 struct mailmh_folder * folder;
938 struct mailmh_msg_info * msg_info; 1019 struct mailmh_msg_info * msg_info;
939 chashdatum key; 1020 chashdatum key;
940 chashdatum data; 1021 chashdatum data;
941 1022
942 folder = get_mh_cur_folder(session); 1023 folder = get_mh_cur_folder(session);
943 1024
944#if 0 1025#if 0
945 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num); 1026 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num);
946 if (msg_info == NULL) 1027 if (msg_info == NULL)
947 return MAIL_ERROR_CACHE_MISS; 1028 return MAIL_ERROR_CACHE_MISS;
948#endif 1029#endif
949 key.data = &num; 1030 key.data = &num;
950 key.len = sizeof(num); 1031 key.len = sizeof(num);
951 r = chash_get(folder->fl_msgs_hash, &key, &data); 1032 r = chash_get(folder->fl_msgs_hash, &key, &data);
952 if (r < 0) 1033 if (r < 0)
953 return MAIL_ERROR_CACHE_MISS; 1034 return MAIL_ERROR_CACHE_MISS;
954 msg_info = data.data; 1035 msg_info = data.data;
955 1036
956 snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope", 1037 snprintf(keyname, PATH_MAX, "%u-%lu-%lu-envelope",
957 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size); 1038 num, (unsigned long) msg_info->msg_mtime,
1039 (unsigned long) msg_info->msg_size);
958 1040
959 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields); 1041 r = generic_cache_fields_read(cache_db, mmapstr, keyname, &fields);
960 if (r != MAIL_NO_ERROR) { 1042 if (r != MAIL_NO_ERROR) {
961 res = r; 1043 res = r;
962 goto err; 1044 goto err;
963 } 1045 }
964 1046
965 * result = fields; 1047 * result = fields;
966 1048
967 return MAIL_NO_ERROR; 1049 return MAIL_NO_ERROR;
968 1050
969 err: 1051 err:
970 return res; 1052 return res;
971} 1053}
972 1054
973static int 1055static int
974write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, 1056write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr,
975 mailsession * session, uint32_t num, 1057 mailsession * session, uint32_t num,
976 struct mailimf_fields * fields) 1058 struct mailimf_fields * fields)
977{ 1059{
978 int r; 1060 int r;
979 char keyname[PATH_MAX]; 1061 char keyname[PATH_MAX];
980 int res; 1062 int res;
981 struct mailmh_folder * folder; 1063 struct mailmh_folder * folder;
982 chashdatum key; 1064 chashdatum key;
983 chashdatum data; 1065 chashdatum data;
984 struct mailmh_msg_info * msg_info; 1066 struct mailmh_msg_info * msg_info;
985 1067
986 folder = get_mh_cur_folder(session); 1068 folder = get_mh_cur_folder(session);
987#if 0 1069#if 0
988 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num); 1070 msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, num);
989 if (msg_info == NULL) { 1071 if (msg_info == NULL) {
990 res = MAIL_ERROR_CACHE_MISS; 1072 res = MAIL_ERROR_CACHE_MISS;
991 goto err; 1073 goto err;
992 } 1074 }
993#endif 1075#endif
994 key.data = &num; 1076 key.data = &num;
995 key.len = sizeof(num); 1077 key.len = sizeof(num);
996 r = chash_get(folder->fl_msgs_hash, &key, &data); 1078 r = chash_get(folder->fl_msgs_hash, &key, &data);
997 if (r < 0) 1079 if (r < 0)
998 return MAIL_ERROR_CACHE_MISS; 1080 return MAIL_ERROR_CACHE_MISS;
999 msg_info = data.data; 1081 msg_info = data.data;
1000 1082
1001 snprintf(keyname, PATH_MAX, "%u-%u-%u-envelope", 1083 snprintf(keyname, PATH_MAX, "%u-%lu-%lu-envelope",
1002 num, (uint32_t) msg_info->msg_mtime, msg_info->msg_size); 1084 num, (unsigned long) msg_info->msg_mtime,
1085 (unsigned long) msg_info->msg_size);
1003 1086
1004 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields); 1087 r = generic_cache_fields_write(cache_db, mmapstr, keyname, fields);
1005 if (r != MAIL_NO_ERROR) { 1088 if (r != MAIL_NO_ERROR) {
1006 res = r; 1089 res = r;
1007 goto err; 1090 goto err;
1008 } 1091 }
1009 1092
1010 return MAIL_NO_ERROR; 1093 return MAIL_NO_ERROR;
1011 1094
1012 err: 1095 err:
1013 return res; 1096 return res;
1014} 1097}
1015 1098
1016static int 1099static int
1017mhdriver_cached_get_envelopes_list(mailsession * session, 1100mhdriver_cached_get_envelopes_list(mailsession * session,
1018 struct mailmessage_list * env_list) 1101 struct mailmessage_list * env_list)
1019{ 1102{
1020 int r; 1103 int r;
1021 unsigned int i; 1104 unsigned int i;
1022 char filename_env[PATH_MAX]; 1105 char filename_env[PATH_MAX];
1023 char filename_flags[PATH_MAX]; 1106 char filename_flags[PATH_MAX];
1024 struct mail_cache_db * cache_db_env; 1107 struct mail_cache_db * cache_db_env;
1025 struct mail_cache_db * cache_db_flags; 1108 struct mail_cache_db * cache_db_flags;
1026 MMAPString * mmapstr; 1109 MMAPString * mmapstr;