I am managing my email adresses with dot-qmail
files. After moving to a new server in august 2013, I choosed Postfix
as my MTA :)
So then, I tried Sieve for delivery to my mailboxes. But the style of the dot-qmail files was much easier to maintain. Then I tried to get my old dot-qmail files to work together with the new Postfix setup. And yes, after some patching and scripting, the local dot-qmail delivery works perfectly together with Postfix ;)
Here is a step by step guide of the setup I am using now:
- Create some catchall email adresses for your domains, which sould be deliverd to you local dot-qmail files.
Then create one .forward file with that content in your home directory:
# pipe all mail to our local qmail-local-deliver shell script... | ~/bin/qmail-local-deliver
- The seekablepipe script should be saved to your ~/bin directory:
#!/bin/sh # source: https://www.mail-archive.com/tmda-users@tmda.net/msg06211.html set -e tmp=/tmp/seekable.$$ exec 3<&0 4<&1 >$tmp <$tmp rm $tmp cat <&3 exec ${1+"$@"} 1<&4 3>&- 4>&-
- The qmail-local-deliver script is started via the .forward file of your home directory. This
script will invoke the patched qmail-local, which then delivers the mail to your Maildir folders ;)
#!/bin/sh ###################################################################### # Copyright © 2013 - 2014 Tino Reichardt # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License Version 2, as # published by the Free Software Foundation. ###################################################################### # ctime /TR 2013-08-22 # mtime /TR 2014-04-11 (licensing details added) ###################################################################### # first $home/bin export PATH="$HOME/bin:/usr/bin:/bin" # ORIGINAL_RECIPIENT is since Postfix 2.5 export RECIPIENT=$ORIGINAL_RECIPIENT #DOMAIN=example.org #HOME=/home/username #LOCAL=username #RECIPIENT=username@example.org #ORIGINAL_RECIPIENT=lala-lala@example2.org #PWD=/var/spool/postfix #SENDER=sender@remote-example.org #USER=username # USER="username" -> okay # SENDER -> okay LOCAL=`echo $RECIPIENT|cut -d@ -f1` DASH="-" EXT=$LOCAL DOMAIN=`echo $RECIPIENT|cut -d@ -f2` # HOME="$HOME" -> each domain gets it's own Inbox ;) HOME="" test "$DOMAIN" = "domain1.example.org" && HOME="/home/username/mail/domain1" test "$DOMAIN" = "domain2.example.org" && HOME="/home/username/mail/domain2" test "$DOMAIN" = "domain3.example.org" && HOME="/home/username/mail/domain3" test "$DOMAIN" = "example.org" && HOME="/home/username/mail/other" test "$DOMAIN" = "lala.example.org" && HOME="/home/username/mail/lala" test "$DOMAIN" = "example.com" && HOME="/home/username/mail/othercom" if [ "x$HOME" = "x" ]; then HOME="/home/username/mail/default" fi # Delivered-To is correctly created by qmail-local # you can remove headers like this, if you want: #grep -v '^Delivered-To: username@example.org' | \ #grep -v '^X-Original-To:' | \ # usage: qmail-local [ -nN ] -- user homedir local dash ext domain sender aliasempty seekablepipe qmail-local -- \ "$USER" "$HOME" "$LOCAL" "$DASH" \ "$EXT" "$DOMAIN" "$SENDER" ./ e=$? # log it in the end... for debugging... echo "qmail-local $e \"$USER\" \"$HOME\" \"$LOCAL\" \ \"$DASH\" \"$EXT\" \"$DOMAIN\" \"$SENDER\" \ ./" >> $HOME/.maillog (($e == 111)) && exit 75 (($e == 100)) && exit 77 exit $e ###################################################################### # exit codes of .forward: # OK 0 /* successful termination */ # USAGE 64 /* command line usage error */ # DATAERR 65 /* data format error */ # NOINPUT 66 /* cannot open input */ # NOUSER 67 /* addressee unknown */ # NOHOST 68 /* host name unknown */ # UNAVAILABLE 69 /* service unavailable */ # SOFTWARE 70 /* internal software error */ # OSERR 71 /* system error (e.g., can't fork) */ # OSFILE 72 /* critical OS file missing */ # CANTCREAT 73 /* can't create (user) output file */ # IOERR 74 /* input/output error */ # TEMPFAIL 75 /* temp failure; user is invited to retry */ # PROTOCOL 76 /* remote error in protocol */ # NOPERM 77 /* permission denied */ # CONFIG 78 /* configuration error */ ######################################################################
- Here is the small patch of qmail-local.c, which
provides some little changes for getting mail forwarding to work within the dot-qmail files.
The patch should be applied against the original qmail-1.03.tar.gz from 1997 ;)I hereby place this patch for qmail into the public domain. You are free to modify it, distribute modified versions, etc. Tino Reichardt --- qmail-local.c 2013-10-03 11:02:42.000000000 +0200 +++ qmail-local-tr.c 2013-10-03 11:04:06.523416132 +0200 @@ -41,6 +41,7 @@ void temp_qmail(fn) char *fn; { strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.3.0)"); } +int numforward; int flagdoit; int flag99; @@ -260,33 +261,49 @@ } } -unsigned long mailforward_qp = 0; - void mailforward(recips) char **recips; { - struct qmail qqt; - char *qqx; - substdio ss; - int match; + const char *sendmail = "/usr/lib/sendmail.postfix"; + int child; + char **args = (char **) alloc((numforward + 2 + 1) * sizeof(char *)); + int wstat; + stralloc sender_sa = {0}; + int i; if (seek_begin(0) == -1) temp_rewind(); - substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); + if (!stralloc_copys(&sender_sa, "-f")) temp_nomem(); + if (!stralloc_cats(&sender_sa, sender)) temp_nomem(); + if (!stralloc_0(&sender_sa)) temp_nomem(); - if (qmail_open(&qqt) == -1) temp_fork(); - mailforward_qp = qmail_qp(&qqt); - qmail_put(&qqt,dtline.s,dtline.len); - do + switch(child = fork()) { - if (getln(&ss,&messline,&match,'\n') != 0) { qmail_fail(&qqt); break; } - qmail_put(&qqt,messline.s,messline.len); + case -1: + temp_fork(); + case 0: + /* just pipe to the sendmail of postfix ... */ + args[0] = sendmail; args[1] = sender_sa.s; args[numforward + 2] = 0; + for (i = 0; i < numforward; i++) args[i + 2] = recips[i]; + sig_pipedefault(); + execv(*args,args); + strerr_die3x(111,"Unable to run /usr/lib/sendmail.postfix: ",error_str(errno),". (#4.3.0)"); + } + + wait_pid(&wstat,child); + if (wait_crashed(wstat)) + temp_childcrashed(); + + /* no stralloc_free() here... but mail addys are not very long */ + /* free(recip.s); */ + + switch(wait_exitcode(wstat)) + { + case 100: + case 64: case 65: case 70: case 76: case 77: case 78: case 112: _exit(100); + case 0: break; + case 99: flag99 = 1; break; + default: _exit(111); } - while (match); - qmail_from(&qqt,ueo.s); - while (*recips) qmail_to(&qqt,*recips++); - qqx = qmail_close(&qqt); - if (!*qqx) return; - strerr_die3x(*qqx == 'D' ? 100 : 111,"Unable to forward message: ",qqx + 1,"."); } void bouncexf() @@ -425,12 +442,6 @@ substdio_puts(subfdoutsmall,"+"); substdio_put(subfdoutsmall,count_buf,fmt_ulong(count_buf,count_program)); substdio_puts(subfdoutsmall,"\n"); - if (mailforward_qp) - { - substdio_puts(subfdoutsmall,"qp "); - substdio_put(subfdoutsmall,count_buf,fmt_ulong(count_buf,mailforward_qp)); - substdio_puts(subfdoutsmall,"\n"); - } substdio_flush(subfdoutsmall); } @@ -453,7 +464,6 @@ int j; int k; int fd; - int numforward; char **recips; datetime_sec starttime; int flagforwardonly;
DOWNLOAD