git/builtin-mailinfo.c

989 lines
20 KiB
C
Raw Normal View History

/*
* Another stupid program, this one parsing the headers of an
* email to figure out authorship and subject
*/
#include "cache.h"
#include "builtin.h"
#include "utf8.h"
static FILE *cmitmsg, *patchfile, *fin, *fout;
static int keep_subject;
static const char *metainfo_charset;
static char line[1000];
static char name[1000];
static char email[1000];
static enum {
TE_DONTCARE, TE_QP, TE_BASE64,
} transfer_encoding;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static enum {
TYPE_TEXT, TYPE_OTHER,
} message_type;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static char charset[256];
static int patch_lines;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static char **p_hdr_data, **s_hdr_data;
#define MAX_HDR_PARSED 10
#define MAX_BOUNDARIES 5
static char *sanity_check(char *name, char *email)
{
int len = strlen(name);
if (len < 3 || len > 60)
return email;
if (strchr(name, '@') || strchr(name, '<') || strchr(name, '>'))
return email;
return name;
}
static int bogus_from(char *line)
{
/* John Doe <johndoe> */
char *bra, *ket, *dst, *cp;
/* This is fallback, so do not bother if we already have an
* e-mail address.
*/
if (*email)
return 0;
bra = strchr(line, '<');
if (!bra)
return 0;
ket = strchr(bra, '>');
if (!ket)
return 0;
for (dst = email, cp = bra+1; cp < ket; )
*dst++ = *cp++;
*dst = 0;
for (cp = line; isspace(*cp); cp++)
;
for (bra--; isspace(*bra); bra--)
*bra = 0;
cp = sanity_check(cp, email);
strcpy(name, cp);
return 1;
}
static int handle_from(char *in_line)
{
char line[1000];
char *at;
char *dst;
strcpy(line, in_line);
at = strchr(line, '@');
if (!at)
return bogus_from(line);
/*
* If we already have one email, don't take any confusing lines
*/
if (*email && strchr(at+1, '@'))
return 0;
/* Pick up the string around '@', possibly delimited with <>
* pair; that is the email part. White them out while copying.
*/
while (at > line) {
char c = at[-1];
if (isspace(c))
break;
if (c == '<') {
at[-1] = ' ';
break;
}
at--;
}
dst = email;
for (;;) {
unsigned char c = *at;
if (!c || c == '>' || isspace(c)) {
if (c == '>')
*at = ' ';
break;
}
*at++ = ' ';
*dst++ = c;
}
*dst++ = 0;
/* The remainder is name. It could be "John Doe <john.doe@xz>"
* or "john.doe@xz (John Doe)", but we have whited out the
* email part, so trim from both ends, possibly removing
* the () pair at the end.
*/
at = line + strlen(line);
while (at > line) {
unsigned char c = *--at;
if (!isspace(c)) {
at[(c == ')') ? 0 : 1] = 0;
break;
}
}
at = line;
for (;;) {
unsigned char c = *at;
if (!c || !isspace(c)) {
if (c == '(')
at++;
break;
}
at++;
}
at = sanity_check(at, email);
strcpy(name, at);
return 1;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static int handle_header(char *line, char *data, int ofs)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (!line || !data)
return 1;
strcpy(data, line+ofs);
return 0;
}
/* NOTE NOTE NOTE. We do not claim we do full MIME. We just attempt
* to have enough heuristics to grok MIME encoded patches often found
* on our mailing lists. For example, we do not even treat header lines
* case insensitively.
*/
static int slurp_attr(const char *line, const char *name, char *attr)
{
const char *ends, *ap = strcasestr(line, name);
size_t sz;
if (!ap) {
*attr = 0;
return 0;
}
ap += strlen(name);
if (*ap == '"') {
ap++;
ends = "\"";
}
else
ends = "; \t";
sz = strcspn(ap, ends);
memcpy(attr, ap, sz);
attr[sz] = 0;
return 1;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
struct content_type {
char *boundary;
int boundary_len;
};
static struct content_type content[MAX_BOUNDARIES];
static struct content_type *content_top = content;
static int handle_content_type(char *line)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
char boundary[256];
if (strcasestr(line, "text/") == NULL)
message_type = TYPE_OTHER;
if (slurp_attr(line, "boundary=", boundary + 2)) {
memcpy(boundary, "--", 2);
if (content_top++ >= &content[MAX_BOUNDARIES]) {
fprintf(stderr, "Too many boundaries to handle\n");
exit(1);
}
content_top->boundary_len = strlen(boundary);
content_top->boundary = xmalloc(content_top->boundary_len+1);
strcpy(content_top->boundary, boundary);
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (slurp_attr(line, "charset=", charset)) {
int i, c;
for (i = 0; (c = charset[i]) != 0; i++)
charset[i] = tolower(c);
}
return 0;
}
static int handle_content_transfer_encoding(char *line)
{
if (strcasestr(line, "base64"))
transfer_encoding = TE_BASE64;
else if (strcasestr(line, "quoted-printable"))
transfer_encoding = TE_QP;
else
transfer_encoding = TE_DONTCARE;
return 0;
}
static int is_multipart_boundary(const char *line)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
return (!memcmp(line, content_top->boundary, content_top->boundary_len));
}
static int eatspace(char *line)
{
int len = strlen(line);
while (len > 0 && isspace(line[len-1]))
line[--len] = 0;
return len;
}
static char *cleanup_subject(char *subject)
{
for (;;) {
char *p;
int len, remove;
switch (*subject) {
case 'r': case 'R':
if (!memcmp("e:", subject+1, 2)) {
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
subject += 3;
continue;
}
break;
case ' ': case '\t': case ':':
subject++;
continue;
case '[':
p = strchr(subject, ']');
if (!p) {
subject++;
continue;
}
len = strlen(p);
remove = p - subject;
if (remove <= len *2) {
subject = p+1;
continue;
}
break;
}
eatspace(subject);
return subject;
}
}
static void cleanup_space(char *buf)
{
unsigned char c;
while ((c = *buf) != 0) {
buf++;
if (isspace(c)) {
buf[-1] = ' ';
c = *buf;
while (isspace(c)) {
int len = strlen(buf);
memmove(buf, buf+1, len);
c = *buf;
}
}
}
}
static void decode_header(char *it, unsigned itsize);
static const char *header[MAX_HDR_PARSED] = {
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
"From","Subject","Date",
};
static int check_header(char *line, unsigned linesize, char **hdr_data, int overwrite)
{
int i;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
/* search for the interesting parts */
for (i = 0; header[i]; i++) {
int len = strlen(header[i]);
if ((!hdr_data[i] || overwrite) &&
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
!strncasecmp(line, header[i], len) &&
line[len] == ':' && isspace(line[len + 1])) {
/* Unwrap inline B and Q encoding, and optionally
* normalize the meta information to utf8.
*/
decode_header(line + len + 2, linesize - len - 2);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
hdr_data[i] = xmalloc(1000 * sizeof(char));
if (! handle_header(line, hdr_data[i], len + 2)) {
return 1;
}
}
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
/* Content stuff */
if (!strncasecmp(line, "Content-Type", 12) &&
line[12] == ':' && isspace(line[12 + 1])) {
decode_header(line + 12 + 2, linesize - 12 - 2);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (! handle_content_type(line)) {
return 1;
}
}
if (!strncasecmp(line, "Content-Transfer-Encoding", 25) &&
line[25] == ':' && isspace(line[25 + 1])) {
decode_header(line + 25 + 2, linesize - 25 - 2);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (! handle_content_transfer_encoding(line)) {
return 1;
}
}
/* for inbody stuff */
if (!memcmp(">From", line, 5) && isspace(line[5]))
return 1;
if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
for (i = 0; header[i]; i++) {
if (!memcmp("Subject: ", header[i], 9)) {
if (! handle_header(line, hdr_data[i], 0)) {
return 1;
}
}
}
}
/* no match */
return 0;
}
static int is_rfc2822_header(char *line)
{
/*
* The section that defines the loosest possible
* field name is "3.6.8 Optional fields".
*
* optional-field = field-name ":" unstructured CRLF
* field-name = 1*ftext
* ftext = %d33-57 / %59-126
*/
int ch;
char *cp = line;
/* Count mbox From headers as headers */
if (!memcmp(line, "From ", 5) || !memcmp(line, ">From ", 6))
return 1;
while ((ch = *cp++)) {
if (ch == ':')
return cp != line;
if ((33 <= ch && ch <= 57) ||
(59 <= ch && ch <= 126))
continue;
break;
}
return 0;
}
/*
* sz is size of 'line' buffer in bytes. Must be reasonably
* long enough to hold one physical real-world e-mail line.
*/
static int read_one_header_line(char *line, int sz, FILE *in)
{
int len;
/*
* We will read at most (sz-1) bytes and then potentially
* re-add NUL after it. Accessing line[sz] after this is safe
* and we can allow len to grow up to and including sz.
*/
sz--;
/* Get the first part of the line. */
if (!fgets(line, sz, in))
return 0;
/*
* Is it an empty line or not a valid rfc2822 header?
* If so, stop here, and return false ("not a header")
*/
len = eatspace(line);
if (!len || !is_rfc2822_header(line)) {
/* Re-add the newline */
line[len] = '\n';
line[len + 1] = '\0';
return 0;
}
/*
* Now we need to eat all the continuation lines..
* Yuck, 2822 header "folding"
*/
for (;;) {
int peek, addlen;
static char continuation[1000];
peek = fgetc(in); ungetc(peek, in);
if (peek != ' ' && peek != '\t')
break;
if (!fgets(continuation, sizeof(continuation), in))
break;
addlen = eatspace(continuation);
if (len < sz - 1) {
if (addlen >= sz - len)
addlen = sz - len - 1;
memcpy(line + len, continuation, addlen);
line[len] = '\n';
len += addlen;
}
}
line[len] = 0;
return 1;
}
static int decode_q_segment(char *in, char *ot, unsigned otsize, char *ep, int rfc2047)
{
char *otend = ot + otsize;
int c;
while ((c = *in++) != 0 && (in <= ep)) {
if (ot == otend) {
*--ot = '\0';
return -1;
}
if (c == '=') {
int d = *in++;
if (d == '\n' || !d)
break; /* drop trailing newline */
*ot++ = ((hexval(d) << 4) | hexval(*in++));
continue;
}
if (rfc2047 && c == '_') /* rfc2047 4.2 (2) */
c = 0x20;
*ot++ = c;
}
*ot = 0;
return 0;
}
static int decode_b_segment(char *in, char *ot, unsigned otsize, char *ep)
{
/* Decode in..ep, possibly in-place to ot */
int c, pos = 0, acc = 0;
char *otend = ot + otsize;
while ((c = *in++) != 0 && (in <= ep)) {
if (ot == otend) {
*--ot = '\0';
return -1;
}
if (c == '+')
c = 62;
else if (c == '/')
c = 63;
else if ('A' <= c && c <= 'Z')
c -= 'A';
else if ('a' <= c && c <= 'z')
c -= 'a' - 26;
else if ('0' <= c && c <= '9')
c -= '0' - 52;
else if (c == '=') {
/* padding is almost like (c == 0), except we do
* not output NUL resulting only from it;
* for now we just trust the data.
*/
c = 0;
}
else
continue; /* garbage */
switch (pos++) {
case 0:
acc = (c << 2);
break;
case 1:
*ot++ = (acc | (c >> 4));
acc = (c & 15) << 4;
break;
case 2:
*ot++ = (acc | (c >> 2));
acc = (c & 3) << 6;
break;
case 3:
*ot++ = (acc | c);
acc = pos = 0;
break;
}
}
*ot = 0;
return 0;
}
Do a better job at guessing unknown character sets At least in the kernel development community, we're generally slowly converting to UTF-8 everywhere, and the old default of Latin1 in emails is being supplanted by UTF-8, and it doesn't necessarily show up as such in the mail headers (because, quite frankly, when people send patches around, they want the email client to do as little as humanly possible about the patch) Despite that, it's often the case that email addresses etc still have Latin1, so I've seen emails where this is a mixed bag, with Signed-off parts being copied from email (and containing Latin1 characters), and the rest of the email being a patch in UTF-8. So this suggests a very natural change: if the target character set is utf-8 (the default), and if the source already looks like utf-8, just assume that it doesn't need any conversion at all. Only assume that it needs conversion if it isn't already valid utf-8, in which case we (for historical reasons) will assume it's Latin1. Basically no really _valid_ latin1 will ever look like utf-8, so while this changes our historical behaviour, it doesn't do so in practice, and makes the default behaviour saner for the case where the input was already in proper format. We could do a more fancy guess, of course, but this correctly handled a series of patches I just got from Andrew that had a mixture of Latin1 and UTF-8 (in different emails, but without any character set indication). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-18 01:34:44 +08:00
/*
* When there is no known charset, guess.
*
* Right now we assume that if the target is UTF-8 (the default),
* and it already looks like UTF-8 (which includes US-ASCII as its
* subset, of course) then that is what it is and there is nothing
* to do.
*
* Otherwise, we default to assuming it is Latin1 for historical
* reasons.
*/
static const char *guess_charset(const char *line, const char *target_charset)
{
if (is_encoding_utf8(target_charset)) {
if (is_utf8(line))
return NULL;
}
return "latin1";
}
static void convert_to_utf8(char *line, unsigned linesize, const char *charset)
{
Do a better job at guessing unknown character sets At least in the kernel development community, we're generally slowly converting to UTF-8 everywhere, and the old default of Latin1 in emails is being supplanted by UTF-8, and it doesn't necessarily show up as such in the mail headers (because, quite frankly, when people send patches around, they want the email client to do as little as humanly possible about the patch) Despite that, it's often the case that email addresses etc still have Latin1, so I've seen emails where this is a mixed bag, with Signed-off parts being copied from email (and containing Latin1 characters), and the rest of the email being a patch in UTF-8. So this suggests a very natural change: if the target character set is utf-8 (the default), and if the source already looks like utf-8, just assume that it doesn't need any conversion at all. Only assume that it needs conversion if it isn't already valid utf-8, in which case we (for historical reasons) will assume it's Latin1. Basically no really _valid_ latin1 will ever look like utf-8, so while this changes our historical behaviour, it doesn't do so in practice, and makes the default behaviour saner for the case where the input was already in proper format. We could do a more fancy guess, of course, but this correctly handled a series of patches I just got from Andrew that had a mixture of Latin1 and UTF-8 (in different emails, but without any character set indication). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-18 01:34:44 +08:00
char *out;
if (!charset || !*charset) {
charset = guess_charset(line, metainfo_charset);
if (!charset)
return;
}
if (!strcmp(metainfo_charset, charset))
return;
Do a better job at guessing unknown character sets At least in the kernel development community, we're generally slowly converting to UTF-8 everywhere, and the old default of Latin1 in emails is being supplanted by UTF-8, and it doesn't necessarily show up as such in the mail headers (because, quite frankly, when people send patches around, they want the email client to do as little as humanly possible about the patch) Despite that, it's often the case that email addresses etc still have Latin1, so I've seen emails where this is a mixed bag, with Signed-off parts being copied from email (and containing Latin1 characters), and the rest of the email being a patch in UTF-8. So this suggests a very natural change: if the target character set is utf-8 (the default), and if the source already looks like utf-8, just assume that it doesn't need any conversion at all. Only assume that it needs conversion if it isn't already valid utf-8, in which case we (for historical reasons) will assume it's Latin1. Basically no really _valid_ latin1 will ever look like utf-8, so while this changes our historical behaviour, it doesn't do so in practice, and makes the default behaviour saner for the case where the input was already in proper format. We could do a more fancy guess, of course, but this correctly handled a series of patches I just got from Andrew that had a mixture of Latin1 and UTF-8 (in different emails, but without any character set indication). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-18 01:34:44 +08:00
out = reencode_string(line, metainfo_charset, charset);
if (!out)
die("cannot convert from %s to %s\n",
Do a better job at guessing unknown character sets At least in the kernel development community, we're generally slowly converting to UTF-8 everywhere, and the old default of Latin1 in emails is being supplanted by UTF-8, and it doesn't necessarily show up as such in the mail headers (because, quite frankly, when people send patches around, they want the email client to do as little as humanly possible about the patch) Despite that, it's often the case that email addresses etc still have Latin1, so I've seen emails where this is a mixed bag, with Signed-off parts being copied from email (and containing Latin1 characters), and the rest of the email being a patch in UTF-8. So this suggests a very natural change: if the target character set is utf-8 (the default), and if the source already looks like utf-8, just assume that it doesn't need any conversion at all. Only assume that it needs conversion if it isn't already valid utf-8, in which case we (for historical reasons) will assume it's Latin1. Basically no really _valid_ latin1 will ever look like utf-8, so while this changes our historical behaviour, it doesn't do so in practice, and makes the default behaviour saner for the case where the input was already in proper format. We could do a more fancy guess, of course, but this correctly handled a series of patches I just got from Andrew that had a mixture of Latin1 and UTF-8 (in different emails, but without any character set indication). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-18 01:34:44 +08:00
charset, metainfo_charset);
strlcpy(line, out, linesize);
free(out);
}
static int decode_header_bq(char *it, unsigned itsize)
{
char *in, *out, *ep, *cp, *sp;
char outbuf[1000];
int rfc2047 = 0;
in = it;
out = outbuf;
while ((ep = strstr(in, "=?")) != NULL) {
int sz, encoding;
char charset_q[256], piecebuf[256];
rfc2047 = 1;
if (in != ep) {
sz = ep - in;
memcpy(out, in, sz);
out += sz;
in += sz;
}
/* E.g.
* ep : "=?iso-2022-jp?B?GyR...?= foo"
* ep : "=?ISO-8859-1?Q?Foo=FCbar?= baz"
*/
ep += 2;
cp = strchr(ep, '?');
if (!cp)
return rfc2047; /* no munging */
for (sp = ep; sp < cp; sp++)
charset_q[sp - ep] = tolower(*sp);
charset_q[cp - ep] = 0;
encoding = cp[1];
if (!encoding || cp[2] != '?')
return rfc2047; /* no munging */
ep = strstr(cp + 3, "?=");
if (!ep)
return rfc2047; /* no munging */
switch (tolower(encoding)) {
default:
return rfc2047; /* no munging */
case 'b':
sz = decode_b_segment(cp + 3, piecebuf, sizeof(piecebuf), ep);
break;
case 'q':
sz = decode_q_segment(cp + 3, piecebuf, sizeof(piecebuf), ep, 1);
break;
}
if (sz < 0)
return rfc2047;
if (metainfo_charset)
convert_to_utf8(piecebuf, sizeof(piecebuf), charset_q);
sz = strlen(piecebuf);
if (outbuf + sizeof(outbuf) <= out + sz)
return rfc2047; /* no munging */
strcpy(out, piecebuf);
out += sz;
in = ep + 2;
}
strcpy(out, in);
strlcpy(it, outbuf, itsize);
return rfc2047;
}
static void decode_header(char *it, unsigned itsize)
{
if (decode_header_bq(it, itsize))
return;
/* otherwise "it" is a straight copy of the input.
* This can be binary guck but there is no charset specified.
*/
if (metainfo_charset)
convert_to_utf8(it, itsize, "");
}
static void decode_transfer_encoding(char *line, unsigned linesize)
{
char *ep;
switch (transfer_encoding) {
case TE_QP:
ep = line + strlen(line);
decode_q_segment(line, line, linesize, ep, 0);
break;
case TE_BASE64:
ep = line + strlen(line);
decode_b_segment(line, line, linesize, ep);
break;
case TE_DONTCARE:
break;
}
}
static int handle_filter(char *line, unsigned linesize);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static int find_boundary(void)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
while(fgets(line, sizeof(line), fin) != NULL) {
if (is_multipart_boundary(line))
return 1;
}
return 0;
}
static int handle_boundary(void)
{
char newline[]="\n";
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
again:
if (!memcmp(line+content_top->boundary_len, "--", 2)) {
/* we hit an end boundary */
/* pop the current boundary off the stack */
free(content_top->boundary);
/* technically won't happen as is_multipart_boundary()
will fail first. But just in case..
*/
if (content_top-- < content) {
fprintf(stderr, "Detected mismatched boundaries, "
"can't recover\n");
exit(1);
}
handle_filter(newline, sizeof(newline));
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
/* skip to the next boundary */
if (!find_boundary())
return 0;
goto again;
}
/* set some defaults */
transfer_encoding = TE_DONTCARE;
charset[0] = 0;
message_type = TYPE_TEXT;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
/* slurp in this section's info */
while (read_one_header_line(line, sizeof(line), fin))
check_header(line, sizeof(line), p_hdr_data, 0);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
/* eat the blank line after section info */
return (fgets(line, sizeof(line), fin) != NULL);
}
static inline int patchbreak(const char *line)
{
/* Beginning of a "diff -" header? */
if (!memcmp("diff -", line, 6))
return 1;
/* CVS "Index: " line? */
if (!memcmp("Index: ", line, 7))
return 1;
/*
* "--- <filename>" starts patches without headers
* "---<sp>*" is a manual separator
*/
if (!memcmp("---", line, 3)) {
line += 3;
/* space followed by a filename? */
if (line[0] == ' ' && !isspace(line[1]))
return 1;
/* Just whitespace? */
for (;;) {
unsigned char c = *line++;
if (c == '\n')
return 1;
if (!isspace(c))
break;
}
return 0;
}
return 0;
}
static int handle_commit_msg(char *line, unsigned linesize)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static int still_looking = 1;
char *endline = line + linesize;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (!cmitmsg)
return 0;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (still_looking) {
char *cp = line;
if (isspace(*line)) {
for (cp = line + 1; *cp; cp++) {
if (!isspace(*cp))
break;
}
if (!*cp)
return 0;
}
if ((still_looking = check_header(cp, endline - cp, s_hdr_data, 0)) != 0)
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
return 0;
}
/* normalize the log message to UTF-8. */
if (metainfo_charset)
convert_to_utf8(line, endline - line, charset);
if (patchbreak(line)) {
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
fclose(cmitmsg);
cmitmsg = NULL;
return 1;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
fputs(line, cmitmsg);
return 0;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static int handle_patch(char *line)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
fputs(line, patchfile);
patch_lines++;
return 0;
}
static int handle_filter(char *line, unsigned linesize)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static int filter = 0;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
/* filter tells us which part we left off on
* a non-zero return indicates we hit a filter point
*/
switch (filter) {
case 0:
if (!handle_commit_msg(line, linesize))
break;
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
filter++;
case 1:
if (!handle_patch(line))
break;
filter++;
default:
return 1;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
return 0;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static void handle_body(void)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
int rc = 0;
static char newline[2000];
static char *np = newline;
/* Skip up to the first boundary */
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (content_top->boundary) {
if (!find_boundary())
return;
}
do {
/* process any boundary lines */
if (content_top->boundary && is_multipart_boundary(line)) {
/* flush any leftover */
if ((transfer_encoding == TE_BASE64) &&
(np != newline)) {
handle_filter(newline, sizeof(newline));
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
}
if (!handle_boundary())
return;
}
/* Unwrap transfer encoding */
decode_transfer_encoding(line, sizeof(line));
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
switch (transfer_encoding) {
case TE_BASE64:
case TE_QP:
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
{
char *op = line;
/* binary data most likely doesn't have newlines */
if (message_type != TYPE_TEXT) {
rc = handle_filter(line, sizeof(newline));
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
break;
}
/* this is a decoded line that may contain
* multiple new lines. Pass only one chunk
* at a time to handle_filter()
*/
do {
while (*op != '\n' && *op != 0)
*np++ = *op++;
*np = *op;
if (*np != 0) {
/* should be sitting on a new line */
*(++np) = 0;
op++;
rc = handle_filter(newline, sizeof(newline));
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
np = newline;
}
} while (*op != 0);
/* the partial chunk is saved in newline and
* will be appended by the next iteration of fgets
*/
break;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
default:
rc = handle_filter(line, sizeof(newline));
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
if (rc)
/* nothing left to filter */
break;
} while (fgets(line, sizeof(line), fin));
return;
}
static void output_header_lines(FILE *fout, const char *hdr, char *data)
{
while (1) {
char *ep = strchr(data, '\n');
int len;
if (!ep)
len = strlen(data);
else
len = ep - data;
fprintf(fout, "%s: %.*s\n", hdr, len, data);
if (!ep)
break;
data = ep + 1;
}
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
static void handle_info(void)
{
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
char *sub;
char *hdr;
int i;
for (i = 0; header[i]; i++) {
/* only print inbody headers if we output a patch file */
if (patch_lines && s_hdr_data[i])
hdr = s_hdr_data[i];
else if (p_hdr_data[i])
hdr = p_hdr_data[i];
else
continue;
if (!memcmp(header[i], "Subject", 7)) {
if (keep_subject)
sub = hdr;
else {
sub = cleanup_subject(hdr);
cleanup_space(sub);
}
output_header_lines(fout, "Subject", sub);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
} else if (!memcmp(header[i], "From", 4)) {
handle_from(hdr);
fprintf(fout, "Author: %s\n", name);
fprintf(fout, "Email: %s\n", email);
} else {
cleanup_space(hdr);
fprintf(fout, "%s: %s\n", header[i], hdr);
}
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
fprintf(fout, "\n");
}
static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
const char *msg, const char *patch)
{
int peek;
keep_subject = ks;
metainfo_charset = encoding;
fin = in;
fout = out;
cmitmsg = fopen(msg, "w");
if (!cmitmsg) {
perror(msg);
return -1;
}
patchfile = fopen(patch, "w");
if (!patchfile) {
perror(patch);
fclose(cmitmsg);
return -1;
}
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(char *));
s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(char *));
do {
peek = fgetc(in);
} while (isspace(peek));
ungetc(peek, in);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
/* process the email header */
while (read_one_header_line(line, sizeof(line), fin))
check_header(line, sizeof(line), p_hdr_data, 1);
builtin-mailinfo.c infrastrcture changes I am working on a project that required parsing through regular mboxes that didn't necessarily have patches embedded in them. I started by creating my own modified copy of git-am and working from there. Very quickly, I noticed git-mailinfo wasn't able to handle a big chunk of my email. After hacking up numerous solutions and running into more limitations, I decided it was just easier to rewrite a big chunk of it. The following patch has a bunch of fixes and features that I needed in order for me do what I wanted. Note: I'm didn't follow any email rfc papers but I don't think any of the changes I did required much knowledge (besides the boundary stuff). List of major changes/fixes: - can't create empty patch files fix - empty patch files don't fail, this failure will come inside git-am - multipart boundaries are now handled - only output inbody headers if a patch exists otherwise assume those headers are part of the reply and instead output the original headers - decode and filter base64 patches correctly - various other accidental fixes I believe I didn't break any existing functionality or compatibility (other than what I describe above, which is really only the empty patch file). I tested this through various mailing list archives and everything seemed to parse correctly (a couple thousand emails). [jc: squashed in another patch from Don's five patch series to fix the test case, as this patch exposes the bug in the test.] Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-13 03:52:04 +08:00
handle_body();
handle_info();
return 0;
}
static const char mailinfo_usage[] =
"git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";
int cmd_mailinfo(int argc, const char **argv, const char *prefix)
{
const char *def_charset;
/* NEEDSWORK: might want to do the optional .git/ directory
* discovery
*/
git_config(git_default_config);
def_charset = (git_commit_encoding ? git_commit_encoding : "utf-8");
metainfo_charset = def_charset;
while (1 < argc && argv[1][0] == '-') {
if (!strcmp(argv[1], "-k"))
keep_subject = 1;
else if (!strcmp(argv[1], "-u"))
metainfo_charset = def_charset;
else if (!strcmp(argv[1], "-n"))
metainfo_charset = NULL;
else if (!prefixcmp(argv[1], "--encoding="))
metainfo_charset = argv[1] + 11;
else
usage(mailinfo_usage);
argc--; argv++;
}
if (argc != 3)
usage(mailinfo_usage);
return !!mailinfo(stdin, stdout, keep_subject, metainfo_charset, argv[1], argv[2]);
}