comparison src/lib-imap-storage/imap-msgpart-url.c @ 14594:27c8a6c9088d

Error handling API changes to previous IMAP URL related changes.
author Timo Sirainen <tss@iki.fi>
date Sat, 02 Jun 2012 19:01:25 +0300
parents 07e6ca397a72
children 6fb61872b30a
comparison
equal deleted inserted replaced
14593:e445670e7332 14594:27c8a6c9088d
42 mpurl->partial_offset = url->partial_offset; 42 mpurl->partial_offset = url->partial_offset;
43 mpurl->partial_size = url->partial_size; 43 mpurl->partial_size = url->partial_size;
44 return mpurl; 44 return mpurl;
45 } 45 }
46 46
47 struct imap_msgpart_url * 47 int imap_msgpart_url_parse(struct mail_user *user, struct mailbox *selected_box,
48 imap_msgpart_url_parse(struct mail_user *user, struct mailbox *selected_box, 48 const char *urlstr, struct imap_msgpart_url **url_r,
49 const char *urlstr, const char **error_r) 49 const char **error_r)
50 { 50 {
51 struct mailbox_status box_status; 51 struct mailbox_status box_status;
52 struct imap_url base_url, *url; 52 struct imap_url base_url, *url;
53 const char *error; 53 const char *error;
54 54
60 base_url.mailbox = mailbox_get_vname(selected_box); 60 base_url.mailbox = mailbox_get_vname(selected_box);
61 base_url.uidvalidity = box_status.uidvalidity; 61 base_url.uidvalidity = box_status.uidvalidity;
62 } 62 }
63 63
64 /* parse url */ 64 /* parse url */
65 url = imap_url_parse(urlstr, NULL, &base_url, 65 if (imap_url_parse(urlstr, &base_url,
66 IMAP_URL_PARSE_REQUIRE_RELATIVE, &error); 66 IMAP_URL_PARSE_REQUIRE_RELATIVE, &url, &error) < 0) {
67 if (url == NULL) {
68 *error_r = t_strconcat("Invalid IMAP URL: ", error, NULL); 67 *error_r = t_strconcat("Invalid IMAP URL: ", error, NULL);
69 return NULL; 68 return -1;
70 } 69 }
71 if (url->mailbox == NULL) { 70 if (url->mailbox == NULL) {
72 *error_r = "Mailbox-relative IMAP URL, but no mailbox selected"; 71 *error_r = "Mailbox-relative IMAP URL, but no mailbox selected";
73 return NULL; 72 return -1;
74 } 73 }
75 if (url->uid == 0 || url->search_program != NULL) { 74 if (url->uid == 0 || url->search_program != NULL) {
76 *error_r = "Invalid messagepart IMAP URL"; 75 *error_r = "Invalid messagepart IMAP URL";
77 return NULL; 76 return -1;
78 } 77 }
79 return imap_msgpart_url_create(user, url); 78 *url_r = imap_msgpart_url_create(user, url);
79 return 0;
80 } 80 }
81 81
82 struct mailbox *imap_msgpart_url_get_mailbox(struct imap_msgpart_url *mpurl) 82 struct mailbox *imap_msgpart_url_get_mailbox(struct imap_msgpart_url *mpurl)
83 { 83 {
84 return mpurl->box; 84 return mpurl->box;
85 } 85 }
86 86
87 struct mailbox * 87 int imap_msgpart_url_open_mailbox(struct imap_msgpart_url *mpurl,
88 imap_msgpart_url_open_mailbox(struct imap_msgpart_url *mpurl, 88 struct mailbox **box_r, const char **error_r)
89 const char **error_r)
90 { 89 {
91 struct mailbox_status box_status; 90 struct mailbox_status box_status;
92 enum mail_error error_code; 91 enum mail_error error_code;
93 enum mailbox_flags flags = MAILBOX_FLAG_READONLY; 92 enum mailbox_flags flags = MAILBOX_FLAG_READONLY;
94 struct mail_namespace *ns; 93 struct mail_namespace *ns;
95 struct mailbox *box; 94 struct mailbox *box;
96 95
97 if (mpurl->box != NULL) 96 if (mpurl->box != NULL) {
98 return mpurl->box; 97 *box_r = mpurl->box;
98 return 1;
99 }
99 100
100 /* find mailbox namespace */ 101 /* find mailbox namespace */
101 ns = mail_namespace_find(mpurl->user->namespaces, mpurl->mailbox); 102 ns = mail_namespace_find(mpurl->user->namespaces, mpurl->mailbox);
102 if (ns == NULL) { 103 if (ns == NULL) {
103 *error_r = "Nonexistent mailbox namespace"; 104 *error_r = "Nonexistent mailbox namespace";
104 return NULL; 105 return 0;
105 } 106 }
106 107
107 /* open mailbox */ 108 /* open mailbox */
108 box = mailbox_alloc(ns->list, mpurl->mailbox, flags); 109 box = mailbox_alloc(ns->list, mpurl->mailbox, flags);
109 if (mailbox_open(box) < 0) { 110 if (mailbox_open(box) < 0) {
110 *error_r = mail_storage_get_last_error(mailbox_get_storage(box), 111 *error_r = mail_storage_get_last_error(mailbox_get_storage(box),
111 &error_code); 112 &error_code);
112 mailbox_free(&box); 113 mailbox_free(&box);
113 return NULL; 114 return error_code == MAIL_ERROR_TEMP ? -1 : 0;
114 } 115 }
115 116
116 /* verify UIDVALIDITY */ 117 /* verify UIDVALIDITY */
117 mailbox_get_open_status(box, STATUS_UIDVALIDITY, &box_status); 118 mailbox_get_open_status(box, STATUS_UIDVALIDITY, &box_status);
118 if (mpurl->uidvalidity > 0 && 119 if (mpurl->uidvalidity > 0 &&
119 box_status.uidvalidity != mpurl->uidvalidity) { 120 box_status.uidvalidity != mpurl->uidvalidity) {
120 *error_r = "Invalid UIDVALIDITY"; 121 *error_r = "Invalid UIDVALIDITY";
121 mailbox_free(&box); 122 mailbox_free(&box);
122 return NULL; 123 return 0;
123 } 124 }
124 mpurl->box = box; 125 mpurl->box = box;
125 return box; 126 *box_r = box;
126 } 127 return 1;
127 128 }
128 struct mail * 129
129 imap_msgpart_url_open_mail(struct imap_msgpart_url *mpurl, const char **error_r) 130 int imap_msgpart_url_open_mail(struct imap_msgpart_url *mpurl,
131 struct mail **mail_r, const char **error_r)
130 { 132 {
131 struct mailbox_transaction_context *t; 133 struct mailbox_transaction_context *t;
132 struct mail *mail; 134 struct mailbox *box;
133 135 struct mail *mail;
134 if (mpurl->mail != NULL) 136 int ret;
135 return mpurl->mail; 137
138 if (mpurl->mail != NULL) {
139 *mail_r = mpurl->mail;
140 return 1;
141 }
136 142
137 /* open mailbox if it is not yet open */ 143 /* open mailbox if it is not yet open */
138 if (mpurl->box == NULL) { 144 if ((ret = imap_msgpart_url_open_mailbox(mpurl, &box, error_r)) <= 0)
139 if (imap_msgpart_url_open_mailbox(mpurl, error_r) == NULL) 145 return ret;
140 return NULL;
141 }
142 146
143 /* start transaction */ 147 /* start transaction */
144 t = mailbox_transaction_begin(mpurl->box, 0); 148 t = mailbox_transaction_begin(box, 0);
145 mail = mail_alloc(t, 0, NULL); 149 mail = mail_alloc(t, 0, NULL);
146 150
147 /* find the message */ 151 /* find the message */
148 if (!mail_set_uid(mail, mpurl->uid)) { 152 if (!mail_set_uid(mail, mpurl->uid)) {
149 *error_r = "Message not found"; 153 *error_r = "Message not found";
150 mail_free(&mail); 154 mail_free(&mail);
151 mailbox_transaction_rollback(&t); 155 mailbox_transaction_rollback(&t);
152 return NULL; 156 return 0;
153 } 157 }
154 158
155 mpurl->trans = t; 159 mpurl->trans = t;
156 mpurl->mail = mail; 160 mpurl->mail = mail;
157 return mail; 161 *mail_r = mail;
158 } 162 return 1;
159 163 }
160 bool imap_msgpart_url_read_part(struct imap_msgpart_url *mpurl, 164
161 struct istream **stream_r, uoff_t *size_r, 165 int imap_msgpart_url_read_part(struct imap_msgpart_url *mpurl,
162 const char **error_r) 166 struct istream **stream_r, uoff_t *size_r,
163 { 167 const char **error_r)
168 {
169 struct mail *mail;
164 struct istream *input; 170 struct istream *input;
165 uoff_t part_size; 171 uoff_t part_size;
172 int ret;
166 173
167 if (mpurl->input != NULL) { 174 if (mpurl->input != NULL) {
168 i_stream_seek(mpurl->input, 0); 175 i_stream_seek(mpurl->input, 0);
169 *stream_r = mpurl->input; 176 *stream_r = mpurl->input;
170 *size_r = mpurl->part_size; 177 *size_r = mpurl->part_size;
171 return TRUE; 178 return 1;
172 } 179 }
173 180
174 /* open mailbox if it is not yet open */ 181 /* open mail if it is not yet open */
175 if (mpurl->mail == NULL) { 182 if ((ret = imap_msgpart_url_open_mail(mpurl, &mail, error_r)) <= 0)
176 if (imap_msgpart_url_open_mail(mpurl, error_r) == NULL) 183 return ret;
177 return FALSE;
178 }
179 184
180 /* open the referenced part as a stream */ 185 /* open the referenced part as a stream */
181 if (!imap_msgpart_open(mpurl->mail, mpurl->section, 186 if ((ret = imap_msgpart_open(mail, mpurl->section,
182 mpurl->partial_offset, mpurl->partial_size, 187 mpurl->partial_offset, mpurl->partial_size,
183 &input, &part_size, error_r)) 188 &input, &part_size, error_r)) <= 0)
184 return FALSE; 189 return ret;
185 190
186 mpurl->input = input; 191 mpurl->input = input;
187 mpurl->part_size = part_size; 192 mpurl->part_size = part_size;
188 193
189 *stream_r = input; 194 *stream_r = input;
190 *size_r = part_size; 195 *size_r = part_size;
191 return TRUE; 196 return 1;
192 } 197 }
193 198
194 bool imap_msgpart_url_verify(struct imap_msgpart_url *mpurl, 199 int imap_msgpart_url_verify(struct imap_msgpart_url *mpurl,
195 const char **error_r) 200 const char **error_r)
196 { 201 {
202 struct mail *mail;
203 int ret;
204
197 if (mpurl->input != NULL) 205 if (mpurl->input != NULL)
198 return TRUE; 206 return 1;
199 207
200 /* open mailbox if it is not yet open */ 208 /* open mail if it is not yet open */
201 if (mpurl->mail == NULL) { 209 if ((ret = imap_msgpart_url_open_mail(mpurl, &mail, error_r)) <= 0)
202 if (imap_msgpart_url_open_mail(mpurl, error_r) == NULL) 210 return ret;
203 return FALSE;
204 }
205 211
206 /* open the referenced part as a stream */ 212 /* open the referenced part as a stream */
207 if (!imap_msgpart_verify(mpurl->mail, mpurl->section, error_r)) 213 return imap_msgpart_verify(mail, mpurl->section, error_r);
208 return FALSE;
209 return TRUE;
210 } 214 }
211 215
212 void imap_msgpart_url_free(struct imap_msgpart_url **_mpurl) 216 void imap_msgpart_url_free(struct imap_msgpart_url **_mpurl)
213 { 217 {
214 struct imap_msgpart_url *mpurl = *_mpurl; 218 struct imap_msgpart_url *mpurl = *_mpurl;