Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Aug 2014 13:55:00 +0000 (UTC)
From:      Vsevolod Stakhov <vsevolod@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r363709 - in head/mail/exim: . files
Message-ID:  <201408011355.s71Dt03S006357@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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, &param_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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408011355.s71Dt03S006357>