imap-urlauth-fetch.c revision 96fbbe9c6fd04bca25770020bf94eec50888bc9b
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "llist.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "net.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-user.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-error.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-url.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-msgpart-url.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-urlauth-private.h"
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen#include "imap-urlauth-fetch.h"
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen#include "imap-urlauth-connection.h"
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainenstruct imap_urlauth_fetch_url {
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen struct imap_urlauth_fetch_url *prev, *next;
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen char *url;
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen enum imap_urlauth_fetch_flags flags;
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen};
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainenstruct imap_urlauth_fetch {
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen struct imap_urlauth_context *uctx;
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen imap_urlauth_fetch_callback_t *callback;
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen void *context;
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen /* local urls */
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen struct imap_urlauth_fetch_url *local_urls_head, *local_urls_tail;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct imap_msgpart_url *local_url;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int pending_requests;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char *url;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum imap_urlauth_fetch_flags flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct istream *input;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t size;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen char *bodypartstruct;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen char *error;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int succeeded:1;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen unsigned int binary_has_nuls:1;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen } pending_reply;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int failed:1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen unsigned int waiting:1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen};
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainenstatic void imap_urlauth_fetch_abort_local(struct imap_urlauth_fetch *ufetch)
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen{
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen struct imap_urlauth_fetch_url *url, *url_next;
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen if (ufetch->local_url != NULL) {
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen ufetch->pending_requests--;
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen imap_msgpart_url_free(&ufetch->local_url);
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen }
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen i_free_and_null(ufetch->pending_reply.url);
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen i_free_and_null(ufetch->pending_reply.bodypartstruct);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free_and_null(ufetch->pending_reply.error);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if (ufetch->pending_reply.input != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_unref(&ufetch->pending_reply.input);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen url = ufetch->local_urls_head;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (; url != NULL; url = url_next) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen url_next = url->next;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(url->url);
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen i_free(url);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen ufetch->pending_requests--;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->local_urls_head = ufetch->local_urls_tail = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void imap_urlauth_fetch_abort(struct imap_urlauth_fetch *ufetch)
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen{
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if (ufetch->pending_requests > 0)
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen imap_urlauth_request_abort_by_context(ufetch->uctx->conn, ufetch);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen imap_urlauth_fetch_abort_local(ufetch);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(ufetch->pending_requests == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void imap_urlauth_fetch_fail(struct imap_urlauth_fetch *ufetch)
659fe5d24825b160cae512538088020d97a60239Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen imap_urlauth_fetch_abort(ufetch);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ufetch->failed = TRUE;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstruct imap_urlauth_fetch *
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenimap_urlauth_fetch_init(struct imap_urlauth_context *uctx,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen imap_urlauth_fetch_callback_t *callback, void *context)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen struct imap_urlauth_fetch *ufetch;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ufetch = i_new(struct imap_urlauth_fetch, 1);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ufetch->uctx = uctx;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ufetch->callback = callback;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ufetch->context = context;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return ufetch;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenvoid imap_urlauth_fetch_deinit(struct imap_urlauth_fetch **_ufetch)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen{
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen struct imap_urlauth_fetch *ufetch = *_ufetch;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen *_ufetch = NULL;
9e59a1f3f095b3099478562cf3f3970a24736970Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen imap_urlauth_fetch_abort(ufetch);
178511b57faa7c3f8203dd8b7e4059d00cbfc23aTimo Sirainen i_free(ufetch);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen}
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenimap_urlauth_fetch_error(struct imap_urlauth_fetch *ufetch, const char *url,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen enum imap_urlauth_fetch_flags url_flags,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const char *error)
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen{
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen struct imap_urlauth_fetch_reply reply;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen int ret;
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen ufetch->pending_requests--;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen memset(&reply, 0, sizeof(reply));
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen reply.url = url;
9e59a1f3f095b3099478562cf3f3970a24736970Timo Sirainen reply.flags = url_flags;
9e59a1f3f095b3099478562cf3f3970a24736970Timo Sirainen reply.succeeded = FALSE;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen reply.error = error;
96c253a039f102fa78a313ee05200ab3970112dcTimo Sirainen
96c253a039f102fa78a313ee05200ab3970112dcTimo Sirainen T_BEGIN {
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen ret = ufetch->callback(&reply, ufetch->pending_requests == 0,
96c253a039f102fa78a313ee05200ab3970112dcTimo Sirainen ufetch->context);
96c253a039f102fa78a313ee05200ab3970112dcTimo Sirainen } T_END;
e5c08648676d1989f6e70b95e5990c26b3e8b96bTimo Sirainen
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen if (ret == 0)
c3412ddeb9abc13f99d3caf50faf76cd99f7e9d2Timo Sirainen ufetch->waiting = TRUE;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen else if (ret < 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen imap_urlauth_fetch_fail(ufetch);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainenstatic void
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenimap_urlauth_fetch_local(struct imap_urlauth_fetch *ufetch, const char *url,
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen enum imap_urlauth_fetch_flags url_flags,
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen struct imap_url *imap_url)
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen{
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen struct imap_urlauth_fetch_reply reply;
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen struct imap_msgpart_open_result mpresult;
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen const char *error, *errormsg = NULL, *bpstruct = NULL;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen bool debug = ufetch->uctx->user->mail_debug, success;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen enum mail_error error_code;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen struct imap_msgpart_url *mpurl = NULL;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen int ret;
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen success = TRUE;
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen if (debug)
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen i_debug("Fetching local URLAUTH %s", url);
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen if (url_flags == 0)
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen url_flags = IMAP_URLAUTH_FETCH_FLAG_BODY;
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen /* fetch URL */
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen if (imap_url == NULL) {
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen ret = imap_urlauth_fetch(ufetch->uctx, url,
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen &mpurl, &error_code, &error);
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen } else {
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen ret = imap_urlauth_fetch_parsed(ufetch->uctx, imap_url,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen &mpurl, &error_code, &error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ret <= 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ret == 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen errormsg = t_strdup_printf("Failed to fetch URLAUTH \"%s\": %s",
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen url, error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (debug)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_debug("%s", errormsg);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen success = FALSE;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen /* fetch metadata */
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (success && (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen imap_msgpart_url_set_decode_to_binary(mpurl);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (success &&
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (url_flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ret = imap_msgpart_url_get_bodypartstructure(mpurl, &bpstruct, &error);
755fe6da51ab7f54aa1d86913cb344bffef60e79Timo Sirainen if (ret <= 0) {
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (ret == 0) {
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen errormsg = t_strdup_printf
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen ("Failed to read URLAUTH \"%s\": %s", url, error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (debug)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_debug("%s", errormsg);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen success = FALSE;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen /* if requested, read the message part the URL points to */
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen memset(&mpresult, 0, sizeof(mpresult));
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen if (success && ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BODY) != 0 ||
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0)) {
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen ret = imap_msgpart_url_read_part(mpurl, &mpresult, &error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ret <= 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ret == 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen errormsg = t_strdup_printf
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ("Failed to read URLAUTH \"%s\": %s", url, error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (debug)
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen i_debug("%s", errormsg);
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen }
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen success = FALSE;
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen }
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen }
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen if (debug && success) {
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen if (bpstruct != NULL)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_debug("Fetched URLAUTH yielded BODYPARTSTRUCTURE (%s)", bpstruct);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (mpresult.size == 0 || mpresult.input == NULL)
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen i_debug("Fetched URLAUTH yielded empty result");
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen else {
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen i_debug("Fetched URLAUTH yielded %"PRIuUOFF_T" bytes "
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen "of %smessage data", mpresult.size,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (mpresult.binary_decoded_input_has_nuls ? "binary " : ""));
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen }
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if (!success && ret < 0) {
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen ufetch->pending_requests--;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen (void)ufetch->callback(NULL, TRUE, ufetch->context);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen imap_urlauth_fetch_fail(ufetch);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen return;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen }
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen memset(&reply, 0, sizeof(reply));
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen reply.url = url;
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen reply.flags = url_flags;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen reply.error = errormsg;
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen reply.succeeded = success;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen reply.bodypartstruct = bpstruct;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen reply.binary_has_nuls = mpresult.binary_decoded_input_has_nuls;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen reply.size = mpresult.size;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen reply.input = mpresult.input;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ret = ufetch->callback(&reply, ufetch->pending_requests == 1,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->context);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ret == 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->local_url = mpurl;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->waiting = TRUE;
a393d9d6dabdc46cf724f8cb004a652b4036d53dTimo Sirainen } else {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ufetch->pending_requests--;
a393d9d6dabdc46cf724f8cb004a652b4036d53dTimo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (mpurl != NULL)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen imap_msgpart_url_free(&mpurl);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ret < 0)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen imap_urlauth_fetch_fail(ufetch);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen}
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainenstatic int
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainenimap_urlauth_fetch_request_callback(struct imap_urlauth_fetch_reply *reply,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen void *context)
a393d9d6dabdc46cf724f8cb004a652b4036d53dTimo Sirainen{
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen struct imap_urlauth_fetch *ufetch =
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (struct imap_urlauth_fetch *)context;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen int ret = 1;
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen if (ufetch->waiting && reply != NULL) {
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen i_assert(ufetch->pending_reply.url == NULL);
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.url = i_strdup(reply->url);
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.flags = reply->flags;
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.bodypartstruct =
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen i_strdup(reply->bodypartstruct);
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.error = i_strdup(reply->error);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (reply->input != NULL) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->pending_reply.input = reply->input;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen i_stream_ref(ufetch->pending_reply.input);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen }
484efa22e65c509f787dbbc892351146c726c257Timo Sirainen ufetch->pending_reply.size = reply->size;
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.succeeded = reply->succeeded;
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen ufetch->pending_reply.binary_has_nuls = reply->binary_has_nuls;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return 0;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ufetch->waiting = FALSE;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->pending_requests--;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (!ufetch->failed) {
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen bool last = ufetch->pending_requests == 0 || reply == NULL;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen ret = ufetch->callback(reply, last, ufetch->context);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen }
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen /* report failure only once */
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (ret < 0 || reply == NULL) {
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (!ufetch->failed)
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen imap_urlauth_fetch_abort_local(ufetch);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen ufetch->failed = TRUE;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen }
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (ret != 0)
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen imap_urlauth_fetch_deinit(&ufetch);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen return ret;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen}
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainenint imap_urlauth_fetch_url(struct imap_urlauth_fetch *ufetch, const char *url,
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen enum imap_urlauth_fetch_flags url_flags)
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen{
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen struct imap_urlauth_context *uctx = ufetch->uctx;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen enum imap_url_parse_flags url_parse_flags =
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen IMAP_URL_PARSE_ALLOW_URLAUTH;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen struct mail_user *mail_user = uctx->user;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen struct imap_url *imap_url;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen const char *error, *errormsg;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
f0f9c8e94abac18f8acd91b9e724c4c32863723aTimo Sirainen /* parse the url */
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (imap_url_parse(url, NULL, url_parse_flags, &imap_url, &error) < 0) {
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen errormsg = t_strdup_printf(
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen "Failed to fetch URLAUTH \"%s\": %s", url, error);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (mail_user->mail_debug)
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen i_debug("%s", errormsg);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen ufetch->pending_requests++;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen imap_urlauth_fetch_error(ufetch, url, url_flags, errormsg);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen return 1;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen }
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen ufetch->failed = FALSE;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen ufetch->pending_requests++;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen /* if access user and target user match, handle fetch request locally */
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (imap_url->userid != NULL &&
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen strcmp(mail_user->username, imap_url->userid) == 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen if (ufetch->waiting) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen struct imap_urlauth_fetch_url *url_local;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen url_local = i_new(struct imap_urlauth_fetch_url, 1);
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen url_local->url = i_strdup(url);
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen url_local->flags = url_flags;
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen DLLIST2_APPEND(&ufetch->local_urls_head,
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen &ufetch->local_urls_tail, url_local);
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen } else T_BEGIN {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen imap_urlauth_fetch_local(ufetch, url,
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen url_flags, imap_url);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen } T_END;
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen imap_url = NULL;
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen /* don't try to fetch remote URLs that are already known to fail access */
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen } else if (!imap_urlauth_check(uctx, imap_url, TRUE, &error)) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen errormsg = t_strdup_printf(
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen "Failed to fetch URLAUTH \"%s\": %s", url, error);
8af07808ba203f8709e2ff9eaf2291e1c4a4d53dTimo Sirainen if (mail_user->mail_debug)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_debug("%s", errormsg);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen imap_urlauth_fetch_error(ufetch, url, url_flags, errormsg);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen imap_url = NULL;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen /* create request for url */
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen if (imap_url != NULL && imap_url->userid != NULL) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (void)imap_urlauth_request_new(uctx->conn, imap_url->userid,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen url, url_flags,
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen imap_urlauth_fetch_request_callback, ufetch);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_assert(uctx->conn != NULL);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (imap_urlauth_connection_connect(uctx->conn) < 0)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return -1;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return (ufetch->pending_requests > 0 ? 0 : 1);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen}
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainenbool imap_urlauth_fetch_continue(struct imap_urlauth_fetch *ufetch)
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen{
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen struct imap_urlauth_fetch_url *url, *url_next;
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen int ret;
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ufetch->failed)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return FALSE;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (!ufetch->waiting) {
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen /* not waiting for local request handling */
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen imap_urlauth_connection_continue(ufetch->uctx->conn);
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen return ufetch->pending_requests > 0;
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen }
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (ufetch->local_url != NULL) {
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen ufetch->pending_requests--;
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen imap_msgpart_url_free(&ufetch->local_url);
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen }
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen ufetch->waiting = FALSE;
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen /* handle pending remote reply */
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen if (ufetch->pending_reply.url != NULL) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen struct imap_urlauth_fetch_reply reply;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ufetch->pending_requests--;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen memset(&reply, 0, sizeof(reply));
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen reply.url = ufetch->pending_reply.url;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen reply.flags = ufetch->pending_reply.flags;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.bodypartstruct = ufetch->pending_reply.bodypartstruct;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.error = ufetch->pending_reply.error;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.input = ufetch->pending_reply.input;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.size = ufetch->pending_reply.size;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.succeeded = ufetch->pending_reply.succeeded;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen reply.binary_has_nuls = ufetch->pending_reply.binary_has_nuls;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen ret = ufetch->callback(&reply, ufetch->pending_requests == 0,
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen ufetch->context);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (ufetch->pending_reply.url != NULL)
e5ee67f18b03015c88b579c8c1f17ebe6ce19b76Timo Sirainen i_free(ufetch->pending_reply.url);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (ufetch->pending_reply.input != NULL)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_stream_unref(&ufetch->pending_reply.input);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (ufetch->pending_reply.bodypartstruct != NULL)
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen i_free(ufetch->pending_reply.bodypartstruct);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ufetch->pending_reply.error != NULL)
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen i_free(ufetch->pending_reply.error);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (ret < 0) {
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen imap_urlauth_fetch_fail(ufetch);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen return FALSE;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen }
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen imap_urlauth_connection_continue(ufetch->uctx->conn);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (ret == 0) {
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen ufetch->waiting = TRUE;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen return TRUE;
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen }
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen }
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen /* handle pending local urls */
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen url = ufetch->local_urls_head;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen while (url != NULL) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen url_next = url->next;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen T_BEGIN {
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen imap_urlauth_fetch_local(ufetch, url->url,
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen url->flags, NULL);
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen } T_END;
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen DLLIST2_REMOVE(&ufetch->local_urls_head,
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen &ufetch->local_urls_tail, url);
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen i_free(url->url);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen i_free(url);
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ufetch->waiting)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return TRUE;
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen url = url_next;
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen }
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return ufetch->pending_requests > 0;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen}
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen