mlmmj

changeset dfc9ab125fd4

Fix spelling of 'receive' and 'voodoo'; make mlmmj-recieve a symlink
author Chris Webb
date Sun, 03 Oct 2010 21:40:42 +1100
parents fd77dd58bde1
children fdc57c9e5f56
files .hgignore ChangeLog Makefile.am README README.exim4 README.postfix README.qmail configure.ac contrib/Makefile.am contrib/amime-receive/mlmmj-amime-receive contrib/receivestrip/Makefile.am contrib/receivestrip/README contrib/receivestrip/mlmmj-receive-strip.c contrib/recievestrip/Makefile.am contrib/recievestrip/README contrib/recievestrip/mlmmj-recieve-strip.c include/do_all_the_voodo_here.h include/do_all_the_voodoo_here.h include/mlmmj-receive.h include/mlmmj-recieve.h man/mlmmj-bounce.1 man/mlmmj-list.1 man/mlmmj-process.1 man/mlmmj-receive.1 man/mlmmj-recieve.1 man/mlmmj-sub.1 src/Makefile.am src/do_all_the_voodo_here.c src/do_all_the_voodoo_here.c src/mlmmj-make-ml.sh.in src/mlmmj-process.c src/mlmmj-receive.c src/mlmmj-recieve.c src/mlmmj-send.c
diffstat 34 files changed, 1107 insertions(+), 1102 deletions(-) [+]
line diff
     1.1 --- a/.hgignore	Mon Sep 27 10:59:35 2010 +1000
     1.2 +++ b/.hgignore	Sun Oct 03 21:40:42 2010 +1100
     1.3 @@ -26,7 +26,7 @@
     1.4  ^src/mlmmj-list$
     1.5  ^src/mlmmj-maintd$
     1.6  ^src/mlmmj-process$
     1.7 -^src/mlmmj-recieve$
     1.8 +^src/mlmmj-receive$
     1.9  ^src/mlmmj-send$
    1.10  ^src/mlmmj-sub$
    1.11  ^src/mlmmj-unsub$
     2.1 --- a/ChangeLog	Mon Sep 27 10:59:35 2010 +1000
     2.2 +++ b/ChangeLog	Sun Oct 03 21:40:42 2010 +1100
     2.3 @@ -1,3 +1,5 @@
     2.4 + o Correct spelling of 'receive' and 'voodoo' throughout the code and
     2.5 +   documentation, making mlmmj-recieve a symlink to mlmmj-receive (Chris Webb)
     2.6   o Richer MIME list texts with inline messages (English only so far)
     2.7   o Add $random0$ through $random5$ substitutions
     2.8   o Add a $subject$ substitution for list texts
     3.1 --- a/Makefile.am	Mon Sep 27 10:59:35 2010 +1000
     3.2 +++ b/Makefile.am	Sun Oct 03 21:40:42 2010 +1100
     3.3 @@ -10,7 +10,7 @@
     3.4  dist-hook:
     3.5  	rm -rf `find $(distdir)/ -name CVS`
     3.6  
     3.7 -man1_MANS = man/mlmmj-bounce.1 man/mlmmj-make-ml.sh.1 man/mlmmj-recieve.1 \
     3.8 +man1_MANS = man/mlmmj-bounce.1 man/mlmmj-make-ml.sh.1 man/mlmmj-receive.1 \
     3.9  	    man/mlmmj-sub.1 man/mlmmj-maintd.1 man/mlmmj-process.1 \
    3.10  	    man/mlmmj-send.1 man/mlmmj-unsub.1 man/mlmmj-list.1
    3.11  
     4.1 --- a/README	Mon Sep 27 10:59:35 2010 +1000
     4.2 +++ b/README	Sun Oct 03 21:40:42 2010 +1100
     4.3 @@ -30,8 +30,8 @@
     4.4      $ ./configure && make && make install
     4.5  
     4.6  		If you want to filter multipart/mime messages, pass the option
     4.7 -		--enable-recieve-strip to configure, and take a look at
     4.8 -		contrib/recievestrip/README.
     4.9 +		--enable-receive-strip to configure, and take a look at
    4.10 +		contrib/receivestrip/README.
    4.11  
    4.12   1) Configure a recipient delimiter. The default is to use '+', and in
    4.13      Postfix it's done by adding
    4.14 @@ -83,7 +83,7 @@
    4.15   3) Make the changes to your mailserver aliases that came as output from
    4.16      mlmmj-make-ml.sh. Following the example above they will look like this:
    4.17  
    4.18 -    mlmmj-test:     "|/usr/bin/mlmmj-recieve -L /var/spool/mlmmj/mlmmj-test"
    4.19 +    mlmmj-test:     "|/usr/bin/mlmmj-receive -L /var/spool/mlmmj/mlmmj-test"
    4.20  
    4.21      NOTE: Don't forget newaliases.
    4.22  
     5.1 --- a/README.exim4	Mon Sep 27 10:59:35 2010 +1000
     5.2 +++ b/README.exim4	Sun Oct 03 21:40:42 2010 +1100
     5.3 @@ -76,7 +76,7 @@
     5.4    domains = !+mlmmj_domains : !+local_domains
     5.5  [...]
     5.6  
     5.7 -5. Somewhere in the transports section. (Change the path of mlmmj-recieve if you
     5.8 +5. Somewhere in the transports section. (Change the path of mlmmj-receive if you
     5.9  don't use the default location!):
    5.10  
    5.11  mlmmj_transport:
    5.12 @@ -86,7 +86,7 @@
    5.13    group = mlmmj
    5.14    home_directory = MLMMJ_HOME
    5.15    current_directory = MLMMJ_HOME
    5.16 -  command = /usr/local/bin/mlmmj-recieve -F -L MLMMJ_HOME/${lc:$local_part}
    5.17 +  command = /usr/local/bin/mlmmj-receive -F -L MLMMJ_HOME/${lc:$local_part}
    5.18  
    5.19  If you want VERP to be done by your MTA, also add this:
    5.20  
     6.1 --- a/README.postfix	Mon Sep 27 10:59:35 2010 +1000
     6.2 +++ b/README.postfix	Sun Oct 03 21:40:42 2010 +1100
     6.3 @@ -99,22 +99,22 @@
     6.4      Now we setup the 'mlmmj' transport.  The 'mlmmj' in mlmmj:$1 above
     6.5      indicates a transport listed in the postfix master.cf file.  We are
     6.6      just going to create a transport called 'mlmmj' but it is nothing
     6.7 -    more than a pipe(8) to the mlmmj-recieve program that is invoked as
     6.8 +    more than a pipe(8) to the mlmmj-receive program that is invoked as
     6.9      the 'mlmmj' user.
    6.10  
    6.11          master.cf:
    6.12              # mlmmj mailing lists
    6.13              mlmmj   unix  -       n       n       -       -       pipe
    6.14 -                flags=DORhu user=mlmmj argv=/usr/local/bin/mlmmj-recieve -F -L /var/spool/mlmmj/$nexthop/
    6.15 +                flags=DORhu user=mlmmj argv=/usr/local/bin/mlmmj-receive -F -L /var/spool/mlmmj/$nexthop/
    6.16  
    6.17      This takes the pipe(8) postfix delivery agent and tells it to invoke
    6.18 -    '/usr/local/bin/mlmmj-recieve' as the 'mlmmj' user and pipe the
    6.19 +    '/usr/local/bin/mlmmj-receive' as the 'mlmmj' user and pipe the
    6.20      email to it on stdin.  This mode of transportation is given the name
    6.21      'mlmmj'.
    6.22  
    6.23      The 'flags' parameter to pipe(8) is pretty critical here. In
    6.24 -    particular if the 'R' option is not used mlmmj-recieve fails to
    6.25 -    recieve the mail correctly. The options mean:
    6.26 +    particular if the 'R' option is not used mlmmj-receive fails to
    6.27 +    receive the mail correctly. The options mean:
    6.28  
    6.29          D - Prepend a 'Delivered-To: recipient' header
    6.30          O - Prepend an 'X-Original-To: recipient' header
     7.1 --- a/README.qmail	Mon Sep 27 10:59:35 2010 +1000
     7.2 +++ b/README.qmail	Sun Oct 03 21:40:42 2010 +1100
     7.3 @@ -26,7 +26,7 @@
     7.4     # cd ${LISTDIR}/control/; echo '-' > delimiter
     7.5  - chown and chmod the file according to the mlmmj configuration
     7.6  - create dot-qmail files for the list to handle direct requests and extensions:
     7.7 -   # echo -e "|${BINDIR}/mlmmj-recieve -L ${LISTDIR}" > ${DQFILE}
     7.8 +   # echo -e "|${BINDIR}/mlmmj-receive -L ${LISTDIR}" > ${DQFILE}
     7.9  - chown and chmod the files according to the qmail (and vpopmail) configuration
    7.10  
    7.11  WARNING: REMEMBER that the delimiter is -, so do not use + when composing mail
    7.12 @@ -53,7 +53,7 @@
    7.13  # echo '-' > delimiter
    7.14  # chown vpopmail:vchkpw delimiter
    7.15  # cd /home/vpopmail/domains/programmazione.it/
    7.16 -# echo -e "|/usr/local/bin/mlmmj-recieve -L /var/spool/mlmmj/ml/" > .qmail-ml
    7.17 +# echo -e "|/usr/local/bin/mlmmj-receive -L /var/spool/mlmmj/ml/" > .qmail-ml
    7.18  # cp -a .qmail-ml .qmail-ml-default
    7.19  # cat *-default
    7.20  # chown vpopmail:vchkpw .qmail-ml .qmail-ml-default
     8.1 --- a/configure.ac	Mon Sep 27 10:59:35 2010 +1000
     8.2 +++ b/configure.ac	Sun Oct 03 21:40:42 2010 +1100
     8.3 @@ -5,7 +5,7 @@
     8.4  AC_SUBST(VERSION)
     8.5  
     8.6  AM_INIT_AUTOMAKE(mlmmj, $VERSION)
     8.7 -AC_CONFIG_SRCDIR([src/mlmmj-recieve.c])
     8.8 +AC_CONFIG_SRCDIR([src/mlmmj-receive.c])
     8.9  AM_CONFIG_HEADER([config.h])
    8.10  
    8.11  # Checks for programs.
    8.12 @@ -33,10 +33,10 @@
    8.13  
    8.14  AC_SUBST(textlibdir)
    8.15  
    8.16 -AC_ARG_ENABLE([recieve-strip],
    8.17 -  AS_HELP_STRING([--enable-recieve-strip],
    8.18 -                 [build mlmmj-recieve-strip (default is no)]))
    8.19 -AM_CONDITIONAL(WANT_RECIEVESTRIP, test x"$enable_recieve_strip" = xyes)
    8.20 +AC_ARG_ENABLE([receive-strip],
    8.21 +  AS_HELP_STRING([--enable-receive-strip],
    8.22 +                 [build mlmmj-receive-strip (default is no)]))
    8.23 +AM_CONDITIONAL(WANT_RECEIVESTRIP, test x"$enable_receive_strip" = xyes)
    8.24  
    8.25  # Checks for library functions.
    8.26  AC_FUNC_MALLOC
    8.27 @@ -48,5 +48,5 @@
    8.28  AC_CONFIG_FILES([src/mlmmj-make-ml.sh])
    8.29  AC_CONFIG_FILES([listtexts/Makefile])
    8.30  AC_CONFIG_FILES([contrib/Makefile])
    8.31 -AC_CONFIG_FILES([contrib/recievestrip/Makefile])
    8.32 +AC_CONFIG_FILES([contrib/receivestrip/Makefile])
    8.33  AC_OUTPUT
     9.1 --- a/contrib/Makefile.am	Mon Sep 27 10:59:35 2010 +1000
     9.2 +++ b/contrib/Makefile.am	Sun Oct 03 21:40:42 2010 +1100
     9.3 @@ -1,4 +1,4 @@
     9.4  ## Process this file with automake to produce Makefile.in
     9.5  
     9.6  EXTRA_DIST = web amime-receive
     9.7 -SUBDIRS = recievestrip
     9.8 +SUBDIRS = receivestrip
    10.1 --- a/contrib/amime-receive/mlmmj-amime-receive	Mon Sep 27 10:59:35 2010 +1000
    10.2 +++ b/contrib/amime-receive/mlmmj-amime-receive	Sun Oct 03 21:40:42 2010 +1100
    10.3 @@ -2,12 +2,12 @@
    10.4  # 
    10.5  # mlmmj-amime-receive
    10.6  #
    10.7 -# Take mail from stdin, pipe it through altermime and then to mlmmj-recieve
    10.8 +# Take mail from stdin, pipe it through altermime and then to mlmmj-receive
    10.9  # needed to add footers in a MIME-aware way
   10.10  #
   10.11  # requires altermime, see http://www.pldaniels.com/altermime/
   10.12  #
   10.13 -# just replace mlmmj-recieve (sic) with mlmmj-amime-receive, e.g. in /etc/aliases:
   10.14 +# just replace mlmmj-receive with mlmmj-amime-receive, e.g. in /etc/aliases:
   10.15  # myml:   "|/usr/bin/mlmmj-amime-receive -L /var/spool/mlmmj/myml/"
   10.16  #
   10.17  # put the footer-text for the different MIME-types into 
   10.18 @@ -20,12 +20,12 @@
   10.19  # Licensed under MIT License, see LICENSE file coming with mlmmj
   10.20  #
   10.21  
   10.22 -MLMMJRECIEVE=/usr/bin/mlmmj-recieve
   10.23 +MLMMJRECEIVE=/usr/bin/mlmmj-receive
   10.24  ALTERMIME=/usr/bin/altermime
   10.25  
   10.26  # check executables
   10.27 -if ! [ -x $MLMMJRECIEVE ]; then
   10.28 -    echo "can't find $MLMMJRECIEVE executable, aborting"
   10.29 +if ! [ -x $MLMMJRECEIVE ]; then
   10.30 +    echo "can't find $MLMMJRECEIVE executable, aborting"
   10.31      exit 1
   10.32  fi
   10.33  
   10.34 @@ -86,4 +86,4 @@
   10.35  cd $MLPATH
   10.36  
   10.37  # pipe the calls
   10.38 -$ALTERMIME --input=- ${PARAM} | $MLMMJRECIEVE "$@"
   10.39 +$ALTERMIME --input=- ${PARAM} | $MLMMJRECEIVE "$@"
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/contrib/receivestrip/Makefile.am	Sun Oct 03 21:40:42 2010 +1100
    11.3 @@ -0,0 +1,14 @@
    11.4 +#
    11.5 +
    11.6 +AUTOMAKE_OPTIONS = foreign
    11.7 +
    11.8 +AM_CFLAGS = -g -Wall -pedantic -Wsign-compare -DDEFAULTTEXTDIR='"@textlibdir@"'
    11.9 +INCLUDES = -I$(srcdir)/../../include
   11.10 +
   11.11 +if WANT_RECEIVESTRIP
   11.12 +  bin_PROGRAMS = mlmmj-receive-strip
   11.13 +endif
   11.14 +
   11.15 +mlmmj_receive_strip_SOURCES = mlmmj-receive-strip.c ../../src/mygetline.c ../../src/memory.c ../../src/readn.c  \
   11.16 +				../../src/strgen.c ../../src/random-int.c  ../../src/log_error.c ../../src/print-version.c \
   11.17 +				../../src/writen.c ../../src/dumpfd2fd.c ../../src/ctrlvalues.c ../../src/chomp.c
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/contrib/receivestrip/README	Sun Oct 03 21:40:42 2010 +1100
    12.3 @@ -0,0 +1,37 @@
    12.4 +mlmmj-receive-strip is a replacement for mlmmj-receive
    12.5 +
    12.6 +It opens the files control/mimedeny and control/mimestrip to get a list of mimetypes
    12.7 +for parts of multipart/mime messages that should be denied or stripped
    12.8 +
    12.9 +The parts then get stripped directly when the mail is received.
   12.10 +
   12.11 +mlmmj-receive-strip also appends an extra header
   12.12 +
   12.13 +X-ThisMailContainsUnwantedMimeParts: Y when the mail contains unwanted mime parts
   12.14 +
   12.15 +
   12.16 +Usage:
   12.17 +Compile the program in this directory with make and use "make install" to install it.
   12.18 +Afterwards replace mlmmj-receive with mlmmj-receive-strip in /etc/aliases for the mailinglist
   12.19 +you want to enable stripping and run newaliases
   12.20 +
   12.21 +
   12.22 +Then create the files mimedeny mimestrip in the control directory of your mailinglist.
   12.23 +
   12.24 +If control/mimestrip for example contains:
   12.25 +
   12.26 +text/html
   12.27 +application/octet-stream
   12.28 +
   12.29 +html texts and binarys will be stripped from the mail.
   12.30 +
   12.31 +When you also want to deny mails with certain mimeparts add the mimetypes to the mimedeny file
   12.32 +and add the following lines to the control/access file:
   12.33 +
   12.34 +deny ^X-ThisMailContainsUnwantedMimeParts: Y
   12.35 +allow
   12.36 +
   12.37 +You will most likely want to remove the X-ThisMailContainsUnwantedMimeParts
   12.38 +header by adding the following line to the control/delheaders file:
   12.39 +
   12.40 +X-ThisMailContainsUnwantedMimeParts:
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/contrib/receivestrip/mlmmj-receive-strip.c	Sun Oct 03 21:40:42 2010 +1100
    13.3 @@ -0,0 +1,523 @@
    13.4 +/* Copyright (C) 2007 Sascha Sommer <ssommer at suse.de>
    13.5 + *
    13.6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    13.7 + * of this software and associated documentation files (the "Software"), to
    13.8 + * deal in the Software without restriction, including without limitation the
    13.9 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   13.10 + * sell copies of the Software, and to permit persons to whom the Software is
   13.11 + * furnished to do so, subject to the following conditions:
   13.12 + *
   13.13 + * The above copyright notice and this permission notice shall be included in
   13.14 + * all copies or substantial portions of the Software.
   13.15 + *
   13.16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   13.17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   13.18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   13.19 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   13.20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   13.21 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   13.22 + * IN THE SOFTWARE.
   13.23 + */
   13.24 +
   13.25 +/* a version of mlmmj-receive that parses the mail on the fly and strips unwanted
   13.26 +   mime parts
   13.27 +   opens the files control/mimedeny and control/mimestrip for a list of mime
   13.28 +   types for body parts that should be denied or stripped.
   13.29 +   It adds an extra header X-ThisMailContainsUnwantedMimeParts: Y for mails that
   13.30 +   contain disallowed mimeparts and X-ThisMailContainsUnwantedMimeParts: N otherwise
   13.31 +*/
   13.32 +
   13.33 +#include <stdlib.h>
   13.34 +#include <string.h>
   13.35 +#include <unistd.h>
   13.36 +#include <sys/stat.h>
   13.37 +#include <fcntl.h>
   13.38 +#include <stdio.h>
   13.39 +#include <errno.h>
   13.40 +#include <string.h>
   13.41 +#include <sys/types.h>
   13.42 +
   13.43 +
   13.44 +
   13.45 +#include "mlmmj.h"
   13.46 +#include "mygetline.h"
   13.47 +#include "gethdrline.h"
   13.48 +#include "strgen.h"
   13.49 +#include "chomp.h"
   13.50 +#include "ctrlvalue.h"
   13.51 +#include "ctrlvalues.h"
   13.52 +
   13.53 +#include "log_error.h"
   13.54 +#include "wrappers.h"
   13.55 +#include "memory.h"
   13.56 +
   13.57 +#define UNWANTED_MIME_HDR "X-ThisMailContainsUnwantedMimeParts: N\n"
   13.58 +
   13.59 +/* append a copy of a string to a string list */
   13.60 +static void append_strtolist(struct strlist *list, char* str) {
   13.61 +	list->count++;
   13.62 +	list->strs = myrealloc(list->strs,
   13.63 +                         sizeof(char *) * (list->count + 1));
   13.64 +	list->strs[list->count-1] = mystrdup(str);
   13.65 +	list->strs[list->count] = NULL;
   13.66 +}
   13.67 +
   13.68 +/* free all strings in a strlist */
   13.69 +static void free_strlist(struct strlist *list) {
   13.70 +	if(!list)
   13.71 +		return;
   13.72 +	if(list->strs) {
   13.73 +		int i;
   13.74 +		for(i=0;i < list->count;i++)
   13.75 +			myfree(list->strs[i]);
   13.76 +		myfree(list->strs);
   13.77 +	}
   13.78 +	list->strs = NULL;
   13.79 +	list->count = 0;
   13.80 +}
   13.81 +
   13.82 +static int findit(char *line, char **headers)
   13.83 +{
   13.84 +        int i = 0;
   13.85 +        size_t len;
   13.86 +
   13.87 +	if (!headers)
   13.88 +		return 0;
   13.89 +
   13.90 +        while(headers[i]) {
   13.91 +                len = strlen(headers[i]);
   13.92 +                if(strncasecmp(line, headers[i], len) == 0)
   13.93 +                        return 1;
   13.94 +                i++;
   13.95 +        }
   13.96 +
   13.97 +        return 0;
   13.98 +}
   13.99 +
  13.100 +/* extract mime_type and boundary from the Content-Type header
  13.101 + * allocates a string for the mime_type if one is found
  13.102 + * always allocates a boundarie (using "--" when none is found)
  13.103 + * the caller needs to free the allocated strings
  13.104 +*/
  13.105 +static void extract_boundary(struct strlist *allhdrs, char** mime_type, char** boundary)
  13.106 +{
  13.107 +	int x;
  13.108 +	*boundary = NULL;
  13.109 +	*mime_type = NULL;
  13.110 +	for( x = 0 ; x < allhdrs->count ; x++ ){
  13.111 +		char* hdr = allhdrs->strs[x];
  13.112 +		if(hdr && !strncasecmp(hdr,"Content-Type:",13)){
  13.113 +			char* pos = hdr + 13;
  13.114 +			size_t len = 0;
  13.115 +
  13.116 +			/* find the start of the mimetype */
  13.117 +			while(*pos && (*pos == ' ' || *pos == '\t'))
  13.118 +				++pos;
  13.119 +
  13.120 +			if(*pos == '"'){                   /* handle quoted mime types */
  13.121 +				++pos;
  13.122 +				while(pos[len] && pos[len] != '"')
  13.123 +					++len;
  13.124 +			}else{
  13.125 +				while(pos[len] && pos[len] != ' ' && pos[len] != '\t' && pos[len] != ';')
  13.126 +					++len;
  13.127 +			}
  13.128 +
  13.129 +			/* extract mime type if any */
  13.130 +			if(len){
  13.131 +				*mime_type = mymalloc(len+1);
  13.132 +				strncpy(*mime_type,pos,len);
  13.133 +				(*mime_type)[len] = '\0';
  13.134 +			}
  13.135 +
  13.136 +			pos += len;
  13.137 +			len = 0;
  13.138 +			/* find start of the boundary info */
  13.139 +			while(*pos && strncasecmp(pos,"boundary=",9))
  13.140 +				++pos;
  13.141 +			if(*pos == '\0')         /* no boundary */
  13.142 +				break;
  13.143 +
  13.144 +			pos += 9;
  13.145 +			if(*pos == '"'){         /* quoted boundary */
  13.146 +				++pos;
  13.147 +				while(pos[len] && pos[len] != '"')
  13.148 +					++len;
  13.149 +			}else{                  /* unquoted boundary */
  13.150 +				while(pos[len] && pos[len] != ' ' && pos[len] != '\t' && pos[len] != ';')
  13.151 +					++len;
  13.152 +			}
  13.153 +
  13.154 +			/* extract boundary */
  13.155 +			*boundary = mymalloc(len + 3);
  13.156 +			strcpy(*boundary,"--");
  13.157 +			strncat(*boundary,pos,len);
  13.158 +			break;
  13.159 +		}
  13.160 +	}
  13.161 +}
  13.162 +
  13.163 +/* read all mail headers and save them in a strlist
  13.164 + * check what to do with parts that contain the given mime_type
  13.165 + *return values
  13.166 + * 0: ok
  13.167 + * 1: strip
  13.168 + * sets deny to 1 if the entire mail should be denied
  13.169 + */
  13.170 +#define MIME_OK 0
  13.171 +#define MIME_STRIP 1
  13.172 +static int read_hdrs(int fd, struct strlist *allhdrs,struct strlist* delmime,struct strlist* denymime,int* deny,char** boundary) {
  13.173 +	int result = MIME_OK;
  13.174 +	char* mime_type = NULL;
  13.175 +	allhdrs->strs = NULL;
  13.176 +	allhdrs->count = 0;
  13.177 +	/* read headers */
  13.178 +	while(1) {
  13.179 +		char* line = mygetline(fd);
  13.180 +		if(!line)        /* end of file and also end of headers */
  13.181 +			break;
  13.182 +
  13.183 +		/* end of headers */
  13.184 +		if(line[0] == '\n'){
  13.185 +			myfree(line);
  13.186 +			break;
  13.187 +		}
  13.188 +		if(!allhdrs->count || ((line[0] != '\t') && (line[0] != ' '))) /* first header line or no more unfolding */
  13.189 +			append_strtolist(allhdrs,line);
  13.190 +		else{
  13.191 +			char* tmp = concatstr(2, allhdrs->strs[allhdrs->count-1], line);
  13.192 +			myfree(allhdrs->strs[allhdrs->count-1]);
  13.193 +		 	allhdrs->strs[allhdrs->count-1] = tmp;
  13.194 +		}
  13.195 +		myfree(line);
  13.196 +	}
  13.197 +	extract_boundary(allhdrs,&mime_type,boundary);
  13.198 +	if(mime_type) {
  13.199 +		/* check if this part should be stripped */
  13.200 +		if(delmime && findit(mime_type, delmime->strs))
  13.201 +			result = MIME_STRIP;
  13.202 +		/* check if the mail should be denied */
  13.203 +		if(denymime && findit(mime_type, denymime->strs))
  13.204 +			*deny = 1;
  13.205 +		myfree(mime_type);
  13.206 +	}
  13.207 +	return result;
  13.208 +}
  13.209 +
  13.210 +/* writes the mail headers if unwantedmime_hdrpos is not NULL an UNWANTED_MIME_HDR
  13.211 + * is inserted and its position saved in unwantedmime_hdrpos
  13.212 + * returns 0 on success
  13.213 + */
  13.214 +static int write_hdrs(int outfd,struct strlist* hdrs,off_t* unwantedmime_hdrpos) {
  13.215 +	int i;
  13.216 +	for(i = 0; i < hdrs->count ; i++) {
  13.217 +		if(writen(outfd, hdrs->strs[i], strlen(hdrs->strs[i])) < 0){
  13.218 +			log_error(LOG_ARGS, "Error when dumping headers");
  13.219 +			return -1;
  13.220 +		}
  13.221 +	}
  13.222 +
  13.223 +	/* if this is not the header of an embedded part add the header that will
  13.224 +	   indicate if the mail contains unwanted mime parts */
  13.225 +	if(unwantedmime_hdrpos) {
  13.226 +		if(writen(outfd, UNWANTED_MIME_HDR,strlen(UNWANTED_MIME_HDR)) < 0){
  13.227 +			log_error(LOG_ARGS, "Error writting unwanted mime header");
  13.228 +			return -1;
  13.229 +		}
  13.230 +		/* get the current position so that we can update the header later */
  13.231 +		*unwantedmime_hdrpos = lseek(outfd,0,SEEK_CUR);
  13.232 +		if(*unwantedmime_hdrpos < 2){
  13.233 +			log_error(LOG_ARGS, "Error getting file position");
  13.234 +			return -1;
  13.235 +		}
  13.236 +		*unwantedmime_hdrpos -= 2;
  13.237 +	}
  13.238 +
  13.239 +	/* write a single line feed to terminate the header part */
  13.240 +	if(writen(outfd, "\n", 1) < 0) {
  13.241 +		log_error(LOG_ARGS,"Error writting end of hdrs.");
  13.242 +		return -1;
  13.243 +	}
  13.244 +	return 0;
  13.245 +}
  13.246 +
  13.247 +/* set the unwanted mime_hdr to Y */
  13.248 +static int update_unwantedmime_hdr(int outfd,off_t unwantedmime_hdrpos) {
  13.249 +	/* seek to the header position */
  13.250 +	if(lseek(outfd,unwantedmime_hdrpos,SEEK_SET) < 0) {
  13.251 +		log_error(LOG_ARGS,"Error seeking to the unwantedmime_hdr");
  13.252 +		return -1;
  13.253 +	}
  13.254 +
  13.255 +	/* update the header */
  13.256 +	if(writen(outfd, "Y\n",2) < 0){
  13.257 +		log_error(LOG_ARGS, "Error writting extra header");
  13.258 +		return -1;
  13.259 +	}
  13.260 +
  13.261 +	/* seek back to the end of the mail */
  13.262 +	if(lseek(outfd,0,SEEK_END) < 0) {
  13.263 +		log_error(LOG_ARGS,"Error seeking to the mail end");
  13.264 +		return -1;
  13.265 +	}
  13.266 +	return 0;
  13.267 +}
  13.268 +
  13.269 +static int parse_body(int infd,int outfd, struct strlist* delmime, struct strlist* denymime,
  13.270 +			int* deny,char* boundary){
  13.271 +	int strip = 0;
  13.272 +	char* line;
  13.273 +	while((line = mygetline(infd))) {
  13.274 +		if(boundary && !strncmp(line,boundary,strlen(boundary))){
  13.275 +			strip = 0;
  13.276 +			/* check if the boundary is the beginning of a new part */
  13.277 +			if(strncmp(line + strlen(boundary),"--",2)){
  13.278 +				struct strlist hdrs;
  13.279 +				char* new_boundary = NULL;
  13.280 +				/* check if this part should be stripped */
  13.281 +				if(read_hdrs(infd, &hdrs,delmime,denymime,deny,&new_boundary) == MIME_STRIP)
  13.282 +					strip = 1;
  13.283 +				else {
  13.284 +					/* write boundary */
  13.285 +					if(writen(outfd, line, strlen(line)) < 0){
  13.286 +						log_error(LOG_ARGS, "Error writting boundary");
  13.287 +						return -1;
  13.288 +					}
  13.289 +					/* write hdr */
  13.290 +					if(write_hdrs(outfd, &hdrs, NULL) < 0){
  13.291 +						log_error(LOG_ARGS, "Error writting hdrs");
  13.292 +						return -1;
  13.293 +					}
  13.294 +					/* parse embedded part if a new boundary was found */
  13.295 +					if(new_boundary && parse_body(infd,outfd,delmime,denymime,deny,new_boundary) != 0) {
  13.296 +						log_error(LOG_ARGS, "Could not parse embedded part");
  13.297 +						return -1;
  13.298 +					}
  13.299 +				}
  13.300 +				free_strlist(&hdrs);
  13.301 +				if(new_boundary)
  13.302 +					myfree(new_boundary);
  13.303 +			}else{
  13.304 +				/* write end of part */
  13.305 +				if(writen(outfd, line, strlen(line)) < 0){
  13.306 +					log_error(LOG_ARGS, "Error writting hdrs");
  13.307 +					return -1;
  13.308 +				}
  13.309 +				/* and leave */
  13.310 +				myfree(line);
  13.311 +				break;
  13.312 +			}
  13.313 +		}else {
  13.314 +			if(!strip) { /* write the current line */
  13.315 +				if(writen(outfd, line, strlen(line)) < 0){
  13.316 +					log_error(LOG_ARGS, "Error when dumping line");
  13.317 +					return -1;
  13.318 +				}
  13.319 +			}
  13.320 +		}
  13.321 +		myfree(line);
  13.322 +	}
  13.323 +	return 0;
  13.324 +}
  13.325 +
  13.326 +
  13.327 +
  13.328 +
  13.329 +
  13.330 +/* read a mail stripping unwanted parts */
  13.331 +static int dump_mail(int infd, int outfd,char* listdir) {
  13.332 +	struct strlist hdrs;
  13.333 +	struct strlist* delmime;
  13.334 +	struct strlist* denymime;
  13.335 +	char* boundary=NULL;
  13.336 +	int deny = 0;
  13.337 +	int result;
  13.338 +	off_t unwantedmime_hdr_pos = 0;
  13.339 +
  13.340 +	/* get list control values */
  13.341 +	delmime = ctrlvalues(listdir, "mimestrip");
  13.342 +	denymime = ctrlvalues(listdir, "mimedeny");
  13.343 +
  13.344 +	/* read mail header */
  13.345 +	result = read_hdrs(infd, &hdrs,delmime,denymime,&deny,&boundary);
  13.346 +	/* write mail header */
  13.347 +	if(write_hdrs(outfd,&hdrs,&unwantedmime_hdr_pos) < 0) {
  13.348 +		log_error(LOG_ARGS, "Could not write mail headers");
  13.349 +		return -1;
  13.350 +	}
  13.351 +
  13.352 +	/* free mail header */
  13.353 +	free_strlist(&hdrs);
  13.354 +
  13.355 +	if(result == MIME_OK && !deny) {
  13.356 +		/* try to parse the mail */
  13.357 +		if(parse_body(infd,outfd,delmime,denymime,&deny,boundary) != 0) {
  13.358 +			log_error(LOG_ARGS, "Could not parse mail");
  13.359 +			return -1;
  13.360 +		}
  13.361 +		myfree(boundary);
  13.362 +	}else
  13.363 +		deny = 1;
  13.364 +
  13.365 +	/* dump rest of mail */
  13.366 +        if(dumpfd2fd(infd, outfd) != 0) {
  13.367 +		log_error(LOG_ARGS, "Could not receive mail");
  13.368 +		return -1;
  13.369 +        }
  13.370 +
  13.371 +	/* update header */
  13.372 +	if(deny) {
  13.373 +		if(update_unwantedmime_hdr(outfd,unwantedmime_hdr_pos) != 0) {
  13.374 +			log_error(LOG_ARGS, "Could not update header");
  13.375 +			return -1;
  13.376 +		}
  13.377 +	}
  13.378 +
  13.379 +	/* free mime types */
  13.380 +	if(delmime) {
  13.381 +		free_strlist(delmime);
  13.382 +		myfree(delmime);
  13.383 +	}
  13.384 +	if(denymime) {
  13.385 +		free_strlist(denymime);
  13.386 +		myfree(denymime);
  13.387 +	}
  13.388 +	return 0;
  13.389 +}
  13.390 +
  13.391 +static void print_help(const char *prg)
  13.392 +{
  13.393 +        printf("Usage: %s -L /path/to/listdir [-h] [-V] [-P] [-F]\n"
  13.394 +	       " -h: This help\n"
  13.395 +	       " -F: Don't fork in the background\n"
  13.396 +	       " -L: Full path to list directory\n"
  13.397 +	       " -P: Don't execute mlmmj-process\n"
  13.398 +	       " -V: Print version\n", prg);
  13.399 +	exit(EXIT_SUCCESS);
  13.400 +}
  13.401 +
  13.402 +int main(int argc, char **argv)
  13.403 +{
  13.404 +	char *infilename = NULL, *listdir = NULL;
  13.405 +	char *randomstr = random_str();
  13.406 +	char *mlmmjprocess, *bindir;
  13.407 +	int fd, opt, noprocess = 0, nofork = 0;
  13.408 +	struct stat st;
  13.409 +	uid_t uid;
  13.410 +	pid_t childpid;
  13.411 +
  13.412 +	CHECKFULLPATH(argv[0]);
  13.413 +
  13.414 +	log_set_name(argv[0]);
  13.415 +
  13.416 +	bindir = mydirname(argv[0]);
  13.417 +	mlmmjprocess = concatstr(2, bindir, "/mlmmj-process");
  13.418 +	myfree(bindir);
  13.419 +
  13.420 +	while ((opt = getopt(argc, argv, "hPVL:F")) != -1) {
  13.421 +		switch(opt) {
  13.422 +		case 'h':
  13.423 +			print_help(argv[0]);
  13.424 +			break;
  13.425 +		case 'L':
  13.426 +			listdir = optarg;
  13.427 +			break;
  13.428 +		case 'P':
  13.429 +			noprocess = 1;
  13.430 +			break;
  13.431 +		case 'F':
  13.432 +			nofork = 1;
  13.433 +			break;
  13.434 +		case 'V':
  13.435 +			print_version(argv[0]);
  13.436 +			exit(0);
  13.437 +		}
  13.438 +	}
  13.439 +
  13.440 +	if(listdir == NULL) {
  13.441 +		fprintf(stderr, "You have to specify -L\n");
  13.442 +		fprintf(stderr, "%s -h for help\n", argv[0]);
  13.443 +		exit(EXIT_FAILURE);
  13.444 +	}
  13.445 +
  13.446 +	/* Lets make sure no random user tries to send mail to the list */
  13.447 +	if(listdir) {
  13.448 +		if(stat(listdir, &st) == 0) {
  13.449 +			uid = getuid();
  13.450 +			if(uid && uid != st.st_uid) {
  13.451 +				log_error(LOG_ARGS,
  13.452 +					"Have to invoke either as root "
  13.453 +					"or as the user owning listdir "
  13.454 +					"Invoked with uid = [%d]", (int)uid);
  13.455 +				writen(STDERR_FILENO,
  13.456 +					"Have to invoke either as root "
  13.457 +					"or as the user owning listdir\n", 60);
  13.458 +				exit(EXIT_FAILURE);
  13.459 +			}
  13.460 +		} else {
  13.461 +			log_error(LOG_ARGS, "Could not stat %s", listdir);
  13.462 +			exit(EXIT_FAILURE);
  13.463 +		}
  13.464 +	}
  13.465 +
  13.466 +	infilename = concatstr(3, listdir, "/incoming/", randomstr);
  13.467 +	myfree(randomstr);
  13.468 +	fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  13.469 +	while(fd < 0 && errno == EEXIST) {
  13.470 +		myfree(infilename);
  13.471 +		randomstr = random_str();
  13.472 +		infilename = concatstr(3, listdir, "/incoming/", randomstr);
  13.473 +		myfree(randomstr);
  13.474 +		fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  13.475 +	}
  13.476 +
  13.477 +	if(fd < 0) {
  13.478 +		log_error(LOG_ARGS, "could not create mail file in "
  13.479 +				    "%s/incoming directory", listdir);
  13.480 +		myfree(infilename);
  13.481 +		exit(EXIT_FAILURE);
  13.482 +	}
  13.483 +
  13.484 +	if(dump_mail(fileno(stdin), fd, listdir) != 0) {
  13.485 +		log_error(LOG_ARGS, "Could not receive mail");
  13.486 +		exit(EXIT_FAILURE);
  13.487 +	}
  13.488 +
  13.489 +#if 0
  13.490 +	log_oper(listdir, OPLOGFNAME, "mlmmj-receive got %s", infilename);
  13.491 +#endif
  13.492 +	fsync(fd);
  13.493 +	close(fd);
  13.494 +
  13.495 +	if(noprocess) {
  13.496 +		myfree(infilename);
  13.497 +		exit(EXIT_SUCCESS);
  13.498 +	}
  13.499 +
  13.500 +	/*
  13.501 +	 * Now we fork so we can exit with success since it could potentially
  13.502 +	 * take a long time for mlmmj-send to finish delivering the mails and
  13.503 +	 * returning, making it susceptible to getting a SIGKILL from the
  13.504 +	 * mailserver invoking mlmmj-receive.
  13.505 +	 */
  13.506 +	if (!nofork) {
  13.507 +		childpid = fork();
  13.508 +		if(childpid < 0)
  13.509 +			log_error(LOG_ARGS, "fork() failed! Proceeding anyway");
  13.510 +
  13.511 +		if(childpid)
  13.512 +			exit(EXIT_SUCCESS); /* Parent says: "bye bye kids!"*/
  13.513 +
  13.514 +		close(0);
  13.515 +		close(1);
  13.516 +		close(2);
  13.517 +	}
  13.518 +
  13.519 +	execlp(mlmmjprocess, mlmmjprocess,
  13.520 +				"-L", listdir,
  13.521 +				"-m", infilename, NULL);
  13.522 +	log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjprocess);
  13.523 +
  13.524 +	exit(EXIT_FAILURE);
  13.525 +}
  13.526 +
    14.1 --- a/contrib/recievestrip/Makefile.am	Mon Sep 27 10:59:35 2010 +1000
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,14 +0,0 @@
    14.4 -#
    14.5 -
    14.6 -AUTOMAKE_OPTIONS = foreign
    14.7 -
    14.8 -AM_CFLAGS = -g -Wall -pedantic -Wsign-compare -DDEFAULTTEXTDIR='"@textlibdir@"'
    14.9 -INCLUDES = -I$(srcdir)/../../include
   14.10 -
   14.11 -if WANT_RECIEVESTRIP
   14.12 -  bin_PROGRAMS = mlmmj-recieve-strip
   14.13 -endif
   14.14 -
   14.15 -mlmmj_recieve_strip_SOURCES = mlmmj-recieve-strip.c ../../src/mygetline.c ../../src/memory.c ../../src/readn.c  \
   14.16 -				../../src/strgen.c ../../src/random-int.c  ../../src/log_error.c ../../src/print-version.c \
   14.17 -				../../src/writen.c ../../src/dumpfd2fd.c ../../src/ctrlvalues.c ../../src/chomp.c
    15.1 --- a/contrib/recievestrip/README	Mon Sep 27 10:59:35 2010 +1000
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,37 +0,0 @@
    15.4 -mlmmj-recieve-strip is a replacement for mlmmj-recieve
    15.5 -
    15.6 -It opens the files control/mimedeny and control/mimestrip to get a list of mimetypes
    15.7 -for parts of multipart/mime messages that should be denied or stripped
    15.8 -
    15.9 -The parts then get stripped directly when the mail is recieved.
   15.10 -
   15.11 -mlmmj-recieve-strip also appends an extra header
   15.12 -
   15.13 -X-ThisMailContainsUnwantedMimeParts: Y when the mail contains unwanted mime parts
   15.14 -
   15.15 -
   15.16 -Usage:
   15.17 -Compile the program in this directory with make and use "make install" to install it.
   15.18 -Afterwards replace mlmmj-receive with mlmmj-receive-strip in /etc/aliases for the mailinglist
   15.19 -you want to enable stripping and run newaliases
   15.20 -
   15.21 -
   15.22 -Then create the files mimedeny mimestrip in the control directory of your mailinglist.
   15.23 -
   15.24 -If control/mimestrip for example contains:
   15.25 -
   15.26 -text/html
   15.27 -application/octet-stream
   15.28 -
   15.29 -html texts and binarys will be stripped from the mail.
   15.30 -
   15.31 -When you also want to deny mails with certain mimeparts add the mimetypes to the mimedeny file
   15.32 -and add the following lines to the control/access file:
   15.33 -
   15.34 -deny ^X-ThisMailContainsUnwantedMimeParts: Y
   15.35 -allow
   15.36 -
   15.37 -You will most likely want to remove the X-ThisMailContainsUnwantedMimeParts
   15.38 -header by adding the following line to the control/delheaders file:
   15.39 -
   15.40 -X-ThisMailContainsUnwantedMimeParts:
    16.1 --- a/contrib/recievestrip/mlmmj-recieve-strip.c	Mon Sep 27 10:59:35 2010 +1000
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,523 +0,0 @@
    16.4 -/* Copyright (C) 2007 Sascha Sommer <ssommer at suse.de>
    16.5 - *
    16.6 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    16.7 - * of this software and associated documentation files (the "Software"), to
    16.8 - * deal in the Software without restriction, including without limitation the
    16.9 - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   16.10 - * sell copies of the Software, and to permit persons to whom the Software is
   16.11 - * furnished to do so, subject to the following conditions:
   16.12 - *
   16.13 - * The above copyright notice and this permission notice shall be included in
   16.14 - * all copies or substantial portions of the Software.
   16.15 - *
   16.16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16.17 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   16.18 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   16.19 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   16.20 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   16.21 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   16.22 - * IN THE SOFTWARE.
   16.23 - */
   16.24 -
   16.25 -/* a version of mlmmj-recieve that parses the mail on the fly and strips unwanted
   16.26 -   mime parts
   16.27 -   opens the files control/mimedeny and control/mimestrip for a list of mime
   16.28 -   types for body parts that should be denied or stripped.
   16.29 -   It adds an extra header X-ThisMailContainsUnwantedMimeParts: Y for mails that
   16.30 -   contain disallowed mimeparts and X-ThisMailContainsUnwantedMimeParts: N otherwise
   16.31 -*/
   16.32 -
   16.33 -#include <stdlib.h>
   16.34 -#include <string.h>
   16.35 -#include <unistd.h>
   16.36 -#include <sys/stat.h>
   16.37 -#include <fcntl.h>
   16.38 -#include <stdio.h>
   16.39 -#include <errno.h>
   16.40 -#include <string.h>
   16.41 -#include <sys/types.h>
   16.42 -
   16.43 -
   16.44 -
   16.45 -#include "mlmmj.h"
   16.46 -#include "mygetline.h"
   16.47 -#include "gethdrline.h"
   16.48 -#include "strgen.h"
   16.49 -#include "chomp.h"
   16.50 -#include "ctrlvalue.h"
   16.51 -#include "ctrlvalues.h"
   16.52 -
   16.53 -#include "log_error.h"
   16.54 -#include "wrappers.h"
   16.55 -#include "memory.h"
   16.56 -
   16.57 -#define UNWANTED_MIME_HDR "X-ThisMailContainsUnwantedMimeParts: N\n"
   16.58 -
   16.59 -/* append a copy of a string to a string list */
   16.60 -static void append_strtolist(struct strlist *list, char* str) {
   16.61 -	list->count++;
   16.62 -	list->strs = myrealloc(list->strs,
   16.63 -                         sizeof(char *) * (list->count + 1));
   16.64 -	list->strs[list->count-1] = mystrdup(str);
   16.65 -	list->strs[list->count] = NULL;
   16.66 -}
   16.67 -
   16.68 -/* free all strings in a strlist */
   16.69 -static void free_strlist(struct strlist *list) {
   16.70 -	if(!list)
   16.71 -		return;
   16.72 -	if(list->strs) {
   16.73 -		int i;
   16.74 -		for(i=0;i < list->count;i++)
   16.75 -			myfree(list->strs[i]);
   16.76 -		myfree(list->strs);
   16.77 -	}
   16.78 -	list->strs = NULL;
   16.79 -	list->count = 0;
   16.80 -}
   16.81 -
   16.82 -static int findit(char *line, char **headers)
   16.83 -{
   16.84 -        int i = 0;
   16.85 -        size_t len;
   16.86 -
   16.87 -	if (!headers)
   16.88 -		return 0;
   16.89 -
   16.90 -        while(headers[i]) {
   16.91 -                len = strlen(headers[i]);
   16.92 -                if(strncasecmp(line, headers[i], len) == 0)
   16.93 -                        return 1;
   16.94 -                i++;
   16.95 -        }
   16.96 -
   16.97 -        return 0;
   16.98 -}
   16.99 -
  16.100 -/* extract mime_type and boundary from the Content-Type header
  16.101 - * allocates a string for the mime_type if one is found
  16.102 - * always allocates a boundarie (using "--" when none is found)
  16.103 - * the caller needs to free the allocated strings
  16.104 -*/
  16.105 -static void extract_boundary(struct strlist *allhdrs, char** mime_type, char** boundary)
  16.106 -{
  16.107 -	int x;
  16.108 -	*boundary = NULL;
  16.109 -	*mime_type = NULL;
  16.110 -	for( x = 0 ; x < allhdrs->count ; x++ ){
  16.111 -		char* hdr = allhdrs->strs[x];
  16.112 -		if(hdr && !strncasecmp(hdr,"Content-Type:",13)){
  16.113 -			char* pos = hdr + 13;
  16.114 -			size_t len = 0;
  16.115 -
  16.116 -			/* find the start of the mimetype */
  16.117 -			while(*pos && (*pos == ' ' || *pos == '\t'))
  16.118 -				++pos;
  16.119 -
  16.120 -			if(*pos == '"'){                   /* handle quoted mime types */
  16.121 -				++pos;
  16.122 -				while(pos[len] && pos[len] != '"')
  16.123 -					++len;
  16.124 -			}else{
  16.125 -				while(pos[len] && pos[len] != ' ' && pos[len] != '\t' && pos[len] != ';')
  16.126 -					++len;
  16.127 -			}
  16.128 -
  16.129 -			/* extract mime type if any */
  16.130 -			if(len){
  16.131 -				*mime_type = mymalloc(len+1);
  16.132 -				strncpy(*mime_type,pos,len);
  16.133 -				(*mime_type)[len] = '\0';
  16.134 -			}
  16.135 -
  16.136 -			pos += len;
  16.137 -			len = 0;
  16.138 -			/* find start of the boundary info */
  16.139 -			while(*pos && strncasecmp(pos,"boundary=",9))
  16.140 -				++pos;
  16.141 -			if(*pos == '\0')         /* no boundary */
  16.142 -				break;
  16.143 -
  16.144 -			pos += 9;
  16.145 -			if(*pos == '"'){         /* quoted boundary */
  16.146 -				++pos;
  16.147 -				while(pos[len] && pos[len] != '"')
  16.148 -					++len;
  16.149 -			}else{                  /* unquoted boundary */
  16.150 -				while(pos[len] && pos[len] != ' ' && pos[len] != '\t' && pos[len] != ';')
  16.151 -					++len;
  16.152 -			}
  16.153 -
  16.154 -			/* extract boundary */
  16.155 -			*boundary = mymalloc(len + 3);
  16.156 -			strcpy(*boundary,"--");
  16.157 -			strncat(*boundary,pos,len);
  16.158 -			break;
  16.159 -		}
  16.160 -	}
  16.161 -}
  16.162 -
  16.163 -/* read all mail headers and save them in a strlist
  16.164 - * check what to do with parts that contain the given mime_type
  16.165 - *return values
  16.166 - * 0: ok
  16.167 - * 1: strip
  16.168 - * sets deny to 1 if the entire mail should be denied
  16.169 - */
  16.170 -#define MIME_OK 0
  16.171 -#define MIME_STRIP 1
  16.172 -static int read_hdrs(int fd, struct strlist *allhdrs,struct strlist* delmime,struct strlist* denymime,int* deny,char** boundary) {
  16.173 -	int result = MIME_OK;
  16.174 -	char* mime_type = NULL;
  16.175 -	allhdrs->strs = NULL;
  16.176 -	allhdrs->count = 0;
  16.177 -	/* read headers */
  16.178 -	while(1) {
  16.179 -		char* line = mygetline(fd);
  16.180 -		if(!line)        /* end of file and also end of headers */
  16.181 -			break;
  16.182 -
  16.183 -		/* end of headers */
  16.184 -		if(line[0] == '\n'){
  16.185 -			myfree(line);
  16.186 -			break;
  16.187 -		}
  16.188 -		if(!allhdrs->count || ((line[0] != '\t') && (line[0] != ' '))) /* first header line or no more unfolding */
  16.189 -			append_strtolist(allhdrs,line);
  16.190 -		else{
  16.191 -			char* tmp = concatstr(2, allhdrs->strs[allhdrs->count-1], line);
  16.192 -			myfree(allhdrs->strs[allhdrs->count-1]);
  16.193 -		 	allhdrs->strs[allhdrs->count-1] = tmp;
  16.194 -		}
  16.195 -		myfree(line);
  16.196 -	}
  16.197 -	extract_boundary(allhdrs,&mime_type,boundary);
  16.198 -	if(mime_type) {
  16.199 -		/* check if this part should be stripped */
  16.200 -		if(delmime && findit(mime_type, delmime->strs))
  16.201 -			result = MIME_STRIP;
  16.202 -		/* check if the mail should be denied */
  16.203 -		if(denymime && findit(mime_type, denymime->strs))
  16.204 -			*deny = 1;
  16.205 -		myfree(mime_type);
  16.206 -	}
  16.207 -	return result;
  16.208 -}
  16.209 -
  16.210 -/* writes the mail headers if unwantedmime_hdrpos is not NULL an UNWANTED_MIME_HDR
  16.211 - * is inserted and its position saved in unwantedmime_hdrpos
  16.212 - * returns 0 on success
  16.213 - */
  16.214 -static int write_hdrs(int outfd,struct strlist* hdrs,off_t* unwantedmime_hdrpos) {
  16.215 -	int i;
  16.216 -	for(i = 0; i < hdrs->count ; i++) {
  16.217 -		if(writen(outfd, hdrs->strs[i], strlen(hdrs->strs[i])) < 0){
  16.218 -			log_error(LOG_ARGS, "Error when dumping headers");
  16.219 -			return -1;
  16.220 -		}
  16.221 -	}
  16.222 -
  16.223 -	/* if this is not the header of an embedded part add the header that will
  16.224 -	   indicate if the mail contains unwanted mime parts */
  16.225 -	if(unwantedmime_hdrpos) {
  16.226 -		if(writen(outfd, UNWANTED_MIME_HDR,strlen(UNWANTED_MIME_HDR)) < 0){
  16.227 -			log_error(LOG_ARGS, "Error writting unwanted mime header");
  16.228 -			return -1;
  16.229 -		}
  16.230 -		/* get the current position so that we can update the header later */
  16.231 -		*unwantedmime_hdrpos = lseek(outfd,0,SEEK_CUR);
  16.232 -		if(*unwantedmime_hdrpos < 2){
  16.233 -			log_error(LOG_ARGS, "Error getting file position");
  16.234 -			return -1;
  16.235 -		}
  16.236 -		*unwantedmime_hdrpos -= 2;
  16.237 -	}
  16.238 -
  16.239 -	/* write a single line feed to terminate the header part */
  16.240 -	if(writen(outfd, "\n", 1) < 0) {
  16.241 -		log_error(LOG_ARGS,"Error writting end of hdrs.");
  16.242 -		return -1;
  16.243 -	}
  16.244 -	return 0;
  16.245 -}
  16.246 -
  16.247 -/* set the unwanted mime_hdr to Y */
  16.248 -static int update_unwantedmime_hdr(int outfd,off_t unwantedmime_hdrpos) {
  16.249 -	/* seek to the header position */
  16.250 -	if(lseek(outfd,unwantedmime_hdrpos,SEEK_SET) < 0) {
  16.251 -		log_error(LOG_ARGS,"Error seeking to the unwantedmime_hdr");
  16.252 -		return -1;
  16.253 -	}
  16.254 -
  16.255 -	/* update the header */
  16.256 -	if(writen(outfd, "Y\n",2) < 0){
  16.257 -		log_error(LOG_ARGS, "Error writting extra header");
  16.258 -		return -1;
  16.259 -	}
  16.260 -
  16.261 -	/* seek back to the end of the mail */
  16.262 -	if(lseek(outfd,0,SEEK_END) < 0) {
  16.263 -		log_error(LOG_ARGS,"Error seeking to the mail end");
  16.264 -		return -1;
  16.265 -	}
  16.266 -	return 0;
  16.267 -}
  16.268 -
  16.269 -static int parse_body(int infd,int outfd, struct strlist* delmime, struct strlist* denymime,
  16.270 -			int* deny,char* boundary){
  16.271 -	int strip = 0;
  16.272 -	char* line;
  16.273 -	while((line = mygetline(infd))) {
  16.274 -		if(boundary && !strncmp(line,boundary,strlen(boundary))){
  16.275 -			strip = 0;
  16.276 -			/* check if the boundary is the beginning of a new part */
  16.277 -			if(strncmp(line + strlen(boundary),"--",2)){
  16.278 -				struct strlist hdrs;
  16.279 -				char* new_boundary = NULL;
  16.280 -				/* check if this part should be stripped */
  16.281 -				if(read_hdrs(infd, &hdrs,delmime,denymime,deny,&new_boundary) == MIME_STRIP)
  16.282 -					strip = 1;
  16.283 -				else {
  16.284 -					/* write boundary */
  16.285 -					if(writen(outfd, line, strlen(line)) < 0){
  16.286 -						log_error(LOG_ARGS, "Error writting boundary");
  16.287 -						return -1;
  16.288 -					}
  16.289 -					/* write hdr */
  16.290 -					if(write_hdrs(outfd, &hdrs, NULL) < 0){
  16.291 -						log_error(LOG_ARGS, "Error writting hdrs");
  16.292 -						return -1;
  16.293 -					}
  16.294 -					/* parse embedded part if a new boundary was found */
  16.295 -					if(new_boundary && parse_body(infd,outfd,delmime,denymime,deny,new_boundary) != 0) {
  16.296 -						log_error(LOG_ARGS, "Could not parse embedded part");
  16.297 -						return -1;
  16.298 -					}
  16.299 -				}
  16.300 -				free_strlist(&hdrs);
  16.301 -				if(new_boundary)
  16.302 -					myfree(new_boundary);
  16.303 -			}else{
  16.304 -				/* write end of part */
  16.305 -				if(writen(outfd, line, strlen(line)) < 0){
  16.306 -					log_error(LOG_ARGS, "Error writting hdrs");
  16.307 -					return -1;
  16.308 -				}
  16.309 -				/* and leave */
  16.310 -				myfree(line);
  16.311 -				break;
  16.312 -			}
  16.313 -		}else {
  16.314 -			if(!strip) { /* write the current line */
  16.315 -				if(writen(outfd, line, strlen(line)) < 0){
  16.316 -					log_error(LOG_ARGS, "Error when dumping line");
  16.317 -					return -1;
  16.318 -				}
  16.319 -			}
  16.320 -		}
  16.321 -		myfree(line);
  16.322 -	}
  16.323 -	return 0;
  16.324 -}
  16.325 -
  16.326 -
  16.327 -
  16.328 -
  16.329 -
  16.330 -/* read a mail stripping unwanted parts */
  16.331 -static int dump_mail(int infd, int outfd,char* listdir) {
  16.332 -	struct strlist hdrs;
  16.333 -	struct strlist* delmime;
  16.334 -	struct strlist* denymime;
  16.335 -	char* boundary=NULL;
  16.336 -	int deny = 0;
  16.337 -	int result;
  16.338 -	off_t unwantedmime_hdr_pos = 0;
  16.339 -
  16.340 -	/* get list control values */
  16.341 -	delmime = ctrlvalues(listdir, "mimestrip");
  16.342 -	denymime = ctrlvalues(listdir, "mimedeny");
  16.343 -
  16.344 -	/* read mail header */
  16.345 -	result = read_hdrs(infd, &hdrs,delmime,denymime,&deny,&boundary);
  16.346 -	/* write mail header */
  16.347 -	if(write_hdrs(outfd,&hdrs,&unwantedmime_hdr_pos) < 0) {
  16.348 -		log_error(LOG_ARGS, "Could not write mail headers");
  16.349 -		return -1;
  16.350 -	}
  16.351 -
  16.352 -	/* free mail header */
  16.353 -	free_strlist(&hdrs);
  16.354 -
  16.355 -	if(result == MIME_OK && !deny) {
  16.356 -		/* try to parse the mail */
  16.357 -		if(parse_body(infd,outfd,delmime,denymime,&deny,boundary) != 0) {
  16.358 -			log_error(LOG_ARGS, "Could not parse mail");
  16.359 -			return -1;
  16.360 -		}
  16.361 -		myfree(boundary);
  16.362 -	}else
  16.363 -		deny = 1;
  16.364 -
  16.365 -	/* dump rest of mail */
  16.366 -        if(dumpfd2fd(infd, outfd) != 0) {
  16.367 -		log_error(LOG_ARGS, "Could not recieve mail");
  16.368 -		return -1;
  16.369 -        }
  16.370 -
  16.371 -	/* update header */
  16.372 -	if(deny) {
  16.373 -		if(update_unwantedmime_hdr(outfd,unwantedmime_hdr_pos) != 0) {
  16.374 -			log_error(LOG_ARGS, "Could not update header");
  16.375 -			return -1;
  16.376 -		}
  16.377 -	}
  16.378 -
  16.379 -	/* free mime types */
  16.380 -	if(delmime) {
  16.381 -		free_strlist(delmime);
  16.382 -		myfree(delmime);
  16.383 -	}
  16.384 -	if(denymime) {
  16.385 -		free_strlist(denymime);
  16.386 -		myfree(denymime);
  16.387 -	}
  16.388 -	return 0;
  16.389 -}
  16.390 -
  16.391 -static void print_help(const char *prg)
  16.392 -{
  16.393 -        printf("Usage: %s -L /path/to/listdir [-h] [-V] [-P] [-F]\n"
  16.394 -	       " -h: This help\n"
  16.395 -	       " -F: Don't fork in the background\n"
  16.396 -	       " -L: Full path to list directory\n"
  16.397 -	       " -P: Don't execute mlmmj-process\n"
  16.398 -	       " -V: Print version\n", prg);
  16.399 -	exit(EXIT_SUCCESS);
  16.400 -}
  16.401 -
  16.402 -int main(int argc, char **argv)
  16.403 -{
  16.404 -	char *infilename = NULL, *listdir = NULL;
  16.405 -	char *randomstr = random_str();
  16.406 -	char *mlmmjprocess, *bindir;
  16.407 -	int fd, opt, noprocess = 0, nofork = 0;
  16.408 -	struct stat st;
  16.409 -	uid_t uid;
  16.410 -	pid_t childpid;
  16.411 -
  16.412 -	CHECKFULLPATH(argv[0]);
  16.413 -
  16.414 -	log_set_name(argv[0]);
  16.415 -
  16.416 -	bindir = mydirname(argv[0]);
  16.417 -	mlmmjprocess = concatstr(2, bindir, "/mlmmj-process");
  16.418 -	myfree(bindir);
  16.419 -
  16.420 -	while ((opt = getopt(argc, argv, "hPVL:F")) != -1) {
  16.421 -		switch(opt) {
  16.422 -		case 'h':
  16.423 -			print_help(argv[0]);
  16.424 -			break;
  16.425 -		case 'L':
  16.426 -			listdir = optarg;
  16.427 -			break;
  16.428 -		case 'P':
  16.429 -			noprocess = 1;
  16.430 -			break;
  16.431 -		case 'F':
  16.432 -			nofork = 1;
  16.433 -			break;
  16.434 -		case 'V':
  16.435 -			print_version(argv[0]);
  16.436 -			exit(0);
  16.437 -		}
  16.438 -	}
  16.439 -
  16.440 -	if(listdir == NULL) {
  16.441 -		fprintf(stderr, "You have to specify -L\n");
  16.442 -		fprintf(stderr, "%s -h for help\n", argv[0]);
  16.443 -		exit(EXIT_FAILURE);
  16.444 -	}
  16.445 -
  16.446 -	/* Lets make sure no random user tries to send mail to the list */
  16.447 -	if(listdir) {
  16.448 -		if(stat(listdir, &st) == 0) {
  16.449 -			uid = getuid();
  16.450 -			if(uid && uid != st.st_uid) {
  16.451 -				log_error(LOG_ARGS,
  16.452 -					"Have to invoke either as root "
  16.453 -					"or as the user owning listdir "
  16.454 -					"Invoked with uid = [%d]", (int)uid);
  16.455 -				writen(STDERR_FILENO,
  16.456 -					"Have to invoke either as root "
  16.457 -					"or as the user owning listdir\n", 60);
  16.458 -				exit(EXIT_FAILURE);
  16.459 -			}
  16.460 -		} else {
  16.461 -			log_error(LOG_ARGS, "Could not stat %s", listdir);
  16.462 -			exit(EXIT_FAILURE);
  16.463 -		}
  16.464 -	}
  16.465 -
  16.466 -	infilename = concatstr(3, listdir, "/incoming/", randomstr);
  16.467 -	myfree(randomstr);
  16.468 -	fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  16.469 -	while(fd < 0 && errno == EEXIST) {
  16.470 -		myfree(infilename);
  16.471 -		randomstr = random_str();
  16.472 -		infilename = concatstr(3, listdir, "/incoming/", randomstr);
  16.473 -		myfree(randomstr);
  16.474 -		fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  16.475 -	}
  16.476 -
  16.477 -	if(fd < 0) {
  16.478 -		log_error(LOG_ARGS, "could not create mail file in "
  16.479 -				    "%s/incoming directory", listdir);
  16.480 -		myfree(infilename);
  16.481 -		exit(EXIT_FAILURE);
  16.482 -	}
  16.483 -
  16.484 -	if(dump_mail(fileno(stdin), fd, listdir) != 0) {
  16.485 -		log_error(LOG_ARGS, "Could not recieve mail");
  16.486 -		exit(EXIT_FAILURE);
  16.487 -	}
  16.488 -
  16.489 -#if 0
  16.490 -	log_oper(listdir, OPLOGFNAME, "mlmmj-recieve got %s", infilename);
  16.491 -#endif
  16.492 -	fsync(fd);
  16.493 -	close(fd);
  16.494 -
  16.495 -	if(noprocess) {
  16.496 -		myfree(infilename);
  16.497 -		exit(EXIT_SUCCESS);
  16.498 -	}
  16.499 -
  16.500 -	/*
  16.501 -	 * Now we fork so we can exit with success since it could potentially
  16.502 -	 * take a long time for mlmmj-send to finish delivering the mails and
  16.503 -	 * returning, making it susceptible to getting a SIGKILL from the
  16.504 -	 * mailserver invoking mlmmj-recieve.
  16.505 -	 */
  16.506 -	if (!nofork) {
  16.507 -		childpid = fork();
  16.508 -		if(childpid < 0)
  16.509 -			log_error(LOG_ARGS, "fork() failed! Proceeding anyway");
  16.510 -
  16.511 -		if(childpid)
  16.512 -			exit(EXIT_SUCCESS); /* Parent says: "bye bye kids!"*/
  16.513 -
  16.514 -		close(0);
  16.515 -		close(1);
  16.516 -		close(2);
  16.517 -	}
  16.518 -
  16.519 -	execlp(mlmmjprocess, mlmmjprocess,
  16.520 -				"-L", listdir,
  16.521 -				"-m", infilename, NULL);
  16.522 -	log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjprocess);
  16.523 -
  16.524 -	exit(EXIT_FAILURE);
  16.525 -}
  16.526 -
    17.1 --- a/include/do_all_the_voodo_here.h	Mon Sep 27 10:59:35 2010 +1000
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,35 +0,0 @@
    17.4 -/* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
    17.5 - *
    17.6 - * $Id$
    17.7 - *
    17.8 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    17.9 - * of this software and associated documentation files (the "Software"), to
   17.10 - * deal in the Software without restriction, including without limitation the
   17.11 - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   17.12 - * sell copies of the Software, and to permit persons to whom the Software is
   17.13 - * furnished to do so, subject to the following conditions:
   17.14 - *
   17.15 - * The above copyright notice and this permission notice shall be included in
   17.16 - * all copies or substantial portions of the Software.
   17.17 - *
   17.18 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17.19 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17.20 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   17.21 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   17.22 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   17.23 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   17.24 - * IN THE SOFTWARE.
   17.25 - */
   17.26 -
   17.27 -#ifndef DO_ALL_THE_VOODO_HERE_H
   17.28 -#define DO_ALL_THE_VOODO_HERE_H
   17.29 -
   17.30 -#include "mlmmj.h" /* For struct mailhdr and struct strlist */
   17.31 -
   17.32 -int findit(const char *line, const char **headers);
   17.33 -void getinfo(const char *line, struct mailhdr *readhdrs);
   17.34 -int do_all_the_voodo_here(int infd, int outfd, int hdrfd, int footfd,
   17.35 -	      const char **delhdrs, struct mailhdr *readhdrs,
   17.36 -	      struct strlist *allhdrs, const char *subjectprefix);
   17.37 -
   17.38 -#endif /* DO_ALL_THE_VOODO_HERE_H */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/include/do_all_the_voodoo_here.h	Sun Oct 03 21:40:42 2010 +1100
    18.3 @@ -0,0 +1,35 @@
    18.4 +/* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
    18.5 + *
    18.6 + * $Id$
    18.7 + *
    18.8 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    18.9 + * of this software and associated documentation files (the "Software"), to
   18.10 + * deal in the Software without restriction, including without limitation the
   18.11 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   18.12 + * sell copies of the Software, and to permit persons to whom the Software is
   18.13 + * furnished to do so, subject to the following conditions:
   18.14 + *
   18.15 + * The above copyright notice and this permission notice shall be included in
   18.16 + * all copies or substantial portions of the Software.
   18.17 + *
   18.18 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   18.19 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18.20 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   18.21 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   18.22 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   18.23 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   18.24 + * IN THE SOFTWARE.
   18.25 + */
   18.26 +
   18.27 +#ifndef DO_ALL_THE_VOODOO_HERE_H
   18.28 +#define DO_ALL_THE_VOODOO_HERE_H
   18.29 +
   18.30 +#include "mlmmj.h" /* For struct mailhdr and struct strlist */
   18.31 +
   18.32 +int findit(const char *line, const char **headers);
   18.33 +void getinfo(const char *line, struct mailhdr *readhdrs);
   18.34 +int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
   18.35 +	      const char **delhdrs, struct mailhdr *readhdrs,
   18.36 +	      struct strlist *allhdrs, const char *subjectprefix);
   18.37 +
   18.38 +#endif /* DO_ALL_THE_VOODOO_HERE_H */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/include/mlmmj-receive.h	Sun Oct 03 21:40:42 2010 +1100
    19.3 @@ -0,0 +1,30 @@
    19.4 +/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
    19.5 + *
    19.6 + * $Id$
    19.7 + *
    19.8 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    19.9 + * of this software and associated documentation files (the "Software"), to
   19.10 + * deal in the Software without restriction, including without limitation the
   19.11 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   19.12 + * sell copies of the Software, and to permit persons to whom the Software is
   19.13 + * furnished to do so, subject to the following conditions:
   19.14 + *
   19.15 + * The above copyright notice and this permission notice shall be included in
   19.16 + * all copies or substantial portions of the Software.
   19.17 + *
   19.18 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19.19 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19.20 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   19.21 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19.22 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   19.23 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   19.24 + * IN THE SOFTWARE.
   19.25 + */
   19.26 +
   19.27 +#ifndef MMJML_RECEIVE_H
   19.28 +#define MMJML_RECEIVE_H
   19.29 +
   19.30 +void free_str_array(char **to_free);
   19.31 +
   19.32 +
   19.33 +#endif /* MMJML_RECEIVE_H */
    20.1 --- a/include/mlmmj-recieve.h	Mon Sep 27 10:59:35 2010 +1000
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,30 +0,0 @@
    20.4 -/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
    20.5 - *
    20.6 - * $Id$
    20.7 - *
    20.8 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    20.9 - * of this software and associated documentation files (the "Software"), to
   20.10 - * deal in the Software without restriction, including without limitation the
   20.11 - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   20.12 - * sell copies of the Software, and to permit persons to whom the Software is
   20.13 - * furnished to do so, subject to the following conditions:
   20.14 - *
   20.15 - * The above copyright notice and this permission notice shall be included in
   20.16 - * all copies or substantial portions of the Software.
   20.17 - *
   20.18 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   20.19 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   20.20 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   20.21 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20.22 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20.23 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   20.24 - * IN THE SOFTWARE.
   20.25 - */
   20.26 -
   20.27 -#ifndef MMJML_RECIEVE_H
   20.28 -#define MMJML_RECIEVE_H
   20.29 -
   20.30 -void free_str_array(char **to_free);
   20.31 -
   20.32 -
   20.33 -#endif /* MMJML_RECIEVE_H */
    21.1 --- a/man/mlmmj-bounce.1	Mon Sep 27 10:59:35 2010 +1000
    21.2 +++ b/man/mlmmj-bounce.1	Sun Oct 03 21:40:42 2010 +1100
    21.3 @@ -29,7 +29,7 @@
    21.4  The above shows that message number 109 bounced 1094409801 seconds after epoch
    21.5  which is in human date stamps is Sunday September 5th 20:43:21 2004.
    21.6  
    21.7 -The last bounce mail recieved to the address is saved in <listdir>/bounce/<addrstring>.lastmsg.
    21.8 +The last bounce mail received to the address is saved in <listdir>/bounce/<addrstring>.lastmsg.
    21.9  
   21.10  When the \fB\-p\fR option is used it sends out a probe email including info
   21.11  that it's a bounce probe and a list of the bounced message numbers. The
    22.1 --- a/man/mlmmj-list.1	Mon Sep 27 10:59:35 2010 +1000
    22.2 +++ b/man/mlmmj-list.1	Sun Oct 03 21:40:42 2010 +1100
    22.3 @@ -1,4 +1,4 @@
    22.4 -.TH mlmmj-list "1" "November 2004" mlmmj-recieve
    22.5 +.TH mlmmj-list "1" "November 2004" mlmmj-receive
    22.6  .SH NAME
    22.7  mlmmj-list \- list people / subscribers associated with a list
    22.8  .SH SYNOPSIS
    23.1 --- a/man/mlmmj-process.1	Mon Sep 27 10:59:35 2010 +1000
    23.2 +++ b/man/mlmmj-process.1	Sun Oct 03 21:40:42 2010 +1100
    23.3 @@ -41,7 +41,7 @@
    23.4  List control
    23.5  
    23.6  In case there's a mail with a recipient delimiter it's not a regular list mail.
    23.7 -Processing of these happens in mlmmj-recieve as well. Examples of such are
    23.8 +Processing of these happens in mlmmj-receive as well. Examples of such are
    23.9  subscription requests, mails to owner etc.
   23.10  It will base it's recipient delimiter detection on the Delivered-To: header if
   23.11  present. If not, the To: header is used.
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/man/mlmmj-receive.1	Sun Oct 03 21:40:42 2010 +1100
    24.3 @@ -0,0 +1,41 @@
    24.4 +.TH mlmmj-receive "1" "September 2004" mlmmj-receive
    24.5 +.SH NAME
    24.6 +mlmmj-receive \- receive mails for an mlmmj managed mailinglist
    24.7 +.SH SYNOPSIS
    24.8 +.B mlmmj-receive
    24.9 +\fI-L /path/to/listdir \fR[\fI-h\fR] [\fI-V\fR] [\fI-P\fR] [\fI-F\fR]
   24.10 +.HP
   24.11 +\fB\-h\fR: This help
   24.12 +.HP
   24.13 +\fB\-F\fR: Don't fork in the background (debugging only)
   24.14 +.HP
   24.15 +\fB\-L\fR: Full path to list directory
   24.16 +.HP
   24.17 +\fB\-P\fR: Don't execute mlmmj-process (debugging only)
   24.18 +.HP
   24.19 +\fB\-V\fR: Print version
   24.20 +.SH DESCRIPTION
   24.21 +The mlmmj-receive binary is the one specified in the mailserver configuration
   24.22 +file (aliases file), which writes the mail to the <listdir>/incoming directory
   24.23 +and invokes mlmmj-process unless the \fB\-P\fR option is specified. On systems
   24.24 +using mailservers supporting the \fB/etc/aliases\fR file, a line to activate
   24.25 +an mlmmj managed mailinglist would look like this:
   24.26 +.LP
   24.27 +list: "|/usr/bin/mlmmj-receive -L /var/spool/mlmmj/list/"
   24.28 +
   24.29 +It's very important to specify the full path to the binary, or the mailinglist
   24.30 +will not function.
   24.31 +
   24.32 +When the \fB\-F\fR option is used, it will not fork in the background. The
   24.33 +reason it forks is that if delivery of a mail takes longer time than the mail
   24.34 +server will allow a command to be idle before presumed dead, the mail server
   24.35 +would kill it.
   24.36 +
   24.37 +.SH "SEE ALSO"
   24.38 +mlmmj-process(1)
   24.39 +.SH AUTHORS
   24.40 +This manual page was written by the following persons:
   24.41 +.HP
   24.42 +Søren Boll Overgaard <boll@debian.org> (based on html2man output)
   24.43 +.HP
   24.44 +Mads Martin Jørgensen <mmj@mmj.dk>
    25.1 --- a/man/mlmmj-recieve.1	Mon Sep 27 10:59:35 2010 +1000
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,41 +0,0 @@
    25.4 -.TH mlmmj-recieve "1" "September 2004" mlmmj-recieve
    25.5 -.SH NAME
    25.6 -mlmmj-recieve \- recieve mails for an mlmmj managed mailinglist
    25.7 -.SH SYNOPSIS
    25.8 -.B mlmmj-recieve
    25.9 -\fI-L /path/to/listdir \fR[\fI-h\fR] [\fI-V\fR] [\fI-P\fR] [\fI-F\fR]
   25.10 -.HP
   25.11 -\fB\-h\fR: This help
   25.12 -.HP
   25.13 -\fB\-F\fR: Don't fork in the background (debugging only)
   25.14 -.HP
   25.15 -\fB\-L\fR: Full path to list directory
   25.16 -.HP
   25.17 -\fB\-P\fR: Don't execute mlmmj-process (debugging only)
   25.18 -.HP
   25.19 -\fB\-V\fR: Print version
   25.20 -.SH DESCRIPTION
   25.21 -The mlmmj-recieve binary is the one specified in the mailserver configuration
   25.22 -file (aliases file), which writes the mail to the <listdir>/incoming directory
   25.23 -and invokes mlmmj-process unless the \fB\-P\fR option is specified. On systems
   25.24 -using mailservers supporting the \fB/etc/aliases\fR file, a line to activate
   25.25 -an mlmmj managed mailinglist would look like this:
   25.26 -.LP
   25.27 -list: "|/usr/bin/mlmmj-recieve -L /var/spool/mlmmj/list/"
   25.28 -
   25.29 -It's very important to specify the full path to the binary, or the mailinglist
   25.30 -will not function.
   25.31 -
   25.32 -When the \fB\-F\fR option is used, it will not fork in the background. The
   25.33 -reason it forks is that if delivery of a mail takes longer time than the mail
   25.34 -server will allow a command to be idle before presumed dead, the mail server
   25.35 -would kill it.
   25.36 -
   25.37 -.SH "SEE ALSO"
   25.38 -mlmmj-process(1)
   25.39 -.SH AUTHORS
   25.40 -This manual page was written by the following persons:
   25.41 -.HP
   25.42 -Søren Boll Overgaard <boll@debian.org> (based on html2man output)
   25.43 -.HP
   25.44 -Mads Martin Jørgensen <mmj@mmj.dk>
    26.1 --- a/man/mlmmj-sub.1	Mon Sep 27 10:59:35 2010 +1000
    26.2 +++ b/man/mlmmj-sub.1	Sun Oct 03 21:40:42 2010 +1100
    26.3 @@ -39,7 +39,7 @@
    26.4  having correct permissions.
    26.5  
    26.6  The nomail version of the list is a list version where people are subscribed
    26.7 -like usual, but they won't recieve any postings to the list. This is useful for
    26.8 +like usual, but they won't receive any postings to the list. This is useful for
    26.9  people who read the mailinglist through a news gateway, but want to be able to
   26.10  post to the list.
   26.11  
    27.1 --- a/src/Makefile.am	Mon Sep 27 10:59:35 2010 +1000
    27.2 +++ b/src/Makefile.am	Sun Oct 03 21:40:42 2010 +1100
    27.3 @@ -5,7 +5,7 @@
    27.4  AM_CFLAGS = -g -Wall -pedantic -Wsign-compare -DDEFAULTTEXTDIR='"@textlibdir@"'
    27.5  INCLUDES = -I$(srcdir)/../include
    27.6  
    27.7 -bin_PROGRAMS = mlmmj-send mlmmj-recieve mlmmj-process mlmmj-sub \
    27.8 +bin_PROGRAMS = mlmmj-send mlmmj-receive mlmmj-process mlmmj-sub \
    27.9                 mlmmj-unsub mlmmj-bounce mlmmj-maintd mlmmj-list
   27.10  
   27.11  bin_SCRIPTS = mlmmj-make-ml.sh
   27.12 @@ -19,7 +19,7 @@
   27.13  		     statctrl.c ctrlvalue.c getaddrsfromfd.c readn.c \
   27.14  		     getlistdelim.c
   27.15  
   27.16 -mlmmj_recieve_SOURCES = mlmmj-recieve.c writen.c random-int.c strgen.c \
   27.17 +mlmmj_receive_SOURCES = mlmmj-receive.c writen.c random-int.c strgen.c \
   27.18  			print-version.c log_error.c dumpfd2fd.c memory.c \
   27.19  			log_oper.c mylocking.c readn.c
   27.20  
   27.21 @@ -27,7 +27,7 @@
   27.22  			incindexfile.c itoa.c getlistaddr.c chomp.c \
   27.23  			mylocking.c listcontrol.c random-int.c strgen.c \
   27.24  			print-version.c send_help.c prepstdreply.c \
   27.25 -			do_all_the_voodo_here.c mygetline.c gethdrline.c \
   27.26 +			do_all_the_voodoo_here.c mygetline.c gethdrline.c \
   27.27  			log_error.c statctrl.c ctrlvalue.c dumpfd2fd.c \
   27.28  			subscriberfuncs.c ctrlvalues.c memory.c log_oper.c \
   27.29  			send_list.c readn.c getlistdelim.c unistr.c
   27.30 @@ -59,3 +59,6 @@
   27.31  
   27.32  mlmmj_list_SOURCES = mlmmj-list.c strgen.c writen.c print-version.c memory.c \
   27.33  		     log_error.c random-int.c readn.c
   27.34 +
   27.35 +install-exec-hook:
   27.36 +	ln -f -s mlmmj-receive $(DESTDIR)$(bindir)/mlmmj-recieve
    28.1 --- a/src/do_all_the_voodo_here.c	Mon Sep 27 10:59:35 2010 +1000
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,190 +0,0 @@
    28.4 -/* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
    28.5 - *
    28.6 - * $Id$
    28.7 - *
    28.8 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    28.9 - * of this software and associated documentation files (the "Software"), to
   28.10 - * deal in the Software without restriction, including without limitation the
   28.11 - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   28.12 - * sell copies of the Software, and to permit persons to whom the Software is
   28.13 - * furnished to do so, subject to the following conditions:
   28.14 - *
   28.15 - * The above copyright notice and this permission notice shall be included in
   28.16 - * all copies or substantial portions of the Software.
   28.17 - *
   28.18 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   28.19 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   28.20 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   28.21 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   28.22 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   28.23 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   28.24 - * IN THE SOFTWARE.
   28.25 - */
   28.26 -
   28.27 -#include <stdlib.h>
   28.28 -#include <string.h>
   28.29 -#include <unistd.h>
   28.30 -
   28.31 -#include "mlmmj.h"
   28.32 -#include "mygetline.h"
   28.33 -#include "gethdrline.h"
   28.34 -#include "strgen.h"
   28.35 -#include "chomp.h"
   28.36 -#include "ctrlvalue.h"
   28.37 -#include "do_all_the_voodo_here.h"
   28.38 -#include "log_error.h"
   28.39 -#include "wrappers.h"
   28.40 -#include "memory.h"
   28.41 -
   28.42 -int findit(const char *line, const char **headers)
   28.43 -{
   28.44 -	int i = 0;
   28.45 -	size_t len;
   28.46 -
   28.47 -	while(headers[i]) {
   28.48 -		len = strlen(headers[i]);
   28.49 -		if(strncasecmp(line, headers[i], len) == 0)
   28.50 -			return 1;
   28.51 -		i++;
   28.52 -	}
   28.53 -
   28.54 -	return 0;
   28.55 -}
   28.56 -
   28.57 -void getinfo(const char *line, struct mailhdr *readhdrs)
   28.58 -{
   28.59 -	int i = 0;
   28.60 -	size_t tokenlen, linelen, valuelen;
   28.61 -
   28.62 -	while(readhdrs[i].token) {
   28.63 -		tokenlen = strlen(readhdrs[i].token);
   28.64 -		linelen = strlen(line);
   28.65 -		if(strncasecmp(line, readhdrs[i].token, tokenlen) == 0) {
   28.66 -			readhdrs[i].valuecount++;
   28.67 -			valuelen = linelen - tokenlen + 1;
   28.68 -			readhdrs[i].values =
   28.69 -				(char **)myrealloc(readhdrs[i].values,
   28.70 -				  readhdrs[i].valuecount * sizeof(char *));
   28.71 -			readhdrs[i].values[readhdrs[i].valuecount - 1] =
   28.72 -					(char *)mymalloc(valuelen + 1);
   28.73 -			strncpy(readhdrs[i].values[readhdrs[i].valuecount - 1],
   28.74 -						line+tokenlen, valuelen);
   28.75 -			chomp(readhdrs[i].values[readhdrs[i].valuecount - 1]);
   28.76 -		}
   28.77 -		i++;
   28.78 -	}
   28.79 -}
   28.80 -
   28.81 -int do_all_the_voodo_here(int infd, int outfd, int hdrfd, int footfd,
   28.82 -		 const char **delhdrs, struct mailhdr *readhdrs,
   28.83 -		 struct strlist *allhdrs, const char *prefix)
   28.84 -{
   28.85 -	char *hdrline, *subject, *unqp;
   28.86 -	int hdrsadded = 0;
   28.87 -	int subject_present = 0;
   28.88 -
   28.89 -	allhdrs->count = 0;
   28.90 -	allhdrs->strs = NULL;
   28.91 -
   28.92 -	while((hdrline = gethdrline(infd))) {
   28.93 -		/* Done with headers? Then add extra if wanted*/
   28.94 -		if((strncasecmp(hdrline, "mime", 4) == 0) ||
   28.95 -			((strlen(hdrline) == 1) && (hdrline[0] == '\n'))){
   28.96 -
   28.97 -			/* add extra headers */
   28.98 -			if(!hdrsadded && hdrfd >= 0) {
   28.99 -				if(dumpfd2fd(hdrfd, outfd) < 0) {
  28.100 -					log_error(LOG_ARGS, "Could not "
  28.101 -						"add extra headers");
  28.102 -					myfree(hdrline);
  28.103 -					return -1;
  28.104 -				} else
  28.105 -					hdrsadded = 1;
  28.106 -			}
  28.107 -			
  28.108 -			fsync(outfd);
  28.109 -
  28.110 -			/* end of headers, write single LF */ 
  28.111 -			if(hdrline[0] == '\n') {
  28.112 -				/* but first add Subject if none is present
  28.113 -				 * and a prefix is defined */
  28.114 -				if (prefix && !subject_present)
  28.115 -				{
  28.116 -					subject = concatstr(3, "Subject: ", 
  28.117 -								prefix, "\n");
  28.118 -					writen(outfd, subject, strlen(subject));
  28.119 -					myfree(subject);
  28.120 -					subject_present = 1;
  28.121 -				}
  28.122 -
  28.123 -				if(writen(outfd, hdrline, strlen(hdrline))
  28.124 -						< 0) {
  28.125 -					myfree(hdrline);
  28.126 -					log_error(LOG_ARGS,
  28.127 -							"Error writing hdrs.");
  28.128 -					return -1;
  28.129 -				}
  28.130 -				myfree(hdrline);
  28.131 -				break;
  28.132 -			}
  28.133 -		}
  28.134 -		/* Do we want info from hdrs? Get it before it's gone */
  28.135 -		if(readhdrs)
  28.136 -			getinfo(hdrline, readhdrs);
  28.137 -
  28.138 -		/* Snatch a copy of the header */
  28.139 -		allhdrs->count++;
  28.140 -		allhdrs->strs = myrealloc(allhdrs->strs,
  28.141 -					sizeof(char *) * (allhdrs->count + 1));
  28.142 -		allhdrs->strs[allhdrs->count-1] = mystrdup(hdrline);
  28.143 -		allhdrs->strs[allhdrs->count] = NULL;  /* XXX why, why, why? */
  28.144 -
  28.145 -		/* Add Subject: prefix if wanted */
  28.146 -		if(prefix) {
  28.147 -			if(strncasecmp(hdrline, "Subject:", 8) == 0) {
  28.148 -				subject_present = 1;
  28.149 -				unqp = cleanquotedp(hdrline + 8);
  28.150 -				if(strstr(hdrline + 8, prefix) == NULL &&
  28.151 -				   strstr(unqp, prefix) == NULL) {
  28.152 -					subject = concatstr(3,
  28.153 -							"Subject: ", prefix,
  28.154 -							hdrline + 8);
  28.155 -					writen(outfd, subject,
  28.156 -							strlen(subject));
  28.157 -					myfree(subject);
  28.158 -					myfree(hdrline);
  28.159 -					myfree(unqp);
  28.160 -					continue;
  28.161 -				}
  28.162 -				myfree(unqp);
  28.163 -			}
  28.164 -		}
  28.165 -		
  28.166 -		/* Should it be stripped? */
  28.167 -		if(delhdrs) {
  28.168 -			if(!findit(hdrline, delhdrs))
  28.169 -				writen(outfd, hdrline, strlen(hdrline));
  28.170 -		} else
  28.171 -			writen(outfd, hdrline, strlen(hdrline));
  28.172 -
  28.173 -
  28.174 -		myfree(hdrline);
  28.175 -	}
  28.176 -
  28.177 -	/* Just print the rest of the mail */
  28.178 -	if(dumpfd2fd(infd, outfd) < 0) {
  28.179 -		log_error(LOG_ARGS, "Error when dumping rest of mail");
  28.180 -		return -1;
  28.181 -	}
  28.182 -
  28.183 -	/* No more, lets add the footer if one */
  28.184 -	if(footfd >= 0)
  28.185 -		if(dumpfd2fd(footfd, outfd) < 0) {
  28.186 -			log_error(LOG_ARGS, "Error when adding footer");
  28.187 -			return -1;
  28.188 -		}
  28.189 -
  28.190 -	fsync(outfd);
  28.191 -
  28.192 -	return 0;
  28.193 -}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/src/do_all_the_voodoo_here.c	Sun Oct 03 21:40:42 2010 +1100
    29.3 @@ -0,0 +1,190 @@
    29.4 +/* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
    29.5 + *
    29.6 + * $Id$
    29.7 + *
    29.8 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    29.9 + * of this software and associated documentation files (the "Software"), to
   29.10 + * deal in the Software without restriction, including without limitation the
   29.11 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   29.12 + * sell copies of the Software, and to permit persons to whom the Software is
   29.13 + * furnished to do so, subject to the following conditions:
   29.14 + *
   29.15 + * The above copyright notice and this permission notice shall be included in
   29.16 + * all copies or substantial portions of the Software.
   29.17 + *
   29.18 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   29.19 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   29.20 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   29.21 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   29.22 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   29.23 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   29.24 + * IN THE SOFTWARE.
   29.25 + */
   29.26 +
   29.27 +#include <stdlib.h>
   29.28 +#include <string.h>
   29.29 +#include <unistd.h>
   29.30 +
   29.31 +#include "mlmmj.h"
   29.32 +#include "mygetline.h"
   29.33 +#include "gethdrline.h"
   29.34 +#include "strgen.h"
   29.35 +#include "chomp.h"
   29.36 +#include "ctrlvalue.h"
   29.37 +#include "do_all_the_voodoo_here.h"
   29.38 +#include "log_error.h"
   29.39 +#include "wrappers.h"
   29.40 +#include "memory.h"
   29.41 +
   29.42 +int findit(const char *line, const char **headers)
   29.43 +{
   29.44 +	int i = 0;
   29.45 +	size_t len;
   29.46 +
   29.47 +	while(headers[i]) {
   29.48 +		len = strlen(headers[i]);
   29.49 +		if(strncasecmp(line, headers[i], len) == 0)
   29.50 +			return 1;
   29.51 +		i++;
   29.52 +	}
   29.53 +
   29.54 +	return 0;
   29.55 +}
   29.56 +
   29.57 +void getinfo(const char *line, struct mailhdr *readhdrs)
   29.58 +{
   29.59 +	int i = 0;
   29.60 +	size_t tokenlen, linelen, valuelen;
   29.61 +
   29.62 +	while(readhdrs[i].token) {
   29.63 +		tokenlen = strlen(readhdrs[i].token);
   29.64 +		linelen = strlen(line);
   29.65 +		if(strncasecmp(line, readhdrs[i].token, tokenlen) == 0) {
   29.66 +			readhdrs[i].valuecount++;
   29.67 +			valuelen = linelen - tokenlen + 1;
   29.68 +			readhdrs[i].values =
   29.69 +				(char **)myrealloc(readhdrs[i].values,
   29.70 +				  readhdrs[i].valuecount * sizeof(char *));
   29.71 +			readhdrs[i].values[readhdrs[i].valuecount - 1] =
   29.72 +					(char *)mymalloc(valuelen + 1);
   29.73 +			strncpy(readhdrs[i].values[readhdrs[i].valuecount - 1],
   29.74 +						line+tokenlen, valuelen);
   29.75 +			chomp(readhdrs[i].values[readhdrs[i].valuecount - 1]);
   29.76 +		}
   29.77 +		i++;
   29.78 +	}
   29.79 +}
   29.80 +
   29.81 +int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
   29.82 +		 const char **delhdrs, struct mailhdr *readhdrs,
   29.83 +		 struct strlist *allhdrs, const char *prefix)
   29.84 +{
   29.85 +	char *hdrline, *subject, *unqp;
   29.86 +	int hdrsadded = 0;
   29.87 +	int subject_present = 0;
   29.88 +
   29.89 +	allhdrs->count = 0;
   29.90 +	allhdrs->strs = NULL;
   29.91 +
   29.92 +	while((hdrline = gethdrline(infd))) {
   29.93 +		/* Done with headers? Then add extra if wanted*/
   29.94 +		if((strncasecmp(hdrline, "mime", 4) == 0) ||
   29.95 +			((strlen(hdrline) == 1) && (hdrline[0] == '\n'))){
   29.96 +
   29.97 +			/* add extra headers */
   29.98 +			if(!hdrsadded && hdrfd >= 0) {
   29.99 +				if(dumpfd2fd(hdrfd, outfd) < 0) {
  29.100 +					log_error(LOG_ARGS, "Could not "
  29.101 +						"add extra headers");
  29.102 +					myfree(hdrline);
  29.103 +					return -1;
  29.104 +				} else
  29.105 +					hdrsadded = 1;
  29.106 +			}
  29.107 +			
  29.108 +			fsync(outfd);
  29.109 +
  29.110 +			/* end of headers, write single LF */ 
  29.111 +			if(hdrline[0] == '\n') {
  29.112 +				/* but first add Subject if none is present
  29.113 +				 * and a prefix is defined */
  29.114 +				if (prefix && !subject_present)
  29.115 +				{
  29.116 +					subject = concatstr(3, "Subject: ", 
  29.117 +								prefix, "\n");
  29.118 +					writen(outfd, subject, strlen(subject));
  29.119 +					myfree(subject);
  29.120 +					subject_present = 1;
  29.121 +				}
  29.122 +
  29.123 +				if(writen(outfd, hdrline, strlen(hdrline))
  29.124 +						< 0) {
  29.125 +					myfree(hdrline);
  29.126 +					log_error(LOG_ARGS,
  29.127 +							"Error writing hdrs.");
  29.128 +					return -1;
  29.129 +				}
  29.130 +				myfree(hdrline);
  29.131 +				break;
  29.132 +			}
  29.133 +		}
  29.134 +		/* Do we want info from hdrs? Get it before it's gone */
  29.135 +		if(readhdrs)
  29.136 +			getinfo(hdrline, readhdrs);
  29.137 +
  29.138 +		/* Snatch a copy of the header */
  29.139 +		allhdrs->count++;
  29.140 +		allhdrs->strs = myrealloc(allhdrs->strs,
  29.141 +					sizeof(char *) * (allhdrs->count + 1));
  29.142 +		allhdrs->strs[allhdrs->count-1] = mystrdup(hdrline);
  29.143 +		allhdrs->strs[allhdrs->count] = NULL;  /* XXX why, why, why? */
  29.144 +
  29.145 +		/* Add Subject: prefix if wanted */
  29.146 +		if(prefix) {
  29.147 +			if(strncasecmp(hdrline, "Subject:", 8) == 0) {
  29.148 +				subject_present = 1;
  29.149 +				unqp = cleanquotedp(hdrline + 8);
  29.150 +				if(strstr(hdrline + 8, prefix) == NULL &&
  29.151 +				   strstr(unqp, prefix) == NULL) {
  29.152 +					subject = concatstr(3,
  29.153 +							"Subject: ", prefix,
  29.154 +							hdrline + 8);
  29.155 +					writen(outfd, subject,
  29.156 +							strlen(subject));
  29.157 +					myfree(subject);
  29.158 +					myfree(hdrline);
  29.159 +					myfree(unqp);
  29.160 +					continue;
  29.161 +				}
  29.162 +				myfree(unqp);
  29.163 +			}
  29.164 +		}
  29.165 +		
  29.166 +		/* Should it be stripped? */
  29.167 +		if(delhdrs) {
  29.168 +			if(!findit(hdrline, delhdrs))
  29.169 +				writen(outfd, hdrline, strlen(hdrline));
  29.170 +		} else
  29.171 +			writen(outfd, hdrline, strlen(hdrline));
  29.172 +
  29.173 +
  29.174 +		myfree(hdrline);
  29.175 +	}
  29.176 +
  29.177 +	/* Just print the rest of the mail */
  29.178 +	if(dumpfd2fd(infd, outfd) < 0) {
  29.179 +		log_error(LOG_ARGS, "Error when dumping rest of mail");
  29.180 +		return -1;
  29.181 +	}
  29.182 +
  29.183 +	/* No more, lets add the footer if one */
  29.184 +	if(footfd >= 0)
  29.185 +		if(dumpfd2fd(footfd, outfd) < 0) {
  29.186 +			log_error(LOG_ARGS, "Error when adding footer");
  29.187 +			return -1;
  29.188 +		}
  29.189 +
  29.190 +	fsync(outfd);
  29.191 +
  29.192 +	return 0;
  29.193 +}
    30.1 --- a/src/mlmmj-make-ml.sh.in	Mon Sep 27 10:59:35 2010 +1000
    30.2 +++ b/src/mlmmj-make-ml.sh.in	Sun Oct 03 21:40:42 2010 +1100
    30.3 @@ -120,9 +120,9 @@
    30.4  LISTADDRESS="$LISTNAME@$FQDN"
    30.5  echo "$LISTADDRESS" > "$LISTDIR"/control/"listaddress"
    30.6  
    30.7 -MLMMJRECIEVE=`which mlmmj-recieve 2>/dev/null`
    30.8 -if [ -z "$MLMMJRECIEVE" ]; then
    30.9 -	MLMMJRECIEVE="/path/to/mlmmj-recieve"
   30.10 +MLMMJRECEIVE=`which mlmmj-receive 2>/dev/null`
   30.11 +if [ -z "$MLMMJRECEIVE" ]; then
   30.12 +	MLMMJRECEIVE="/path/to/mlmmj-receive"
   30.13  fi
   30.14  
   30.15  MLMMJMAINTD=`which mlmmj-maintd 2>/dev/null`
   30.16 @@ -130,7 +130,7 @@
   30.17  	MLMMJMAINTD="/path/to/mlmmj-maintd"
   30.18  fi
   30.19  
   30.20 -ALIAS="$LISTNAME:  \"|$MLMMJRECIEVE -L $SPOOLDIR/$LISTNAME/\""
   30.21 +ALIAS="$LISTNAME:  \"|$MLMMJRECEIVE -L $SPOOLDIR/$LISTNAME/\""
   30.22  CRONENTRY="0 */2 * * * \"$MLMMJMAINTD -F -L $SPOOLDIR/$LISTNAME/\""
   30.23  
   30.24  if [ -n "$A_CREATE" ]; then
    31.1 --- a/src/mlmmj-process.c	Mon Sep 27 10:59:35 2010 +1000
    31.2 +++ b/src/mlmmj-process.c	Sun Oct 03 21:40:42 2010 +1100
    31.3 @@ -40,7 +40,7 @@
    31.4  #include "getlistdelim.h"
    31.5  #include "listcontrol.h"
    31.6  #include "strgen.h"
    31.7 -#include "do_all_the_voodo_here.h"
    31.8 +#include "do_all_the_voodoo_here.h"
    31.9  #include "log_error.h"
   31.10  #include "mygetline.h"
   31.11  #include "statctrl.h"
   31.12 @@ -501,13 +501,13 @@
   31.13  		exit(EXIT_FAILURE);
   31.14  	}
   31.15  
   31.16 -    /* hdrfd is checked in do_all_the_voodo_here(), because the
   31.17 +    /* hdrfd is checked in do_all_the_voodoo_here(), because the
   31.18       * customheaders file might not exist */
   31.19  	headerfilename = concatstr(2, listdir, "/control/customheaders");
   31.20  	hdrfd = open(headerfilename, O_RDONLY);
   31.21  	myfree(headerfilename);
   31.22  
   31.23 -    /* footfd is checked in do_all_the_voodo_here(), see above */
   31.24 +    /* footfd is checked in do_all_the_voodoo_here(), see above */
   31.25  	footerfilename = concatstr(2, listdir, "/control/footer");
   31.26  	footfd = open(footerfilename, O_RDONLY);
   31.27  	myfree(footerfilename);
   31.28 @@ -527,10 +527,10 @@
   31.29  
   31.30  	subjectprefix = ctrlvalue(listdir, "prefix");
   31.31  
   31.32 -	if(do_all_the_voodo_here(rawmailfd, donemailfd, hdrfd, footfd,
   31.33 +	if(do_all_the_voodoo_here(rawmailfd, donemailfd, hdrfd, footfd,
   31.34  				(const char**)delheaders->strs, readhdrs,
   31.35  				&allheaders, subjectprefix) < 0) {
   31.36 -		log_error(LOG_ARGS, "Error in do_all_the_voodo_here");
   31.37 +		log_error(LOG_ARGS, "Error in do_all_the_voodoo_here");
   31.38  		exit(EXIT_FAILURE);
   31.39  	}
   31.40  
   31.41 @@ -646,10 +646,10 @@
   31.42  						    "output mail file");
   31.43  				exit(EXIT_FAILURE);
   31.44  			}
   31.45 -			if(do_all_the_voodo_here(rawmailfd, donemailfd, -1,
   31.46 +			if(do_all_the_voodoo_here(rawmailfd, donemailfd, -1,
   31.47  					-1, (const char**)delheaders->strs,
   31.48  					NULL, &allheaders, NULL) < 0) {
   31.49 -				log_error(LOG_ARGS, "do_all_the_voodo_here");
   31.50 +				log_error(LOG_ARGS, "do_all_the_voodoo_here");
   31.51  				exit(EXIT_FAILURE);
   31.52  			}
   31.53  			close(rawmailfd);
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/src/mlmmj-receive.c	Sun Oct 03 21:40:42 2010 +1100
    32.3 @@ -0,0 +1,185 @@
    32.4 +/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
    32.5 + *
    32.6 + * $Id$
    32.7 + *
    32.8 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    32.9 + * of this software and associated documentation files (the "Software"), to
   32.10 + * deal in the Software without restriction, including without limitation the
   32.11 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   32.12 + * sell copies of the Software, and to permit persons to whom the Software is
   32.13 + * furnished to do so, subject to the following conditions:
   32.14 + *
   32.15 + * The above copyright notice and this permission notice shall be included in
   32.16 + * all copies or substantial portions of the Software.
   32.17 + *
   32.18 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   32.19 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   32.20 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   32.21 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   32.22 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   32.23 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   32.24 + * IN THE SOFTWARE.
   32.25 + */
   32.26 +
   32.27 +#include <stdio.h>
   32.28 +#include <stdlib.h>
   32.29 +#include <unistd.h>
   32.30 +#include <errno.h>
   32.31 +#include <string.h>
   32.32 +#include <sys/types.h>
   32.33 +#include <sys/stat.h>
   32.34 +#include <fcntl.h>
   32.35 +#include <libgen.h>
   32.36 +
   32.37 +#include "mlmmj.h"
   32.38 +#include "wrappers.h"
   32.39 +#include "mygetline.h"
   32.40 +#include "strgen.h"
   32.41 +#include "log_error.h"
   32.42 +#include "memory.h"
   32.43 +
   32.44 +extern char *optarg;
   32.45 +
   32.46 +static void print_help(const char *prg)
   32.47 +{
   32.48 +        printf("Usage: %s -L /path/to/listdir [-s sender@example.org] [-e extension] [-h] [-V] [-P] [-F]\n"
   32.49 +	       " -h: This help\n"
   32.50 +	       " -F: Don't fork in the background\n"
   32.51 +	       " -L: Full path to list directory\n"
   32.52 +	       " -s: Specify sender address\n"
   32.53 +	       " -e: The foo part of user+foo@example.org\n"
   32.54 +	       " -P: Don't execute mlmmj-process\n"
   32.55 +	       " -V: Print version\n", prg);
   32.56 +	exit(EXIT_SUCCESS);
   32.57 +}
   32.58 +
   32.59 +int main(int argc, char **argv)
   32.60 +{
   32.61 +	char *infilename = NULL, *listdir = NULL;
   32.62 +	char *randomstr = random_str();
   32.63 +	char *mlmmjprocess, *bindir;
   32.64 +	int fd, opt, noprocess = 0, nofork = 0;
   32.65 +	struct stat st;
   32.66 +	uid_t uid;
   32.67 +	pid_t childpid;
   32.68 +
   32.69 +	CHECKFULLPATH(argv[0]);
   32.70 +	
   32.71 +	log_set_name(argv[0]);
   32.72 +
   32.73 +	bindir = mydirname(argv[0]);
   32.74 +	mlmmjprocess = concatstr(2, bindir, "/mlmmj-process");
   32.75 +	myfree(bindir);
   32.76 +	
   32.77 +	while ((opt = getopt(argc, argv, "hPVL:s:e:F")) != -1) {
   32.78 +		switch(opt) {
   32.79 +		case 'h':
   32.80 +			print_help(argv[0]);
   32.81 +			break;
   32.82 +		case 'L':
   32.83 +			listdir = optarg;
   32.84 +			break;
   32.85 +		case 's':
   32.86 +			setenv("SENDER", optarg, 1);
   32.87 +			break;
   32.88 +		case 'e':
   32.89 +			setenv("EXTENSION", optarg, 1);
   32.90 +			break;
   32.91 +		case 'P':
   32.92 +			noprocess = 1;
   32.93 +			break;
   32.94 +		case 'F':
   32.95 +			nofork = 1;
   32.96 +			break;
   32.97 +		case 'V':
   32.98 +			print_version(argv[0]);
   32.99 +			exit(0);
  32.100 +		}
  32.101 +	}
  32.102 +
  32.103 +	if(listdir == NULL) {
  32.104 +		fprintf(stderr, "You have to specify -L\n");
  32.105 +		fprintf(stderr, "%s -h for help\n", argv[0]);
  32.106 +		exit(EXIT_FAILURE);
  32.107 +	}
  32.108 +
  32.109 +	/* Lets make sure no random user tries to send mail to the list */
  32.110 +	if(listdir) {
  32.111 +		if(stat(listdir, &st) == 0) {
  32.112 +			uid = getuid();
  32.113 +			if(uid && uid != st.st_uid) {
  32.114 +				log_error(LOG_ARGS,
  32.115 +					"Have to invoke either as root "
  32.116 +					"or as the user owning listdir "
  32.117 +					"Invoked with uid = [%d]", (int)uid);
  32.118 +				writen(STDERR_FILENO,
  32.119 +					"Have to invoke either as root "
  32.120 +					"or as the user owning listdir\n", 60);
  32.121 +				exit(EXIT_FAILURE);
  32.122 +			}
  32.123 +		} else {
  32.124 +			log_error(LOG_ARGS, "Could not stat %s", listdir);
  32.125 +			exit(EXIT_FAILURE);
  32.126 +		}
  32.127 +	}
  32.128 +	
  32.129 +	infilename = concatstr(3, listdir, "/incoming/", randomstr);
  32.130 +	myfree(randomstr);
  32.131 +	fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  32.132 +	while(fd < 0 && errno == EEXIST) {
  32.133 +		myfree(infilename);
  32.134 +		randomstr = random_str();
  32.135 +		infilename = concatstr(3, listdir, "/incoming/", randomstr);
  32.136 +		myfree(randomstr);
  32.137 +		fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  32.138 +	}
  32.139 +
  32.140 +	if(fd < 0) {
  32.141 +		log_error(LOG_ARGS, "could not create mail file in "
  32.142 +				    "%s/incoming directory", listdir);
  32.143 +		myfree(infilename);
  32.144 +		exit(EXIT_FAILURE);
  32.145 +	}
  32.146 +	
  32.147 +	if(dumpfd2fd(fileno(stdin), fd) != 0) {
  32.148 +		log_error(LOG_ARGS, "Could not receive mail");
  32.149 +		exit(EXIT_FAILURE);
  32.150 +	}
  32.151 +
  32.152 +#if 0
  32.153 +	log_oper(listdir, OPLOGFNAME, "mlmmj-receive got %s", infilename);
  32.154 +#endif
  32.155 +	fsync(fd);
  32.156 +	close(fd);
  32.157 +
  32.158 +	if(noprocess) {
  32.159 +		myfree(infilename);
  32.160 +		exit(EXIT_SUCCESS);
  32.161 +	}
  32.162 +
  32.163 +	/*
  32.164 +	 * Now we fork so we can exit with success since it could potentially
  32.165 +	 * take a long time for mlmmj-send to finish delivering the mails and
  32.166 +	 * returning, making it susceptible to getting a SIGKILL from the
  32.167 +	 * mailserver invoking mlmmj-receive.
  32.168 +	 */
  32.169 +	if (!nofork) {
  32.170 +		childpid = fork();
  32.171 +		if(childpid < 0)
  32.172 +			log_error(LOG_ARGS, "fork() failed! Proceeding anyway");
  32.173 +	
  32.174 +		if(childpid)
  32.175 +			exit(EXIT_SUCCESS); /* Parent says: "bye bye kids!"*/
  32.176 +
  32.177 +		close(0);
  32.178 +		close(1);
  32.179 +		close(2);
  32.180 +	}
  32.181 +
  32.182 +	execlp(mlmmjprocess, mlmmjprocess,
  32.183 +				"-L", listdir,
  32.184 +				"-m", infilename, (char *)NULL);
  32.185 +	log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjprocess);
  32.186 +
  32.187 +	exit(EXIT_FAILURE);
  32.188 +}
    33.1 --- a/src/mlmmj-recieve.c	Mon Sep 27 10:59:35 2010 +1000
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,185 +0,0 @@
    33.4 -/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
    33.5 - *
    33.6 - * $Id$
    33.7 - *
    33.8 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    33.9 - * of this software and associated documentation files (the "Software"), to
   33.10 - * deal in the Software without restriction, including without limitation the
   33.11 - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   33.12 - * sell copies of the Software, and to permit persons to whom the Software is
   33.13 - * furnished to do so, subject to the following conditions:
   33.14 - *
   33.15 - * The above copyright notice and this permission notice shall be included in
   33.16 - * all copies or substantial portions of the Software.
   33.17 - *
   33.18 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   33.19 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   33.20 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   33.21 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   33.22 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   33.23 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   33.24 - * IN THE SOFTWARE.
   33.25 - */
   33.26 -
   33.27 -#include <stdio.h>
   33.28 -#include <stdlib.h>
   33.29 -#include <unistd.h>
   33.30 -#include <errno.h>
   33.31 -#include <string.h>
   33.32 -#include <sys/types.h>
   33.33 -#include <sys/stat.h>
   33.34 -#include <fcntl.h>
   33.35 -#include <libgen.h>
   33.36 -
   33.37 -#include "mlmmj.h"
   33.38 -#include "wrappers.h"
   33.39 -#include "mygetline.h"
   33.40 -#include "strgen.h"
   33.41 -#include "log_error.h"
   33.42 -#include "memory.h"
   33.43 -
   33.44 -extern char *optarg;
   33.45 -
   33.46 -static void print_help(const char *prg)
   33.47 -{
   33.48 -        printf("Usage: %s -L /path/to/listdir [-s sender@example.org] [-e extension] [-h] [-V] [-P] [-F]\n"
   33.49 -	       " -h: This help\n"
   33.50 -	       " -F: Don't fork in the background\n"
   33.51 -	       " -L: Full path to list directory\n"
   33.52 -	       " -s: Specify sender address\n"
   33.53 -	       " -e: The foo part of user+foo@example.org\n"
   33.54 -	       " -P: Don't execute mlmmj-process\n"
   33.55 -	       " -V: Print version\n", prg);
   33.56 -	exit(EXIT_SUCCESS);
   33.57 -}
   33.58 -
   33.59 -int main(int argc, char **argv)
   33.60 -{
   33.61 -	char *infilename = NULL, *listdir = NULL;
   33.62 -	char *randomstr = random_str();
   33.63 -	char *mlmmjprocess, *bindir;
   33.64 -	int fd, opt, noprocess = 0, nofork = 0;
   33.65 -	struct stat st;
   33.66 -	uid_t uid;
   33.67 -	pid_t childpid;
   33.68 -
   33.69 -	CHECKFULLPATH(argv[0]);
   33.70 -	
   33.71 -	log_set_name(argv[0]);
   33.72 -
   33.73 -	bindir = mydirname(argv[0]);
   33.74 -	mlmmjprocess = concatstr(2, bindir, "/mlmmj-process");
   33.75 -	myfree(bindir);
   33.76 -	
   33.77 -	while ((opt = getopt(argc, argv, "hPVL:s:e:F")) != -1) {
   33.78 -		switch(opt) {
   33.79 -		case 'h':
   33.80 -			print_help(argv[0]);
   33.81 -			break;
   33.82 -		case 'L':
   33.83 -			listdir = optarg;
   33.84 -			break;
   33.85 -		case 's':
   33.86 -			setenv("SENDER", optarg, 1);
   33.87 -			break;
   33.88 -		case 'e':
   33.89 -			setenv("EXTENSION", optarg, 1);
   33.90 -			break;
   33.91 -		case 'P':
   33.92 -			noprocess = 1;
   33.93 -			break;
   33.94 -		case 'F':
   33.95 -			nofork = 1;
   33.96 -			break;
   33.97 -		case 'V':
   33.98 -			print_version(argv[0]);
   33.99 -			exit(0);
  33.100 -		}
  33.101 -	}
  33.102 -
  33.103 -	if(listdir == NULL) {
  33.104 -		fprintf(stderr, "You have to specify -L\n");
  33.105 -		fprintf(stderr, "%s -h for help\n", argv[0]);
  33.106 -		exit(EXIT_FAILURE);
  33.107 -	}
  33.108 -
  33.109 -	/* Lets make sure no random user tries to send mail to the list */
  33.110 -	if(listdir) {
  33.111 -		if(stat(listdir, &st) == 0) {
  33.112 -			uid = getuid();
  33.113 -			if(uid && uid != st.st_uid) {
  33.114 -				log_error(LOG_ARGS,
  33.115 -					"Have to invoke either as root "
  33.116 -					"or as the user owning listdir "
  33.117 -					"Invoked with uid = [%d]", (int)uid);
  33.118 -				writen(STDERR_FILENO,
  33.119 -					"Have to invoke either as root "
  33.120 -					"or as the user owning listdir\n", 60);
  33.121 -				exit(EXIT_FAILURE);
  33.122 -			}
  33.123 -		} else {
  33.124 -			log_error(LOG_ARGS, "Could not stat %s", listdir);
  33.125 -			exit(EXIT_FAILURE);
  33.126 -		}
  33.127 -	}
  33.128 -	
  33.129 -	infilename = concatstr(3, listdir, "/incoming/", randomstr);
  33.130 -	myfree(randomstr);
  33.131 -	fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  33.132 -	while(fd < 0 && errno == EEXIST) {
  33.133 -		myfree(infilename);
  33.134 -		randomstr = random_str();
  33.135 -		infilename = concatstr(3, listdir, "/incoming/", randomstr);
  33.136 -		myfree(randomstr);
  33.137 -		fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
  33.138 -	}
  33.139 -
  33.140 -	if(fd < 0) {
  33.141 -		log_error(LOG_ARGS, "could not create mail file in "
  33.142 -				    "%s/incoming directory", listdir);
  33.143 -		myfree(infilename);
  33.144 -		exit(EXIT_FAILURE);
  33.145 -	}
  33.146 -	
  33.147 -	if(dumpfd2fd(fileno(stdin), fd) != 0) {
  33.148 -		log_error(LOG_ARGS, "Could not recieve mail");
  33.149 -		exit(EXIT_FAILURE);
  33.150 -	}
  33.151 -
  33.152 -#if 0
  33.153 -	log_oper(listdir, OPLOGFNAME, "mlmmj-recieve got %s", infilename);
  33.154 -#endif
  33.155 -	fsync(fd);
  33.156 -	close(fd);
  33.157 -
  33.158 -	if(noprocess) {
  33.159 -		myfree(infilename);
  33.160 -		exit(EXIT_SUCCESS);
  33.161 -	}
  33.162 -
  33.163 -	/*
  33.164 -	 * Now we fork so we can exit with success since it could potentially
  33.165 -	 * take a long time for mlmmj-send to finish delivering the mails and
  33.166 -	 * returning, making it susceptible to getting a SIGKILL from the
  33.167 -	 * mailserver invoking mlmmj-recieve.
  33.168 -	 */
  33.169 -	if (!nofork) {
  33.170 -		childpid = fork();
  33.171 -		if(childpid < 0)
  33.172 -			log_error(LOG_ARGS, "fork() failed! Proceeding anyway");
  33.173 -	
  33.174 -		if(childpid)
  33.175 -			exit(EXIT_SUCCESS); /* Parent says: "bye bye kids!"*/
  33.176 -
  33.177 -		close(0);
  33.178 -		close(1);
  33.179 -		close(2);
  33.180 -	}
  33.181 -
  33.182 -	execlp(mlmmjprocess, mlmmjprocess,
  33.183 -				"-L", listdir,
  33.184 -				"-m", infilename, (char *)NULL);
  33.185 -	log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjprocess);
  33.186 -
  33.187 -	exit(EXIT_FAILURE);
  33.188 -}
    34.1 --- a/src/mlmmj-send.c	Mon Sep 27 10:59:35 2010 +1000
    34.2 +++ b/src/mlmmj-send.c	Sun Oct 03 21:40:42 2010 +1100
    34.3 @@ -446,7 +446,7 @@
    34.4  	}
    34.5  	for(i = 0; i < addrs->count; i++) {
    34.6  		if(gotsigterm) {
    34.7 -			log_error(LOG_ARGS, "TERM signal recieved, "
    34.8 +			log_error(LOG_ARGS, "TERM signal received, "
    34.9  					"shutting down.");
   34.10  			return -1;
   34.11  		}
   34.12 @@ -640,7 +640,7 @@
   34.13  		}
   34.14  		if(gotsigterm && listaddr && archivefilename) {
   34.15  			/* we got SIGTERM, so save the addresses and bail */
   34.16 -			log_error(LOG_ARGS, "TERM signal recieved, "
   34.17 +			log_error(LOG_ARGS, "TERM signal received, "
   34.18  						"shutting down.");
   34.19  			index = get_index_from_filename(archivefilename);
   34.20  			status = requeuemail(listdir, index, addrs, i);