|
|
|
@ -128,7 +128,6 @@ struct imap_cmd_cb {
@@ -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, ...)
@@ -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; |
|
|
|
@ -558,20 +557,6 @@ static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx,
@@ -558,20 +557,6 @@ static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx,
|
|
|
|
|
return cmd; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
__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,
@@ -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,
@@ -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,
@@ -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)
@@ -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)
@@ -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
@@ -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)
@@ -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:
@@ -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)
@@ -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)
@@ -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; |
|
|
|
|
|
|
|
|
|