Commit f8fb0dab f8fb0dabcdedd106332122edc06c5f71ee2ae271 by Sam Roberts

Moved the mailbox creation functionality of folder_imap_create()

into mailbox_imap_open(). Now mailbox_imap_open() will fail if the
mailbox doesn't exist, or can't be created despite creation being
requested (like the other types of mailbox).
1 parent 5fb0001d
...@@ -229,8 +229,117 @@ mailbox_imap_destroy (mailbox_t mailbox) ...@@ -229,8 +229,117 @@ mailbox_imap_destroy (mailbox_t mailbox)
229 static int 229 static int
230 mailbox_imap_open (mailbox_t mailbox, int flags) 230 mailbox_imap_open (mailbox_t mailbox, int flags)
231 { 231 {
232 int status = 0;
233 m_imap_t m_imap = mailbox->data;
234 f_imap_t f_imap = m_imap->f_imap;
235 folder_t folder = f_imap->folder;
236 struct folder_list folders = { 0 };
237
238 /* m_imap must have been created during mailbox initialization. */
239 assert (mailbox->data);
240 assert (m_imap->name);
241
232 mailbox->flags = flags; 242 mailbox->flags = flags;
233 return folder_open (mailbox->folder, flags); 243
244 if ((status = folder_open (mailbox->folder, flags)))
245 return status;
246
247 /* We might not have to SELECT the mailbox, but we need to know it
248 exists, and CREATE it if it doesn't, and CREATE is specified in
249 the flags.
250 */
251
252 switch (m_imap->state)
253 {
254 case IMAP_NO_STATE:
255 m_imap->state = IMAP_LIST;
256
257 case IMAP_LIST:
258 status = folder_list (folder, NULL, m_imap->name, &folders);
259 if (status != 0)
260 {
261 if (status != EAGAIN && status != EINPROGRESS && status != EINTR)
262 m_imap->state = IMAP_NO_STATE;
263
264 return status;
265 }
266 m_imap->state = IMAP_NO_STATE;
267 if (folders.num)
268 return 0;
269
270 if ((flags & MU_STREAM_CREAT) == 0)
271 return ENOENT;
272
273 m_imap->state = IMAP_CREATE;
274
275 case IMAP_CREATE:
276 switch (f_imap->state)
277 {
278 case IMAP_NO_STATE:
279 {
280 char *path;
281 size_t len;
282 url_get_path (folder->url, NULL, 0, &len);
283 if (len == 0)
284 return 0;
285 path = calloc (len + 1, sizeof (*path));
286 if (path == NULL)
287 return ENOMEM;
288 url_get_path (folder->url, path, len + 1, NULL);
289 status = imap_writeline (f_imap, "g%u CREATE %s\r\n",
290 f_imap->seq, path);
291 MAILBOX_DEBUG2 (folder, MU_DEBUG_PROT, "g%u CREATE %s\n",
292 f_imap->seq, path);
293 f_imap->seq++;
294 free (path);
295 if (status != 0)
296 {
297 m_imap->state = f_imap->state = IMAP_NO_STATE;
298 return status;
299 }
300 f_imap->state = IMAP_CREATE;
301 }
302
303 case IMAP_CREATE:
304 status = imap_send (f_imap);
305 if (status != 0)
306 {
307 if (status != EAGAIN && status != EINPROGRESS
308 && status != EINTR)
309 m_imap->state = f_imap->state = IMAP_NO_STATE;
310
311 return status;
312 }
313 f_imap->state = IMAP_CREATE_ACK;
314
315 case IMAP_CREATE_ACK:
316 status = imap_parse (f_imap);
317 if (status != 0)
318 {
319 if (status == EINVAL)
320 status = EACCES;
321
322 if (status != EAGAIN && status != EINPROGRESS
323 && status != EINTR)
324 m_imap->state = f_imap->state = IMAP_NO_STATE;
325
326 return status;
327 }
328 f_imap->state = IMAP_NO_STATE;
329
330 default:
331 status = EINVAL;
332 break;
333 }
334 m_imap->state = IMAP_NO_STATE;
335 break;
336
337 default:
338 status = EINVAL;
339 break;
340 }
341
342 return status;
234 } 343 }
235 344
236 /* We can not close the folder in term of shuting down the connection but if 345 /* We can not close the folder in term of shuting down the connection but if
......