You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@apache.org on 2006/01/06 06:18:04 UTC
svn commit: r366430 - in /httpd/mod_mbox/branches/surgery: ./ include/
src/libmbox/ src/libmime/ src/module/
Author: maxime
Date: Thu Jan 5 21:17:52 2006
New Revision: 366430
URL: http://svn.apache.org/viewcvs?rev=366430&view=rev
Log:
Include MIME decoding and CTE handling to libmbox
Added:
httpd/mod_mbox/branches/surgery/src/libmbox/mbox_cte.c (with props)
httpd/mod_mbox/branches/surgery/src/libmbox/mbox_mime.c (with props)
Removed:
httpd/mod_mbox/branches/surgery/src/libmime/
httpd/mod_mbox/branches/surgery/src/module/mod_mbox_cte.c
Modified:
httpd/mod_mbox/branches/surgery/Makefile.am
httpd/mod_mbox/branches/surgery/configure.ac
httpd/mod_mbox/branches/surgery/include/libmbox.h
httpd/mod_mbox/branches/surgery/src/libmbox/Makefile.am
httpd/mod_mbox/branches/surgery/src/module/Makefile.am
httpd/mod_mbox/branches/surgery/src/module/mod_mbox.h
httpd/mod_mbox/branches/surgery/src/module/mod_mbox_mime.c
Modified: httpd/mod_mbox/branches/surgery/Makefile.am
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/Makefile.am?rev=366430&r1=366429&r2=366430&view=diff
==============================================================================
--- httpd/mod_mbox/branches/surgery/Makefile.am (original)
+++ httpd/mod_mbox/branches/surgery/Makefile.am Thu Jan 5 21:17:52 2006
@@ -8,4 +8,4 @@
README \
STATUS
-SUBDIRS = src/libmbox src/libmime src/mod-mbox-util src/module
+SUBDIRS = src/libmbox src/mod-mbox-util src/module
Modified: httpd/mod_mbox/branches/surgery/configure.ac
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/configure.ac?rev=366430&r1=366429&r2=366430&view=diff
==============================================================================
--- httpd/mod_mbox/branches/surgery/configure.ac (original)
+++ httpd/mod_mbox/branches/surgery/configure.ac Thu Jan 5 21:17:52 2006
@@ -39,7 +39,7 @@
BIN_LDFLAGS="${LUCENE4C_LIBS} `${APR_CONFIG} --link-libtool` `${APU_CONFIG} --link-libtool` `${APU_CONFIG} --ldflags --libs` `${APR_CONFIG} --ldflags --libs`"
AC_SUBST(BIN_LDFLAGS)
-AC_CONFIG_FILES([Makefile src/module/Makefile src/libmbox/Makefile src/libmime/Makefile src/mod-mbox-util/Makefile])
+AC_CONFIG_FILES([Makefile src/module/Makefile src/libmbox/Makefile src/mod-mbox-util/Makefile])
AC_OUTPUT
echo "---"
Modified: httpd/mod_mbox/branches/surgery/include/libmbox.h
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/include/libmbox.h?rev=366430&r1=366429&r2=366430&view=diff
==============================================================================
--- httpd/mod_mbox/branches/surgery/include/libmbox.h (original)
+++ httpd/mod_mbox/branches/surgery/include/libmbox.h Thu Jan 5 21:17:52 2006
@@ -28,6 +28,7 @@
#include "util_script.h"
#include <stdio.h>
+#include <ctype.h>
#include "apr.h"
#include "apr_pools.h"
@@ -36,6 +37,7 @@
#include "apr_buckets.h"
#include "apr_dbm.h"
#include "apr_mmap.h"
+#include "apr_xlate.h"
#ifndef NO_MBOX_SEARCH
#include "lcn_init.h"
@@ -95,10 +97,6 @@
*/
typedef char* ID;
-/* Typedefs for Message and Container */
-typedef struct Message_Struct Message;
-typedef struct Container_Struct Container;
-
typedef struct mbox_mime_message
{
char *body;
@@ -115,6 +113,10 @@
unsigned int sub_count;
} mbox_mime_message_t;
+/* Typedefs for Message and Container */
+typedef struct Message_Struct Message;
+typedef struct Container_Struct Container;
+
/* The basic information about a message. */
struct Message_Struct
{
@@ -278,6 +280,20 @@
query_callback_fn_t* cb, void* baton);
apr_status_t mbox_search_close(mbox_searcher_t* ctx);
+
+/** mbox_mime */
+mbox_mime_message_t *mbox_mime_decode_multipart(apr_pool_t *p, char *body,
+ char *ct, mbox_cte_e cte,
+ char *boundary);
+
+/** mbox_cte **/
+const char *mbox_cte_to_char(mbox_cte_e cte);
+apr_size_t mbox_cte_decode_qp(char* p);
+apr_size_t mbox_cte_decode_b64(char *src);
+apr_size_t mbox_cte_escape_html(apr_pool_t *p, const char *s,
+ apr_size_t len, char **body);
+char *mbox_cte_decode_rfc2047(apr_pool_t *p, char *src);
+char *mbox_cte_decode_header(apr_pool_t *p, char *src);
#ifdef __cplusplus
}
Modified: httpd/mod_mbox/branches/surgery/src/libmbox/Makefile.am
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/src/libmbox/Makefile.am?rev=366430&r1=366429&r2=366430&view=diff
==============================================================================
--- httpd/mod_mbox/branches/surgery/src/libmbox/Makefile.am (original)
+++ httpd/mod_mbox/branches/surgery/src/libmbox/Makefile.am Thu Jan 5 21:17:52 2006
@@ -8,8 +8,10 @@
mbox_parse.c \
mbox_sort.c \
mbox_thread.c \
+ mbox_mime.c \
+ mbox_cte.c \
mbox_externals.c
-
+
libmbox_la_CFLAGS = -Wall ${MODULE_CFLAGS}
libmbox_la_LDFLAGS = -avoid-version ${MODULE_LDFLAGS}
Added: httpd/mod_mbox/branches/surgery/src/libmbox/mbox_cte.c
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/src/libmbox/mbox_cte.c?rev=366430&view=auto
==============================================================================
--- httpd/mod_mbox/branches/surgery/src/libmbox/mbox_cte.c (added)
+++ httpd/mod_mbox/branches/surgery/src/libmbox/mbox_cte.c Thu Jan 5 21:17:52 2006
@@ -0,0 +1,385 @@
+/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Decoding common Content-Encodings of E-Mail functions.
+ *
+ * These decoding functions do not copy data.
+ */
+
+#include "libmbox.h"
+
+/*
+ * The char64 macro and `mime_decode_b64' routine are taken from
+ * metamail 2.7, which is copyright (c) 1991 Bell Communications
+ * Research, Inc. (Bellcore). The following license applies to all
+ * code below this point:
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore. BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
+ */
+
+static char index_64[128] = {
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
+ 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+ -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+ 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+};
+
+#define char64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
+
+const char *mbox_cte_to_char(mbox_cte_e cte)
+{
+ switch(cte) {
+ case CTE_NONE:
+ return "None";
+ case CTE_7BIT:
+ return "7-Bit";
+ case CTE_8BIT:
+ return "8-Bit";
+ case CTE_UUENCODE:
+ return "uuencode";
+ case CTE_BINARY:
+ return "Binary";
+ case CTE_QP:
+ return "Quoted Printable";
+ case CTE_BASE64:
+ return "Base64";
+ default:
+ return "Unknown CTE";
+ }
+}
+
+/* Unlike the original ap_escape_html, this one is also binary
+ * safe.
+ */
+apr_size_t mbox_cte_escape_html(apr_pool_t *p, const char *s,
+ apr_size_t len, char **body)
+{
+ char *x;
+ int i, j;
+
+ /* First, count the number of extra characters */
+ for (i = 0, j = 0; i < len; i++) {
+ if ((s[i] == '<') || (s[i] == '>')) {
+ j += 3;
+ }
+ else if (s[i] == '&') {
+ j += 4;
+ }
+ }
+
+ /* If there is nothing to escape, just copy the body to the new
+ string */
+ if (j == 0) {
+ j = len;
+ x = apr_pstrmemdup(p, s, len);
+ }
+
+ /* Otherwise, we have some extra characters to insert : allocate
+ enough space for them, and process the data. */
+ else {
+ x = apr_palloc(p, i + j);
+
+ for (i = 0, j = 0; i < len; i++, j++) {
+ if (s[i] == '<') {
+ memcpy(&x[j], "<", 4);
+ j += 3;
+ }
+ else if (s[i] == '>') {
+ memcpy(&x[j], ">", 4);
+ j += 3;
+ }
+ else if (s[i] == '&') {
+ memcpy(&x[j], "&", 5);
+ j += 4;
+ }
+ else {
+ x[j] = s[i];
+ }
+ }
+ }
+
+ *body = x;
+ return j;
+}
+
+/* Decode BASE64 encoded data */
+apr_size_t mbox_cte_decode_b64(char *src)
+{
+ apr_size_t len = 0;
+
+ int newline = 1, data_done = 0;
+ int c1, c2, c3, c4;
+ char *dst;
+
+ dst = src;
+
+ while ((c1 = *src++) != '\0') {
+ if (isspace(c1)) {
+ if (c1 == '\n') {
+ newline = 1;
+ } else {
+ newline = 0;
+ }
+ continue;
+ }
+
+ if (data_done) {
+ continue;
+ }
+
+ newline = 0;
+
+ do {
+ c2 = *src++;
+ } while (c2 != '\0' && isspace(c2));
+
+ do {
+ c3 = *src++;
+ } while (c3 != '\0' && isspace(c3));
+
+ do {
+ c4 = *src++;
+ } while (c4 != '\0' && isspace(c4));
+
+ /* Premature EOF. Should return an Error? */
+ if ((c2 == '\0') || (c3 == '\0') || (c4 == '\0')) {
+ return len;
+ }
+
+ if (c1 == '=' || c2 == '=') {
+ data_done = 1;
+ continue;
+ }
+
+ c1 = char64(c1);
+ c2 = char64(c2);
+ *dst++ = (c1 << 2) | ((c2 & 0x30) >> 4);
+ len++;
+
+ if (c3 == '=') {
+ data_done = 1;
+ }
+ else {
+ c3 = char64(c3);
+ *dst++ = ((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2);
+ len++;
+
+ if (c4 == '=') {
+ data_done = 1;
+ }
+ else {
+ c4 = char64(c4);
+ *dst++ = ((c3 & 0x03) << 6) | c4;
+ len++;
+ }
+ }
+ }
+
+ *dst = '\0';
+ return len;
+}
+
+static int hex2dec_char(char ch)
+{
+ if (isdigit(ch)) {
+ return ch - '0';
+ }
+ else if (isupper(ch)) {
+ return ch - 'A' + 10;
+ }
+ else {
+ return ch - 'a' + 10;
+ }
+}
+
+/* Decode quoted-printable to raw text. */
+apr_size_t mbox_cte_decode_qp(char* p)
+{
+ apr_size_t len = 0;
+ char *src, *dst;
+
+ dst = src = p;
+ while (*src != '\0') {
+ if (*src == '=') {
+ if (*++src == '\n') {
+ ++src;
+ continue;
+ }
+ else {
+ int hi, lo;
+ hi = hex2dec_char(*src++);
+ lo = hex2dec_char(*src);
+ *dst = (hi * 16) + lo;
+ }
+ }
+ else {
+ *dst = *src;
+ }
+
+ ++dst, ++src;
+ len++;
+ }
+
+ return len;
+}
+
+/* This function performs the decoding of strings like :
+ * =?UTF-8?B?QnJhbmtvIMSMaWJlag==?=
+ *
+ * These strings complies to the following syntax :
+ * =?charset?mode?data?= rest
+ */
+char *mbox_cte_decode_rfc2047(apr_pool_t *p, char *src)
+{
+ apr_xlate_t *xlate;
+
+ char *charset, *mode, *data, *rest;
+ int i;
+
+ /* Look for charset */
+ charset = strstr(src, "=?");
+ if (!charset) {
+ return src;
+ }
+ *charset = 0;
+ charset += strlen("=?");
+
+ /* Encoding mode (first '?' after charset) */
+ mode = strstr(charset, "?");
+ if (!mode) {
+ return src;
+ }
+ *mode = 0;
+ mode++;
+
+ /* Fetch data */
+ data = strstr(mode, "?");
+ if (!data) {
+ return src;
+ }
+ *data = 0;
+ data++;
+
+ /* Look for the end bound */
+ rest = strstr(data, "?=");
+ if (!rest) {
+ return src;
+ }
+ *rest = 0;
+
+ /* Quoted-Printable decoding : mode 'q' */
+ if ((*mode == 'q') || (*mode == 'Q')) {
+ apr_size_t data_len;
+ int i;
+
+ /* In QP header encoding, spaces are encoded either in =20 (as
+ in all QP encoding) or in underscores '_' (for header
+ encoding). The first case will be handle by the QP
+ decoding, so we must handle the other one */
+ for (i = 0; i < strlen(data); i++) {
+ if (data[i] == '_') {
+ data[i] = ' ';
+ }
+ }
+
+ data_len = mbox_cte_decode_qp(data);
+ data[data_len] = 0;
+ }
+ else if ((*mode == 'b') || (*mode == 'B')) {
+ apr_size_t data_len;
+
+ data_len = mbox_cte_decode_b64(data);
+ data[data_len] = 0;
+ }
+
+ /* Convert charset to uppercase */
+ for (i=0; i<strlen(charset); i++) {
+ charset[i] = toupper(charset[i]);
+ }
+
+ /* Charset conversion */
+ if (apr_xlate_open(&xlate, "UTF-8", charset, p) == APR_SUCCESS) {
+ apr_size_t inbytes_left, outbytes_left;
+ apr_size_t outbuf_len = strlen(data);
+
+ char *new_data;
+
+ /* Allocate some memory for our resulting data, and initialize
+ counters. */
+ new_data = apr_palloc(p, outbuf_len);
+ inbytes_left = strlen(data);
+ outbytes_left = strlen(data);
+
+ /* Convert */
+ // apr_xlate_conv_buffer(xlate, data, &inbytes_left,
+ // new_data, &outbytes_left);
+
+ // new_data[outbuf_len - outbytes_left] = 0;
+ // data = new_data;
+
+ apr_xlate_close(xlate);
+ }
+
+ return data;
+}
+
+/* MIME header decoding (see RFC 2047). */
+char *mbox_cte_decode_header(apr_pool_t *p, char *src)
+{
+ char *start, *end, *part;
+ char *result = "";
+
+ do {
+ char c;
+
+ start = strstr(src, "=?");
+ if (!start) {
+ result = apr_psprintf(p, "%s%s", result, src);
+ return result;
+ }
+
+ end = strstr(start, "?=");
+ if (!end) {
+ result = apr_psprintf(p, "%s%s", result, src);
+ return result;
+ }
+
+ c = *start;
+ *start = 0;
+ result = apr_psprintf(p, "%s%s", result, src);
+ *start = c;
+
+ part = mbox_cte_decode_rfc2047(p, start);
+ result = apr_psprintf(p, "%s%s", result, part);
+
+ src = end + 2;
+ } while (src && *src);
+
+ return result;
+}
Propchange: httpd/mod_mbox/branches/surgery/src/libmbox/mbox_cte.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_mbox/branches/surgery/src/libmbox/mbox_mime.c
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/src/libmbox/mbox_mime.c?rev=366430&view=auto
==============================================================================
--- httpd/mod_mbox/branches/surgery/src/libmbox/mbox_mime.c (added)
+++ httpd/mod_mbox/branches/surgery/src/libmbox/mbox_mime.c Thu Jan 5 21:17:52 2006
@@ -0,0 +1,280 @@
+/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* MIME parsing and structure management functions.
+ */
+
+#include "libmbox.h"
+
+/* Decode a multipart (or not) email. In order to support multiple
+ * levels of MIME parts, this function is recursive.
+ */
+mbox_mime_message_t *mbox_mime_decode_multipart(apr_pool_t *p, char *body,
+ char *ct, mbox_cte_e cte,
+ char *boundary)
+{
+ mbox_mime_message_t *mail;
+ char *tmp = NULL, *k = NULL, *end_bound = NULL;
+ char *headers_bound = NULL;
+
+ if (!body) {
+ return NULL;
+ }
+
+ /* Locate the end of part headers */
+ headers_bound = ap_strstr(body, "\n\n");
+ if (!headers_bound) {
+ return NULL;
+ }
+
+ /* If no Content-Type is provided, it means that we are parsing a
+ sub-part of the multipart message. The Content-Type header
+ should then be the first line of the part. If not, use
+ text/plain as default for the sub-part. */
+ tmp = ap_strstr(body, "Content-Type: ");
+ if (!ct && (!tmp || tmp > headers_bound)) {
+ ct = "text/plain";
+ }
+
+ mail = apr_pcalloc(p, sizeof(mbox_mime_message_t));
+
+ /* If no Content-Type is given, we have to look for it. */
+ if (!ct) {
+ tmp += sizeof("Content-Type: ") - 1;
+ k = strchr(tmp, ';');
+
+ /* Isolate the Content-Type string (between 'Content-Type: '
+ and ';' or end of line */
+ if (k && k < headers_bound) {
+ *k = 0;
+ }
+ else {
+ k = tmp;
+ while (*k) {
+ if (isspace(*k)) {
+ *k = 0;
+ break;
+ }
+ *k++;
+ }
+ }
+
+ /* Copy the Content-Type and reset *k */
+ mail->content_type = apr_pstrdup(p, tmp);
+ *k = ';';
+
+ /* If available, get MIME part name */
+ tmp = ap_strstr(body, "name=");
+ if (tmp && tmp < headers_bound) {
+ tmp += sizeof("name=") - 1;
+ k = tmp;
+
+ while (*k) {
+ if (isspace(*k) || *k == ';') {
+ *k = 0;
+ break;
+ }
+ *k++;
+ }
+
+ /* Check for double quotes */
+ if ((*tmp == '"') && (tmp[strlen(tmp)-1] == '"')) {
+ mail->content_name = apr_pstrndup(p, tmp+1, strlen(tmp) - 2);
+ }
+ else {
+ mail->content_name = apr_pstrdup(p, tmp);
+ }
+
+ *k = ';';
+ }
+ }
+ else {
+ mail->content_type = ct;
+ }
+
+ /* Now we have a Content-Type. Look for other useful header information */
+
+ /* Check Content-Disposition if the match is within the headers */
+ tmp = ap_strstr(body, "Content-Disposition: ");
+ if (tmp && tmp < headers_bound) {
+ tmp += sizeof("Content-Disposition: ") - 1;
+ k = tmp;
+
+ while (*k) {
+ if (isspace(*k) || *k == ';') {
+ *k = 0;
+ break;
+ }
+ *k++;
+ }
+
+ /* Copy the Content-Disposition and reset *k */
+ mail->content_disposition = apr_pstrdup(p, tmp);
+ *k = '\n';
+ }
+ else {
+ mail->content_disposition = apr_pstrdup(p, "inline");
+ }
+
+ /* Check Content-Transfer-Encoding, if needed */
+ if (cte == CTE_NONE)
+ {
+ tmp = ap_strstr(body, "Content-Transfer-Encoding: ");
+ if (tmp && tmp < headers_bound) {
+ tmp += sizeof("Content-Transfer-Encoding: ") - 1;
+ k = tmp;
+
+ while (*k) {
+ if (isspace(*k) || *k == ';') {
+ *k = 0;
+ break;
+ }
+ *k++;
+ }
+
+ /* Copy the Content-Disposition and reset *k */
+ mail->cte = mbox_parse_cte_header(tmp);
+ *k = '\n';
+ }
+ }
+ else {
+ mail->cte = cte;
+ }
+
+ /* Now we have all the headers we need. Start processing the
+ body. If the Content-Type was given at call time, the body
+ starts where it's given. Otherwise it's after the headers
+ (first new empty line) */
+
+ if (ct) {
+ mail->body = body;
+ }
+ else {
+ mail->body = ap_strstr(body, "\n\n");
+ if (mail->body != NULL) {
+ mail->body += 2;
+ }
+ }
+
+ /* If the mail is a multipart message, search for the boundary,
+ and process its sub parts by recursive calls. */
+ if (strncmp(mail->content_type, "multipart/", strlen("multipart/")) == 0) {
+ int end = 0, count = 0;
+ char *search, *bound;
+
+ /* If the boundary was not given, we must look for it in the headers */
+ if (!boundary) {
+ tmp = ap_strstr(body, "boundary=\"");
+ if (!tmp) {
+ return NULL;
+ }
+
+ tmp += sizeof("boundary=\"") - 1;
+ k = tmp;
+
+ while (*k) {
+ if (*k == '"') {
+ *k = 0;
+ break;
+ }
+ *k++;
+ }
+
+ mail->boundary = apr_pstrdup(p, tmp);
+ *k = '"';
+ }
+
+ /* Otherwise, the boundary is as given to us */
+ else {
+ mail->boundary = boundary;
+ }
+
+ /* Now we have our boundary string. We must : look for it once
+ (begining of MIME part) and then look for the end boundary :
+ --boundary-- to mark the end of the MIME part */
+
+ /* The start boundary */
+ bound = ap_strstr(mail->body, mail->boundary);
+ if (!bound) {
+ return NULL;
+ }
+
+ /* The end boudary */
+ end_bound = apr_psprintf(p, "--%s--", mail->boundary);
+ tmp = ap_strstr(mail->body, end_bound);
+ if (!tmp) {
+ return NULL;
+ }
+ *tmp = 0;
+
+ /* Set the search begining to the line after the start boundary. */
+ search = bound + strlen(mail->boundary) + 1;
+
+ /* While the MIME part is not finished, go through all sub parts */
+ while (!end) {
+ char *inbound;
+
+ inbound = ap_strstr(search+strlen(mail->boundary), mail->boundary);
+ if (inbound) {
+ char *t = inbound - 2;
+ *t = 0;
+ }
+
+ /* Allocate a new pointer for the sub part, and parse it. */
+ mail->sub = realloc(mail->sub, ++count * sizeof(struct mimemsg *));
+ mail->sub[count-1] = mbox_mime_decode_multipart(p, search, NULL, CTE_NONE, NULL);
+
+ /* If the boudary is found again, it means we have another
+ MIME part in the same multipart message. Set the new
+ search begining to the line after this new start
+ boundary */
+ if (inbound) {
+ char *t = inbound - 2;
+ *t = '-';
+
+ search = inbound + strlen(mail->boundary) + 1;
+
+ if (mail->sub[count-1] && mail->sub[count-1]->body) {
+ mail->sub[count-1]->body_len = inbound - mail->sub[count-1]->body - 2;
+ }
+ }
+
+ /* Otherwise, the MIME part is finished. */
+ else {
+ mail->sub_count = count;
+ end = 1;
+ }
+ }
+
+ /* Finally reset the end-body pointer. */
+ // *tmp = '-';
+ }
+
+ /* If the parsed body is not multipart or is a MIME part, the body
+ length is the length of the body string (no surprise here). If
+ it's a MIME part, its correct length will be set after the call
+ to mbox_mime_decode_multipart just a dozen lines above. */
+ else {
+ if (mail->body != NULL) {
+ mail->body_len = strlen(mail->body);
+ }
+ else {
+ mail->body_len = 0;
+ }
+ }
+
+ return mail;
+}
Propchange: httpd/mod_mbox/branches/surgery/src/libmbox/mbox_mime.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: httpd/mod_mbox/branches/surgery/src/module/Makefile.am
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/src/module/Makefile.am?rev=366430&r1=366429&r2=366430&view=diff
==============================================================================
--- httpd/mod_mbox/branches/surgery/src/module/Makefile.am (original)
+++ httpd/mod_mbox/branches/surgery/src/module/Makefile.am Thu Jan 5 21:17:52 2006
@@ -5,9 +5,7 @@
mod_mbox_file.c \
mod_mbox_out.c \
mod_mbox_search.c \
- mod_mbox_index.c \
- mod_mbox_cte.c \
- mod_mbox_mime.c
+ mod_mbox_index.c
mod_mbox_la_LIBADD = $(top_builddir)/src/libmbox/libmbox.la
mod_mbox_la_CFLAGS = -Wall ${MODULE_CFLAGS}
Modified: httpd/mod_mbox/branches/surgery/src/module/mod_mbox.h
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/src/module/mod_mbox.h?rev=366430&r1=366429&r2=366430&view=diff
==============================================================================
--- httpd/mod_mbox/branches/surgery/src/module/mod_mbox.h (original)
+++ httpd/mod_mbox/branches/surgery/src/module/mod_mbox.h Thu Jan 5 21:17:52 2006
@@ -30,10 +30,8 @@
#include "apr_dbm.h"
#include "apr_hash.h"
#include "apr_fnmatch.h"
-#include "apr_xlate.h"
#include <stdio.h>
-#include <ctype.h>
#include "libmbox.h"
@@ -115,19 +113,7 @@
apr_status_t mbox_static_message(request_rec *r, apr_file_t *f);
apr_status_t mbox_xml_message(request_rec *r, apr_file_t *f);
-/* CTE decoding functions */
-const char *mbox_cte_to_char(mbox_cte_e cte);
-apr_size_t mbox_cte_decode_qp(char* p);
-apr_size_t mbox_cte_decode_b64(char *src);
-apr_size_t mbox_cte_escape_html(apr_pool_t *p, const char *s,
- apr_size_t len, char **body);
-char *mbox_cte_decode_rfc2047(apr_pool_t *p, char *src);
-char *mbox_cte_decode_header(apr_pool_t *p, char *src);
-
-/* MIME decoding functions */
-mbox_mime_message_t *mbox_mime_decode_multipart(apr_pool_t *p, char *body,
- char *ct, mbox_cte_e cte,
- char *boundary);
+/* MIME structure displaying */
char *mbox_mime_decode_body(apr_pool_t *p, mbox_cte_e cte, char *body, apr_size_t len);
char *mbox_mime_get_body(apr_pool_t *p, mbox_mime_message_t *m);
void mbox_mime_display_static_structure(request_rec *r, mbox_mime_message_t *m,
Modified: httpd/mod_mbox/branches/surgery/src/module/mod_mbox_mime.c
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/branches/surgery/src/module/mod_mbox_mime.c?rev=366430&r1=366429&r2=366430&view=diff
==============================================================================
--- httpd/mod_mbox/branches/surgery/src/module/mod_mbox_mime.c (original)
+++ httpd/mod_mbox/branches/surgery/src/module/mod_mbox_mime.c Thu Jan 5 21:17:52 2006
@@ -19,266 +19,6 @@
#include "mod_mbox.h"
-/* Decode a multipart (or not) email. In order to support multiple
- * levels of MIME parts, this function is recursive.
- */
-mbox_mime_message_t *mbox_mime_decode_multipart(apr_pool_t *p, char *body,
- char *ct, mbox_cte_e cte,
- char *boundary)
-{
- mbox_mime_message_t *mail;
- char *tmp = NULL, *k = NULL, *end_bound = NULL;
- char *headers_bound = NULL;
-
- if (!body) {
- return NULL;
- }
-
- /* Locate the end of part headers */
- headers_bound = ap_strstr(body, "\n\n");
- if (!headers_bound) {
- return NULL;
- }
-
- /* If no Content-Type is provided, it means that we are parsing a
- sub-part of the multipart message. The Content-Type header
- should then be the first line of the part. If not, use
- text/plain as default for the sub-part. */
- tmp = ap_strstr(body, "Content-Type: ");
- if (!ct && (!tmp || tmp > headers_bound)) {
- ct = "text/plain";
- }
-
- mail = apr_pcalloc(p, sizeof(mbox_mime_message_t));
-
- /* If no Content-Type is given, we have to look for it. */
- if (!ct) {
- tmp += sizeof("Content-Type: ") - 1;
- k = strchr(tmp, ';');
-
- /* Isolate the Content-Type string (between 'Content-Type: '
- and ';' or end of line */
- if (k && k < headers_bound) {
- *k = 0;
- }
- else {
- k = tmp;
- while (*k) {
- if (isspace(*k)) {
- *k = 0;
- break;
- }
- *k++;
- }
- }
-
- /* Copy the Content-Type and reset *k */
- mail->content_type = apr_pstrdup(p, tmp);
- *k = ';';
-
- /* If available, get MIME part name */
- tmp = ap_strstr(body, "name=");
- if (tmp && tmp < headers_bound) {
- tmp += sizeof("name=") - 1;
- k = tmp;
-
- while (*k) {
- if (isspace(*k) || *k == ';') {
- *k = 0;
- break;
- }
- *k++;
- }
-
- /* Check for double quotes */
- if ((*tmp == '"') && (tmp[strlen(tmp)-1] == '"')) {
- mail->content_name = apr_pstrndup(p, tmp+1, strlen(tmp) - 2);
- }
- else {
- mail->content_name = apr_pstrdup(p, tmp);
- }
-
- *k = ';';
- }
- }
- else {
- mail->content_type = ct;
- }
-
- /* Now we have a Content-Type. Look for other useful header information */
-
- /* Check Content-Disposition if the match is within the headers */
- tmp = ap_strstr(body, "Content-Disposition: ");
- if (tmp && tmp < headers_bound) {
- tmp += sizeof("Content-Disposition: ") - 1;
- k = tmp;
-
- while (*k) {
- if (isspace(*k) || *k == ';') {
- *k = 0;
- break;
- }
- *k++;
- }
-
- /* Copy the Content-Disposition and reset *k */
- mail->content_disposition = apr_pstrdup(p, tmp);
- *k = '\n';
- }
- else {
- mail->content_disposition = apr_pstrdup(p, "inline");
- }
-
- /* Check Content-Transfer-Encoding, if needed */
- if (cte == CTE_NONE)
- {
- tmp = ap_strstr(body, "Content-Transfer-Encoding: ");
- if (tmp && tmp < headers_bound) {
- tmp += sizeof("Content-Transfer-Encoding: ") - 1;
- k = tmp;
-
- while (*k) {
- if (isspace(*k) || *k == ';') {
- *k = 0;
- break;
- }
- *k++;
- }
-
- /* Copy the Content-Disposition and reset *k */
- mail->cte = mbox_parse_cte_header(tmp);
- *k = '\n';
- }
- }
- else {
- mail->cte = cte;
- }
-
- /* Now we have all the headers we need. Start processing the
- body. If the Content-Type was given at call time, the body
- starts where it's given. Otherwise it's after the headers
- (first new empty line) */
-
- if (ct) {
- mail->body = body;
- }
- else {
- mail->body = ap_strstr(body, "\n\n");
- if (mail->body != NULL) {
- mail->body += 2;
- }
- }
-
- /* If the mail is a multipart message, search for the boundary,
- and process its sub parts by recursive calls. */
- if (strncmp(mail->content_type, "multipart/", strlen("multipart/")) == 0) {
- int end = 0, count = 0;
- char *search, *bound;
-
- /* If the boundary was not given, we must look for it in the headers */
- if (!boundary) {
- tmp = ap_strstr(body, "boundary=\"");
- if (!tmp) {
- return NULL;
- }
-
- tmp += sizeof("boundary=\"") - 1;
- k = tmp;
-
- while (*k) {
- if (*k == '"') {
- *k = 0;
- break;
- }
- *k++;
- }
-
- mail->boundary = apr_pstrdup(p, tmp);
- *k = '"';
- }
-
- /* Otherwise, the boundary is as given to us */
- else {
- mail->boundary = boundary;
- }
-
- /* Now we have our boundary string. We must : look for it once
- (begining of MIME part) and then look for the end boundary :
- --boundary-- to mark the end of the MIME part */
-
- /* The start boundary */
- bound = ap_strstr(mail->body, mail->boundary);
- if (!bound) {
- return NULL;
- }
-
- /* The end boudary */
- end_bound = apr_psprintf(p, "--%s--", mail->boundary);
- tmp = ap_strstr(mail->body, end_bound);
- if (!tmp) {
- return NULL;
- }
- *tmp = 0;
-
- /* Set the search begining to the line after the start boundary. */
- search = bound + strlen(mail->boundary) + 1;
-
- /* While the MIME part is not finished, go through all sub parts */
- while (!end) {
- char *inbound;
-
- inbound = ap_strstr(search+strlen(mail->boundary), mail->boundary);
- if (inbound) {
- char *t = inbound - 2;
- *t = 0;
- }
-
- /* Allocate a new pointer for the sub part, and parse it. */
- mail->sub = realloc(mail->sub, ++count * sizeof(struct mimemsg *));
- mail->sub[count-1] = mbox_mime_decode_multipart(p, search, NULL, CTE_NONE, NULL);
-
- /* If the boudary is found again, it means we have another
- MIME part in the same multipart message. Set the new
- search begining to the line after this new start
- boundary */
- if (inbound) {
- char *t = inbound - 2;
- *t = '-';
-
- search = inbound + strlen(mail->boundary) + 1;
-
- if (mail->sub[count-1] && mail->sub[count-1]->body) {
- mail->sub[count-1]->body_len = inbound - mail->sub[count-1]->body - 2;
- }
- }
-
- /* Otherwise, the MIME part is finished. */
- else {
- mail->sub_count = count;
- end = 1;
- }
- }
-
- /* Finally reset the end-body pointer. */
- // *tmp = '-';
- }
-
- /* If the parsed body is not multipart or is a MIME part, the body
- length is the length of the body string (no surprise here). If
- it's a MIME part, its correct length will be set after the call
- to mbox_mime_decode_multipart just a dozen lines above. */
- else {
- if (mail->body != NULL) {
- mail->body_len = strlen(mail->body);
- }
- else {
- mail->body_len = 0;
- }
- }
-
- return mail;
-}
-
/* Decode a MIME part body, according to its CTE. */
char *mbox_mime_decode_body(apr_pool_t *p, mbox_cte_e cte, char *body, apr_size_t len)
{