upload-archive: use argv_array to store client arguments
[gitweb.git] / imap-send.c
index 10236f3611a9a4ffb3cd7e2d264526bff2cf88c8..21dc20b57d392c5789043968d28a3b958b2b50c7 100644 (file)
@@ -33,12 +33,6 @@ typedef void *SSL;
 #include <openssl/hmac.h>
 #endif
 
-struct store {
-       /* currently open mailbox */
-       const char *name; /* foreign! maybe preset? */
-       int uidvalidity;
-};
-
 static const char imap_send_usage[] = "git imap-send < <mbox>";
 
 #undef DRV_OK
@@ -123,7 +117,8 @@ struct imap {
 };
 
 struct imap_store {
-       struct store gen;
+       /* currently open mailbox */
+       const char *name; /* foreign! maybe preset? */
        int uidvalidity;
        struct imap *imap;
        const char *prefix;
@@ -619,7 +614,7 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb,
        *p++ = 0;
        arg = next_arg(&s);
        if (!strcmp("UIDVALIDITY", arg)) {
-               if (!(arg = next_arg(&s)) || !(ctx->gen.uidvalidity = atoi(arg))) {
+               if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg))) {
                        fprintf(stderr, "IMAP error: malformed UIDVALIDITY status\n");
                        return RESP_BAD;
                }
@@ -637,7 +632,7 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb,
                for (; isspace((unsigned char)*p); p++);
                fprintf(stderr, "*** IMAP ALERT *** %s\n", p);
        } else if (cb && cb->ctx && !strcmp("APPENDUID", arg)) {
-               if (!(arg = next_arg(&s)) || !(ctx->gen.uidvalidity = atoi(arg)) ||
+               if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg)) ||
                    !(arg = next_arg(&s)) || !(*(int *)cb->ctx = atoi(arg))) {
                        fprintf(stderr, "IMAP error: malformed APPENDUID status\n");
                        return RESP_BAD;
@@ -792,9 +787,9 @@ static void imap_close_server(struct imap_store *ictx)
        free(imap);
 }
 
-static void imap_close_store(struct store *ctx)
+static void imap_close_store(struct imap_store *ctx)
 {
-       imap_close_server((struct imap_store *)ctx);
+       imap_close_server(ctx);
        free(ctx);
 }
 
@@ -879,7 +874,7 @@ static int auth_cram_md5(struct imap_store *ctx, struct imap_cmd *cmd, const cha
        return 0;
 }
 
-static struct store *imap_open_store(struct imap_server_conf *srvc)
+static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
 {
        struct imap_store *ctx;
        struct imap *imap;
@@ -1089,58 +1084,51 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)
        } /* !preauth */
 
        ctx->prefix = "";
-       return (struct store *)ctx;
+       return ctx;
 
 bail:
-       imap_close_store(&ctx->gen);
+       imap_close_store(ctx);
        return NULL;
 }
 
+/*
+ * Insert CR characters as necessary in *msg to ensure that every LF
+ * character in *msg is preceded by a CR.
+ */
 static void lf_to_crlf(struct strbuf *msg)
 {
-       size_t new_len;
        char *new;
-       int i, j, lfnum = 0;
-
-       if (msg->buf[0] == '\n')
-               lfnum++;
-       for (i = 1; i < msg->len; i++) {
-               if (msg->buf[i - 1] != '\r' && msg->buf[i] == '\n')
-                       lfnum++;
+       size_t i, j;
+       char lastc;
+
+       /* First pass: tally, in j, the size of the new string: */
+       for (i = j = 0, lastc = '\0'; i < msg->len; i++) {
+               if (msg->buf[i] == '\n' && lastc != '\r')
+                       j++; /* a CR will need to be added here */
+               lastc = msg->buf[i];
+               j++;
        }
 
-       new_len = msg->len + lfnum;
-       new = xmalloc(new_len + 1);
-       if (msg->buf[0] == '\n') {
-               new[0] = '\r';
-               new[1] = '\n';
-               i = 1;
-               j = 2;
-       } else {
-               new[0] = msg->buf[0];
-               i = 1;
-               j = 1;
-       }
-       for ( ; i < msg->len; i++) {
-               if (msg->buf[i] != '\n') {
-                       new[j++] = msg->buf[i];
-                       continue;
-               }
-               if (msg->buf[i - 1] != '\r')
+       new = xmalloc(j + 1);
+
+       /*
+        * Second pass: write the new string.  Note that this loop is
+        * otherwise identical to the first pass.
+        */
+       for (i = j = 0, lastc = '\0'; i < msg->len; i++) {
+               if (msg->buf[i] == '\n' && lastc != '\r')
                        new[j++] = '\r';
-               /* otherwise it already had CR before */
-               new[j++] = '\n';
+               lastc = new[j++] = msg->buf[i];
        }
-       strbuf_attach(msg, new, new_len, new_len + 1);
+       strbuf_attach(msg, new, j, j + 1);
 }
 
 /*
  * Store msg to IMAP.  Also detach and free the data from msg->data,
  * leaving msg->data empty.
  */
-static int imap_store_msg(struct store *gctx, struct strbuf *msg)
+static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg)
 {
-       struct imap_store *ctx = (struct imap_store *)gctx;
        struct imap *imap = ctx->imap;
        struct imap_cmd_cb cb;
        const char *prefix, *box;
@@ -1152,7 +1140,7 @@ static int imap_store_msg(struct store *gctx, struct strbuf *msg)
        cb.dlen = msg->len;
        cb.data = strbuf_detach(msg, NULL);
 
-       box = gctx->name;
+       box = ctx->name;
        prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
        cb.create = 0;
        ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" ", prefix, box);
@@ -1308,7 +1296,7 @@ int main(int argc, char **argv)
 {
        struct strbuf all_msgs = STRBUF_INIT;
        struct strbuf msg = STRBUF_INIT;
-       struct store *ctx = NULL;
+       struct imap_store *ctx = NULL;
        int ofs = 0;
        int r;
        int total, n = 0;