svn commit: r363709 - in head/mail/exim: . files
Vsevolod Stakhov
vsevolod at FreeBSD.org
Fri Aug 1 13:55:01 UTC 2014
Author: vsevolod
Date: Fri Aug 1 13:54:59 2014
New Revision: 363709
URL: http://svnweb.freebsd.org/changeset/ports/363709
QAT: https://qat.redports.org/buildarchive/r363709/
Log:
- Add patch recommended by the exim developers to fix mime regression in 4.83
- Remove SA_1024 as it has been adandoned long ago [1]
- Fix message in post-install stage [1]
- Bump revision
Submitted by: Victor Ustugov via jabber [1]
Added:
head/mail/exim/files/patch-src__mime.c (contents, props changed)
Deleted:
head/mail/exim/files/extra-patch-so_1024-delimiter
Modified:
head/mail/exim/Makefile
head/mail/exim/distinfo
head/mail/exim/files/POST-INSTALL-NOTES
head/mail/exim/options
head/mail/exim/pkg-plist
Modified: head/mail/exim/Makefile
==============================================================================
--- head/mail/exim/Makefile Fri Aug 1 13:38:30 2014 (r363708)
+++ head/mail/exim/Makefile Fri Aug 1 13:54:59 2014 (r363709)
@@ -3,7 +3,7 @@
PORTNAME= exim
PORTVERSION?= ${EXIM_VERSION}
-PORTREVISION= 2
+PORTREVISION= 3
CATEGORIES= mail ipv6
MASTER_SITES= ${MASTER_SITE_EXIM:S/$/:exim/}
MASTER_SITE_SUBDIR= exim4/:exim
@@ -57,7 +57,6 @@ PGSQL_USE= pgsql=yes
REDIS_LIB_DEPENDS= libhiredis.so:${PORTSDIR}/databases/hiredis
SASLAUTHD_RUN_DEPENDS= ${LOCALBASE}/sbin/saslauthd:${PORTSDIR}/security/cyrus-sasl2-saslauthd
SA_EXIM_RUN_DEPENDS= ${LOCALBASE}/bin/spamc:${PORTSDIR}/mail/spamassassin
-SO_1024_LDFLAGS= -lz
SPF_LIB_DEPENDS= libspf2.so:${PORTSDIR}/mail/libspf2
SQLITE_USE= sqlite=yes
SQLITE_USES= pkgconfig
@@ -88,14 +87,8 @@ MASTER_SITE_SUBDIR+= sa-exim/:sa_exim
DISTFILES+= sa-exim-${SA_EXIM_VERSION}.tar.gz:sa_exim
.endif
-.if ${PORT_OPTIONS:MSO_1024} || defined(FETCH_ALL)
-MASTER_SITES+= ftp://ftp.renatasystems.org/pub/FreeBSD/ports/distfiles/:so_1024
-DISTFILES+= spamooborona1024-src-${SO_1024_VERSION}.tar.gz:so_1024
-.endif
-
EXIM_VERSION= 4.83
SA_EXIM_VERSION=4.2
-SO_1024_VERSION=3.2
EXIM_INSTALL_ARG+= "-no_chown" "-no_symlink"
.if !defined(EXIMON_ONLY)
@@ -519,10 +512,6 @@ post-extract:
.if ${PORT_OPTIONS:MSA_EXIM}
@cd ${WRKDIR} && ${TAR} ${EXTRACT_BEFORE_ARGS} ${_DISTDIR}/sa-exim-${SA_EXIM_VERSION}.tar.gz ${EXTRACT_AFTER_ARGS}
.endif
-.if ${PORT_OPTIONS:MSO_1024}
- @cd ${WRKDIR} && ${TAR} ${EXTRACT_BEFORE_ARGS} ${_DISTDIR}/spamooborona1024-src-${SO_1024_VERSION}.tar.gz ${EXTRACT_AFTER_ARGS}
- @cd ${WRKDIR} && ${PATCH} --quiet < ${FILESDIR}/extra-patch-so_1024-delimiter
-.endif
do-configure:
@${MKDIR} ${WRKSRC}/Local
@@ -550,11 +539,6 @@ do-configure:
@${REINPLACE_CMD} -e 's,/usr/bin/spamc,${LOCALBASE}/bin/spamc,' \
${WRKDIR}/sa-exim-${SA_EXIM_VERSION}/sa-exim.conf
.endif
-.if ${PORT_OPTIONS:MSO_1024}
- @${REINPLACE_CMD} -E -e 's/^(LOCAL_SCAN_SOURCE=).*/\1Local\/local_scan_1024.c/' \
- ${WRKSRC}/OS/Makefile-Default
- @${CP} ${WRKDIR}/local_scan_1024.c ${WRKSRC}/Local
-.endif
@${REINPLACE_CMD} -E -e 's/XX_STRIPCMD_XX/${STRIP_CMD:S,/,\/,g}/' \
${WRKSRC}/OS/Makefile-FreeBSD
@(cd ${WRKSRC}; ${SETENV} ${MAKE_ENV} ${MAKE} ${MAKE_FLAGS} ${MAKEFILE} ${MAKE_ARGS} configure)
@@ -577,9 +561,6 @@ post-install:
${INSTALL_SCRIPT} ${WRKDIR}/${script}.sh ${STAGEDIR}${PREFIX}/etc/periodic/daily/${script}
.endfor
.endif
-.if ${PORT_OPTIONS:MSO_1024}
- @${MKDIR} -m 750 ${STAGEDIR}var/spool/spamooborona
-.endif
@${MKDIR} -m 750 ${STAGEDIR}${LOGDIR}
@${INSTALL_MAN} ${WRKSRC}/doc/exim.8 ${STAGEDIR}${MAN8PREFIX}/man/man8
.if ${PORT_OPTIONS:MDOCS}
Modified: head/mail/exim/distinfo
==============================================================================
--- head/mail/exim/distinfo Fri Aug 1 13:38:30 2014 (r363708)
+++ head/mail/exim/distinfo Fri Aug 1 13:54:59 2014 (r363709)
@@ -2,5 +2,3 @@ SHA256 (exim/exim-4.83.tar.bz2) = efa031
SIZE (exim/exim-4.83.tar.bz2) = 1761169
SHA256 (exim/sa-exim-4.2.tar.gz) = 72e0a735547f18b05785e6c58a71d24623858f0f5234a5dc0e24cb453999e99a
SIZE (exim/sa-exim-4.2.tar.gz) = 66575
-SHA256 (exim/spamooborona1024-src-3.2.tar.gz) = ab22a430f3860460045f6b213c68c89700a0cd10cbb6c7a808ece326c53787ee
-SIZE (exim/spamooborona1024-src-3.2.tar.gz) = 8537
Modified: head/mail/exim/files/POST-INSTALL-NOTES
==============================================================================
--- head/mail/exim/files/POST-INSTALL-NOTES Fri Aug 1 13:38:30 2014 (r363708)
+++ head/mail/exim/files/POST-INSTALL-NOTES Fri Aug 1 13:54:59 2014 (r363709)
@@ -30,7 +30,7 @@ To use Exim instead of sendmail on start
'daily_submit_queuerun' to "NO" in periodic.conf(5),
if you intend to manage queue runners / deliveries closely.
*) Set the 'exim_enable' rc.conf(5) variable to 'YES'.
-*) Start exim with '%%RC_DIR%%/exim%%RC_SUFX%% start'.
+*) Start exim with '%%PREFIX%%/etc/rc.d/exim start'.
You may also want to configure newsyslog(8) to rotate Exim log files:
Added: head/mail/exim/files/patch-src__mime.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/mail/exim/files/patch-src__mime.c Fri Aug 1 13:54:59 2014 (r363709)
@@ -0,0 +1,1191 @@
+X-Git-Url: http://git.exim.org/exim.git/blobdiff_plain/1bd0d12bcbf4f51bd78c60d5bae01f1ff38c5a84..4fd5d2bf25195969b9c6a6c23a59c495400ece8d:/src/src/mime.c
+
+diff --git a/src/src/mime.c b/src/src/mime.c
+index 2233dac..95d3da4 100644
+--- src/mime.c
++++ src/mime.c
+@@ -6,7 +6,7 @@
+ /* License: GPL */
+
+ #include "exim.h"
+-#ifdef WITH_CONTENT_SCAN
++#ifdef WITH_CONTENT_SCAN /* entire file */
+ #include "mime.h"
+ #include <sys/stat.h>
+
+@@ -21,7 +21,9 @@ uschar *mime_current_boundary = NULL;
+ give info on detected "problems" in MIME
+ encodings. Those are defined in mime.h. */
+
+-void mime_set_anomaly(int level, const char *text) {
++void
++mime_set_anomaly(int level, const char *text)
++{
+ mime_anomaly_level = level;
+ mime_anomaly_text = CUS text;
+ }
+@@ -39,36 +41,37 @@ void mime_set_anomaly(int level, const char *text) {
+ 0-255 - char to write
+ */
+
+-uschar *mime_decode_qp_char(uschar *qp_p, int *c) {
+- uschar *initial_pos = qp_p;
++uschar *
++mime_decode_qp_char(uschar *qp_p, int *c)
++{
++uschar *initial_pos = qp_p;
++
++/* advance one char */
++qp_p++;
++
++/* Check for two hex digits and decode them */
++if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
++ {
++ /* Do hex conversion */
++ *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) <<4;
++ qp_p++;
++ *c |= isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10;
++ return qp_p + 1;
++ }
+
+- /* advance one char */
++/* tab or whitespace may follow just ignore it if it precedes \n */
++while (*qp_p == '\t' || *qp_p == ' ' || *qp_p == '\r')
+ qp_p++;
+
+- /* Check for two hex digits and decode them */
+- if (isxdigit(*qp_p) && isxdigit(qp_p[1])) {
+- /* Do hex conversion */
+- if (isdigit(*qp_p)) {*c = *qp_p - '0';}
+- else {*c = toupper(*qp_p) - 'A' + 10;};
+- *c <<= 4;
+- if (isdigit(qp_p[1])) {*c |= qp_p[1] - '0';}
+- else {*c |= toupper(qp_p[1]) - 'A' + 10;};
+- return qp_p + 2;
+- };
+-
+- /* tab or whitespace may follow just ignore it if it precedes \n */
+- while (*qp_p == '\t' || *qp_p == ' ' || *qp_p == '\r')
+- qp_p++;
+-
+- if (*qp_p == '\n') {
+- /* hit soft line break */
+- *c = -1;
+- return qp_p;
+- };
+-
+- /* illegal char here */
+- *c = -2;
+- return initial_pos;
++if (*qp_p == '\n') /* hit soft line break */
++ {
++ *c = -1;
++ return qp_p;
++ }
++
++/* illegal char here */
++*c = -2;
++return initial_pos;
+ }
+
+
+@@ -79,18 +82,19 @@ mime_decode_asis(FILE* in, FILE* out, uschar* boundary)
+ ssize_t len, size = 0;
+ uschar buffer[MIME_MAX_LINE_LENGTH];
+
+- while(fgets(CS buffer, MIME_MAX_LINE_LENGTH, mime_stream) != NULL) {
++ while(fgets(CS buffer, MIME_MAX_LINE_LENGTH, mime_stream) != NULL)
++ {
+ if (boundary != NULL
+- && Ustrncmp(buffer, "--", 2) == 0
+- && Ustrncmp((buffer+2), boundary, Ustrlen(boundary)) == 0
+- )
++ && Ustrncmp(buffer, "--", 2) == 0
++ && Ustrncmp((buffer+2), boundary, Ustrlen(boundary)) == 0
++ )
+ break;
+
+ len = Ustrlen(buffer);
+ if (fwrite(buffer, 1, (size_t)len, out) < len)
+ return -1;
+ size += len;
+- } /* while */
++ } /* while */
+ return size;
+ }
+
+@@ -107,26 +111,29 @@ mime_decode_base64(FILE* in, FILE* out, uschar* boundary)
+ opos = obuf;
+
+ while (Ufgets(ibuf, MIME_MAX_LINE_LENGTH, in) != NULL)
+- {
++ {
+ if (boundary != NULL
+- && Ustrncmp(ibuf, "--", 2) == 0
+- && Ustrncmp((ibuf+2), boundary, Ustrlen(boundary)) == 0
+- )
++ && Ustrncmp(ibuf, "--", 2) == 0
++ && Ustrncmp((ibuf+2), boundary, Ustrlen(boundary)) == 0
++ )
+ break;
+
+- for (ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos != 0; ++ipos) {
+- /* skip padding */
+- if (*ipos == '=') {
++ for (ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos != 0; ++ipos)
++ {
++ if (*ipos == '=') /* skip padding */
++ {
+ ++bytestate;
+ continue;
+- }
+- /* skip bad characters */
+- if (mime_b64[*ipos] == 128) {
++ }
++ if (mime_b64[*ipos] == 128) /* skip bad characters */
++ {
+ mime_set_anomaly(MIME_ANOMALY_BROKEN_BASE64);
+ continue;
+- }
++ }
++
+ /* simple state-machine */
+- switch((bytestate++) & 3) {
++ switch((bytestate++) & 3)
++ {
+ case 0:
+ *opos = mime_b64[*ipos] << 2;
+ break;
+@@ -144,27 +151,28 @@ mime_decode_base64(FILE* in, FILE* out, uschar* boundary)
+ *opos |= mime_b64[*ipos];
+ ++opos;
+ break;
+- } /* switch */
+- } /* for */
++ } /* switch */
++ } /* for */
++
+ /* something to write? */
+ len = opos - obuf;
+- if (len > 0) {
+- if (fwrite(obuf, 1, len, out) != len)
+- return -1; /* error */
++ if (len > 0)
++ {
++ if (fwrite(obuf, 1, len, out) != len) return -1; /* error */
+ size += len;
+ /* copy incomplete last byte to start of obuf, where we continue */
+ if ((bytestate & 3) != 0)
+ *obuf = *opos;
+ opos = obuf;
+- }
+- } /* while */
++ }
++ } /* while */
+
+ /* write out last byte if it was incomplete */
+- if (bytestate & 3) {
+- if (fwrite(obuf, 1, 1, out) != 1)
+- return -1;
+- ++size;
+- }
++ if (bytestate & 3)
++ {
++ if (fwrite(obuf, 1, 1, out) != 1) return -1;
++ ++size;
++ }
+
+ return size;
+ }
+@@ -174,219 +182,232 @@ mime_decode_base64(FILE* in, FILE* out, uschar* boundary)
+ static ssize_t
+ mime_decode_qp(FILE* in, FILE* out, uschar* boundary)
+ {
+- uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH];
+- uschar *ipos, *opos;
+- ssize_t len, size = 0;
++uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH];
++uschar *ipos, *opos;
++ssize_t len, size = 0;
+
+- while (fgets(CS ibuf, MIME_MAX_LINE_LENGTH, in) != NULL)
++while (fgets(CS ibuf, MIME_MAX_LINE_LENGTH, in) != NULL)
+ {
+- if (boundary != NULL
+- && Ustrncmp(ibuf, "--", 2) == 0
+- && Ustrncmp((ibuf+2), boundary, Ustrlen(boundary)) == 0
+- )
+- break; /* todo: check for missing boundary */
++ if (boundary != NULL
++ && Ustrncmp(ibuf, "--", 2) == 0
++ && Ustrncmp((ibuf+2), boundary, Ustrlen(boundary)) == 0
++ )
++ break; /* todo: check for missing boundary */
+
+- ipos = ibuf;
+- opos = obuf;
+-
+- while (*ipos != 0) {
+- if (*ipos == '=') {
+- int decode_qp_result;
+-
+- ipos = mime_decode_qp_char(ipos, &decode_qp_result);
++ ipos = ibuf;
++ opos = obuf;
+
+- if (decode_qp_result == -2) {
+- /* Error from decoder. ipos is unchanged. */
+- mime_set_anomaly(MIME_ANOMALY_BROKEN_QP);
+- *opos = '=';
+- ++opos;
+- ++ipos;
+- }
+- else if (decode_qp_result == -1) {
+- break;
+- }
+- else if (decode_qp_result >= 0) {
+- *opos = decode_qp_result;
+- ++opos;
+- }
++ while (*ipos != 0)
++ {
++ if (*ipos == '=')
++ {
++ int decode_qp_result;
++
++ ipos = mime_decode_qp_char(ipos, &decode_qp_result);
++
++ if (decode_qp_result == -2)
++ {
++ /* Error from decoder. ipos is unchanged. */
++ mime_set_anomaly(MIME_ANOMALY_BROKEN_QP);
++ *opos = '=';
++ ++opos;
++ ++ipos;
++ }
++ else if (decode_qp_result == -1)
++ break;
++ else if (decode_qp_result >= 0)
++ {
++ *opos = decode_qp_result;
++ ++opos;
++ }
+ }
+- else {
+- *opos = *ipos;
+- ++opos;
+- ++ipos;
++ else
++ {
++ *opos = *ipos;
++ ++opos;
++ ++ipos;
+ }
+ }
+- /* something to write? */
+- len = opos - obuf;
+- if (len > 0) {
+- if (fwrite(obuf, 1, len, out) != len)
+- return -1; /* error */
+- size += len;
++ /* something to write? */
++ len = opos - obuf;
++ if (len > 0)
++ {
++ if (fwrite(obuf, 1, len, out) != len) return -1; /* error */
++ size += len;
+ }
+ }
+- return size;
++return size;
+ }
+
+
+-FILE *mime_get_decode_file(uschar *pname, uschar *fname) {
+- FILE *f = NULL;
+- uschar *filename;
++FILE *
++mime_get_decode_file(uschar *pname, uschar *fname)
++{
++FILE *f = NULL;
++uschar *filename;
+
+- filename = (uschar *)malloc(2048);
++filename = (uschar *)malloc(2048);
+
+- if ((pname != NULL) && (fname != NULL)) {
+- (void)string_format(filename, 2048, "%s/%s", pname, fname);
+- f = modefopen(filename,"wb+",SPOOL_MODE);
+- }
+- else if (pname == NULL) {
+- f = modefopen(fname,"wb+",SPOOL_MODE);
++if (pname && fname)
++ {
++ (void)string_format(filename, 2048, "%s/%s", pname, fname);
++ f = modefopen(filename,"wb+",SPOOL_MODE);
+ }
+- else if (fname == NULL) {
+- int file_nr = 0;
+- int result = 0;
++else if (!pname)
++ f = modefopen(fname,"wb+",SPOOL_MODE);
++else if (!fname)
++ {
++ int file_nr = 0;
++ int result = 0;
++
++ /* must find first free sequential filename */
++ do
++ {
++ struct stat mystat;
++ (void)string_format(filename, 2048,
++ "%s/%s-%05u", pname, message_id, file_nr++);
++ /* security break */
++ if (file_nr >= 1024)
++ break;
++ result = stat(CS filename, &mystat);
++ } while(result != -1);
+
+- /* must find first free sequential filename */
+- do {
+- struct stat mystat;
+- (void)string_format(filename,2048,"%s/%s-%05u", pname, message_id, file_nr);
+- file_nr++;
+- /* security break */
+- if (file_nr >= 1024)
+- break;
+- result = stat(CS filename,&mystat);
+- }
+- while(result != -1);
+- f = modefopen(filename,"wb+",SPOOL_MODE);
+- };
++ f = modefopen(filename, "wb+", SPOOL_MODE);
++ }
+
+- /* set expansion variable */
+- mime_decoded_filename = filename;
++/* set expansion variable */
++mime_decoded_filename = filename;
+
+- return f;
++return f;
+ }
+
+
+-int mime_decode(uschar **listptr) {
+- int sep = 0;
+- uschar *list = *listptr;
+- uschar *option;
+- uschar option_buffer[1024];
+- uschar decode_path[1024];
+- FILE *decode_file = NULL;
+- long f_pos = 0;
+- ssize_t size_counter = 0;
+- ssize_t (*decode_function)(FILE*, FILE*, uschar*);
+-
+- if (mime_stream == NULL)
++int
++mime_decode(uschar **listptr)
++{
++int sep = 0;
++uschar *list = *listptr;
++uschar *option;
++uschar option_buffer[1024];
++uschar decode_path[1024];
++FILE *decode_file = NULL;
++long f_pos = 0;
++ssize_t size_counter = 0;
++ssize_t (*decode_function)(FILE*, FILE*, uschar*);
++
++if (mime_stream == NULL)
++ return FAIL;
++
++f_pos = ftell(mime_stream);
++
++/* build default decode path (will exist since MBOX must be spooled up) */
++(void)string_format(decode_path,1024,"%s/scan/%s",spool_directory,message_id);
++
++/* try to find 1st option */
++if ((option = string_nextinlist(&list, &sep,
++ option_buffer,
++ sizeof(option_buffer))) != NULL)
++ {
++ /* parse 1st option */
++ if ( (Ustrcmp(option,"false") == 0) || (Ustrcmp(option,"0") == 0) )
++ /* explicitly no decoding */
+ return FAIL;
+
+- f_pos = ftell(mime_stream);
+-
+- /* build default decode path (will exist since MBOX must be spooled up) */
+- (void)string_format(decode_path,1024,"%s/scan/%s",spool_directory,message_id);
+-
+- /* try to find 1st option */
+- if ((option = string_nextinlist(&list, &sep,
+- option_buffer,
+- sizeof(option_buffer))) != NULL) {
++ if (Ustrcmp(option,"default") == 0)
++ /* explicit default path + file names */
++ goto DEFAULT_PATH;
+
+- /* parse 1st option */
+- if ( (Ustrcmp(option,"false") == 0) || (Ustrcmp(option,"0") == 0) ) {
+- /* explicitly no decoding */
+- return FAIL;
+- };
++ if (option[0] == '/')
++ {
++ struct stat statbuf;
+
+- if (Ustrcmp(option,"default") == 0) {
+- /* explicit default path + file names */
+- goto DEFAULT_PATH;
+- };
++ memset(&statbuf,0,sizeof(statbuf));
+
+- if (option[0] == '/') {
+- struct stat statbuf;
+-
+- memset(&statbuf,0,sizeof(statbuf));
+-
+- /* assume either path or path+file name */
+- if ( (stat(CS option, &statbuf) == 0) && S_ISDIR(statbuf.st_mode) )
+- /* is directory, use it as decode_path */
+- decode_file = mime_get_decode_file(option, NULL);
+- else
+- /* does not exist or is a file, use as full file name */
+- decode_file = mime_get_decode_file(NULL, option);
+- }
++ /* assume either path or path+file name */
++ if ( (stat(CS option, &statbuf) == 0) && S_ISDIR(statbuf.st_mode) )
++ /* is directory, use it as decode_path */
++ decode_file = mime_get_decode_file(option, NULL);
+ else
+- /* assume file name only, use default path */
+- decode_file = mime_get_decode_file(decode_path, option);
+- }
+- else
+- /* no option? patch default path */
+- DEFAULT_PATH: decode_file = mime_get_decode_file(decode_path, NULL);
+-
+- if (decode_file == NULL)
+- return DEFER;
+-
+- /* decode according to mime type */
+- if (mime_content_transfer_encoding == NULL)
+- /* no encoding, dump as-is */
+- decode_function = mime_decode_asis;
+- else if (Ustrcmp(mime_content_transfer_encoding, "base64") == 0)
+- decode_function = mime_decode_base64;
+- else if (Ustrcmp(mime_content_transfer_encoding, "quoted-printable") == 0)
+- decode_function = mime_decode_qp;
++ /* does not exist or is a file, use as full file name */
++ decode_file = mime_get_decode_file(NULL, option);
++ }
+ else
+- /* unknown encoding type, just dump as-is */
+- decode_function = mime_decode_asis;
++ /* assume file name only, use default path */
++ decode_file = mime_get_decode_file(decode_path, option);
++ }
++else
++ {
++ /* no option? patch default path */
++DEFAULT_PATH:
++ decode_file = mime_get_decode_file(decode_path, NULL);
++ }
+
+- size_counter = decode_function(mime_stream, decode_file, mime_current_boundary);
++if (!decode_file)
++ return DEFER;
+
+- clearerr(mime_stream);
+- fseek(mime_stream, f_pos, SEEK_SET);
++/* decode according to mime type */
++decode_function =
++ !mime_content_transfer_encoding
++ ? mime_decode_asis /* no encoding, dump as-is */
++ : Ustrcmp(mime_content_transfer_encoding, "base64") == 0
++ ? mime_decode_base64
++ : Ustrcmp(mime_content_transfer_encoding, "quoted-printable") == 0
++ ? mime_decode_qp
++ : mime_decode_asis; /* unknown encoding type, just dump as-is */
+
+- if (fclose(decode_file) != 0 || size_counter < 0)
+- return DEFER;
++size_counter = decode_function(mime_stream, decode_file, mime_current_boundary);
+
+- /* round up to the next KiB */
+- mime_content_size = (size_counter + 1023) / 1024;
++clearerr(mime_stream);
++fseek(mime_stream, f_pos, SEEK_SET);
+
+- return OK;
+-}
++if (fclose(decode_file) != 0 || size_counter < 0)
++ return DEFER;
+
+-int mime_get_header(FILE *f, uschar *header) {
+- int c = EOF;
+- int done = 0;
+- int header_value_mode = 0;
+- int header_open_brackets = 0;
+- int num_copied = 0;
++/* round up to the next KiB */
++mime_content_size = (size_counter + 1023) / 1024;
+
+- while(!done) {
++return OK;
++}
+
+- c = fgetc(f);
+- if (c == EOF) break;
++int
++mime_get_header(FILE *f, uschar *header)
++{
++int c = EOF;
++int done = 0;
++int header_value_mode = 0;
++int header_open_brackets = 0;
++int num_copied = 0;
+
+- /* always skip CRs */
+- if (c == '\r') continue;
++while(!done)
++ {
++ if ((c = fgetc(f)) == EOF) break;
++
++ /* always skip CRs */
++ if (c == '\r') continue;
++
++ if (c == '\n')
++ {
++ if (num_copied > 0)
++ {
++ /* look if next char is '\t' or ' ' */
++ if ((c = fgetc(f)) == EOF) break;
++ if ( (c == '\t') || (c == ' ') ) continue;
++ (void)ungetc(c,f);
++ }
++ /* end of the header, terminate with ';' */
++ c = ';';
++ done = 1;
++ }
+
+- if (c == '\n') {
+- if (num_copied > 0) {
+- /* look if next char is '\t' or ' ' */
+- c = fgetc(f);
+- if (c == EOF) break;
+- if ( (c == '\t') || (c == ' ') ) continue;
+- (void)ungetc(c,f);
+- };
+- /* end of the header, terminate with ';' */
+- c = ';';
+- done = 1;
+- };
+-
+- /* skip control characters */
+- if (c < 32) continue;
+-
+- if (header_value_mode) {
+- /* --------- value mode ----------- */
+- /* skip leading whitespace */
+- if ( ((c == '\t') || (c == ' ')) && (header_value_mode == 1) )
+- continue;
++ /* skip control characters */
++ if (c < 32) continue;
++
++ if (header_value_mode)
++ {
++ /* --------- value mode ----------- */
++ /* skip leading whitespace */
++ if ( ((c == '\t') || (c == ' ')) && (header_value_mode == 1) )
++ continue;
+
+ /* we have hit a non-whitespace char, start copying value data */
+ header_value_mode = 2;
+@@ -400,295 +421,320 @@ int mime_get_header(FILE *f, uschar *header) {
+ };
+ /* -------------------------------- */
+ }
+- else {
+- /* -------- non-value mode -------- */
+- /* skip whitespace + tabs */
+- if ( (c == ' ') || (c == '\t') )
+- continue;
+- if (c == '\\') {
+- /* quote next char. can be used
+- to escape brackets. */
+- c = fgetc(f);
+- if (c == EOF) break;
++ else
++ {
++ /* -------- non-value mode -------- */
++ /* skip whitespace + tabs */
++ if ( (c == ' ') || (c == '\t') )
++ continue;
++ if (c == '\\')
++ {
++ /* quote next char. can be used
++ to escape brackets. */
++ if ((c = fgetc(f)) == EOF) break;
+ }
+- else if (c == '(') {
+- header_open_brackets++;
+- continue;
++ else if (c == '(')
++ {
++ header_open_brackets++;
++ continue;
+ }
+- else if ((c == ')') && header_open_brackets) {
+- header_open_brackets--;
+- continue;
++ else if ((c == ')') && header_open_brackets)
++ {
++ header_open_brackets--;
++ continue;
+ }
+- else if ( (c == '=') && !header_open_brackets ) {
+- /* enter value mode */
+- header_value_mode = 1;
+- };
++ else if ( (c == '=') && !header_open_brackets ) /* enter value mode */
++ header_value_mode = 1;
+
+- /* skip chars while we are in a comment */
+- if (header_open_brackets > 0)
+- continue;
+- /* -------------------------------- */
+- };
++ /* skip chars while we are in a comment */
++ if (header_open_brackets > 0)
++ continue;
++ /* -------------------------------- */
++ }
+
+- /* copy the char to the buffer */
+- header[num_copied] = (uschar)c;
+- /* raise counter */
+- num_copied++;
++ /* copy the char to the buffer */
++ header[num_copied++] = (uschar)c;
+
+- /* break if header buffer is full */
+- if (num_copied > MIME_MAX_HEADER_SIZE-1) {
+- done = 1;
+- };
+- };
++ /* break if header buffer is full */
++ if (num_copied > MIME_MAX_HEADER_SIZE-1)
++ done = 1;
++ }
+
+- if ((num_copied > 0) && (header[num_copied-1] != ';')) {
+- header[num_copied-1] = ';';
+- };
++if ((num_copied > 0) && (header[num_copied-1] != ';'))
++ header[num_copied-1] = ';';
+
+- /* 0-terminate */
+- header[num_copied] = '\0';
++/* 0-terminate */
++header[num_copied] = '\0';
+
+- /* return 0 for EOF or empty line */
+- if ((c == EOF) || (num_copied == 1))
+- return 0;
+- else
+- return 1;
++/* return 0 for EOF or empty line */
++if ((c == EOF) || (num_copied == 1))
++ return 0;
++else
++ return 1;
+ }
+
+
+-int mime_acl_check(uschar *acl, FILE *f, struct mime_boundary_context *context,
+- uschar **user_msgptr, uschar **log_msgptr) {
+- int rc = OK;
+- uschar *header = NULL;
+- struct mime_boundary_context nested_context;
+-
+- /* reserve a line buffer to work in */
+- header = (uschar *)malloc(MIME_MAX_HEADER_SIZE+1);
+- if (header == NULL) {
+- log_write(0, LOG_PANIC,
+- "MIME ACL: can't allocate %d bytes of memory.", MIME_MAX_HEADER_SIZE+1);
+- return DEFER;
+- };
+-
+- /* Not actually used at the moment, but will be vital to fixing
+- * some RFC 2046 nonconformance later... */
+- nested_context.parent = context;
+-
+- /* loop through parts */
+- while(1) {
+-
+- /* reset all per-part mime variables */
+- mime_anomaly_level = 0;
+- mime_anomaly_text = NULL;
+- mime_boundary = NULL;
+- mime_charset = NULL;
+- mime_decoded_filename = NULL;
+- mime_filename = NULL;
+- mime_content_description = NULL;
+- mime_content_disposition = NULL;
+- mime_content_id = NULL;
+- mime_content_transfer_encoding = NULL;
+- mime_content_type = NULL;
+- mime_is_multipart = 0;
+- mime_content_size = 0;
+-
+- /*
+- If boundary is null, we assume that *f is positioned on the start of headers (for example,
+- at the very beginning of a message.
+- If a boundary is given, we must first advance to it to reach the start of the next header
+- block.
+- */
+-
+- /* NOTE -- there's an error here -- RFC2046 specifically says to
+- * check for outer boundaries. This code doesn't do that, and
+- * I haven't fixed this.
+- *
+- * (I have moved partway towards adding support, however, by adding
+- * a "parent" field to my new boundary-context structure.)
+- */
+- if (context != NULL) {
+- while(fgets(CS header, MIME_MAX_HEADER_SIZE, f) != NULL) {
+- /* boundary line must start with 2 dashes */
+- if (Ustrncmp(header,"--",2) == 0) {
+- if (Ustrncmp((header+2),context->boundary,Ustrlen(context->boundary)) == 0) {
+- /* found boundary */
+- if (Ustrncmp((header+2+Ustrlen(context->boundary)),"--",2) == 0) {
+- /* END boundary found */
+- debug_printf("End boundary found %s\n", context->boundary);
+- return rc;
+- }
+- else {
+- debug_printf("Next part with boundary %s\n", context->boundary);
+- };
+- /* can't use break here */
+- goto DECODE_HEADERS;
+- }
+- };
++int
++mime_acl_check(uschar *acl, FILE *f, struct mime_boundary_context *context,
++ uschar **user_msgptr, uschar **log_msgptr)
++{
++int rc = OK;
++uschar *header = NULL;
++struct mime_boundary_context nested_context;
++
++/* reserve a line buffer to work in */
++if (!(header = (uschar *)malloc(MIME_MAX_HEADER_SIZE+1)))
++ {
++ log_write(0, LOG_PANIC,
++ "MIME ACL: can't allocate %d bytes of memory.", MIME_MAX_HEADER_SIZE+1);
++ return DEFER;
++ }
++
++/* Not actually used at the moment, but will be vital to fixing
++ * some RFC 2046 nonconformance later... */
++nested_context.parent = context;
++
++/* loop through parts */
++while(1)
++ {
++ /* reset all per-part mime variables */
++ mime_anomaly_level = 0;
++ mime_anomaly_text = NULL;
++ mime_boundary = NULL;
++ mime_charset = NULL;
++ mime_decoded_filename = NULL;
++ mime_filename = NULL;
++ mime_content_description = NULL;
++ mime_content_disposition = NULL;
++ mime_content_id = NULL;
++ mime_content_transfer_encoding = NULL;
++ mime_content_type = NULL;
++ mime_is_multipart = 0;
++ mime_content_size = 0;
++
++ /*
++ If boundary is null, we assume that *f is positioned on the start of headers (for example,
++ at the very beginning of a message.
++ If a boundary is given, we must first advance to it to reach the start of the next header
++ block.
++ */
++
++ /* NOTE -- there's an error here -- RFC2046 specifically says to
++ * check for outer boundaries. This code doesn't do that, and
++ * I haven't fixed this.
++ *
++ * (I have moved partway towards adding support, however, by adding
++ * a "parent" field to my new boundary-context structure.)
++ */
++ if (context != NULL)
++ {
++ while(fgets(CS header, MIME_MAX_HEADER_SIZE, f) != NULL)
++ {
++ /* boundary line must start with 2 dashes */
++ if (Ustrncmp(header,"--",2) == 0)
++ {
++ if (Ustrncmp((header+2),context->boundary,Ustrlen(context->boundary)) == 0)
++ {
++ /* found boundary */
++ if (Ustrncmp((header+2+Ustrlen(context->boundary)),"--",2) == 0)
++ {
++ /* END boundary found */
++ debug_printf("End boundary found %s\n", context->boundary);
++ return rc;
++ }
++ else
++ debug_printf("Next part with boundary %s\n", context->boundary);
++
++ /* can't use break here */
++ goto DECODE_HEADERS;
++ }
++ }
+ }
+- /* Hit EOF or read error. Ugh. */
+- debug_printf("Hit EOF ...\n");
+- return rc;
+- };
+-
+- DECODE_HEADERS:
+- /* parse headers, set up expansion variables */
+- while(mime_get_header(f,header)) {
+- int i;
+- /* loop through header list */
+- for (i = 0; i < mime_header_list_size; i++) {
+- uschar *header_value = NULL;
+- int header_value_len = 0;
+-
+- /* found an interesting header? */
+- if (strncmpic(mime_header_list[i].name,header,mime_header_list[i].namelen) == 0) {
+- uschar *p = header + mime_header_list[i].namelen;
+- /* yes, grab the value (normalize to lower case)
+- and copy to its corresponding expansion variable */
+- while(*p != ';') {
+- *p = tolower(*p);
+- p++;
+- };
+- header_value_len = (p - (header + mime_header_list[i].namelen));
+- header_value = (uschar *)malloc(header_value_len+1);
+- memset(header_value,0,header_value_len+1);
+- p = header + mime_header_list[i].namelen;
+- Ustrncpy(header_value, p, header_value_len);
+- debug_printf("Found %s MIME header, value is '%s'\n", mime_header_list[i].name, header_value);
+- *((uschar **)(mime_header_list[i].value)) = header_value;
+-
+- /* make p point to the next character after the closing ';' */
+- p += (header_value_len+1);
+-
+- /* grab all param=value tags on the remaining line, check if they are interesting */
+- NEXT_PARAM_SEARCH: while (*p != 0) {
+- int j;
+- for (j = 0; j < mime_parameter_list_size; j++) {
+- uschar *param_value = NULL;
+- int param_value_len = 0;
+-
+- /* found an interesting parameter? */
+- if (strncmpic(mime_parameter_list[j].name,p,mime_parameter_list[j].namelen) == 0) {
+- uschar *q = p + mime_parameter_list[j].namelen;
+- /* yes, grab the value and copy to its corresponding expansion variable */
+- while (*q && *q != ';')
+- {
+- if (*q == '"') do q++; while (*q != '"');
+- q++;
+- }
+-
+- param_value_len = (q - (p + mime_parameter_list[j].namelen));
+- param_value = (uschar *)malloc(param_value_len+1);
+- memset(param_value,0,param_value_len+1);
+- q = p + mime_parameter_list[j].namelen;
+- Ustrncpy(param_value, q, param_value_len);
+- param_value = rfc2047_decode(param_value, check_rfc2047_length, NULL, 32, ¶m_value_len, &q);
+- debug_printf("Found %s MIME parameter in %s header, value is '%s'\n", mime_parameter_list[j].name, mime_header_list[i].name, param_value);
+- *((uschar **)(mime_parameter_list[j].value)) = param_value;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-ports-all
mailing list