int imap_urlauth_fetch(struct imap_urlauth_context *uctx, const char *urlauth, struct imap_msgpart_url **mpurl_r, enum mail_error *error_code_r, const char **error_r) { struct imap_url *url; enum imap_url_parse_flags url_flags = IMAP_URL_PARSE_ALLOW_URLAUTH; const char *error; /* validate URL */ if (imap_url_parse(urlauth, NULL, url_flags, &url, &error) < 0) { *error_r = t_strdup_printf("Invalid URLAUTH: %s", error); *error_code_r = MAIL_ERROR_PARAMS; return 0; } return imap_urlauth_fetch_parsed(uctx, url, mpurl_r, error_code_r, error_r); }
static void imap_urlauth_fetch_local(struct imap_urlauth_fetch *ufetch, const char *url, enum imap_urlauth_fetch_flags url_flags, struct imap_url *imap_url) { struct imap_urlauth_fetch_reply reply; struct imap_msgpart_open_result mpresult; const char *error, *errormsg = NULL, *bpstruct = NULL; bool debug = ufetch->uctx->user->mail_debug, success; enum mail_error error_code; struct imap_msgpart_url *mpurl = NULL; int ret; success = TRUE; if (debug) i_debug("Fetching local URLAUTH %s", url); if (url_flags == 0) url_flags = IMAP_URLAUTH_FETCH_FLAG_BODY; /* fetch URL */ if (imap_url == NULL) { ret = imap_urlauth_fetch(ufetch->uctx, url, &mpurl, &error_code, &error); } else { ret = imap_urlauth_fetch_parsed(ufetch->uctx, imap_url, &mpurl, &error_code, &error); } if (ret <= 0) { if (ret == 0) { errormsg = t_strdup_printf("Failed to fetch URLAUTH \"%s\": %s", url, error); if (debug) i_debug("%s", errormsg); } success = FALSE; } /* fetch metadata */ if (success && (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0) imap_msgpart_url_set_decode_to_binary(mpurl); if (success && (url_flags & IMAP_URLAUTH_FETCH_FLAG_BODYPARTSTRUCTURE) != 0) { ret = imap_msgpart_url_get_bodypartstructure(mpurl, &bpstruct, &error); if (ret <= 0) { if (ret == 0) { errormsg = t_strdup_printf ("Failed to read URLAUTH \"%s\": %s", url, error); if (debug) i_debug("%s", errormsg); } success = FALSE; } } /* if requested, read the message part the URL points to */ memset(&mpresult, 0, sizeof(mpresult)); if (success && ((url_flags & IMAP_URLAUTH_FETCH_FLAG_BODY) != 0 || (url_flags & IMAP_URLAUTH_FETCH_FLAG_BINARY) != 0)) { ret = imap_msgpart_url_read_part(mpurl, &mpresult, &error); if (ret <= 0) { if (ret == 0) { errormsg = t_strdup_printf ("Failed to read URLAUTH \"%s\": %s", url, error); if (debug) i_debug("%s", errormsg); } success = FALSE; } } if (debug && success) { if (bpstruct != NULL) i_debug("Fetched URLAUTH yielded BODYPARTSTRUCTURE (%s)", bpstruct); if (mpresult.size == 0 || mpresult.input == NULL) i_debug("Fetched URLAUTH yielded empty result"); else { i_debug("Fetched URLAUTH yielded %"PRIuUOFF_T" bytes " "of %smessage data", mpresult.size, (mpresult.binary_decoded_input_has_nuls ? "binary " : "")); } } ufetch->pending_requests--; if (!success && ret < 0) { if (mpurl != NULL) imap_msgpart_url_free(&mpurl); (void)ufetch->callback(NULL, TRUE, ufetch->context); imap_urlauth_fetch_fail(ufetch); return; } memset(&reply, 0, sizeof(reply)); reply.url = url; reply.flags = url_flags; reply.error = errormsg; reply.succeeded = success; reply.bodypartstruct = bpstruct; reply.binary_has_nuls = mpresult.binary_decoded_input_has_nuls; reply.size = mpresult.size; reply.input = mpresult.input; ret = ufetch->callback(&reply, ufetch->pending_requests == 0, ufetch->context); if (ret == 0) { ufetch->local_url = mpurl; ufetch->waiting_local = TRUE; ufetch->pending_requests++; } else { if (mpurl != NULL) imap_msgpart_url_free(&mpurl); if (ret < 0) imap_urlauth_fetch_fail(ufetch); } }