Diffstat (limited to 'kmicromail/libetpan/generic/mboxdriver_cached.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | kmicromail/libetpan/generic/mboxdriver_cached.c | 90 |
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); | |||
65 | static int mboxdriver_cached_parameters(mailsession * session, | 65 | static int mboxdriver_cached_parameters(mailsession * session, |
66 | int id, void * value); | 66 | int id, void * value); |
67 | 67 | ||
68 | static int mboxdriver_cached_connect_path(mailsession * session, char * path); | 68 | static int mboxdriver_cached_connect_path(mailsession * session, char * path); |
69 | 69 | ||
70 | static int mboxdriver_cached_logout(mailsession * session); | 70 | static int mboxdriver_cached_logout(mailsession * session); |
71 | 71 | ||
72 | static int mboxdriver_cached_check_folder(mailsession * session); | 72 | static int mboxdriver_cached_check_folder(mailsession * session); |
73 | 73 | ||
74 | static int mboxdriver_cached_expunge_folder(mailsession * session); | 74 | static int mboxdriver_cached_expunge_folder(mailsession * session); |
75 | 75 | ||
76 | static int mboxdriver_cached_status_folder(mailsession * session, char * mb, | 76 | static 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); |
79 | static int mboxdriver_cached_messages_number(mailsession * session, char * mb, | 79 | static int mboxdriver_cached_messages_number(mailsession * session, char * mb, |
80 | uint32_t * result); | 80 | uint32_t * result); |
81 | static int mboxdriver_cached_recent_number(mailsession * session, char * mb, | 81 | static int mboxdriver_cached_recent_number(mailsession * session, char * mb, |
82 | uint32_t * result); | 82 | uint32_t * result); |
83 | static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, | 83 | static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, |
84 | uint32_t * result); | 84 | uint32_t * result); |
85 | 85 | ||
86 | static int mboxdriver_cached_append_message(mailsession * session, | 86 | static int mboxdriver_cached_append_message(mailsession * session, |
87 | char * message, size_t size); | 87 | char * message, size_t size); |
88 | 88 | ||
89 | static int mboxdriver_cached_append_message_flags(mailsession * session, | ||
90 | char * message, size_t size, struct mail_flags * flags); | ||
91 | |||
89 | static int | 92 | static int |
90 | mboxdriver_cached_get_messages_list(mailsession * session, | 93 | mboxdriver_cached_get_messages_list(mailsession * session, |
91 | struct mailmessage_list ** result); | 94 | struct mailmessage_list ** result); |
92 | 95 | ||
93 | static int | 96 | static int |
94 | mboxdriver_cached_get_envelopes_list(mailsession * session, | 97 | mboxdriver_cached_get_envelopes_list(mailsession * session, |
95 | struct mailmessage_list * env_list); | 98 | struct mailmessage_list * env_list); |
96 | 99 | ||
97 | static int mboxdriver_cached_remove_message(mailsession * session, | 100 | static int mboxdriver_cached_remove_message(mailsession * session, |
98 | uint32_t num); | 101 | uint32_t num); |
99 | 102 | ||
100 | static int mboxdriver_cached_get_message(mailsession * session, | 103 | static int mboxdriver_cached_get_message(mailsession * session, |
101 | uint32_t num, mailmessage ** result); | 104 | uint32_t num, mailmessage ** result); |
102 | 105 | ||
103 | static int mboxdriver_cached_get_message_by_uid(mailsession * session, | 106 | static 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 | ||
107 | static mailsession_driver local_mbox_cached_session_driver = { | 110 | static 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 | ||
154 | mailsession_driver * mbox_cached_session_driver = | 159 | mailsession_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 | ||
163 | static int mbox_error_to_mail_error(int error) | 168 | static int mbox_error_to_mail_error(int error) |
@@ -885,49 +890,126 @@ static int mboxdriver_cached_recent_number(mailsession * session, char * mb, | |||
885 | 890 | ||
886 | static int mboxdriver_cached_unseen_number(mailsession * session, char * mb, | 891 | static 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 | ||
906 | static int mboxdriver_cached_append_message(mailsession * session, | 911 | static 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 | |||
918 | static 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 | ||
912 | static int | 994 | static int |
913 | mboxdriver_cached_get_messages_list(mailsession * session, | 995 | mboxdriver_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 | ||
932 | static int | 1014 | static int |
933 | get_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, | 1015 | get_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 = # | 1034 | key.data = # |
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 | ||
979 | static int | 1062 | static int |
980 | write_cached_envelope(struct mail_cache_db * cache_db, MMAPString * mmapstr, | 1063 | write_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 = # | 1081 | key.data = # |
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 | ||
1023 | static int | 1107 | static int |
1024 | mboxdriver_cached_get_envelopes_list(mailsession * session, | 1108 | mboxdriver_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; |