short i/o: fix calls to write to use xwrite or write_in_full
[gitweb.git] / builtin-mailinfo.c
index ac53f76f689fdc0a44b6e4921dc08b880e1349b0..a67f3eb90b6f715714c6fa7bb931044630c74111 100644 (file)
@@ -2,22 +2,14 @@
  * Another stupid program, this one parsing the headers of an
  * email to figure out authorship and subject
  */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#ifndef NO_ICONV
-#include <iconv.h>
-#endif
-#include "git-compat-util.h"
 #include "cache.h"
 #include "builtin.h"
+#include "utf8.h"
 
 static FILE *cmitmsg, *patchfile, *fin, *fout;
 
-static int keep_subject = 0;
-static const char *metainfo_charset = NULL;
+static int keep_subject;
+static const char *metainfo_charset;
 static char line[1000];
 static char date[1000];
 static char name[1000];
@@ -31,7 +23,7 @@ static char charset[256];
 
 static char multipart_boundary[1000];
 static int multipart_boundary_len;
-static int patch_lines = 0;
+static int patch_lines;
 
 static char *sanity_check(char *name, char *email)
 {
@@ -446,22 +438,11 @@ static int read_one_header_line(char *line, int sz, FILE *in)
                        break;
        }
        /* Count mbox From headers as headers */
-       if (!ofs && !memcmp(line, "From ", 5))
+       if (!ofs && (!memcmp(line, "From ", 5) || !memcmp(line, ">From ", 6)))
                ofs = 1;
        return ofs;
 }
 
-static unsigned hexval(int c)
-{
-       if (c >= '0' && c <= '9')
-               return c - '0';
-       if (c >= 'a' && c <= 'f')
-               return c - 'a' + 10;
-       if (c >= 'A' && c <= 'F')
-               return c - 'A' + 10;
-       return ~0;
-}
-
 static int decode_q_segment(char *in, char *ot, char *ep, int rfc2047)
 {
        int c;
@@ -530,40 +511,18 @@ static int decode_b_segment(char *in, char *ot, char *ep)
 
 static void convert_to_utf8(char *line, char *charset)
 {
-#ifndef NO_ICONV
-       char *in, *out;
-       size_t insize, outsize, nrc;
-       char outbuf[4096]; /* cheat */
        static char latin_one[] = "latin1";
        char *input_charset = *charset ? charset : latin_one;
-       iconv_t conv = iconv_open(metainfo_charset, input_charset);
-
-       if (conv == (iconv_t) -1) {
-               static int warned_latin1_once = 0;
-               if (input_charset != latin_one) {
-                       fprintf(stderr, "cannot convert from %s to %s\n",
-                               input_charset, metainfo_charset);
-                       *charset = 0;
-               }
-               else if (!warned_latin1_once) {
-                       warned_latin1_once = 1;
-                       fprintf(stderr, "tried to convert from %s to %s, "
-                               "but your iconv does not work with it.\n",
-                               input_charset, metainfo_charset);
-               }
+       char *out = reencode_string(line, metainfo_charset, input_charset);
+
+       if (!out) {
+               fprintf(stderr, "cannot convert from %s to %s\n",
+                       input_charset, metainfo_charset);
+               *charset = 0;
                return;
        }
-       in = line;
-       insize = strlen(in);
-       out = outbuf;
-       outsize = sizeof(outbuf);
-       nrc = iconv(conv, &in, &insize, &out, &outsize);
-       iconv_close(conv);
-       if (nrc == (size_t) -1)
-               return;
-       *out = 0;
-       strcpy(line, outbuf);
-#endif
+       strcpy(line, out);
+       free(out);
 }
 
 static int decode_header_bq(char *it)
@@ -836,7 +795,7 @@ int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
 static const char mailinfo_usage[] =
        "git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";
 
-int cmd_mailinfo(int argc, const char **argv, char **envp)
+int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
        /* NEEDSWORK: might want to do the optional .git/ directory
         * discovery
@@ -847,7 +806,8 @@ int cmd_mailinfo(int argc, const char **argv, char **envp)
                if (!strcmp(argv[1], "-k"))
                        keep_subject = 1;
                else if (!strcmp(argv[1], "-u"))
-                       metainfo_charset = git_commit_encoding;
+                       metainfo_charset = (git_commit_encoding
+                                           ? git_commit_encoding : "utf-8");
                else if (!strncmp(argv[1], "--encoding=", 11))
                        metainfo_charset = argv[1] + 11;
                else