665
d(printf("parser::read() reading %d bytes\n", len));
665
d (printf ("parser::read() reading %d bytes\n", len));
667
667
there = MIN (s->inend - s->inptr, len);
668
d(printf("parser::read() there = %d bytes\n", there));
668
d (printf ("parser::read() there = %d bytes\n", there));
670
670
*databuffer = s->inptr;
671
671
s->inptr += there;
848
848
h->boundarylen = strlen (boundary) + 2;
849
849
h->boundarylenfinal = h->boundarylen + 2;
850
850
h->boundary = g_malloc (h->boundarylen + 3);
851
sprintf(h->boundary, "--%s--", boundary);
851
sprintf (h->boundary, "--%s--", boundary);
852
852
folder_push_part (s, h);
853
853
s->state = newstate;
934
934
len = read (s->fd, s->inbuf + inoffset, SCAN_BUF - inoffset);
936
r(printf("read %d bytes, offset = %d\n", len, inoffset));
936
r (printf ("read %d bytes, offset = %d\n", len, inoffset));
938
938
/* add on the last read block */
939
939
s->seek += s->inptr - s->inbuf;
940
940
s->inptr = s->inbuf;
941
941
s->inend = s->inbuf + len + inoffset;
942
942
s->eof = (len == 0);
943
r(printf("content = %d '%.*s'\n",s->inend - s->inptr, s->inend - s->inptr, s->inptr));
943
r (printf ("content = %d '%.*s'\n",s->inend - s->inptr, s->inend - s->inptr, s->inptr));
945
945
s->ioerrno = errno ? errno : EIO;
948
948
g_assert (s->inptr <= s->inend);
950
950
inend_id = purify_watch (&s->inend);
951
inbuffer_id = purify_watch_n(s->inend+1, SCAN_HEAD-1, "rw");
951
inbuffer_id = purify_watch_n (s->inend + 1, SCAN_HEAD - 1, "rw");
953
r(printf("content = %d '%.*s'\n", s->inend - s->inptr, s->inend - s->inptr, s->inptr));
953
r (printf ("content = %d '%.*s'\n", s->inend - s->inptr, s->inend - s->inptr, s->inptr));
954
954
/* set a sentinal, for the inner loops to check against */
955
955
s->inend[0] = '\n';
956
956
return s->inend - s->inptr;
1098
1098
struct _header_scan_stack *part;
1099
1099
gint len = s->inend - boundary; /* make sure we dont access past the buffer */
1101
h(printf("checking boundary marker upto %d bytes\n", len));
1101
h (printf ("checking boundary marker upto %d bytes\n", len));
1102
1102
part = s->parts;
1104
h(printf(" boundary: %s\n", part->boundary));
1105
h(printf(" against: '%.*s'\n", part->boundarylen, boundary));
1104
h (printf (" boundary: %s\n", part->boundary));
1105
h (printf (" against: '%.*s'\n", part->boundarylen, boundary));
1106
1106
if (part->boundary
1107
1107
&& part->boundarylen <= len
1108
1108
&& memcmp (boundary, part->boundary, part->boundarylen) == 0) {
1109
h(printf("matched boundary: %s\n", part->boundary));
1109
h (printf ("matched boundary: %s\n", part->boundary));
1110
1110
/* again, make sure we're in range */
1111
1111
if (part->boundarylenfinal <= len) {
1112
1112
gint extra = part->boundarylenfinal - part->boundarylen;
1120
1120
*lastone = TRUE;
1122
h(printf("checking lastone = %s\n", *lastone?"TRUE":"FALSE"));
1122
h (printf ("checking lastone = %s\n", *lastone?"TRUE":"FALSE"));
1124
h(printf("not enough room to check last one?\n"));
1124
h (printf ("not enough room to check last one?\n"));
1125
1125
*lastone = FALSE;
1127
1127
/*printf("ok, we found it! : %s \n", (*lastone)?"Last one":"More to come?");*/
1255
1255
/* check for sentinal or real end of line */
1256
1256
if (inptr > inend) {
1257
h(printf("not at end of line yet, going further\n"));
1257
h (printf ("not at end of line yet, going further\n"));
1258
1258
/* didn't find end of line within our allowed area */
1260
1260
s->midline = TRUE;
1261
1261
header_append (s, start, inptr);
1263
h(printf("got line part: '%.*s'\n", inptr-1-start, start));
1263
h (printf ("got line part: '%.*s'\n", inptr - 1 - start, start));
1264
1264
/* got a line, strip and add it, process it */
1265
1265
s->midline = FALSE;
1266
1266
header_append (s, start, inptr - 1);
1292
1292
/* otherwise, complete header, add it */
1293
1293
s->outptr[0] = 0;
1295
h(printf("header '%s' at %d\n", s->outbuf, (gint)s->header_start));
1295
h (printf ("header '%s' at %d\n", s->outbuf, (gint) s->header_start));
1297
1297
header_raw_append_parse (&h->headers, s->outbuf, s->header_start);
1298
1298
s->outptr = s->outbuf;
1405
c(printf("ran out of input, dumping what i have (%d) bytes midline = %s\n",
1406
inptr-start, s->midline?"TRUE":"FALSE"));
1409
1407
newatleast = 1;
1410
1408
} while (s->atleast > 1);
1412
c(printf("length read = %d\n", len));
1410
c (printf ("length read = %d\n", len));
1414
1412
if (s->inend > s->inptr) {
1415
1413
start = s->inptr;
1577
printf("\nSCAN STACK:\n");
1578
printf(" '%s' :\n", states[s->state]);
1575
printf ("\nSCAN STACK:\n");
1576
printf (" '%s' :\n", states[s->state]);
1581
printf(" '%s' : %s ", states[hb->savestate], hb->boundary);
1579
printf (" '%s' : %s ", states[hb->savestate], hb->boundary);
1582
1580
if (hb->content_type) {
1583
printf("(%s/%s)", hb->content_type->type, hb->content_type->subtype);
1581
printf ("(%s/%s)", hb->content_type->type, hb->content_type->subtype);
1585
printf("(default)");
1583
printf ("(default)");
1588
1586
hb = hb->parent;
1593
1591
switch (s->state) {
1596
1594
case CAMEL_MIME_PARSER_STATE_INITIAL:
1597
1595
if (s->scan_from) {
1598
1596
h = g_malloc0 (sizeof (*h));
1599
h->boundary = g_strdup("From ");
1597
h->boundary = g_strdup ("From ");
1600
1598
h->boundarylen = strlen (h->boundary);
1601
1599
h->boundarylenfinal = h->boundarylen;
1602
1600
h->from_line = g_byte_array_new ();
1614
1612
hb = folder_scan_content (s, &state, databuffer, datalength);
1615
1613
if (s->scan_pre_from && *datalength > 0) {
1616
d(printf("got pre-from content %d bytes\n", *datalength));
1614
d (printf ("got pre-from content %d bytes\n", *datalength));
1619
1617
} while (hb == h && *datalength > 0);
1621
1619
if (*datalength == 0 && hb == h) {
1622
d(printf("found 'From '\n"));
1620
d (printf ("found 'From '\n"));
1623
1621
s->start_of_from = folder_tell (s);
1624
1622
folder_scan_skip_line (s, h->from_line);
1625
1623
h->savestate = CAMEL_MIME_PARSER_STATE_INITIAL;
1648
1646
/* FIXME: should this check for MIME-Version: 1.0 as well? */
1650
1648
type = CAMEL_MIME_PARSER_STATE_HEADER;
1651
if ((content = camel_header_raw_find(&h->headers, "Content-Type", NULL))
1649
if ((content = camel_header_raw_find (&h->headers, "Content-Type", NULL))
1652
1650
&& (ct = camel_content_type_decode (content))) {
1653
if (!g_ascii_strcasecmp(ct->type, "multipart")) {
1654
if (!camel_content_type_is(ct, "multipart", "signed")
1655
&& (bound = camel_content_type_param(ct, "boundary"))) {
1656
d(printf("multipart, boundary = %s\n", bound));
1651
if (!g_ascii_strcasecmp (ct->type, "multipart")) {
1652
if (!camel_content_type_is (ct, "multipart", "signed")
1653
&& (bound = camel_content_type_param (ct, "boundary"))) {
1654
d (printf ("multipart, boundary = %s\n", bound));
1657
1655
h->boundarylen = strlen (bound) + 2;
1658
1656
h->boundarylenfinal = h->boundarylen + 2;
1659
1657
h->boundary = g_malloc (h->boundarylen + 3);
1660
sprintf(h->boundary, "--%s--", bound);
1658
sprintf (h->boundary, "--%s--", bound);
1661
1659
type = CAMEL_MIME_PARSER_STATE_MULTIPART;
1663
1661
/*camel_content_type_unref(ct);
1664
ct = camel_content_type_decode("text/plain");*/
1662
ct = camel_content_type_decode ("text/plain");*/
1665
1663
/* We can't quite do this, as it will mess up all the offsets ... */
1666
1664
/* camel_header_raw_replace(&h->headers, "Content-Type", "text/plain", offset); */
1667
1665
/*g_warning("Multipart with no boundary, treating as text/plain");*/
1669
} else if (!g_ascii_strcasecmp(ct->type, "message")) {
1670
if (!g_ascii_strcasecmp(ct->subtype, "rfc822")
1671
|| !g_ascii_strcasecmp(ct->subtype, "news")
1667
} else if (!g_ascii_strcasecmp (ct->type, "message")) {
1668
if (!g_ascii_strcasecmp (ct->subtype, "rfc822")
1669
|| !g_ascii_strcasecmp (ct->subtype, "news")
1672
1670
/*|| !g_ascii_strcasecmp(ct->subtype, "partial")*/) {
1673
1671
type = CAMEL_MIME_PARSER_STATE_MESSAGE;
1677
1675
/* make the default type for multipart/digest be message/rfc822 */
1679
&& camel_content_type_is(s->parts->content_type, "multipart", "digest"))) {
1680
ct = camel_content_type_decode("message/rfc822");
1677
&& camel_content_type_is (s->parts->content_type, "multipart", "digest"))) {
1678
ct = camel_content_type_decode ("message/rfc822");
1681
1679
type = CAMEL_MIME_PARSER_STATE_MESSAGE;
1682
d(printf("parent was multipart/digest, autoupgrading to message/rfc822?\n"));
1680
d (printf ("parent was multipart/digest, autoupgrading to message/rfc822?\n"));
1683
1681
/* maybe we should do this too?
1684
1682
* header_raw_append_parse(&h->headers, "Content-Type: message/rfc822", -1);*/
1686
ct = camel_content_type_decode("text/plain");
1684
ct = camel_content_type_decode ("text/plain");
1689
1687
h->content_type = ct;
1704
1702
hb = folder_scan_content (s, &state, databuffer, datalength);
1706
d(printf ("\n\nOriginal content: '"));
1704
d (printf ("\n\nOriginal content: '"));
1707
1705
d (fwrite (*databuffer, sizeof (gchar), *datalength, stdout));
1710
1708
if (*datalength > 0) {
1712
camel_mime_filter_filter (f->filter, *databuffer, *datalength, presize,
1713
databuffer, datalength, &presize);
1710
camel_mime_filter_filter (
1712
*databuffer, *datalength, presize,
1713
databuffer, datalength, &presize);
1714
1714
d (fwrite (*databuffer, sizeof (gchar), *datalength, stdout));
1722
1722
/* check for any filter completion data */
1724
camel_mime_filter_complete (f->filter, *databuffer, *datalength, presize,
1725
databuffer, datalength, &presize);
1724
camel_mime_filter_complete (
1725
f->filter, *databuffer, *datalength, presize,
1726
databuffer, datalength, &presize);
1748
1749
if (*datalength > 0) {
1749
1750
/* instead of a new state, we'll just store it locally and provide
1750
1751
* an accessor function */
1751
d(printf("Multipart %s Content %p: '%.*s'\n",
1752
h->prestage>0?"post":"pre", h, *datalength, *databuffer));
1753
"Multipart %s Content %p: '%.*s'\n",
1754
h->prestage > 0 ? "post" : "pre",
1755
h, *datalength, *databuffer));
1753
1756
if (h->prestage > 0) {
1754
1757
if (h->posttext == NULL)
1755
1758
h->posttext = g_byte_array_new ();
1763
1766
} while (hb == h && *datalength > 0);
1765
1768
if (*datalength == 0 && hb == h && !seenlast) {
1766
d(printf("got boundary: %s last=%d\n", hb->boundary, state));
1769
d (printf ("got boundary: %s last=%d\n", hb->boundary, state));
1767
1770
s->start_of_boundary = folder_tell (s);
1768
1771
folder_scan_skip_line (s, NULL);
1862
1865
name = argv[1];
1864
printf("opening: %s", name);
1867
printf ("opening: %s", name);
1866
1869
for (i = 1; i < argc; i++) {
1867
1870
const gchar *encoding = NULL, *charset = NULL;
1868
1871
gchar *attachname;
1870
1873
name = argv[i];
1871
printf("opening: %s", name);
1874
printf ("opening: %s", name);
1873
1876
fd = g_open (name, O_RDONLY | O_BINARY, 0);
1875
perror("Cannot open mailbox");
1878
perror ("Cannot open mailbox");
1878
1881
s = folder_scan_init ();
1886
1889
while (s->state != CAMEL_MIME_PARSER_STATE_EOF) {
1887
1890
folder_scan_step (s, &data, &len);
1888
printf("\n -- PARSER STEP RETURN -- %d '%s'\n\n", s->state, states[s->state]);
1891
printf ("\n -- PARSER STEP RETURN -- %d '%s'\n\n", s->state, states[s->state]);
1889
1892
switch (s->state) {
1890
1893
case CAMEL_MIME_PARSER_STATE_HEADER:
1891
1894
if (s->parts->content_type
1892
&& (charset = camel_content_type_param(s->parts->content_type, "charset"))) {
1893
if (g_ascii_strcasecmp(charset, "us-ascii")) {
1895
&& (charset = camel_content_type_param (s->parts->content_type, "charset"))) {
1896
if (g_ascii_strcasecmp (charset, "us-ascii")) {
1895
folder_push_filter_charset(s, "UTF-8", charset);
1898
folder_push_filter_charset (s, "UTF-8", charset);
1898
1901
charset = NULL;
1901
1904
charset = NULL;
1904
encoding = camel_header_raw_find(&s->parts->headers, "Content-transfer-encoding", 0);
1905
printf("encoding = '%s'\n", encoding);
1906
if (encoding && !g_ascii_strncasecmp(encoding, " base64", 7)) {
1907
printf("adding base64 filter\n");
1908
attachname = g_strdup_printf("attach.%d.%d", i, attach++);
1907
encoding = camel_header_raw_find (&s->parts->headers, "Content-transfer-encoding", 0);
1908
printf ("encoding = '%s'\n", encoding);
1909
if (encoding && !g_ascii_strncasecmp (encoding, " base64", 7)) {
1910
printf ("adding base64 filter\n");
1911
attachname = g_strdup_printf ("attach.%d.%d", i, attach++);
1910
1913
folder_push_filter_save (s, attachname);
1914
1917
folder_push_filter_mime (s, 0);
1917
if (encoding && !g_ascii_strncasecmp(encoding, " quoted-printable", 17)) {
1918
printf("adding quoted-printable filter\n");
1919
attachname = g_strdup_printf("attach.%d.%d", i, attach++);
1920
if (encoding && !g_ascii_strncasecmp (encoding, " quoted-printable", 17)) {
1921
printf ("adding quoted-printable filter\n");
1922
attachname = g_strdup_printf ("attach.%d.%d", i, attach++);
1921
1924
folder_push_filter_save (s, attachname);
1930
1933
case CAMEL_MIME_PARSER_STATE_BODY:
1931
printf("got body %d '%.*s'\n", len, len, data);
1934
printf ("got body %d '%.*s'\n", len, len, data);
1933
1936
case CAMEL_MIME_PARSER_STATE_BODY_END:
1934
printf("end body %d '%.*s'\n", len, len, data);
1935
if (encoding && !g_ascii_strncasecmp(encoding, " base64", 7)) {
1936
printf("removing filters\n");
1937
printf ("end body %d '%.*s'\n", len, len, data);
1938
if (encoding && !g_ascii_strncasecmp (encoding, " base64", 7)) {
1939
printf ("removing filters\n");
1938
1941
folder_filter_pull (s);
1939
1942
folder_filter_pull (s);
1942
if (encoding && !g_ascii_strncasecmp(encoding, " quoted-printable", 17)) {
1943
printf("removing filters\n");
1945
if (encoding && !g_ascii_strncasecmp (encoding, " quoted-printable", 17)) {
1946
printf ("removing filters\n");
1945
1948
folder_filter_pull (s);
1946
1949
folder_filter_pull (s);