static void filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace) { CamelMimeFilterCharset *charset = (CamelMimeFilterCharset *)mf; size_t inleft, outleft, converted = 0; const char *inbuf; char *outbuf; if (charset->ic == (iconv_t) -1) goto noop; camel_mime_filter_set_size (mf, len * 5 + 16, FALSE); outbuf = mf->outbuf + converted; outleft = mf->outsize - converted; inbuf = in; inleft = len; do { converted = e_iconv (charset->ic, &inbuf, &inleft, &outbuf, &outleft); if (converted == (size_t) -1) { if (errno == E2BIG || errno == EINVAL) break; if (errno == EILSEQ) { /* * EILSEQ An invalid multibyte sequence has been encountered * in the input. * * What we do here is eat the invalid bytes in the sequence and continue */ inbuf++; inleft--; } else { /* unknown error condition */ goto noop; } } } while (((int) inleft) > 0); if (((int) inleft) > 0) { /* We've either got an E2BIG or EINVAL. Save the remainder of the buffer as we'll process this next time through */ camel_mime_filter_backup (mf, inbuf, inleft); } *out = mf->outbuf; *outlen = outbuf - mf->outbuf; *outprespace = mf->outpre; return; noop: *out = in; *outlen = len; *outprespace = prespace; }
static void strip_signature (CamelMimeFilter *filter, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace, int flush) { EMStripSigFilter *stripsig = (EMStripSigFilter *) filter; register const char *inptr = in; const char *inend = in + len; const char *start = NULL; if (stripsig->midline) { while (inptr < inend && *inptr != '\n') inptr++; if (inptr < inend) { stripsig->midline = FALSE; inptr++; } } while (inptr < inend) { if ((inend - inptr) >= 4 && !strncmp (inptr, "-- \n", 4)) { start = inptr; inptr += 4; } else { while (inptr < inend && *inptr != '\n') inptr++; if (inptr == inend) { stripsig->midline = TRUE; break; } inptr++; } } if (start != NULL) inptr = start; if (!flush && inend > inptr) camel_mime_filter_backup (filter, inptr, inend - inptr); else if (!start) inptr = inend; *out = in; *outlen = inptr - in; *outprespace = prespace; }
/* Yes, it is complicated ... */ static void filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace) { CamelMimeFilterFrom *f = (CamelMimeFilterFrom *)mf; register char *inptr, *inend; int left; int midline = f->midline; int fromcount = 0; struct fromnode *head = NULL, *tail = (struct fromnode *)&head, *node; char *outptr; inptr = in; inend = inptr+len; d(printf("Filtering '%.*s'\n", len, in)); /* first, see if we need to escape any from's */ while (inptr<inend) { register int c = -1; if (midline) while (inptr < inend && (c = *inptr++) != '\n') ; if (c == '\n' || !midline) { left = inend-inptr; if (left > 0) { midline = TRUE; if (left < 5) { if (inptr[0] == 'F') { camel_mime_filter_backup(mf, inptr, left); midline = FALSE; inend = inptr; break; } } else { if (!strncmp(inptr, "From ", 5)) { fromcount++; /* yes, we do alloc them on the stack ... at most we're going to get len / 7 of them anyway */ node = alloca(sizeof(*node)); node->pointer = inptr; node->next = NULL; tail->next = node; tail = node; inptr += 5; } } } else { /* \n is at end of line, check next buffer */ midline = FALSE; } } } f->midline = midline; if (fromcount > 0) { camel_mime_filter_set_size(mf, len + fromcount, FALSE); node = head; inptr = in; outptr = mf->outbuf; while (node) { memcpy(outptr, inptr, node->pointer - inptr); outptr += node->pointer - inptr; *outptr++ = '>'; inptr = node->pointer; node = node->next; } memcpy(outptr, inptr, inend - inptr); outptr += inend - inptr; *out = mf->outbuf; *outlen = outptr - mf->outbuf; *outprespace = mf->outbuf - mf->outreal; d(printf("Filtered '%.*s'\n", *outlen, *out)); } else { *out = in; *outlen = inend - in; *outprespace = prespace; d(printf("Filtered '%.*s'\n", *outlen, *out)); } }
static void filter_run(CamelMimeFilter *f, char *in, size_t inlen, size_t prespace, char **out, size_t *outlen, size_t *outprespace, int last) { CamelMimeFilterPgp *pgp = (CamelMimeFilterPgp *) f; const char *start, *inend = in + inlen; register const char *inptr = in; register char *o; gboolean blank; size_t len; /* only need as much space as the input, we're stripping chars */ camel_mime_filter_set_size (f, inlen, FALSE); o = f->outbuf; while (inptr < inend) { start = inptr; blank = TRUE; while (inptr < inend && *inptr != '\n') { if (blank && !strchr (" \t\r", *inptr)) blank = FALSE; inptr++; } if (inptr == inend) { if (!last) { camel_mime_filter_backup (f, start, inend - start); inend = start; } break; } len = inptr - start; if (len > 0 && inptr[-1] == '\r') len--; inptr++; switch (pgp->state) { case PGP_PREFACE: /* check for the beginning of the pgp block */ if (len == BEGIN_PGP_SIGNED_MESSAGE_LEN && !strncmp (start, BEGIN_PGP_SIGNED_MESSAGE, len)) { pgp->state++; break; } memcpy (o, start, inptr - start); o += (inptr - start); break; case PGP_HEADER: /* pgp headers (Hash: SHA1, etc) end with a blank (zero-length, or containing only whitespace) line; see RFC2440 */ if (blank) pgp->state++; break; case PGP_MESSAGE: /* check for beginning of the pgp signature block */ if (len == BEGIN_PGP_SIGNATURE_LEN && !strncmp (start, BEGIN_PGP_SIGNATURE, len)) { pgp->state++; break; } /* do dash decoding */ if (!strncmp (start, "- ", 2)) { /* Dash encoded line found, skip encoding */ start += 2; } memcpy (o, start, inptr - start); o += (inptr - start); break; case PGP_FOOTER: if (len == END_PGP_SIGNATURE_LEN && !strncmp (start, END_PGP_SIGNATURE, len)) pgp->state = PGP_PREFACE; break; } } *out = f->outbuf; *outlen = o - f->outbuf; *outprespace = f->outpre; }