summaryrefslogtreecommitdiff
path: root/imap-send.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2014-09-09 12:54:08 -0700
committerJunio C Hamano <gitster@pobox.com>2014-09-09 12:54:09 -0700
commitc0ad561a468f7f95c3697b73b7cffc2851988a8b (patch)
tree0d6778d054d20a81af0907ca3f9af08256428273 /imap-send.c
parent64014894cfd29114a6b60cc501f06a68b5f3606b (diff)
parente0d8e3084f47189916e3b1d7bf138a4ab6227798 (diff)
downloadgit-c0ad561a468f7f95c3697b73b7cffc2851988a8b.tar.gz
Merge branch 'tf/imap-send-create'
* tf/imap-send-create: imap-send: create target mailbox if it is missing imap-send: clarify CRAM-MD5 vs LOGIN documentation
Diffstat (limited to 'imap-send.c')
-rw-r--r--imap-send.c81
1 files changed, 31 insertions, 50 deletions
diff --git a/imap-send.c b/imap-send.c
index 524fbabc96..87f9bb18f6 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -128,7 +128,6 @@ struct imap_cmd_cb {
char *data;
int dlen;
int uid;
- unsigned create:1, trycreate:1;
};
struct imap_cmd {
@@ -493,9 +492,9 @@ static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
return ret;
}
-static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx,
- struct imap_cmd_cb *cb,
- const char *fmt, va_list ap)
+static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
+ struct imap_cmd_cb *cb,
+ const char *fmt, va_list ap)
{
struct imap *imap = ctx->imap;
struct imap_cmd *cmd;
@@ -559,20 +558,6 @@ static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx,
}
__attribute__((format (printf, 3, 4)))
-static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
- struct imap_cmd_cb *cb,
- const char *fmt, ...)
-{
- struct imap_cmd *ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = v_issue_imap_cmd(ctx, cb, fmt, ap);
- va_end(ap);
- return ret;
-}
-
-__attribute__((format (printf, 3, 4)))
static int imap_exec(struct imap_store *ctx, struct imap_cmd_cb *cb,
const char *fmt, ...)
{
@@ -580,7 +565,7 @@ static int imap_exec(struct imap_store *ctx, struct imap_cmd_cb *cb,
struct imap_cmd *cmdp;
va_start(ap, fmt);
- cmdp = v_issue_imap_cmd(ctx, cb, fmt, ap);
+ cmdp = issue_imap_cmd(ctx, cb, fmt, ap);
va_end(ap);
if (!cmdp)
return RESP_BAD;
@@ -596,7 +581,7 @@ static int imap_exec_m(struct imap_store *ctx, struct imap_cmd_cb *cb,
struct imap_cmd *cmdp;
va_start(ap, fmt);
- cmdp = v_issue_imap_cmd(ctx, cb, fmt, ap);
+ cmdp = issue_imap_cmd(ctx, cb, fmt, ap);
va_end(ap);
if (!cmdp)
return DRV_STORE_BAD;
@@ -714,8 +699,8 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb,
static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
{
struct imap *imap = ctx->imap;
- struct imap_cmd *cmdp, **pcmdp, *ncmdp;
- char *cmd, *arg, *arg1, *p;
+ struct imap_cmd *cmdp, **pcmdp;
+ char *cmd, *arg, *arg1;
int n, resp, resp2, tag;
for (;;) {
@@ -801,30 +786,9 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
if (!strcmp("OK", arg))
resp = DRV_OK;
else {
- if (!strcmp("NO", arg)) {
- if (cmdp->cb.create && cmd && (cmdp->cb.trycreate || !memcmp(cmd, "[TRYCREATE]", 11))) { /* SELECT, APPEND or UID COPY */
- p = strchr(cmdp->cmd, '"');
- if (!issue_imap_cmd(ctx, NULL, "CREATE \"%.*s\"", (int)(strchr(p + 1, '"') - p + 1), p)) {
- resp = RESP_BAD;
- goto normal;
- }
- /* not waiting here violates the spec, but a server that does not
- grok this nonetheless violates it too. */
- cmdp->cb.create = 0;
- if (!(ncmdp = issue_imap_cmd(ctx, &cmdp->cb, "%s", cmdp->cmd))) {
- resp = RESP_BAD;
- goto normal;
- }
- free(cmdp->cmd);
- free(cmdp);
- if (!tcmd)
- return 0; /* ignored */
- if (cmdp == tcmd)
- tcmd = ncmdp;
- continue;
- }
+ if (!strcmp("NO", arg))
resp = RESP_NO;
- } else /*if (!strcmp("BAD", arg))*/
+ else /*if (!strcmp("BAD", arg))*/
resp = RESP_BAD;
fprintf(stderr, "IMAP command '%s' returned response (%s) - %s\n",
memcmp(cmdp->cmd, "LOGIN", 5) ?
@@ -833,7 +797,6 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
}
if ((resp2 = parse_response_code(ctx, &cmdp->cb, cmd)) > resp)
resp = resp2;
- normal:
if (cmdp->cb.done)
cmdp->cb.done(ctx, cmdp, resp);
free(cmdp->cb.data);
@@ -944,7 +907,7 @@ static int auth_cram_md5(struct imap_store *ctx, struct imap_cmd *cmd, const cha
return 0;
}
-static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
+static struct imap_store *imap_open_store(struct imap_server_conf *srvc, char *folder)
{
struct credential cred = CREDENTIAL_INIT;
struct imap_store *ctx;
@@ -1156,6 +1119,25 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
credential_approve(&cred);
credential_clear(&cred);
+ /* check the target mailbox exists */
+ ctx->name = folder;
+ switch (imap_exec(ctx, NULL, "EXAMINE \"%s\"", ctx->name)) {
+ case RESP_OK:
+ /* ok */
+ break;
+ case RESP_BAD:
+ fprintf(stderr, "IMAP error: could not check mailbox\n");
+ goto out;
+ case RESP_NO:
+ if (imap_exec(ctx, NULL, "CREATE \"%s\"", ctx->name) == RESP_OK) {
+ imap_info("Created missing mailbox\n");
+ } else {
+ fprintf(stderr, "IMAP error: could not create missing mailbox\n");
+ goto out;
+ }
+ break;
+ }
+
ctx->prefix = "";
return ctx;
@@ -1164,6 +1146,7 @@ bail:
credential_reject(&cred);
credential_clear(&cred);
+ out:
imap_close_store(ctx);
return NULL;
}
@@ -1219,7 +1202,6 @@ static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg)
box = ctx->name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
- cb.create = 0;
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" ", prefix, box);
imap->caps = imap->rcaps;
if (ret != DRV_OK)
@@ -1418,14 +1400,13 @@ int main(int argc, char **argv)
}
/* write it to the imap server */
- ctx = imap_open_store(&server);
+ ctx = imap_open_store(&server, imap_folder);
if (!ctx) {
fprintf(stderr, "failed to open store\n");
return 1;
}
fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : "");
- ctx->name = imap_folder;
while (1) {
unsigned percent = n * 100 / total;