diet-qmail.patch
changeset 1 32f160a66da4
child 28 4733b8aac58d
equal deleted inserted replaced
0:ad6bd3a91cab 1:32f160a66da4
       
     1 From f3f9a0e61348706d763c41f2ac889425b964cf51 Mon Sep 17 00:00:00 2001
       
     2 From: Tomas Zeman <tzeman@volny.cz>
       
     3 Date: Sat, 3 Nov 2007 22:53:29 +0100
       
     4 Subject: [PATCH] diet-qmail-1.03-1-i686:
       
     5  * added
       
     6 
       
     7 ---
       
     8  source/dietlibc/diet-qmail/FrugalBuild             |  293 +++++
       
     9  source/dietlibc/diet-qmail/ext_todo-20030105.patch | 1238 ++++++++++++++++++++
       
    10  source/dietlibc/diet-qmail/make_cert.sh            |   57 +
       
    11  source/dietlibc/diet-qmail/pop3d_log_run           |   20 +
       
    12  source/dietlibc/diet-qmail/pop3d_run               |   33 +
       
    13  source/dietlibc/diet-qmail/qmail-1.03.errno.patch  |   47 +
       
    14  source/dietlibc/diet-qmail/qmail-dietlibc.patch    |   40 +
       
    15  source/dietlibc/diet-qmail/qmail-smtpd.spam.patch  |   74 ++
       
    16  source/dietlibc/diet-qmail/qmail.profile           |    5 +
       
    17  source/dietlibc/diet-qmail/qmail.rc                |  167 +++
       
    18  source/dietlibc/diet-qmail/qmailqueue-patch        |   72 ++
       
    19  .../diet-qmail/qregex-20060423-qmail.patch         |  688 +++++++++++
       
    20  .../dietlibc/diet-qmail/queue-fix-dietlibc.patch   |   18 +
       
    21  source/dietlibc/diet-qmail/queue-fix-errno.patch   |   14 +
       
    22  source/dietlibc/diet-qmail/rc                      |    7 +
       
    23  source/dietlibc/diet-qmail/send_log_run            |   20 +
       
    24  source/dietlibc/diet-qmail/send_run                |    8 +
       
    25  source/dietlibc/diet-qmail/smtpd_log_run           |   20 +
       
    26  source/dietlibc/diet-qmail/smtpd_run               |   45 +
       
    27  source/dietlibc/diet-qmail/tcp.pop3                |    6 +
       
    28  source/dietlibc/diet-qmail/tcp.smtp                |   81 ++
       
    29  21 files changed, 2953 insertions(+), 0 deletions(-)
       
    30  create mode 100644 source/dietlibc/diet-qmail/FrugalBuild
       
    31  create mode 100644 source/dietlibc/diet-qmail/ext_todo-20030105.patch
       
    32  create mode 100644 source/dietlibc/diet-qmail/make_cert.sh
       
    33  create mode 100644 source/dietlibc/diet-qmail/pop3d_log_run
       
    34  create mode 100644 source/dietlibc/diet-qmail/pop3d_run
       
    35  create mode 100644 source/dietlibc/diet-qmail/qmail-1.03.errno.patch
       
    36  create mode 100644 source/dietlibc/diet-qmail/qmail-dietlibc.patch
       
    37  create mode 100644 source/dietlibc/diet-qmail/qmail-smtpd.spam.patch
       
    38  create mode 100644 source/dietlibc/diet-qmail/qmail.profile
       
    39  create mode 100644 source/dietlibc/diet-qmail/qmail.rc
       
    40  create mode 100644 source/dietlibc/diet-qmail/qmailqueue-patch
       
    41  create mode 100644 source/dietlibc/diet-qmail/qregex-20060423-qmail.patch
       
    42  create mode 100644 source/dietlibc/diet-qmail/queue-fix-dietlibc.patch
       
    43  create mode 100644 source/dietlibc/diet-qmail/queue-fix-errno.patch
       
    44  create mode 100644 source/dietlibc/diet-qmail/rc
       
    45  create mode 100644 source/dietlibc/diet-qmail/send_log_run
       
    46  create mode 100644 source/dietlibc/diet-qmail/send_run
       
    47  create mode 100644 source/dietlibc/diet-qmail/smtpd_log_run
       
    48  create mode 100644 source/dietlibc/diet-qmail/smtpd_run
       
    49  create mode 100644 source/dietlibc/diet-qmail/tcp.pop3
       
    50  create mode 100644 source/dietlibc/diet-qmail/tcp.smtp
       
    51 
       
    52 diff --git a/source/dietlibc/diet-qmail/FrugalBuild b/source/dietlibc/diet-qmail/FrugalBuild
       
    53 new file mode 100644
       
    54 index 0000000..c973246
       
    55 --- /dev/null
       
    56 +++ b/source/dietlibc/diet-qmail/FrugalBuild
       
    57 @@ -0,0 +1,293 @@
       
    58 +# Patched qmail:
       
    59 +#	errno
       
    60 +#	ext_todo
       
    61 +#	qregex
       
    62 +#	qmailqueue
       
    63 +#	smtpd.spam
       
    64 +#	dietlibc
       
    65 +# + queue-fix package with patches:
       
    66 +#	errno
       
    67 +#	dietlibc
       
    68 +# Maintainer: Tomas Zeman <tzeman@volny.cz>
       
    69 +
       
    70 +branch=diet
       
    71 +pkgorig=qmail
       
    72 +pkgname=$branch-$pkgorig
       
    73 +pkgver=1.03
       
    74 +pkgrel=1
       
    75 +pkgdesc="A secure, reliable, efficient, SMTP/POP3 server."
       
    76 +url="http://cr.yp.to/qmail.html"
       
    77 +depends=('daemontools' 'ucspi-tcp' 'openssl')
       
    78 +makedepends=('dietlibc')
       
    79 +backup=(var/qmail/supervise/qmail-pop3d/run \
       
    80 +        var/qmail/supervise/qmail-pop3d/log/run \
       
    81 +        var/qmail/supervise/qmail-send/run \
       
    82 +        var/qmail/supervise/qmail-send/log/run \
       
    83 +        var/qmail/supervise/qmail-smtpd/run \
       
    84 +        var/qmail/supervise/qmail-smtpd/log/run \
       
    85 +        var/qmail/control/concurrencyincoming \
       
    86 +        var/qmail/control/defaultdelivery \
       
    87 +        var/qmail/control/me \
       
    88 +        etc/tcp.smtp etc/tcp.pop3)
       
    89 +provides=('smtp-server' 'pop3-server' 'qmail')
       
    90 +install="$pkgorig.install"
       
    91 +archs=(i686)
       
    92 +up2date="1.03"
       
    93 +source=(http://cr.yp.to/software/$pkgorig-$pkgver.tar.gz \
       
    94 +	qmail-1.03.errno.patch \
       
    95 +	ext_todo-20030105.patch \
       
    96 +	qmailqueue-patch \
       
    97 +	qregex-20060423-qmail.patch \
       
    98 +	qmail-dietlibc.patch \
       
    99 +	qmail-smtpd.spam.patch \
       
   100 +	http://www.netmeridian.com/e-huss/queue-fix-1.4.tar.gz \
       
   101 +	queue-fix-errno.patch \
       
   102 +	queue-fix-dietlibc.patch \
       
   103 +        rc smtpd_run pop3d_run qmail.profile qmail.rc send_log_run \
       
   104 +        send_run smtpd_log_run pop3d_log_run tcp.smtp tcp.pop3 \
       
   105 +        make_cert.sh)
       
   106 +
       
   107 +sha1sums=('18fb960481291a0503e93a94df3f6094edb7f27a' \
       
   108 +          '5cab1d84f67987983d13f10be1577e3da274cb94' \
       
   109 +          'a1ecb939a4aaeeb325d947f3e6416aa63ae97d80' \
       
   110 +          '76240289d52f2aca88004af47e5bd41c969880cf' \
       
   111 +          '40b18255da69a2f36cf8698d8eb907f5f039c0a7' \
       
   112 +          '605e93734c82373383f0284fabc64f85c4c06bfc' \
       
   113 +          '25f4ef231560bbc5fc3c2a82f2f0cd0696deded9' \
       
   114 +          'ce42fcc4daf5076adcf8fea6a9a84f2e1716c67c' \
       
   115 +          '72be22c7987ff3639692cda21c09dec340e06a4a' \
       
   116 +          '7d3525ab4a2e0e2be2bcd074dd94ae2784309d1b' \
       
   117 +          '3111cc689b5b1f6caa38997bf5f85aa3a516ef9c' \
       
   118 +          '3a80e44c97fd3035ce16c68fd2f611a64c61d169' \
       
   119 +          'f14f63c7b1bdc2d1f527249235551dc7f21ad47d' \
       
   120 +          '36951a4c195c72f4194c2d98ce3478c11d85c5bf' \
       
   121 +          '2b29cf70c6cbf52ef5af5da7840c72ae626ccb50' \
       
   122 +          '80543d062529a1eefde0c8b288c411a0b896e950' \
       
   123 +          '5877c8e1896f655bd8f4d98d52e67231c63d9e42' \
       
   124 +          '87ebef35a931cdf43b9ffc6dfe42529a21e562ba' \
       
   125 +          'e53e6248b347be058e3e1973434b2b885c65f091' \
       
   126 +          '27ff6fcaa115d7b59b86f54f970b6271c84ca6d3' \
       
   127 +          'ac0994b0ec0ada5bd28fdce6f8e37e9827357f43' \
       
   128 +          '3e91eb05c9bf51e230f237d19633fc572fbc3540')
       
   129 +
       
   130 +# NOTE: This should be built only as root, 
       
   131 +# not using fakeroot.
       
   132 +
       
   133 +# a small function to add required groups
       
   134 +# & users before building.
       
   135 +pre_build_qmail() {
       
   136 +  # create a tmp dir
       
   137 +  mkdir -p $startdir/src/tmp
       
   138 +  # group: qmail
       
   139 +  if [ ! `grep qmail /etc/group` ]; then
       
   140 +    echo "==> Adding group qmail (temporarily)"
       
   141 +    groupadd -g 2107 qmail &>/dev/null
       
   142 +    touch $startdir/src/tmp/group_qmail
       
   143 +  fi
       
   144 +
       
   145 +  # group: nofiles
       
   146 +  if [ ! `grep nofiles /etc/group` ]; then
       
   147 +    echo "==> Adding group nofiles (temporarily)"
       
   148 +    groupadd -g 2108 nofiles &>/dev/null
       
   149 +    touch $startdir/src/tmp/group_nofiles
       
   150 +  fi
       
   151 +
       
   152 +  # user: alias
       
   153 +  if ! id alias &>/dev/null; then 
       
   154 +    echo "==> Adding user alias (temporarily)"
       
   155 +    useradd -u 7790 -g nofiles -d /var/qmail/alias -s /bin/false alias
       
   156 +    touch $startdir/src/tmp/user_alias
       
   157 +  fi
       
   158 +
       
   159 +  # user: qmaild
       
   160 +  if ! id qmaild &>/dev/null; then
       
   161 +    echo "==> Adding user qmaild (temporarily)"
       
   162 +    useradd -u 7791 -g nofiles -d /var/qmail -s /bin/false qmaild
       
   163 +    touch $startdir/src/tmp/user_qmaild
       
   164 +  fi
       
   165 +
       
   166 +  # user: qmaill
       
   167 +  if ! id qmaill &>/dev/null; then
       
   168 +    echo "==> Adding user qmaill (temporarily)"
       
   169 +    useradd -u 7792 -g nofiles -d /var/qmail -s /bin/false qmaill
       
   170 +    touch $startdir/src/tmp/user_qmaill
       
   171 +  fi
       
   172 + 
       
   173 +  # user: qmailp
       
   174 +  if ! id qmailp &>/dev/null; then
       
   175 +    echo "==> Adding user qmailp (temporarily)"
       
   176 +    useradd -u 7793 -g nofiles -d /var/qmail -s /bin/false qmailp
       
   177 +    touch $startdir/src/tmp/user_qmailp
       
   178 +  fi
       
   179 +
       
   180 +  # user: qmailq
       
   181 +  if ! id qmailq &>/dev/null; then
       
   182 +    echo "==> Adding user qmailq (temporarily)"
       
   183 +    useradd -u 7794 -g qmail -d /var/qmail -s /bin/false qmailq
       
   184 +    touch $startdir/src/tmp/user_qmailq
       
   185 +  fi
       
   186 +
       
   187 +  # user: qmailr
       
   188 +  if ! id qmailr &>/dev/null; then
       
   189 +    echo "==> Adding user: qmailr (temporarily)"
       
   190 +    useradd -u 7795 -g qmail -d /var/qmail -s /bin/false qmailr
       
   191 +    touch $startdir/src/tmp/user_qmailr
       
   192 +  fi
       
   193 +
       
   194 +  # user: qmails
       
   195 +  if ! id qmails &>/dev/null; then
       
   196 +    echo "==> Adding user: qmails (temporarily)"
       
   197 +    useradd -u 7796 -g qmail -d /var/qmail -s /bin/false qmails
       
   198 +    touch $startdir/src/tmp/user_qmails
       
   199 +  fi
       
   200 +}
       
   201 +
       
   202 +# a small function to remove users
       
   203 +# after the build.
       
   204 +post_build_qmail() {
       
   205 +  # remove users
       
   206 +  for user in alias qmail{d,l,p,q,r,s}; do
       
   207 +    if [ -f $startdir/src/tmp/user_${user} ]; then
       
   208 +      echo "==> Removing user: ${user}"
       
   209 +      userdel ${user} &> /dev/null
       
   210 +    fi
       
   211 +  done
       
   212 +
       
   213 +  # remove groups
       
   214 +  for group in nofiles qmail; do
       
   215 +    if [ -f $startdir/src/tmp/group_${group} ]; then 
       
   216 +      echo "==> Removing group: ${group}"
       
   217 +      groupdel ${group} &> /dev/null
       
   218 +    fi
       
   219 +  done
       
   220 +
       
   221 +  # remove temp dir
       
   222 +  rm -rf $startdir/src/tmp
       
   223 +}
       
   224 +
       
   225 +build() {
       
   226 +  # save me some typing ;)
       
   227 +  qmail_dir=$Fdestdir/var/qmail
       
   228 +
       
   229 +
       
   230 +  # add the required groups & users 
       
   231 +  pre_build_qmail || Fdie
       
   232 +
       
   233 +  # start playing with qmail :)
       
   234 +  Fcd $pkgorig-$pkgver
       
   235 +  Fpatch qmail-1.03.errno.patch
       
   236 +  Fpatch ext_todo-20030105.patch
       
   237 +  Fpatch qmailqueue-patch
       
   238 +  Fpatch qregex-20060423-qmail.patch
       
   239 +  Fpatch qmail-dietlibc.patch
       
   240 +  Fpatch qmail-smtpd.spam.patch
       
   241 +
       
   242 +  # compile qmail
       
   243 +  make it man || Fdie 
       
   244 +
       
   245 +  # create dirs
       
   246 +  install -d -m 755 -o root -g qmail $qmail_dir
       
   247 +  for i in bin boot control users; do
       
   248 +    install -d -m 755 -o root -g qmail $qmail_dir/$i
       
   249 +  done
       
   250 +  install -d -m 755 -o alias -g qmail $qmail_dir/alias
       
   251 +  install -d -m 755 -o qmaill $startdir/pkg/var/log/qmail
       
   252 +  install -d -m 755 -o qmaill $startdir/pkg/var/log/qmail/smtpd
       
   253 +  install -d -m 755 -o qmaill $startdir/pkg/var/log/qmail/pop3d
       
   254 +  install -d -m 755 -o qmaill $startdir/pkg/var/log/qmail/send
       
   255 +  mkdir -p $qmail_dir/supervise/qmail-{pop3d,send,smtpd}/log
       
   256 +  install -d -m 710 -o qmailq -g qmail $qmail_dir/queue
       
   257 +
       
   258 +  # install binaries
       
   259 +  for i in binm1{,+df} binm2{,+df} binm3{,+df} home{,+df} proc{,+df}; do
       
   260 +    install -m 755 -o root -g qmail $i $qmail_dir/boot/$i
       
   261 +  done
       
   262 +  install -m 4711 -o qmailq -g qmail qmail-queue \
       
   263 +    $qmail_dir/bin/qmail-queue
       
   264 +  for i in qmail-lspawn qmail-start qmail-newu qmail-newmrh; do
       
   265 +    install -m 700 -o root -g qmail $i $qmail_dir/bin/$i
       
   266 +  done
       
   267 +  for i in qmail-getpw qmail-local qmail-remote qmail-rspawn \
       
   268 +           qmail-clean qmail-send splogger qmail-popup qmail-pw2u \
       
   269 +           qmail-todo; do
       
   270 +    install -m 711 -o root -g qmail $i $qmail_dir/bin/$i
       
   271 +  done
       
   272 +  for i in qmail-inject predate datemail mailsubj qmail-showctl \
       
   273 +	   qmail-qread qmail-qstat qmail-tcpto qmail-tcpok qmail-pop3d \
       
   274 +           qmail-popup qmail-qmqpc qmail-qmqpd qmail-qmtpd qmail-smtpd \
       
   275 +           sendmail tcp-env qreceipt qsmhook qbiff forward preline \
       
   276 +           condredirect bouncesaying except maildirmake maildir2mbox \
       
   277 +           maildirwatch qail elq pinq config-fast; do
       
   278 +    install -m 755 -o root -g qmail $i $qmail_dir/bin/$i
       
   279 +  done
       
   280 +
       
   281 +  # install manpages
       
   282 +  for i in bouncesaying except maildir2mbox maildirwatch preline qreceipt \
       
   283 +           condredirect forward maildirmake mailsubj qbiff tcp-env; do
       
   284 +    install -D -m 644 -o root -g qmail ${i}.1 $qmail_dir/man/man1/${i}.1
       
   285 +  done
       
   286 +  for i in addresses envelopes mbox qmail-header qmail-users dot-qmail \
       
   287 +           maildir qmail-control qmail-log tcp-environ; do
       
   288 +    install -D -m 644 -o root -g qmail ${i}.5 $qmail_dir/man/man5/${i}.5
       
   289 +  done
       
   290 +  for i in forgeries qmail-limits qmail; do
       
   291 +    install -D -m 644 -o root -g qmail ${i}.7 $qmail_dir/man/man7/${i}.7
       
   292 +  done
       
   293 +  for i in qmail-clean qmail-newmrh qmail-qmqpd qmail-rspawn qmail-tcpto \
       
   294 +           qmail-command qmail-newu qmail-qmtpd qmail-send splogger \
       
   295 +           qmail-getpw qmail-pop3d qmail-qread qmail-showctl qmail-inject \
       
   296 +           qmail-popup qmail-qstat qmail-smtpd qmail-local qmail-pw2u \
       
   297 +           qmail-queue qmail-start qmail-lspawn qmail-qmqpc qmail-remote \
       
   298 +           qmail-tcpok; do
       
   299 +    install -D -m 644 -o root -g qmail ${i}.8 $qmail_dir/man/man8/${i}.8
       
   300 +  done
       
   301 +
       
   302 +  # install supervise files
       
   303 +  for i in pop3d send smtpd; do
       
   304 +    install -m 755 $startdir/${i}_run \
       
   305 +      $qmail_dir/supervise/qmail-${i}/run
       
   306 +    install -m 755 $startdir/${i}_log_run \
       
   307 +      $qmail_dir/supervise/qmail-${i}/log/run
       
   308 +  done
       
   309 +
       
   310 +  # install rc
       
   311 +  install -m 755 $startdir/rc \
       
   312 +    $qmail_dir/rc
       
   313 +
       
   314 +  # install concurrencyicoming & defaultdelivery files
       
   315 +  echo 20 > $qmail_dir/control/concurrencyincoming
       
   316 +  echo ./Maildir/ > $qmail_dir/control/defaultdelivery
       
   317 +  chmod 644 $qmail_dir/control/{concurrencyincoming,defaultdelivery}
       
   318 +
       
   319 +  # create sendmail symlinks for compatibility reasons
       
   320 +  for i in sbin lib; do
       
   321 +    mkdir -p $Fdestdir/usr/${i}
       
   322 +    ln -sf /var/qmail/bin/sendmail $Fdestdir/usr/${i}/sendmail
       
   323 +  done
       
   324 +
       
   325 +  # install profile.d file
       
   326 +  install -D -m 755 $startdir/qmail.profile $Fdestdir/etc/profile.d/qmail.sh
       
   327 +
       
   328 +  # install tcp files
       
   329 +  for i in smtp pop3; do
       
   330 +    install -D -m 644 $startdir/tcp.${i} $Fdestdir/etc/tcp.${i}
       
   331 +  done
       
   332 +
       
   333 +  # install cert making script
       
   334 +  install -D -m755 $startdir/make_cert.sh $qmail_dir/bin/make_cert.sh
       
   335 +  
       
   336 +  # install rc.d file
       
   337 +  install -D -m 755 $startdir/qmail.rc $Fdestdir/etc/rc.d/qmail
       
   338 +
       
   339 +  # build and install queue-fix
       
   340 +  Fmessage "Now building queue-fix"
       
   341 +  cd $Fsrcdir/queue-fix-1.4 || Fdie
       
   342 +  Fpatch queue-fix-errno.patch
       
   343 +  Fpatch queue-fix-dietlibc.patch
       
   344 +  make || Fdie
       
   345 +  install -D -m755 queue-fix $qmail_dir/bin/queue-fix
       
   346 + 
       
   347 +  # remove groups & users
       
   348 +  post_build_qmail || Fdie
       
   349 +}
       
   350 +
       
   351 diff --git a/source/dietlibc/diet-qmail/ext_todo-20030105.patch b/source/dietlibc/diet-qmail/ext_todo-20030105.patch
       
   352 new file mode 100644
       
   353 index 0000000..466fb4d
       
   354 --- /dev/null
       
   355 +++ b/source/dietlibc/diet-qmail/ext_todo-20030105.patch
       
   356 @@ -0,0 +1,1238 @@
       
   357 +diff -uN qmail-1.03/EXTTODO qmail-exttodo/EXTTODO
       
   358 +--- qmail-1.03/EXTTODO	Thu Jan  1 01:00:00 1970
       
   359 ++++ qmail-exttodo/EXTTODO	Sun Jan  5 22:12:01 2003
       
   360 +@@ -0,0 +1,114 @@
       
   361 ++EXTTODO by Claudio Jeker <jeker@n-r-g.com> and 
       
   362 ++Andre Oppermann <opi@nrg4u.com>
       
   363 ++(c) 1998,1999,2000,2001,2002 Internet Business Solutions Ltd.
       
   364 ++
       
   365 ++The EXTTODO patch is a part of the qmail-ldap patch.
       
   366 ++This patches for qmail come with NO WARRANTY.
       
   367 ++
       
   368 ++These patches are under the BSD license.
       
   369 ++
       
   370 ++RELEASE: 5. Jan. 2003
       
   371 ++
       
   372 ++EXTTODO:
       
   373 ++======================
       
   374 ++
       
   375 ++TOC:
       
   376 ++ WHAT DOES IT DO
       
   377 ++ INSTALL
       
   378 ++ CONFIG FILES
       
   379 ++ SETUP
       
   380 ++ BIG PICTURE
       
   381 ++
       
   382 ++NEWS:
       
   383 ++ 
       
   384 ++ This is the first release of the EXTTODO patch.
       
   385 ++
       
   386 ++================================================================================
       
   387 ++
       
   388 ++WHAT DOES IT DO
       
   389 ++
       
   390 ++ The exttodo patch addresses a problem known as the silly qmail (queue)
       
   391 ++ problem. This problem is found only on system with high injection rates.
       
   392 ++
       
   393 ++ qmail with a big local and remote concurrency could deliver a tremendous 
       
   394 ++ amount of messages but normally this can not be achieved because qmail-send
       
   395 ++ becomes a bottleneck on those high volumes servers.
       
   396 ++ qmail-send preprocesses all new messages before distributing them for local
       
   397 ++ or remote delivering. In one run qmail-send does one todo run but has the 
       
   398 ++ ability to close multiple jobs. Because of this layout qmail-send can not 
       
   399 ++ feed all the new available (local/remote) delivery slots and therefor it is 
       
   400 ++ not possible to achieve the maximum throughput.
       
   401 ++ This would be a minor problem if one qmail-send run could be done in extreme
       
   402 ++ short time but because of many file system calls (fsync and (un)link) a todo
       
   403 ++ run is expensive and throttles the throughput.
       
   404 ++
       
   405 ++ The exttodo patch tries to solve the problem by moving the todo routine into 
       
   406 ++ an external program. This reduces the run time in qmail-send.
       
   407 ++
       
   408 ++ exttodo adds a new program to qmail called qmail-todo. qmail-todo prepares
       
   409 ++ incoming messages for local and remote delivering (by creating info/<messid>
       
   410 ++ local/<messid> and remote/<messid> and removing todo/<messid>). See also
       
   411 ++ INTERNALS. As next qmail-todo transmits the <messid> to qmail-send which will
       
   412 ++ add this message into the priority queue which schedules the message for 
       
   413 ++ delivery. 
       
   414 ++
       
   415 ++INSTALL
       
   416 ++
       
   417 ++ To enable the exttodo patch you need to define EXTERNAL_TODO while compiling
       
   418 ++ qmail(-ldap) this can be done with the -D flag of cc (e.g. cc -DEXTERNAL_TODO).
       
   419 ++
       
   420 ++ NOTE: the exttodo patch can also be used on qmail systems without the 
       
   421 ++ qmail-ldap patch.
       
   422 ++ 
       
   423 ++================================================================================
       
   424 ++
       
   425 ++CONFIG FILES
       
   426 ++
       
   427 ++ No additional control files are used or needed.
       
   428 ++
       
   429 ++================================================================================
       
   430 ++
       
   431 ++SETUP
       
   432 ++
       
   433 ++ qmail-todo will be started by qmail-start and therefor no additional setup
       
   434 ++ is needed.
       
   435 ++
       
   436 ++ To verify that exttodo is running just check if qmail-todo is running.
       
   437 ++
       
   438 ++================================================================================
       
   439 ++
       
   440 ++BIG PICTURE
       
   441 ++
       
   442 ++               +-------+   +-------+
       
   443 ++               | clean |   | clean |
       
   444 ++               +--0-1--+   +--0-1--+       +-----------+
       
   445 ++         trigger  ^ |         ^ |        +->0,1 lspawn |
       
   446 ++            |     | v         | v       /  +-----------+
       
   447 ++ +-------+  v  +--2-3--+   +--5-6--+   /
       
   448 ++ |       |  |  |       0<--7     1,2<-+
       
   449 ++ | queue |--+--| todo  |   | send  |
       
   450 ++ |       |  |  |       1-->8     3,4<-+
       
   451 ++ +-------+     +-------+   +---0---+   \
       
   452 ++                               |        \  +-----------+
       
   453 ++                               v         +->0,1 rspwan |
       
   454 ++                           +---0---+       +-----------+
       
   455 ++                           | logger|
       
   456 ++                           +-------+
       
   457 ++
       
   458 ++Communication between qmail-send and qmail-todo
       
   459 ++
       
   460 ++todo -> send:
       
   461 ++   D[LRB]<mesgid>\0
       
   462 ++          Start delivery for new message with id <messid>.
       
   463 ++          the character L, R or B defines the type
       
   464 ++          of delivery, local, remote or both respectively.
       
   465 ++   L<string>\0
       
   466 ++          Dump string to the logger without adding additional \n or similar.
       
   467 ++send -> todo:
       
   468 ++   H      Got a SIGHUP reread ~/control/locals and ~/control/virtualdomains
       
   469 ++   X      Quit ASAP.
       
   470 ++
       
   471 ++qmail-todo sends "\0" terminated messages whereas qmail-send just send one
       
   472 ++character to qmail-todo.
       
   473 ++
       
   474 ++
       
   475 +diff -uN qmail-1.03/EXTTODO-INFO qmail-exttodo/EXTTODO-INFO
       
   476 +--- qmail-1.03/EXTTODO-INFO	Thu Jan  1 01:00:00 1970
       
   477 ++++ qmail-exttodo/EXTTODO-INFO	Tue Apr 30 16:49:02 2002
       
   478 +@@ -0,0 +1,11 @@
       
   479 ++Files modified:
       
   480 ++Makefile
       
   481 ++EXTTODO
       
   482 ++FILES
       
   483 ++TARGETS
       
   484 ++qmail-send.c
       
   485 ++qmail-todo.c
       
   486 ++qmail-start.c
       
   487 ++hier.c
       
   488 ++install-big.c
       
   489 ++
       
   490 +diff -uN qmail-1.03/FILES qmail-exttodo/FILES
       
   491 +--- qmail-1.03/FILES	Mon Jun 15 12:53:16 1998
       
   492 ++++ qmail-exttodo/FILES	Mon Apr 22 13:59:28 2002
       
   493 +@@ -431,3 +431,4 @@
       
   494 + tcp-environ.5
       
   495 + constmap.h
       
   496 + constmap.c
       
   497 ++qmail-todo.c
       
   498 +diff -uN qmail-1.03/Makefile qmail-exttodo/Makefile
       
   499 +--- qmail-1.03/Makefile	Mon Jun 15 12:53:16 1998
       
   500 ++++ qmail-exttodo/Makefile	Mon Apr 22 14:55:59 2002
       
   501 +@@ -1,5 +1,7 @@
       
   502 + # Don't edit Makefile! Use conf-* for configuration.
       
   503 + 
       
   504 ++DEFINES=-DEXTERNAL_TODO # use to enable external todo
       
   505 ++
       
   506 + SHELL=/bin/sh
       
   507 + 
       
   508 + default: it
       
   509 +@@ -703,7 +705,7 @@
       
   510 + 
       
   511 + hier.o: \
       
   512 + compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h
       
   513 +-	./compile hier.c
       
   514 ++	./compile $(DEFINES) hier.c
       
   515 + 
       
   516 + home: \
       
   517 + home.sh conf-qmail
       
   518 +@@ -755,7 +757,7 @@
       
   519 + install-big.o: \
       
   520 + compile install-big.c auto_qmail.h auto_split.h auto_uids.h fmt.h \
       
   521 + fifo.h
       
   522 +-	./compile install-big.c
       
   523 ++	./compile $(DEFINES) install-big.c
       
   524 + 
       
   525 + install.o: \
       
   526 + compile install.c substdio.h strerr.h error.h open.h readwrite.h \
       
   527 +@@ -808,7 +810,7 @@
       
   528 + forward preline condredirect bouncesaying except maildirmake \
       
   529 + maildir2mbox maildirwatch qail elq pinq idedit install-big install \
       
   530 + instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \
       
   531 +-binm3 binm3+df
       
   532 ++binm3 binm3+df qmail-todo
       
   533 + 
       
   534 + load: \
       
   535 + make-load warn-auto.sh systype
       
   536 +@@ -1509,7 +1511,7 @@
       
   537 + scan.h case.h auto_qmail.h trigger.h newfield.h stralloc.h quote.h \
       
   538 + qmail.h substdio.h qsutil.h prioq.h datetime.h gen_alloc.h constmap.h \
       
   539 + fmtqfn.h readsubdir.h direntry.h
       
   540 +-	./compile qmail-send.c
       
   541 ++	./compile $(DEFINES) qmail-send.c
       
   542 + 
       
   543 + qmail-showctl: \
       
   544 + load qmail-showctl.o auto_uids.o control.o open.a getln.a stralloc.a \
       
   545 +@@ -1574,7 +1576,7 @@
       
   546 + 
       
   547 + qmail-start.o: \
       
   548 + compile qmail-start.c fd.h prot.h exit.h fork.h auto_uids.h
       
   549 +-	./compile qmail-start.c
       
   550 ++	./compile $(DEFINES) qmail-start.c
       
   551 + 
       
   552 + qmail-tcpok: \
       
   553 + load qmail-tcpok.o open.a lock.a strerr.a substdio.a error.a str.a \
       
   554 +@@ -1605,6 +1607,20 @@
       
   555 + compile qmail-tcpto.c substdio.h subfd.h substdio.h auto_qmail.h \
       
   556 + fmt.h ip.h lock.h error.h exit.h datetime.h now.h datetime.h
       
   557 + 	./compile qmail-tcpto.c
       
   558 ++
       
   559 ++qmail-todo: \
       
   560 ++load qmail-todo.o control.o constmap.o trigger.o fmtqfn.o now.o \
       
   561 ++readsubdir.o case.a ndelay.a getln.a sig.a open.a stralloc.a alloc.a \
       
   562 ++substdio.a error.a str.a fs.a auto_qmail.o auto_split.o
       
   563 ++	./load qmail-todo control.o constmap.o trigger.o fmtqfn.o now.o \
       
   564 ++	readsubdir.o case.a ndelay.a getln.a sig.a open.a stralloc.a \
       
   565 ++	alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_split.o
       
   566 ++
       
   567 ++qmail-todo.o: \
       
   568 ++compile alloc.h auto_qmail.h byte.h constmap.h control.h direntry.h error.h \
       
   569 ++exit.h fmt.h fmtqfn.h getln.h open.h ndelay.h now.h readsubdir.h readwrite.h \
       
   570 ++scan.h select.h str.h stralloc.h substdio.h trigger.h
       
   571 ++	./compile $(DEFINES) qmail-todo.c
       
   572 + 
       
   573 + qmail-upq: \
       
   574 + warn-auto.sh qmail-upq.sh conf-qmail conf-break conf-split
       
   575 +diff -uN qmail-1.03/TARGETS qmail-exttodo/TARGETS
       
   576 +--- qmail-1.03/TARGETS	Mon Jun 15 12:53:16 1998
       
   577 ++++ qmail-exttodo/TARGETS	Mon Apr 22 13:59:32 2002
       
   578 +@@ -385,3 +385,5 @@
       
   579 + man
       
   580 + setup
       
   581 + check
       
   582 ++qmail-todo.o
       
   583 ++qmail-todo
       
   584 +diff -uN qmail-1.03/hier.c qmail-exttodo/hier.c
       
   585 +--- qmail-1.03/hier.c	Mon Jun 15 12:53:16 1998
       
   586 ++++ qmail-exttodo/hier.c	Mon Apr 22 14:01:58 2002
       
   587 +@@ -108,6 +108,9 @@
       
   588 +   c(auto_qmail,"bin","qmail-rspawn",auto_uido,auto_gidq,0711);
       
   589 +   c(auto_qmail,"bin","qmail-clean",auto_uido,auto_gidq,0711);
       
   590 +   c(auto_qmail,"bin","qmail-send",auto_uido,auto_gidq,0711);
       
   591 ++#ifdef EXTERNAL_TODO
       
   592 ++  c(auto_qmail,"bin","qmail-todo",auto_uido,auto_gidq,0711);
       
   593 ++#endif
       
   594 +   c(auto_qmail,"bin","splogger",auto_uido,auto_gidq,0711);
       
   595 +   c(auto_qmail,"bin","qmail-newu",auto_uido,auto_gidq,0700);
       
   596 +   c(auto_qmail,"bin","qmail-newmrh",auto_uido,auto_gidq,0700);
       
   597 +diff -uN qmail-1.03/install-big.c qmail-exttodo/install-big.c
       
   598 +--- qmail-1.03/install-big.c	Mon Jun 15 12:53:16 1998
       
   599 ++++ qmail-exttodo/install-big.c	Mon Apr 22 14:02:11 2002
       
   600 +@@ -108,6 +108,9 @@
       
   601 +   c(auto_qmail,"bin","qmail-rspawn",auto_uido,auto_gidq,0711);
       
   602 +   c(auto_qmail,"bin","qmail-clean",auto_uido,auto_gidq,0711);
       
   603 +   c(auto_qmail,"bin","qmail-send",auto_uido,auto_gidq,0711);
       
   604 ++#ifdef EXTERNAL_TODO
       
   605 ++  c(auto_qmail,"bin","qmail-todo",auto_uido,auto_gidq,0711);
       
   606 ++#endif
       
   607 +   c(auto_qmail,"bin","splogger",auto_uido,auto_gidq,0711);
       
   608 +   c(auto_qmail,"bin","qmail-newu",auto_uido,auto_gidq,0700);
       
   609 +   c(auto_qmail,"bin","qmail-newmrh",auto_uido,auto_gidq,0700);
       
   610 +diff -uN qmail-1.03/qmail-send.c qmail-exttodo/qmail-send.c
       
   611 +--- qmail-1.03/qmail-send.c	Mon Jun 15 12:53:16 1998
       
   612 ++++ qmail-exttodo/qmail-send.c	Sun Jan  5 22:09:42 2003
       
   613 +@@ -1215,6 +1215,7 @@
       
   614 + 
       
   615 + /* this file is too long ---------------------------------------------- TODO */
       
   616 + 
       
   617 ++#ifndef EXTERNAL_TODO
       
   618 + datetime_sec nexttodorun;
       
   619 + DIR *tododir; /* if 0, have to opendir again */
       
   620 + stralloc todoline = {0};
       
   621 +@@ -1438,6 +1439,143 @@
       
   622 +    if (fdchan[c] != -1) close(fdchan[c]);
       
   623 + }
       
   624 + 
       
   625 ++#endif
       
   626 ++
       
   627 ++/* this file is too long ------------------------------------- EXTERNAL TODO */
       
   628 ++
       
   629 ++#ifdef EXTERNAL_TODO
       
   630 ++stralloc todoline = {0};
       
   631 ++char todobuf[2048];
       
   632 ++int todofdin;
       
   633 ++int todofdout;
       
   634 ++int flagtodoalive;
       
   635 ++
       
   636 ++void tododied() { log1("alert: oh no! lost qmail-todo connection! dying...\n");
       
   637 ++ flagexitasap = 1; flagtodoalive = 0; }
       
   638 ++
       
   639 ++void todo_init()
       
   640 ++{
       
   641 ++  todofdout = 7;
       
   642 ++  todofdin = 8;
       
   643 ++  flagtodoalive = 1;
       
   644 ++  /* sync with external todo */
       
   645 ++  if (write(todofdout, "S", 1) != 1) tododied();
       
   646 ++  
       
   647 ++  return;
       
   648 ++}
       
   649 ++
       
   650 ++void todo_selprep(nfds,rfds,wakeup)
       
   651 ++int *nfds;
       
   652 ++fd_set *rfds;
       
   653 ++datetime_sec *wakeup;
       
   654 ++{
       
   655 ++  if (flagexitasap) {
       
   656 ++    if (flagtodoalive) {
       
   657 ++      write(todofdout, "X", 1);
       
   658 ++    }
       
   659 ++  }
       
   660 ++  if (flagtodoalive) {
       
   661 ++    FD_SET(todofdin,rfds);
       
   662 ++    if (*nfds <= todofdin)
       
   663 ++      *nfds = todofdin + 1;
       
   664 ++  }
       
   665 ++}
       
   666 ++
       
   667 ++void todo_del(char* s)
       
   668 ++{
       
   669 ++ int flagchan[CHANNELS];
       
   670 ++ struct prioq_elt pe;
       
   671 ++ unsigned long id;
       
   672 ++ unsigned int len;
       
   673 ++ int c;
       
   674 ++
       
   675 ++ for (c = 0;c < CHANNELS;++c) flagchan[c] = 0;
       
   676 ++ switch(*s++) {
       
   677 ++  case 'L':
       
   678 ++    flagchan[0] = 1;
       
   679 ++    break;
       
   680 ++  case 'R':
       
   681 ++    flagchan[1] = 1;
       
   682 ++    break;
       
   683 ++  case 'B':
       
   684 ++    flagchan[0] = 1;
       
   685 ++    flagchan[1] = 1;
       
   686 ++    break;
       
   687 ++  case 'X':
       
   688 ++    break;
       
   689 ++  default:
       
   690 ++    log1("warning: qmail-send unable to understand qmail-todo\n");
       
   691 ++    return;
       
   692 ++ }
       
   693 ++ 
       
   694 ++ len = scan_ulong(s,&id);
       
   695 ++ if (!len || s[len]) {
       
   696 ++  log1("warning: qmail-send unable to understand qmail-todo\n");
       
   697 ++  return;
       
   698 ++ }
       
   699 ++
       
   700 ++ pe.id = id; pe.dt = now();
       
   701 ++ for (c = 0;c < CHANNELS;++c)
       
   702 ++   if (flagchan[c])
       
   703 ++     while (!prioq_insert(&pqchan[c],&pe)) nomem();
       
   704 ++
       
   705 ++ for (c = 0;c < CHANNELS;++c) if (flagchan[c]) break;
       
   706 ++ if (c == CHANNELS)
       
   707 ++   while (!prioq_insert(&pqdone,&pe)) nomem();
       
   708 ++
       
   709 ++ return;
       
   710 ++}
       
   711 ++
       
   712 ++void todo_do(rfds)
       
   713 ++fd_set *rfds;
       
   714 ++{
       
   715 ++  int r;
       
   716 ++  char ch;
       
   717 ++  int i;
       
   718 ++  
       
   719 ++  if (!flagtodoalive) return;
       
   720 ++  if (!FD_ISSET(todofdin,rfds)) return;
       
   721 ++
       
   722 ++  r = read(todofdin,todobuf,sizeof(todobuf));
       
   723 ++  if (r == -1) return;
       
   724 ++  if (r == 0) {
       
   725 ++    if (flagexitasap)
       
   726 ++      flagtodoalive = 0;
       
   727 ++    else
       
   728 ++      tododied();
       
   729 ++    return;
       
   730 ++  }
       
   731 ++  for (i = 0;i < r;++i) {
       
   732 ++    ch = todobuf[i];
       
   733 ++    while (!stralloc_append(&todoline,&ch)) nomem();
       
   734 ++    if (todoline.len > REPORTMAX)
       
   735 ++      todoline.len = REPORTMAX;
       
   736 ++      /* qmail-todo is responsible for keeping it short */
       
   737 ++    if (!ch && (todoline.len > 1)) {
       
   738 ++      switch (todoline.s[0]) {
       
   739 ++	case 'D':
       
   740 ++	  if (flagexitasap) break;
       
   741 ++	  todo_del(todoline.s + 1);
       
   742 ++	  break;
       
   743 ++	case 'L':
       
   744 ++	  log1(todoline.s + 1);
       
   745 ++	  break;
       
   746 ++	case 'X':
       
   747 ++	  if (flagexitasap)
       
   748 ++	    flagtodoalive = 0;
       
   749 ++	  else
       
   750 ++	    tododied();
       
   751 ++	  break;
       
   752 ++	default:
       
   753 ++	  log1("warning: qmail-send unable to understand qmail-todo: report mangled\n");
       
   754 ++	  break;
       
   755 ++      }
       
   756 ++      todoline.len = 0;
       
   757 ++    }
       
   758 ++  }
       
   759 ++}
       
   760 ++
       
   761 ++#endif
       
   762 + 
       
   763 + /* this file is too long ---------------------------------------------- MAIN */
       
   764 + 
       
   765 +@@ -1504,6 +1642,9 @@
       
   766 +    log1("alert: unable to reread controls: unable to switch to home directory\n");
       
   767 +    return;
       
   768 +   }
       
   769 ++#ifdef EXTERNAL_TODO
       
   770 ++ write(todofdout, "H", 1);
       
   771 ++#endif
       
   772 +  regetcontrols();
       
   773 +  while (chdir("queue") == -1)
       
   774 +   {
       
   775 +@@ -1568,8 +1709,12 @@
       
   776 +  todo_init();
       
   777 +  cleanup_init();
       
   778 + 
       
   779 ++#ifdef EXTERNAL_TODO
       
   780 ++ while (!flagexitasap || !del_canexit() || flagtodoalive)
       
   781 ++#else
       
   782 +  while (!flagexitasap || !del_canexit())
       
   783 +-  {
       
   784 ++#endif
       
   785 ++ {
       
   786 +    recent = now();
       
   787 + 
       
   788 +    if (flagrunasap) { flagrunasap = 0; pqrun(); }
       
   789 +diff -uN qmail-1.03/qmail-start.c qmail-exttodo/qmail-start.c
       
   790 +--- qmail-1.03/qmail-start.c	Mon Jun 15 12:53:16 1998
       
   791 ++++ qmail-exttodo/qmail-start.c	Mon Apr 22 13:55:48 2002
       
   792 +@@ -8,6 +8,9 @@
       
   793 + char *(qcargs[]) = { "qmail-clean", 0 };
       
   794 + char *(qlargs[]) = { "qmail-lspawn", "./Mailbox", 0 };
       
   795 + char *(qrargs[]) = { "qmail-rspawn", 0 };
       
   796 ++#ifdef EXTERNAL_TODO
       
   797 ++char *(qtargs[]) = { "qmail-todo", 0};
       
   798 ++#endif
       
   799 + 
       
   800 + void die() { _exit(111); }
       
   801 + 
       
   802 +@@ -18,13 +21,28 @@
       
   803 + int pi4[2];
       
   804 + int pi5[2];
       
   805 + int pi6[2];
       
   806 +-
       
   807 +-void close23456() { close(2); close(3); close(4); close(5); close(6); }
       
   808 ++#ifdef EXTERNAL_TODO
       
   809 ++int pi7[2];
       
   810 ++int pi8[2];
       
   811 ++int pi9[2];
       
   812 ++int pi10[2];
       
   813 ++#endif
       
   814 ++
       
   815 ++void close23456() { 
       
   816 ++  close(2); close(3); close(4); close(5); close(6); 
       
   817 ++#ifdef EXTERNAL_TODO
       
   818 ++  close(7); close(8);
       
   819 ++#endif
       
   820 ++}
       
   821 + 
       
   822 + void closepipes() {
       
   823 +   close(pi1[0]); close(pi1[1]); close(pi2[0]); close(pi2[1]);
       
   824 +   close(pi3[0]); close(pi3[1]); close(pi4[0]); close(pi4[1]);
       
   825 +   close(pi5[0]); close(pi5[1]); close(pi6[0]); close(pi6[1]);
       
   826 ++#ifdef EXTERNAL_TODO
       
   827 ++  close(pi7[0]); close(pi7[1]); close(pi8[0]); close(pi8[1]);
       
   828 ++	close(pi9[0]); close(pi9[1]); close(pi10[0]); close(pi10[1]);
       
   829 ++#endif
       
   830 + }
       
   831 + 
       
   832 + void main(argc,argv)
       
   833 +@@ -40,6 +58,10 @@
       
   834 +   if (fd_copy(4,0) == -1) die();
       
   835 +   if (fd_copy(5,0) == -1) die();
       
   836 +   if (fd_copy(6,0) == -1) die();
       
   837 ++#ifdef EXTERNAL_TODO
       
   838 ++  if (fd_copy(7,0) == -1) die();
       
   839 ++  if (fd_copy(8,0) == -1) die();
       
   840 ++#endif
       
   841 + 
       
   842 +   if (argv[1]) {
       
   843 +     qlargs[1] = argv[1];
       
   844 +@@ -70,6 +92,12 @@
       
   845 +   if (pipe(pi4) == -1) die();
       
   846 +   if (pipe(pi5) == -1) die();
       
   847 +   if (pipe(pi6) == -1) die();
       
   848 ++#ifdef EXTERNAL_TODO
       
   849 ++  if (pipe(pi7) == -1) die();
       
   850 ++  if (pipe(pi8) == -1) die();
       
   851 ++  if (pipe(pi9) == -1) die();
       
   852 ++  if (pipe(pi10) == -1) die();
       
   853 ++#endif
       
   854 +  
       
   855 +   switch(fork()) {
       
   856 +     case -1: die();
       
   857 +@@ -105,6 +133,34 @@
       
   858 +       execvp(*qcargs,qcargs);
       
   859 +       die();
       
   860 +   }
       
   861 ++
       
   862 ++#ifdef EXTERNAL_TODO
       
   863 ++  switch(fork()) {
       
   864 ++    case -1: die();
       
   865 ++    case 0:
       
   866 ++      if (prot_uid(auto_uids) == -1) die();
       
   867 ++      if (fd_copy(0,pi7[0]) == -1) die();
       
   868 ++      if (fd_copy(1,pi8[1]) == -1) die();
       
   869 ++      close23456();
       
   870 ++      if (fd_copy(2,pi9[1]) == -1) die();
       
   871 ++      if (fd_copy(3,pi10[0]) == -1) die();
       
   872 ++      closepipes();
       
   873 ++      execvp(*qtargs,qtargs);
       
   874 ++      die();
       
   875 ++  }
       
   876 ++
       
   877 ++  switch(fork()) {
       
   878 ++    case -1: die();
       
   879 ++    case 0:
       
   880 ++      if (prot_uid(auto_uidq) == -1) die();
       
   881 ++      if (fd_copy(0,pi9[0]) == -1) die();
       
   882 ++      if (fd_copy(1,pi10[1]) == -1) die();
       
   883 ++      close23456();
       
   884 ++      closepipes();
       
   885 ++      execvp(*qcargs,qcargs);
       
   886 ++      die();
       
   887 ++  }
       
   888 ++#endif
       
   889 +  
       
   890 +   if (prot_uid(auto_uids) == -1) die();
       
   891 +   if (fd_copy(0,1) == -1) die();
       
   892 +@@ -114,6 +170,10 @@
       
   893 +   if (fd_copy(4,pi4[0]) == -1) die();
       
   894 +   if (fd_copy(5,pi5[1]) == -1) die();
       
   895 +   if (fd_copy(6,pi6[0]) == -1) die();
       
   896 ++#ifdef EXTERNAL_TODO
       
   897 ++  if (fd_copy(7,pi7[1]) == -1) die();
       
   898 ++  if (fd_copy(8,pi8[0]) == -1) die();
       
   899 ++#endif
       
   900 +   closepipes();
       
   901 +   execvp(*qsargs,qsargs);
       
   902 +   die();
       
   903 +diff -uN qmail-1.03/qmail-todo.c qmail-exttodo/qmail-todo.c
       
   904 +--- qmail-1.03/qmail-todo.c	Thu Jan  1 01:00:00 1970
       
   905 ++++ qmail-exttodo/qmail-todo.c	Sun Jan  5 22:16:34 2003
       
   906 +@@ -0,0 +1,688 @@
       
   907 ++#include <sys/types.h>
       
   908 ++#include <sys/stat.h>
       
   909 ++#include "alloc.h"
       
   910 ++#include "auto_qmail.h"
       
   911 ++#include "byte.h"
       
   912 ++#include "constmap.h"
       
   913 ++#include "control.h"
       
   914 ++#include "direntry.h"
       
   915 ++#include "error.h"
       
   916 ++#include "exit.h"
       
   917 ++#include "fmt.h"
       
   918 ++#include "fmtqfn.h"
       
   919 ++#include "getln.h"
       
   920 ++#include "open.h"
       
   921 ++#include "ndelay.h"
       
   922 ++#include "now.h"
       
   923 ++#include "readsubdir.h"
       
   924 ++#include "readwrite.h"
       
   925 ++#include "scan.h"
       
   926 ++#include "select.h"
       
   927 ++#include "str.h"
       
   928 ++#include "stralloc.h"
       
   929 ++#include "substdio.h"
       
   930 ++#include "trigger.h"
       
   931 ++
       
   932 ++/* critical timing feature #1: if not triggered, do not busy-loop */
       
   933 ++/* critical timing feature #2: if triggered, respond within fixed time */
       
   934 ++/* important timing feature: when triggered, respond instantly */
       
   935 ++#define SLEEP_TODO 1500 /* check todo/ every 25 minutes in any case */
       
   936 ++#define SLEEP_FUZZ 1 /* slop a bit on sleeps to avoid zeno effect */
       
   937 ++#define SLEEP_FOREVER 86400 /* absolute maximum time spent in select() */
       
   938 ++#define SLEEP_SYSFAIL 123
       
   939 ++
       
   940 ++stralloc percenthack = {0};
       
   941 ++struct constmap mappercenthack;
       
   942 ++stralloc locals = {0};
       
   943 ++struct constmap maplocals;
       
   944 ++stralloc vdoms = {0};
       
   945 ++struct constmap mapvdoms;
       
   946 ++stralloc envnoathost = {0};
       
   947 ++
       
   948 ++char strnum[FMT_ULONG];
       
   949 ++
       
   950 ++/* XXX not good, if qmail-send.c changes this has to be updated */
       
   951 ++#define CHANNELS 2
       
   952 ++char *chanaddr[CHANNELS] = { "local/", "remote/" };
       
   953 ++
       
   954 ++datetime_sec recent;
       
   955 ++
       
   956 ++void log1(char *x);
       
   957 ++void log3(char* x, char* y, char* z);
       
   958 ++
       
   959 ++int flagstopasap = 0;
       
   960 ++void sigterm(void)
       
   961 ++{
       
   962 ++  if (flagstopasap == 0)
       
   963 ++    log1("status: qmail-todo stop processing asap\n");
       
   964 ++  flagstopasap = 1;
       
   965 ++}
       
   966 ++
       
   967 ++int flagreadasap = 0; void sighup(void) { flagreadasap = 1; }
       
   968 ++int flagsendalive = 1; void senddied(void) { flagsendalive = 0; }
       
   969 ++
       
   970 ++void nomem() { log1("alert: out of memory, sleeping...\n"); sleep(10); }
       
   971 ++void pausedir(dir) char *dir;
       
   972 ++{ log3("alert: unable to opendir ",dir,", sleeping...\n"); sleep(10); }
       
   973 ++
       
   974 ++void cleandied()
       
   975 ++{ 
       
   976 ++  log1("alert: qmail-todo: oh no! lost qmail-clean connection! dying...\n");
       
   977 ++  flagstopasap = 1;
       
   978 ++}
       
   979 ++
       
   980 ++
       
   981 ++/* this file is not so long ------------------------------------- FILENAMES */
       
   982 ++
       
   983 ++stralloc fn = {0};
       
   984 ++
       
   985 ++void fnmake_init(void)
       
   986 ++{
       
   987 ++ while (!stralloc_ready(&fn,FMTQFN)) nomem();
       
   988 ++}
       
   989 ++
       
   990 ++void fnmake_info(unsigned long id) { fn.len = fmtqfn(fn.s,"info/",id,1); }
       
   991 ++void fnmake_todo(unsigned long id) { fn.len = fmtqfn(fn.s,"todo/",id,0); }
       
   992 ++void fnmake_mess(unsigned long id) { fn.len = fmtqfn(fn.s,"mess/",id,1); }
       
   993 ++void fnmake_chanaddr(unsigned long id, int c)
       
   994 ++{ fn.len = fmtqfn(fn.s,chanaddr[c],id,1); }
       
   995 ++
       
   996 ++
       
   997 ++/* this file is not so long ------------------------------------- REWRITING */
       
   998 ++
       
   999 ++stralloc rwline = {0};
       
  1000 ++
       
  1001 ++/* 1 if by land, 2 if by sea, 0 if out of memory. not allowed to barf. */
       
  1002 ++/* may trash recip. must set up rwline, between a T and a \0. */
       
  1003 ++int rewrite(char *recip)
       
  1004 ++{
       
  1005 ++  int i;
       
  1006 ++  int j;
       
  1007 ++  char *x;
       
  1008 ++  static stralloc addr = {0};
       
  1009 ++  int at;
       
  1010 ++
       
  1011 ++  if (!stralloc_copys(&rwline,"T")) return 0;
       
  1012 ++  if (!stralloc_copys(&addr,recip)) return 0;
       
  1013 ++
       
  1014 ++  i = byte_rchr(addr.s,addr.len,'@');
       
  1015 ++  if (i == addr.len) {
       
  1016 ++    if (!stralloc_cats(&addr,"@")) return 0;
       
  1017 ++    if (!stralloc_cat(&addr,&envnoathost)) return 0;
       
  1018 ++  }
       
  1019 ++
       
  1020 ++  while (constmap(&mappercenthack,addr.s + i + 1,addr.len - i - 1)) {
       
  1021 ++    j = byte_rchr(addr.s,i,'%');
       
  1022 ++    if (j == i) break;
       
  1023 ++    addr.len = i;
       
  1024 ++    i = j;
       
  1025 ++    addr.s[i] = '@';
       
  1026 ++  }
       
  1027 ++
       
  1028 ++  at = byte_rchr(addr.s,addr.len,'@');
       
  1029 ++
       
  1030 ++  if (constmap(&maplocals,addr.s + at + 1,addr.len - at - 1)) {
       
  1031 ++    if (!stralloc_cat(&rwline,&addr)) return 0;
       
  1032 ++    if (!stralloc_0(&rwline)) return 0;
       
  1033 ++    return 1;
       
  1034 ++  }
       
  1035 ++
       
  1036 ++  for (i = 0;i <= addr.len;++i)
       
  1037 ++    if (!i || (i == at + 1) || (i == addr.len) || ((i > at) && (addr.s[i] == '.')))
       
  1038 ++      if (x = constmap(&mapvdoms,addr.s + i,addr.len - i)) {
       
  1039 ++        if (!*x) break;
       
  1040 ++        if (!stralloc_cats(&rwline,x)) return 0;
       
  1041 ++        if (!stralloc_cats(&rwline,"-")) return 0;
       
  1042 ++        if (!stralloc_cat(&rwline,&addr)) return 0;
       
  1043 ++        if (!stralloc_0(&rwline)) return 0;
       
  1044 ++        return 1;
       
  1045 ++      }
       
  1046 ++ 
       
  1047 ++  if (!stralloc_cat(&rwline,&addr)) return 0;
       
  1048 ++  if (!stralloc_0(&rwline)) return 0;
       
  1049 ++  return 2;
       
  1050 ++}
       
  1051 ++
       
  1052 ++/* this file is not so long --------------------------------- COMMUNICATION */
       
  1053 ++
       
  1054 ++substdio sstoqc; char sstoqcbuf[1024];
       
  1055 ++substdio ssfromqc; char ssfromqcbuf[1024];
       
  1056 ++stralloc comm_buf = {0};
       
  1057 ++int comm_pos;
       
  1058 ++int fdout = -1;
       
  1059 ++int fdin = -1;
       
  1060 ++
       
  1061 ++void comm_init(void)
       
  1062 ++{
       
  1063 ++ substdio_fdbuf(&sstoqc,write,2,sstoqcbuf,sizeof(sstoqcbuf));
       
  1064 ++ substdio_fdbuf(&ssfromqc,read,3,ssfromqcbuf,sizeof(ssfromqcbuf));
       
  1065 ++
       
  1066 ++ fdout = 1; /* stdout */
       
  1067 ++ fdin = 0;  /* stdin */
       
  1068 ++ if (ndelay_on(fdout) == -1)
       
  1069 ++ /* this is so stupid: NDELAY semantics should be default on write */
       
  1070 ++   senddied(); /* drastic, but better than risking deadlock */
       
  1071 ++
       
  1072 ++ while (!stralloc_ready(&comm_buf,1024)) nomem();
       
  1073 ++}
       
  1074 ++
       
  1075 ++int comm_canwrite(void)
       
  1076 ++{
       
  1077 ++ /* XXX: could allow a bigger buffer; say 10 recipients */
       
  1078 ++ /* XXX: returns true if there is something in the buffer */
       
  1079 ++ if (!flagsendalive) return 0;
       
  1080 ++ if (comm_buf.s && comm_buf.len) return 1;
       
  1081 ++ return 0;
       
  1082 ++}
       
  1083 ++
       
  1084 ++void log1(char* x)
       
  1085 ++{
       
  1086 ++  int pos;
       
  1087 ++  
       
  1088 ++  pos = comm_buf.len;
       
  1089 ++  if (!stralloc_cats(&comm_buf,"L")) goto fail;
       
  1090 ++  if (!stralloc_cats(&comm_buf,x)) goto fail;
       
  1091 ++  if (!stralloc_0(&comm_buf)) goto fail;
       
  1092 ++  return;
       
  1093 ++  
       
  1094 ++fail:
       
  1095 ++  /* either all or nothing */
       
  1096 ++  comm_buf.len = pos;
       
  1097 ++}
       
  1098 ++
       
  1099 ++void log3(char* x, char *y, char *z)
       
  1100 ++{
       
  1101 ++  int pos;
       
  1102 ++  
       
  1103 ++  pos = comm_buf.len;
       
  1104 ++  if (!stralloc_cats(&comm_buf,"L")) goto fail;
       
  1105 ++  if (!stralloc_cats(&comm_buf,x)) goto fail;
       
  1106 ++  if (!stralloc_cats(&comm_buf,y)) goto fail;
       
  1107 ++  if (!stralloc_cats(&comm_buf,z)) goto fail;
       
  1108 ++  if (!stralloc_0(&comm_buf)) goto fail;
       
  1109 ++  return;
       
  1110 ++  
       
  1111 ++fail:
       
  1112 ++  /* either all or nothing */
       
  1113 ++  comm_buf.len = pos;
       
  1114 ++}
       
  1115 ++
       
  1116 ++void comm_write(unsigned long id, int local, int remote)
       
  1117 ++{
       
  1118 ++  int pos;
       
  1119 ++  char *s;
       
  1120 ++  
       
  1121 ++  if(local && remote) s="B";
       
  1122 ++  else if(local) s="L";
       
  1123 ++  else if(remote) s="R";
       
  1124 ++  else s="X";
       
  1125 ++  
       
  1126 ++  pos = comm_buf.len;
       
  1127 ++  strnum[fmt_ulong(strnum,id)] = 0;
       
  1128 ++  if (!stralloc_cats(&comm_buf,"D")) goto fail;
       
  1129 ++  if (!stralloc_cats(&comm_buf,s)) goto fail;
       
  1130 ++  if (!stralloc_cats(&comm_buf,strnum)) goto fail;
       
  1131 ++  if (!stralloc_0(&comm_buf)) goto fail;
       
  1132 ++  return;
       
  1133 ++  
       
  1134 ++fail:
       
  1135 ++  /* either all or nothing */
       
  1136 ++  comm_buf.len = pos;
       
  1137 ++}
       
  1138 ++
       
  1139 ++static int issafe(char ch)
       
  1140 ++{
       
  1141 ++ if (ch == '%') return 0; /* general principle: allman's code is crap */
       
  1142 ++ if (ch < 33) return 0;
       
  1143 ++ if (ch > 126) return 0;
       
  1144 ++ return 1;
       
  1145 ++}
       
  1146 ++
       
  1147 ++void comm_info(unsigned long id, unsigned long size, char* from, unsigned long pid, unsigned long uid)
       
  1148 ++{
       
  1149 ++  int pos;
       
  1150 ++  int i;
       
  1151 ++  
       
  1152 ++  pos = comm_buf.len;
       
  1153 ++  if (!stralloc_cats(&comm_buf,"Linfo msg ")) goto fail;
       
  1154 ++  strnum[fmt_ulong(strnum,id)] = 0;
       
  1155 ++  if (!stralloc_cats(&comm_buf,strnum)) goto fail;
       
  1156 ++  if (!stralloc_cats(&comm_buf,": bytes ")) goto fail;
       
  1157 ++  strnum[fmt_ulong(strnum,size)] = 0;
       
  1158 ++  if (!stralloc_cats(&comm_buf,strnum)) goto fail;
       
  1159 ++  if (!stralloc_cats(&comm_buf," from <")) goto fail;
       
  1160 ++  i = comm_buf.len;
       
  1161 ++  if (!stralloc_cats(&comm_buf,from)) goto fail;
       
  1162 ++  for (;i < comm_buf.len;++i)
       
  1163 ++    if (comm_buf.s[i] == '\n')
       
  1164 ++      comm_buf.s[i] = '/';
       
  1165 ++    else
       
  1166 ++      if (!issafe(comm_buf.s[i]))
       
  1167 ++	comm_buf.s[i] = '_';
       
  1168 ++  if (!stralloc_cats(&comm_buf,"> qp ")) goto fail;
       
  1169 ++  strnum[fmt_ulong(strnum,pid)] = 0;
       
  1170 ++  if (!stralloc_cats(&comm_buf,strnum)) goto fail;
       
  1171 ++  if (!stralloc_cats(&comm_buf," uid ")) goto fail;
       
  1172 ++  strnum[fmt_ulong(strnum,uid)] = 0;
       
  1173 ++  if (!stralloc_cats(&comm_buf,strnum)) goto fail;
       
  1174 ++  if (!stralloc_cats(&comm_buf,"\n")) goto fail;
       
  1175 ++  if (!stralloc_0(&comm_buf)) goto fail;
       
  1176 ++  return;
       
  1177 ++  
       
  1178 ++fail:
       
  1179 ++  /* either all or nothing */
       
  1180 ++  comm_buf.len = pos;
       
  1181 ++}
       
  1182 ++
       
  1183 ++void comm_exit(void)
       
  1184 ++{
       
  1185 ++  int w;
       
  1186 ++  
       
  1187 ++  /* if it fails exit, we have already stoped */
       
  1188 ++  if (!stralloc_cats(&comm_buf,"X")) _exit(1);
       
  1189 ++  if (!stralloc_0(&comm_buf)) _exit(1);
       
  1190 ++}
       
  1191 ++
       
  1192 ++void comm_selprep(int *nfds, fd_set *wfds, fd_set *rfds)
       
  1193 ++{
       
  1194 ++  if (flagsendalive) {
       
  1195 ++    if (flagstopasap && comm_canwrite() == 0)
       
  1196 ++      comm_exit();
       
  1197 ++    if (comm_canwrite()) {
       
  1198 ++      FD_SET(fdout,wfds);
       
  1199 ++      if (*nfds <= fdout)
       
  1200 ++	*nfds = fdout + 1;
       
  1201 ++    }
       
  1202 ++    FD_SET(fdin,rfds);
       
  1203 ++    if (*nfds <= fdin)
       
  1204 ++      *nfds = fdin + 1;
       
  1205 ++  }
       
  1206 ++}
       
  1207 ++
       
  1208 ++void comm_do(fd_set *wfds, fd_set *rfds)
       
  1209 ++{
       
  1210 ++  /* first write then read */
       
  1211 ++  if (flagsendalive)
       
  1212 ++    if (comm_canwrite())
       
  1213 ++      if (FD_ISSET(fdout,wfds)) {
       
  1214 ++	int w;
       
  1215 ++	int len;
       
  1216 ++	len = comm_buf.len;
       
  1217 ++	w = write(fdout,comm_buf.s + comm_pos,len - comm_pos);
       
  1218 ++	if (w <= 0) {
       
  1219 ++	  if ((w == -1) && (errno == error_pipe))
       
  1220 ++	    senddied();
       
  1221 ++	} else {
       
  1222 ++	  comm_pos += w;
       
  1223 ++	  if (comm_pos == len) {
       
  1224 ++	    comm_buf.len = 0;
       
  1225 ++	    comm_pos = 0;
       
  1226 ++	  }
       
  1227 ++	}
       
  1228 ++      }
       
  1229 ++  if (flagsendalive)
       
  1230 ++    if (FD_ISSET(fdin,rfds)) {
       
  1231 ++      /* there are only two messages 'H' and 'X' */
       
  1232 ++      char c;
       
  1233 ++      int r;
       
  1234 ++      r = read(fdin, &c, 1);
       
  1235 ++      if (r <= 0) {
       
  1236 ++	if ((r == -1) && (errno != error_intr))
       
  1237 ++	  senddied();
       
  1238 ++      } else {
       
  1239 ++	switch(c) {
       
  1240 ++	  case 'H':
       
  1241 ++	    sighup();
       
  1242 ++	    break;
       
  1243 ++	  case 'X':
       
  1244 ++	    sigterm();
       
  1245 ++	    break;
       
  1246 ++	  default:
       
  1247 ++	    log1("warning: qmail-todo: qmail-send speaks an obscure dialect\n");
       
  1248 ++	    break;
       
  1249 ++	}
       
  1250 ++      }
       
  1251 ++    }
       
  1252 ++}
       
  1253 ++
       
  1254 ++/* this file is not so long ------------------------------------------ TODO */
       
  1255 ++
       
  1256 ++datetime_sec nexttodorun;
       
  1257 ++DIR *tododir; /* if 0, have to opendir again */
       
  1258 ++stralloc todoline = {0};
       
  1259 ++char todobuf[SUBSTDIO_INSIZE];
       
  1260 ++char todobufinfo[512];
       
  1261 ++char todobufchan[CHANNELS][1024];
       
  1262 ++
       
  1263 ++void todo_init(void)
       
  1264 ++{
       
  1265 ++ tododir = 0;
       
  1266 ++ nexttodorun = now();
       
  1267 ++ trigger_set();
       
  1268 ++}
       
  1269 ++
       
  1270 ++void todo_selprep(int *nfds, fd_set *rfds, datetime_sec *wakeup)
       
  1271 ++{
       
  1272 ++ if (flagstopasap) return;
       
  1273 ++ trigger_selprep(nfds,rfds);
       
  1274 ++ if (tododir) *wakeup = 0;
       
  1275 ++ if (*wakeup > nexttodorun) *wakeup = nexttodorun;
       
  1276 ++}
       
  1277 ++
       
  1278 ++void todo_do(fd_set *rfds)
       
  1279 ++{
       
  1280 ++ struct stat st;
       
  1281 ++ substdio ss; int fd;
       
  1282 ++ substdio ssinfo; int fdinfo;
       
  1283 ++ substdio sschan[CHANNELS];
       
  1284 ++ int fdchan[CHANNELS];
       
  1285 ++ int flagchan[CHANNELS];
       
  1286 ++ char ch;
       
  1287 ++ int match;
       
  1288 ++ unsigned long id;
       
  1289 ++ unsigned int len;
       
  1290 ++ direntry *d;
       
  1291 ++ int c;
       
  1292 ++ unsigned long uid;
       
  1293 ++ unsigned long pid;
       
  1294 ++
       
  1295 ++ fd = -1;
       
  1296 ++ fdinfo = -1;
       
  1297 ++ for (c = 0;c < CHANNELS;++c) fdchan[c] = -1;
       
  1298 ++
       
  1299 ++ if (flagstopasap) return;
       
  1300 ++
       
  1301 ++ if (!tododir)
       
  1302 ++  {
       
  1303 ++   if (!trigger_pulled(rfds))
       
  1304 ++     if (recent < nexttodorun)
       
  1305 ++       return;
       
  1306 ++   trigger_set();
       
  1307 ++   tododir = opendir("todo");
       
  1308 ++   if (!tododir)
       
  1309 ++    {
       
  1310 ++     pausedir("todo");
       
  1311 ++     return;
       
  1312 ++    }
       
  1313 ++   nexttodorun = recent + SLEEP_TODO;
       
  1314 ++  }
       
  1315 ++
       
  1316 ++ d = readdir(tododir);
       
  1317 ++ if (!d)
       
  1318 ++  {
       
  1319 ++   closedir(tododir);
       
  1320 ++   tododir = 0;
       
  1321 ++   return;
       
  1322 ++  }
       
  1323 ++ if (str_equal(d->d_name,".")) return;
       
  1324 ++ if (str_equal(d->d_name,"..")) return;
       
  1325 ++ len = scan_ulong(d->d_name,&id);
       
  1326 ++ if (!len || d->d_name[len]) return;
       
  1327 ++
       
  1328 ++ fnmake_todo(id);
       
  1329 ++
       
  1330 ++ fd = open_read(fn.s);
       
  1331 ++ if (fd == -1) { log3("warning: qmail-todo: unable to open ",fn.s,"\n"); return; }
       
  1332 ++
       
  1333 ++ fnmake_mess(id);
       
  1334 ++ /* just for the statistics */
       
  1335 ++ if (stat(fn.s,&st) == -1)
       
  1336 ++  { log3("warning: qmail-todo: unable to stat ",fn.s,"\n"); goto fail; }
       
  1337 ++
       
  1338 ++ for (c = 0;c < CHANNELS;++c)
       
  1339 ++  {
       
  1340 ++   fnmake_chanaddr(id,c);
       
  1341 ++   if (unlink(fn.s) == -1) if (errno != error_noent)
       
  1342 ++    { log3("warning: qmail-todo: unable to unlink ",fn.s,"\n"); goto fail; }
       
  1343 ++  }
       
  1344 ++
       
  1345 ++ fnmake_info(id);
       
  1346 ++ if (unlink(fn.s) == -1) if (errno != error_noent)
       
  1347 ++  { log3("warning: qmail-todo: unable to unlink ",fn.s,"\n"); goto fail; }
       
  1348 ++
       
  1349 ++ fdinfo = open_excl(fn.s);
       
  1350 ++ if (fdinfo == -1)
       
  1351 ++  { log3("warning: qmail-todo: unable to create ",fn.s,"\n"); goto fail; }
       
  1352 ++
       
  1353 ++ strnum[fmt_ulong(strnum,id)] = 0;
       
  1354 ++ log3("new msg ",strnum,"\n");
       
  1355 ++
       
  1356 ++ for (c = 0;c < CHANNELS;++c) flagchan[c] = 0;
       
  1357 ++
       
  1358 ++ substdio_fdbuf(&ss,read,fd,todobuf,sizeof(todobuf));
       
  1359 ++ substdio_fdbuf(&ssinfo,write,fdinfo,todobufinfo,sizeof(todobufinfo));
       
  1360 ++
       
  1361 ++ uid = 0;
       
  1362 ++ pid = 0;
       
  1363 ++
       
  1364 ++ for (;;)
       
  1365 ++  {
       
  1366 ++   if (getln(&ss,&todoline,&match,'\0') == -1)
       
  1367 ++    {
       
  1368 ++     /* perhaps we're out of memory, perhaps an I/O error */
       
  1369 ++     fnmake_todo(id);
       
  1370 ++     log3("warning: qmail-todo: trouble reading ",fn.s,"\n"); goto fail;
       
  1371 ++    }
       
  1372 ++   if (!match) break;
       
  1373 ++
       
  1374 ++   switch(todoline.s[0])
       
  1375 ++    {
       
  1376 ++     case 'u':
       
  1377 ++       scan_ulong(todoline.s + 1,&uid);
       
  1378 ++       break;
       
  1379 ++     case 'p':
       
  1380 ++       scan_ulong(todoline.s + 1,&pid);
       
  1381 ++       break;
       
  1382 ++     case 'F':
       
  1383 ++       if (substdio_putflush(&ssinfo,todoline.s,todoline.len) == -1)
       
  1384 ++	{
       
  1385 ++	 fnmake_info(id);
       
  1386 ++         log3("warning: qmail-todo: trouble writing to ",fn.s,"\n"); goto fail;
       
  1387 ++	}
       
  1388 ++	comm_info(id, (unsigned long) st.st_size, todoline.s + 1, pid, uid);
       
  1389 ++       break;
       
  1390 ++     case 'T':
       
  1391 ++       switch(rewrite(todoline.s + 1))
       
  1392 ++	{
       
  1393 ++	 case 0: nomem(); goto fail;
       
  1394 ++	 case 2: c = 1; break;
       
  1395 ++	 default: c = 0; break;
       
  1396 ++        }
       
  1397 ++       if (fdchan[c] == -1)
       
  1398 ++	{
       
  1399 ++	 fnmake_chanaddr(id,c);
       
  1400 ++	 fdchan[c] = open_excl(fn.s);
       
  1401 ++	 if (fdchan[c] == -1)
       
  1402 ++          { log3("warning: qmail-todo: unable to create ",fn.s,"\n"); goto fail; }
       
  1403 ++	 substdio_fdbuf(&sschan[c]
       
  1404 ++	   ,write,fdchan[c],todobufchan[c],sizeof(todobufchan[c]));
       
  1405 ++	 flagchan[c] = 1;
       
  1406 ++	}
       
  1407 ++       if (substdio_bput(&sschan[c],rwline.s,rwline.len) == -1)
       
  1408 ++        {
       
  1409 ++	 fnmake_chanaddr(id,c);
       
  1410 ++         log3("warning: qmail-todo: trouble writing to ",fn.s,"\n"); goto fail;
       
  1411 ++        }
       
  1412 ++       break;
       
  1413 ++     default:
       
  1414 ++       fnmake_todo(id);
       
  1415 ++       log3("warning: qmail-todo: unknown record type in ",fn.s,"\n"); goto fail;
       
  1416 ++    }
       
  1417 ++  }
       
  1418 ++
       
  1419 ++ close(fd); fd = -1;
       
  1420 ++
       
  1421 ++ fnmake_info(id);
       
  1422 ++ if (substdio_flush(&ssinfo) == -1)
       
  1423 ++  { log3("warning: qmail-todo: trouble writing to ",fn.s,"\n"); goto fail; }
       
  1424 ++ if (fsync(fdinfo) == -1)
       
  1425 ++  { log3("warning: qmail-todo: trouble fsyncing ",fn.s,"\n"); goto fail; }
       
  1426 ++ close(fdinfo); fdinfo = -1;
       
  1427 ++
       
  1428 ++ for (c = 0;c < CHANNELS;++c)
       
  1429 ++   if (fdchan[c] != -1)
       
  1430 ++    {
       
  1431 ++     fnmake_chanaddr(id,c);
       
  1432 ++     if (substdio_flush(&sschan[c]) == -1)
       
  1433 ++      { log3("warning: qmail-todo: trouble writing to ",fn.s,"\n"); goto fail; }
       
  1434 ++     if (fsync(fdchan[c]) == -1)
       
  1435 ++      { log3("warning: qmail-todo: trouble fsyncing ",fn.s,"\n"); goto fail; }
       
  1436 ++     close(fdchan[c]); fdchan[c] = -1;
       
  1437 ++    }
       
  1438 ++
       
  1439 ++ fnmake_todo(id);
       
  1440 ++ if (substdio_putflush(&sstoqc,fn.s,fn.len) == -1) { cleandied(); return; }
       
  1441 ++ if (substdio_get(&ssfromqc,&ch,1) != 1) { cleandied(); return; }
       
  1442 ++ if (ch != '+')
       
  1443 ++  {
       
  1444 ++   log3("warning: qmail-clean unable to clean up ",fn.s,"\n");
       
  1445 ++   return;
       
  1446 ++  }
       
  1447 ++
       
  1448 ++ comm_write(id, flagchan[0], flagchan[1]);
       
  1449 ++ 
       
  1450 ++ return;
       
  1451 ++ 
       
  1452 ++ fail:
       
  1453 ++ if (fd != -1) close(fd);
       
  1454 ++ if (fdinfo != -1) close(fdinfo);
       
  1455 ++ for (c = 0;c < CHANNELS;++c)
       
  1456 ++   if (fdchan[c] != -1) close(fdchan[c]);
       
  1457 ++}
       
  1458 ++
       
  1459 ++/* this file is too long ---------------------------------------------- MAIN */
       
  1460 ++
       
  1461 ++int getcontrols(void)
       
  1462 ++{
       
  1463 ++ if (control_init() == -1) return 0;
       
  1464 ++ if (control_rldef(&envnoathost,"control/envnoathost",1,"envnoathost") != 1) return 0;
       
  1465 ++ if (control_readfile(&locals,"control/locals",1) != 1) return 0;
       
  1466 ++ if (!constmap_init(&maplocals,locals.s,locals.len,0)) return 0;
       
  1467 ++ switch(control_readfile(&percenthack,"control/percenthack",0))
       
  1468 ++  {
       
  1469 ++   case -1: return 0;
       
  1470 ++   case 0: if (!constmap_init(&mappercenthack,"",0,0)) return 0; break;
       
  1471 ++   case 1: if (!constmap_init(&mappercenthack,percenthack.s,percenthack.len,0)) return 0; break;
       
  1472 ++  }
       
  1473 ++ switch(control_readfile(&vdoms,"control/virtualdomains",0))
       
  1474 ++  {
       
  1475 ++   case -1: return 0;
       
  1476 ++   case 0: if (!constmap_init(&mapvdoms,"",0,1)) return 0; break;
       
  1477 ++   case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) return 0; break;
       
  1478 ++  }
       
  1479 ++ return 1;
       
  1480 ++}
       
  1481 ++
       
  1482 ++stralloc newlocals = {0};
       
  1483 ++stralloc newvdoms = {0};
       
  1484 ++
       
  1485 ++void regetcontrols(void)
       
  1486 ++{
       
  1487 ++ int r;
       
  1488 ++
       
  1489 ++ if (control_readfile(&newlocals,"control/locals",1) != 1)
       
  1490 ++  { log1("alert: qmail-todo: unable to reread control/locals\n"); return; }
       
  1491 ++ r = control_readfile(&newvdoms,"control/virtualdomains",0);
       
  1492 ++ if (r == -1)
       
  1493 ++  { log1("alert: qmail-todo: unable to reread control/virtualdomains\n"); return; }
       
  1494 ++
       
  1495 ++ constmap_free(&maplocals);
       
  1496 ++ constmap_free(&mapvdoms);
       
  1497 ++
       
  1498 ++ while (!stralloc_copy(&locals,&newlocals)) nomem();
       
  1499 ++ while (!constmap_init(&maplocals,locals.s,locals.len,0)) nomem();
       
  1500 ++
       
  1501 ++ if (r)
       
  1502 ++  {
       
  1503 ++   while (!stralloc_copy(&vdoms,&newvdoms)) nomem();
       
  1504 ++   while (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) nomem();
       
  1505 ++  }
       
  1506 ++ else
       
  1507 ++   while (!constmap_init(&mapvdoms,"",0,1)) nomem();
       
  1508 ++}
       
  1509 ++
       
  1510 ++void reread(void)
       
  1511 ++{
       
  1512 ++ if (chdir(auto_qmail) == -1)
       
  1513 ++  {
       
  1514 ++   log1("alert: qmail-todo: unable to reread controls: unable to switch to home directory\n");
       
  1515 ++   return;
       
  1516 ++  }
       
  1517 ++ regetcontrols();
       
  1518 ++ while (chdir("queue") == -1)
       
  1519 ++  {
       
  1520 ++   log1("alert: qmail-todo: unable to switch back to queue directory; HELP! sleeping...\n");
       
  1521 ++   sleep(10);
       
  1522 ++  }
       
  1523 ++}
       
  1524 ++
       
  1525 ++void main()
       
  1526 ++{
       
  1527 ++ datetime_sec wakeup;
       
  1528 ++ fd_set rfds;
       
  1529 ++ fd_set wfds;
       
  1530 ++ int nfds;
       
  1531 ++ struct timeval tv;
       
  1532 ++ int r;
       
  1533 ++ char c;
       
  1534 ++
       
  1535 ++ if (chdir(auto_qmail) == -1)
       
  1536 ++  { log1("alert: qmail-todo: cannot start: unable to switch to home directory\n"); _exit(111); }
       
  1537 ++ if (!getcontrols())
       
  1538 ++  { log1("alert: qmail-todo: cannot start: unable to read controls\n"); _exit(111); }
       
  1539 ++ if (chdir("queue") == -1)
       
  1540 ++  { log1("alert: qmail-todo: cannot start: unable to switch to queue directory\n"); _exit(111); }
       
  1541 ++ sig_pipeignore();
       
  1542 ++ umask(077);
       
  1543 ++
       
  1544 ++ fnmake_init();
       
  1545 ++
       
  1546 ++ todo_init();
       
  1547 ++ comm_init();
       
  1548 ++ 
       
  1549 ++ do {
       
  1550 ++   r = read(fdin, &c, 1);
       
  1551 ++   if ((r == -1) && (errno != error_intr))
       
  1552 ++     _exit(100); /* read failed probably qmail-send died */
       
  1553 ++ } while (r =! 1); /* we assume it is a 'S' */
       
  1554 ++ 
       
  1555 ++ for (;;)
       
  1556 ++  {
       
  1557 ++   recent = now();
       
  1558 ++
       
  1559 ++   if (flagreadasap) { flagreadasap = 0; reread(); }
       
  1560 ++   if (!flagsendalive) {
       
  1561 ++     /* qmail-send finaly exited, so do the same. */
       
  1562 ++     if (flagstopasap) _exit(0);
       
  1563 ++     /* qmail-send died. We can not log and we can not work therefor _exit(1). */
       
  1564 ++     _exit(1);
       
  1565 ++   }
       
  1566 ++
       
  1567 ++   wakeup = recent + SLEEP_FOREVER;
       
  1568 ++   FD_ZERO(&rfds);
       
  1569 ++   FD_ZERO(&wfds);
       
  1570 ++   nfds = 1;
       
  1571 ++
       
  1572 ++   todo_selprep(&nfds,&rfds,&wakeup);
       
  1573 ++   comm_selprep(&nfds,&wfds,&rfds);
       
  1574 ++
       
  1575 ++   if (wakeup <= recent) tv.tv_sec = 0;
       
  1576 ++   else tv.tv_sec = wakeup - recent + SLEEP_FUZZ;
       
  1577 ++   tv.tv_usec = 0;
       
  1578 ++
       
  1579 ++   if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) == -1)
       
  1580 ++     if (errno == error_intr)
       
  1581 ++       ;
       
  1582 ++     else
       
  1583 ++       log1("warning: qmail-todo: trouble in select\n");
       
  1584 ++   else
       
  1585 ++    {
       
  1586 ++     recent = now();
       
  1587 ++
       
  1588 ++     todo_do(&rfds);
       
  1589 ++     comm_do(&wfds, &rfds);
       
  1590 ++    }
       
  1591 ++  }
       
  1592 ++  /* NOTREACHED */
       
  1593 ++}
       
  1594 ++
       
  1595 diff --git a/source/dietlibc/diet-qmail/make_cert.sh b/source/dietlibc/diet-qmail/make_cert.sh
       
  1596 new file mode 100644
       
  1597 index 0000000..8b17499
       
  1598 --- /dev/null
       
  1599 +++ b/source/dietlibc/diet-qmail/make_cert.sh
       
  1600 @@ -0,0 +1,57 @@
       
  1601 +#!/bin/sh
       
  1602 +#
       
  1603 +# This script creates ssl certificates for
       
  1604 +# use with qmail.
       
  1605 +#
       
  1606 +
       
  1607 +cert() {
       
  1608 +if openssl req -new -x509 -nodes -out /var/qmail/control/servercert.pem \
       
  1609 +	-days 366 -keyout /var/qmail/control/servercert.pem; then
       
  1610 +  chmod 640 /var/qmail/control/servercert.pem
       
  1611 +  chown qmaild.qmail /var/qmail/control/servercert.pem
       
  1612 +  ln -s /var/qmail/control/servercert.pem /var/qmail/control/clientcert.pem
       
  1613 +  echo "==> Process done."
       
  1614 +else
       
  1615 +  echo "==> Certificate creation failed."
       
  1616 +  exit 1
       
  1617 +fi
       
  1618 +}
       
  1619 +
       
  1620 +cert_req() {
       
  1621 +if openssl req -new -nodes -out req.pem \
       
  1622 +	-keyout /var/qmail/control/servercert.pem; then
       
  1623 +  chmod 640 /var/qmail/control/servercert.pem
       
  1624 +  chown qmaild.qmail /var/qmail/control/servercert.pem
       
  1625 +  ln -s /var/qmail/control/servercert.pem /var/qmail/control/clientcert.pem
       
  1626 +  cat << EOF
       
  1627 +
       
  1628 +==> Process done.
       
  1629 +==> Send req.pem to your CA to obtain signed_req.pem, and do:
       
  1630 +==> cat signed_req.pem >> /var/qmail/control/servercert.pem
       
  1631 +
       
  1632 +EOF
       
  1633 +else 
       
  1634 +  echo "==> Certificate creation failed."
       
  1635 +  exit 1
       
  1636 +fi
       
  1637 +}
       
  1638 +
       
  1639 +case "$1" in 
       
  1640 +  -h|--help)
       
  1641 +    cat << EOF
       
  1642 +    
       
  1643 +This script creates SSL certificates to use with qmail.
       
  1644 +Options :
       
  1645 + -h --help    This help screen
       
  1646 + -r --req     Creates a certificate verification request to 
       
  1647 +              send to your CA.
       
  1648 +EOF
       
  1649 +  ;;
       
  1650 +  -r|--req)
       
  1651 +    cert_req
       
  1652 +  ;;
       
  1653 +  *)
       
  1654 +    cert
       
  1655 +  ;;
       
  1656 +esac
       
  1657 +
       
  1658 diff --git a/source/dietlibc/diet-qmail/pop3d_log_run b/source/dietlibc/diet-qmail/pop3d_log_run
       
  1659 new file mode 100644
       
  1660 index 0000000..941cde1
       
  1661 --- /dev/null
       
  1662 +++ b/source/dietlibc/diet-qmail/pop3d_log_run
       
  1663 @@ -0,0 +1,20 @@
       
  1664 +#!/bin/sh
       
  1665 +# 
       
  1666 +# Edit this file to match your setup.
       
  1667 +# NOTE: This file is automatically backed-up by pacman, 
       
  1668 +# during updates
       
  1669 +#
       
  1670 +
       
  1671 +# Log size rotate size.
       
  1672 +LOG_SIZE="1048576"
       
  1673 +
       
  1674 +# Number of logs to keep.
       
  1675 +LOGS="5"
       
  1676 +
       
  1677 +# Don't change from this point on, unless
       
  1678 +# you really know what you're doing :).
       
  1679 +
       
  1680 +exec /usr/bin/setuidgid qmaill \
       
  1681 +  /usr/bin/multilog t \
       
  1682 +  n${LOGS} s${LOG_SIZE} \
       
  1683 +  /var/log/qmail/pop3d 2>&1
       
  1684 diff --git a/source/dietlibc/diet-qmail/pop3d_run b/source/dietlibc/diet-qmail/pop3d_run
       
  1685 new file mode 100644
       
  1686 index 0000000..a61f0cd
       
  1687 --- /dev/null
       
  1688 +++ b/source/dietlibc/diet-qmail/pop3d_run
       
  1689 @@ -0,0 +1,33 @@
       
  1690 +#!/bin/sh
       
  1691 +#
       
  1692 +# Edit this file to match your setup.
       
  1693 +# NOTE: This file is automatically backed-up by pacman, 
       
  1694 +# during updates
       
  1695 +#
       
  1696 +
       
  1697 +# Password checking program (ie. checkpasswd, vpopmail).
       
  1698 +PASSPROG=""
       
  1699 +
       
  1700 +# FQDN as set in /var/qmail/control/me
       
  1701 +LOCAL=`head -1 /var/qmail/control/me` 
       
  1702 +
       
  1703 +# Maximum memory qmail-pop3d is allowed to use.
       
  1704 +MAX_MEM="2000000"
       
  1705 +
       
  1706 +# Maximum allowed concurrent connections.
       
  1707 +MAX_CON="30" 
       
  1708 +
       
  1709 +# Relay control.
       
  1710 +TCP_CDB="/etc/tcp.pop3.cdb"
       
  1711 +
       
  1712 +# Don't change from this point on, unless
       
  1713 +# you really know what you're doing :).
       
  1714 +POPUP="/var/qmail/bin/qmail-popup"
       
  1715 +POP3D="/var/qmail/bin/qmail-pop3d"
       
  1716 +PORT="110"
       
  1717 +
       
  1718 +exec /usr/bin/softlimit -m $MAX_MEM \
       
  1719 +  /usr/bin/tcpserver -H -l $LOCAL \
       
  1720 +  -v -x $TCP_CDB \
       
  1721 +  -c $MAX_CON -R 0 $PORT \
       
  1722 +  $POPUP $LOCAL $PASSPROG $POP3D Maildir 2>&1
       
  1723 diff --git a/source/dietlibc/diet-qmail/qmail-1.03.errno.patch b/source/dietlibc/diet-qmail/qmail-1.03.errno.patch
       
  1724 new file mode 100644
       
  1725 index 0000000..75e0b7b
       
  1726 --- /dev/null
       
  1727 +++ b/source/dietlibc/diet-qmail/qmail-1.03.errno.patch
       
  1728 @@ -0,0 +1,47 @@
       
  1729 +diff -u qmail-1.03.old/cdb_seek.c qmail-1.03/cdb_seek.c
       
  1730 +--- qmail-1.03.old/cdb_seek.c	1998-06-15 05:52:55.000000000 -0500
       
  1731 ++++ qmail-1.03/cdb_seek.c	2003-01-08 15:55:53.000000000 -0600
       
  1732 +@@ -1,6 +1,5 @@
       
  1733 + #include <sys/types.h>
       
  1734 + #include <errno.h>
       
  1735 +-extern int errno;
       
  1736 + #include "cdb.h"
       
  1737 + 
       
  1738 + #ifndef SEEK_SET
       
  1739 +diff -u qmail-1.03.old/dns.c qmail-1.03/dns.c
       
  1740 +--- qmail-1.03.old/dns.c	1998-06-15 05:52:55.000000000 -0500
       
  1741 ++++ qmail-1.03/dns.c	2003-01-08 16:00:32.000000000 -0600
       
  1742 +@@ -7,8 +7,6 @@
       
  1743 + #include <errno.h>
       
  1744 + extern int res_query();
       
  1745 + extern int res_search();
       
  1746 +-extern int errno;
       
  1747 +-extern int h_errno;
       
  1748 + #include "ip.h"
       
  1749 + #include "ipalloc.h"
       
  1750 + #include "fmt.h"
       
  1751 +diff -u qmail-1.03.old/error.3 qmail-1.03/error.3
       
  1752 +--- qmail-1.03.old/error.3	1998-06-15 05:52:55.000000000 -0500
       
  1753 ++++ qmail-1.03/error.3	2003-01-08 15:58:13.000000000 -0600
       
  1754 +@@ -3,8 +3,7 @@
       
  1755 + error \- syscall error codes
       
  1756 + .SH SYNTAX
       
  1757 + .B #include <error.h>
       
  1758 +-
       
  1759 +-extern int \fBerrno\fP;
       
  1760 ++.B #include <errno.h>
       
  1761 + 
       
  1762 + extern int \fBerror_intr\fP;
       
  1763 + .br
       
  1764 +diff -u qmail-1.03.old/error.h qmail-1.03/error.h
       
  1765 +--- qmail-1.03.old/error.h	1998-06-15 05:52:55.000000000 -0500
       
  1766 ++++ qmail-1.03/error.h	2003-01-08 15:59:13.000000000 -0600
       
  1767 +@@ -1,7 +1,7 @@
       
  1768 + #ifndef ERROR_H
       
  1769 + #define ERROR_H
       
  1770 + 
       
  1771 +-extern int errno;
       
  1772 ++#include <errno.h>
       
  1773 + 
       
  1774 + extern int error_intr;
       
  1775 + extern int error_nomem;
       
  1776 diff --git a/source/dietlibc/diet-qmail/qmail-dietlibc.patch b/source/dietlibc/diet-qmail/qmail-dietlibc.patch
       
  1777 new file mode 100644
       
  1778 index 0000000..52e404c
       
  1779 --- /dev/null
       
  1780 +++ b/source/dietlibc/diet-qmail/qmail-dietlibc.patch
       
  1781 @@ -0,0 +1,40 @@
       
  1782 +dietlibc compile
       
  1783 +
       
  1784 +diff -r df48dd6b95fa conf-cc
       
  1785 +--- a/conf-cc	Thu Nov 01 16:30:40 2007 +0100
       
  1786 ++++ b/conf-cc	Thu Nov 01 16:46:06 2007 +0100
       
  1787 +@@ -1,3 +1,3 @@ cc -O2
       
  1788 +-cc -O2
       
  1789 ++diet gcc -O2
       
  1790 + 
       
  1791 + This will be used to compile .c files.
       
  1792 +diff -r df48dd6b95fa conf-ld
       
  1793 +--- a/conf-ld	Thu Nov 01 16:30:40 2007 +0100
       
  1794 ++++ b/conf-ld	Thu Nov 01 16:46:06 2007 +0100
       
  1795 +@@ -1,3 +1,3 @@ cc -s
       
  1796 +-cc -s
       
  1797 ++diet gcc -s -static
       
  1798 + 
       
  1799 + This will be used to link .o files into an executable.
       
  1800 +diff -r df48dd6b95fa predate.c
       
  1801 +--- a/predate.c	Thu Nov 01 16:30:40 2007 +0100
       
  1802 ++++ b/predate.c	Thu Nov 01 16:46:06 2007 +0100
       
  1803 +@@ -8,7 +8,6 @@
       
  1804 + #include "strerr.h"
       
  1805 + #include "substdio.h"
       
  1806 + #include "subfd.h"
       
  1807 +-#include "readwrite.h"
       
  1808 + #include "exit.h"
       
  1809 + 
       
  1810 + #define FATAL "predate: fatal: "
       
  1811 +diff -r df48dd6b95fa qbiff.c
       
  1812 +--- a/qbiff.c	Thu Nov 01 16:30:40 2007 +0100
       
  1813 ++++ b/qbiff.c	Thu Nov 01 16:46:06 2007 +0100
       
  1814 +@@ -8,7 +8,6 @@
       
  1815 + #define UTMP_FILE "/etc/utmp"
       
  1816 + #endif
       
  1817 + #endif
       
  1818 +-#include "readwrite.h"
       
  1819 + #include "stralloc.h"
       
  1820 + #include "substdio.h"
       
  1821 + #include "subfd.h"
       
  1822 diff --git a/source/dietlibc/diet-qmail/qmail-smtpd.spam.patch b/source/dietlibc/diet-qmail/qmail-smtpd.spam.patch
       
  1823 new file mode 100644
       
  1824 index 0000000..5ef6b6e
       
  1825 --- /dev/null
       
  1826 +++ b/source/dietlibc/diet-qmail/qmail-smtpd.spam.patch
       
  1827 @@ -0,0 +1,74 @@
       
  1828 +stika.net antispam
       
  1829 +
       
  1830 +diff -r 72430e923db2 qmail-smtpd.c
       
  1831 +--- a/qmail-smtpd.c	Thu Nov 01 16:46:06 2007 +0100
       
  1832 ++++ b/qmail-smtpd.c	Thu Nov 01 16:54:59 2007 +0100
       
  1833 +@@ -31,6 +31,7 @@
       
  1834 + #define BMCHECK_BMT 2
       
  1835 + #define BMCHECK_BMTNR 3
       
  1836 + #define BMCHECK_BHELO 4
       
  1837 ++#define BMCHECK_GMF 5	// 20041202 tz - goodmailfrom functionality
       
  1838 +     
       
  1839 + 
       
  1840 + #define MAXHOPS 100
       
  1841 +@@ -108,6 +109,9 @@ int bmfok = 0;
       
  1842 + int bmfok = 0;
       
  1843 + stralloc bmf = {0};
       
  1844 + 
       
  1845 ++int gmfok = 0;
       
  1846 ++stralloc gmf = {0};
       
  1847 ++
       
  1848 + int bmfnrok = 0;
       
  1849 + stralloc bmfnr = {0};
       
  1850 + 
       
  1851 +@@ -140,6 +144,9 @@ void setup()
       
  1852 + 
       
  1853 +   bmfok = control_readfile(&bmf,"control/badmailfrom",0);
       
  1854 +   if (bmfok == -1) die_control();
       
  1855 ++
       
  1856 ++  gmfok = control_readfile(&gmf,"control/goodmailfrom",0);
       
  1857 ++  if (gmfok == -1) die_control();
       
  1858 + 
       
  1859 +   bmfnrok = control_readfile(&bmfnr,"control/badmailfromnorelay",0);
       
  1860 +   if (bmfnrok == -1) die_control();
       
  1861 +@@ -247,6 +254,8 @@ int bmcheck(which) int which;
       
  1862 + 
       
  1863 +   if (which == BMCHECK_BMF) {
       
  1864 +     if (!stralloc_copy(&bmb,&bmf)) die_nomem();
       
  1865 ++  } else if (which == BMCHECK_GMF) {		// 20041202 tz - goodmailfrom
       
  1866 ++    if (!stralloc_copy(&bmb,&gmf)) die_nomem();
       
  1867 +   } else if (which == BMCHECK_BMFNR) {
       
  1868 +     if (!stralloc_copy(&bmb,&bmfnr)) die_nomem();
       
  1869 +   } else if (which == BMCHECK_BMT) {
       
  1870 +@@ -304,6 +313,7 @@ int flagbarfbhelo;
       
  1871 + int flagbarfbhelo;
       
  1872 + stralloc mailfrom = {0};
       
  1873 + stralloc rcptto = {0};
       
  1874 ++int senderallowed = 0;	/* 20021121 tz - our anti-spam */
       
  1875 + 
       
  1876 + void smtp_helo(arg) char *arg;
       
  1877 + {
       
  1878 +@@ -327,6 +337,7 @@ void smtp_mail(arg) char *arg;
       
  1879 +   if (!addrparse(arg)) { err_syntax(); return; }
       
  1880 +   flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */
       
  1881 +   if ((bmfok) && (addr.len != 1)) flagbarfbmf = bmcheck(BMCHECK_BMF);
       
  1882 ++  if (flagbarfbmf && gmfok) flagbarfbmf = !bmcheck(BMCHECK_GMF);	// 20041202 tz - goodmailfrom
       
  1883 +   if ((!flagbarfbmf) && (bmfnrok) && (addr.len != 1) && (!relayclient)) {
       
  1884 +     flagbarfbmf = bmcheck(BMCHECK_BMFNR);
       
  1885 +   }
       
  1886 +@@ -334,6 +345,7 @@ void smtp_mail(arg) char *arg;
       
  1887 +   if (!stralloc_copys(&rcptto,"")) die_nomem();
       
  1888 +   if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
       
  1889 +   if (!stralloc_0(&mailfrom)) die_nomem();
       
  1890 ++  senderallowed = addrallowed();			/* 20021121 tz - our anti-spam */
       
  1891 +   out("250 ok\r\n");
       
  1892 + }
       
  1893 + void smtp_rcpt(arg) char *arg; {
       
  1894 +@@ -377,6 +389,7 @@ void smtp_rcpt(arg) char *arg; {
       
  1895 +   }
       
  1896 +   else
       
  1897 +     if (!addrallowed()) { err_nogateway(); return; }
       
  1898 ++  if (!(addrallowed() || senderallowed)) { err_nogateway(); return; }	/* 20021121 tz - our anti-spam */
       
  1899 +   if (!stralloc_cats(&rcptto,"T")) die_nomem();
       
  1900 +   if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
       
  1901 +   if (!stralloc_0(&rcptto)) die_nomem();
       
  1902 diff --git a/source/dietlibc/diet-qmail/qmail.profile b/source/dietlibc/diet-qmail/qmail.profile
       
  1903 new file mode 100644
       
  1904 index 0000000..3b5fcd0
       
  1905 --- /dev/null
       
  1906 +++ b/source/dietlibc/diet-qmail/qmail.profile
       
  1907 @@ -0,0 +1,5 @@
       
  1908 +#!/bin/sh
       
  1909 +
       
  1910 +export QMAILDIR=/var/qmail
       
  1911 +export PATH=$PATH:$QMAILDIR/bin
       
  1912 +export MANPATH=$MANPATH:$QMAILDIR/man
       
  1913 diff --git a/source/dietlibc/diet-qmail/qmail.rc b/source/dietlibc/diet-qmail/qmail.rc
       
  1914 new file mode 100644
       
  1915 index 0000000..45e716e
       
  1916 --- /dev/null
       
  1917 +++ b/source/dietlibc/diet-qmail/qmail.rc
       
  1918 @@ -0,0 +1,167 @@
       
  1919 +#!/bin/sh
       
  1920 +#
       
  1921 +# qmailctl script (based on lifewithqmail)
       
  1922 +# modified for ArchLinux
       
  1923 +#
       
  1924 +
       
  1925 +. /etc/rc.conf
       
  1926 +. /etc/rc.d/functions
       
  1927 +
       
  1928 +QMAILDUID=`id -u qmaild`
       
  1929 +NOFILESGID=`id -g qmaild`
       
  1930 +
       
  1931 +case "$1" in
       
  1932 +  start)
       
  1933 +    stat_busy "Starting qmail"
       
  1934 +    for i in send smtpd pop3d; do
       
  1935 +      if svok /service/qmail-${i} &>/dev/null ; then
       
  1936 +	echo -n "  ${i}"
       
  1937 +        svc -u /service/qmail-${i}
       
  1938 +      fi
       
  1939 +    done
       
  1940 +    if [ $? -gt 0 ]; then
       
  1941 +      stat_fail
       
  1942 +    else
       
  1943 +      add_daemon qmail
       
  1944 +      stat_done
       
  1945 +    fi
       
  1946 +    ;;
       
  1947 +  stop)
       
  1948 +    stat_busy "Stopping qmail"
       
  1949 +    for i in send smtpd pop3d; do
       
  1950 +      if svok /service/qmail-${i} &>/dev/null ; then
       
  1951 +	echo -n "  ${i}"
       
  1952 +	svc -d /service/qmail-${i}
       
  1953 +      fi
       
  1954 +    done
       
  1955 +    if [ $? -gt 0 ]; then
       
  1956 +      stat_fail
       
  1957 +    else
       
  1958 +      rm_daemon qmail
       
  1959 +      stat_done
       
  1960 +    fi
       
  1961 +    ;;
       
  1962 +  stat)
       
  1963 +    for i in send smtpd pop3d; do
       
  1964 +      if svok /service/qmail-${i} &>/dev/null ; then	    
       
  1965 +        svstat /service/qmail-${i}
       
  1966 +        svstat /service/qmail-${i}/log
       
  1967 +      fi
       
  1968 +    done
       
  1969 +    qmail-qstat
       
  1970 +    ;;
       
  1971 +  doqueue|alrm|flush)
       
  1972 +    stat_busy "Sending ALRM signal to qmail-send"
       
  1973 +    svc -a /service/qmail-send
       
  1974 +    if [ $? -gt 0 ]; then
       
  1975 +      stat_fail
       
  1976 +    else
       
  1977 +      stat_done
       
  1978 +    fi
       
  1979 +    ;;
       
  1980 +  queue)
       
  1981 +    qmail-qstat
       
  1982 +    qmail-qread
       
  1983 +    ;;
       
  1984 +  reload|hup)
       
  1985 +    stat_busy "Sending HUP signal to qmail-send"
       
  1986 +    svc -h /service/qmail-send
       
  1987 +    if [ $? -gt 0 ]; then
       
  1988 +      stat_fail
       
  1989 +    else
       
  1990 +      stat_done
       
  1991 +    fi
       
  1992 +    ;;
       
  1993 +  pause)
       
  1994 +    stat_busy "Pausing qmail"
       
  1995 +    for i in send smtpd pop3d; do
       
  1996 +      if svok /service/qmail-${i} &>/dev/null ; then
       
  1997 +	echo -n "  ${i}"
       
  1998 +        svc -p /service/qmail-${i}
       
  1999 +      fi
       
  2000 +    done
       
  2001 +    if [ $? -gt 0 ]; then
       
  2002 +      stat_fail
       
  2003 +    else
       
  2004 +      stat_done
       
  2005 +    fi 
       
  2006 +    ;;
       
  2007 +  cont)
       
  2008 +    stat_busy "Continuing qmail"
       
  2009 +    for i in send smtpd pop3d; do
       
  2010 +      if svok /service/qmail-${i} &>/dev/null ; then
       
  2011 +	echo -n "  ${i}"
       
  2012 +        svc -c /service/qmail-${i}
       
  2013 +      fi
       
  2014 +    done
       
  2015 +    if [ $? -gt 0 ]; then
       
  2016 +      stat_fail
       
  2017 +    else
       
  2018 +      stat_done
       
  2019 +    fi
       
  2020 +    ;;
       
  2021 +  restart)
       
  2022 +    stat_busy "Restarting qmail"
       
  2023 +    if svok /service/qmail-smtpd &>/dev/null ; then
       
  2024 +      echo -n "  Stopping qmail-smtpd"
       
  2025 +      svc -d /service/qmail-smtpd
       
  2026 +    fi
       
  2027 +    if svok /service/qmail-send &>/dev/null ; then
       
  2028 +      echo -n "  Sending qmail-send SIGTERM and restarting"
       
  2029 +      svc -t /service/qmail-send
       
  2030 +    fi
       
  2031 +    if svok /service/qmail-pop3d &>/dev/null ; then
       
  2032 +      echo -n "  Restarting qmail-pop3d"
       
  2033 +      svc -t /service/qmail-pop3d
       
  2034 +    fi
       
  2035 +    if svok /service/qmail-smtpd &>/dev/null ; then
       
  2036 +      echo -n "  Restarting qmail-smtpd"
       
  2037 +      svc -u /service/qmail-smtpd
       
  2038 +    fi
       
  2039 +    if [ $? -gt 0 ]; then
       
  2040 +      stat_fail
       
  2041 +    else
       
  2042 +      stat_done
       
  2043 +    fi
       
  2044 +    ;;
       
  2045 +  cdb)
       
  2046 +    stat_busy "Reload qmail access control"
       
  2047 +    if [ -f /etc/tcp.smtp ]; then
       
  2048 +      echo -n "  SMTP"
       
  2049 +      tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
       
  2050 +      chmod 644 /etc/tcp.smtp.cdb
       
  2051 +    fi
       
  2052 +    if [ -f /etc/tcp.pop3 ]; then
       
  2053 +      echo -n "  POP3"	    
       
  2054 +      tcprules /etc/tcp.pop3.cdb /etc/tcp.pop3.tmp < /etc/tcp.pop3
       
  2055 +      chmod 644 /etc/tcp.pop3.cdb
       
  2056 +    fi
       
  2057 +    if [ $? -gt 0 ]; then
       
  2058 +      stat_fail
       
  2059 +    else
       
  2060 +      stat_done
       
  2061 +    fi
       
  2062 +    ;;
       
  2063 +  help)
       
  2064 +    cat <<HELP
       
  2065 +   stop -- stops mail service (smtp connections refused, nothing goes out)
       
  2066 +  start -- starts mail service (smtp connection accepted, mail can go out)
       
  2067 +  pause -- temporarily stops mail service (connections accepted, nothing leaves)
       
  2068 +   cont -- continues paused mail service
       
  2069 +   stat -- displays status of mail service
       
  2070 +    cdb -- rebuild the tcpserver cdb file for smtp
       
  2071 +restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it
       
  2072 +doqueue -- sends qmail-send ALRM, scheduling queued messages for delivery
       
  2073 + reload -- sends qmail-send HUP, rereading locals and virtualdomains
       
  2074 +  queue -- shows status of queue
       
  2075 +   alrm -- same as doqueue
       
  2076 +  flush -- same as doqueue
       
  2077 +    hup -- same as reload
       
  2078 +HELP
       
  2079 +    ;;
       
  2080 +  *)
       
  2081 +    echo "Usage: $0 {start|stop|restart|doqueue|flush|reload|stat|pause|cont|cdb|queue|help}"
       
  2082 +    exit 1
       
  2083 +    ;;
       
  2084 +esac
       
  2085 +exit 0
       
  2086 diff --git a/source/dietlibc/diet-qmail/qmailqueue-patch b/source/dietlibc/diet-qmail/qmailqueue-patch
       
  2087 new file mode 100644
       
  2088 index 0000000..ec304b6
       
  2089 --- /dev/null
       
  2090 +++ b/source/dietlibc/diet-qmail/qmailqueue-patch
       
  2091 @@ -0,0 +1,72 @@
       
  2092 +From: Bruce Guenter <bguenter-djb-qmail@qcc.sk.ca>
       
  2093 +To: qmail@list.cr.yp.to
       
  2094 +Subject: QMAILQUEUE patch for qmail-1.03
       
  2095 +Date: Mon, 25 Jan 1999 15:37:21 -0600
       
  2096 +
       
  2097 +Greetings.
       
  2098 +
       
  2099 +Appended is a patch to qmail-1.03 that causes any program that would run
       
  2100 +qmail-queue to look for an environment variable QMAILQUEUE.  If it is
       
  2101 +present, it is used in place of the string "bin/qmail-queue" when
       
  2102 +running qmail-queue.  This could be used, for example, to add a program
       
  2103 +into the qmail-smtpd->qmail-queue pipeline that could do filtering,
       
  2104 +rewrite broken headers, etc. (this is my planned usage for it).
       
  2105 +
       
  2106 +This has undergone virtually no testing, but it looks so simple that it
       
  2107 +almost has to be correct.  No warranties, etc.  Note that the chdir to
       
  2108 +/var/qmail is always done before exec'ing the program.
       
  2109 +
       
  2110 +Does this look like a reasonable thing to do?
       
  2111 +-- 
       
  2112 +Bruce Guenter, QCC Communications Corp.  EMail: bruce.guenter@qcc.sk.ca
       
  2113 +Phone: (306)249-0220               WWW: http://www.qcc.sk.ca/~bguenter/
       
  2114 +
       
  2115 +diff -u qmail-1.03-orig/Makefile qmail-1.03/Makefile
       
  2116 +--- qmail-1.03-orig/Makefile	Mon Jun 15 04:53:16 1998
       
  2117 ++++ qmail-1.03/Makefile	Tue Jan 19 10:52:24 1999
       
  2118 +@@ -1483,12 +1483,12 @@
       
  2119 + trigger.o fmtqfn.o quote.o now.o readsubdir.o qmail.o date822fmt.o \
       
  2120 + datetime.a case.a ndelay.a getln.a wait.a seek.a fd.a sig.a open.a \
       
  2121 + lock.a stralloc.a alloc.a substdio.a error.a str.a fs.a auto_qmail.o \
       
  2122 +-auto_split.o
       
  2123 ++auto_split.o env.a
       
  2124 + 	./load qmail-send qsutil.o control.o constmap.o newfield.o \
       
  2125 + 	prioq.o trigger.o fmtqfn.o quote.o now.o readsubdir.o \
       
  2126 + 	qmail.o date822fmt.o datetime.a case.a ndelay.a getln.a \
       
  2127 + 	wait.a seek.a fd.a sig.a open.a lock.a stralloc.a alloc.a \
       
  2128 +-	substdio.a error.a str.a fs.a auto_qmail.o auto_split.o 
       
  2129 ++	substdio.a error.a str.a fs.a auto_qmail.o auto_split.o env.a
       
  2130 + 
       
  2131 + qmail-send.0: \
       
  2132 + qmail-send.8
       
  2133 +diff -u qmail-1.03-orig/qmail.c qmail-1.03/qmail.c
       
  2134 +--- qmail-1.03-orig/qmail.c	Mon Jun 15 04:53:16 1998
       
  2135 ++++ qmail-1.03/qmail.c	Tue Jan 19 09:57:36 1999
       
  2136 +@@ -6,14 +6,25 @@
       
  2137 + #include "fd.h"
       
  2138 + #include "qmail.h"
       
  2139 + #include "auto_qmail.h"
       
  2140 ++#include "env.h"
       
  2141 + 
       
  2142 +-static char *binqqargs[2] = { "bin/qmail-queue", 0 } ;
       
  2143 ++static char *binqqargs[2] = { 0, 0 } ;
       
  2144 ++
       
  2145 ++static void setup_qqargs()
       
  2146 ++{
       
  2147 ++  if(!binqqargs[0])
       
  2148 ++    binqqargs[0] = env_get("QMAILQUEUE");
       
  2149 ++  if(!binqqargs[0])
       
  2150 ++    binqqargs[0] = "bin/qmail-queue";
       
  2151 ++}
       
  2152 + 
       
  2153 + int qmail_open(qq)
       
  2154 + struct qmail *qq;
       
  2155 + {
       
  2156 +   int pim[2];
       
  2157 +   int pie[2];
       
  2158 ++
       
  2159 ++  setup_qqargs();
       
  2160 + 
       
  2161 +   if (pipe(pim) == -1) return -1;
       
  2162 +   if (pipe(pie) == -1) { close(pim[0]); close(pim[1]); return -1; }
       
  2163 +
       
  2164 diff --git a/source/dietlibc/diet-qmail/qregex-20060423-qmail.patch b/source/dietlibc/diet-qmail/qregex-20060423-qmail.patch
       
  2165 new file mode 100644
       
  2166 index 0000000..6d08258
       
  2167 --- /dev/null
       
  2168 +++ b/source/dietlibc/diet-qmail/qregex-20060423-qmail.patch
       
  2169 @@ -0,0 +1,688 @@
       
  2170 +Fixed qregex-20060423 (pristine is against netqmail)
       
  2171 +
       
  2172 +diff -r 1510847ae5bf Makefile
       
  2173 +--- a/Makefile	Thu Nov 01 16:23:16 2007 +0100
       
  2174 ++++ b/Makefile	Thu Nov 01 16:24:02 2007 +0100
       
  2175 +@@ -1534,16 +1534,16 @@ auto_split.h
       
  2176 + 	./compile qmail-showctl.c
       
  2177 + 
       
  2178 + qmail-smtpd: \
       
  2179 +-load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \
       
  2180 ++load qmail-smtpd.o rcpthosts.o qregex.o commands.o timeoutread.o \
       
  2181 + timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
       
  2182 + date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
       
  2183 +-open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \
       
  2184 ++open.a sig.a case.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
       
  2185 + fs.a auto_qmail.o socket.lib
       
  2186 +-	./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
       
  2187 ++	./load qmail-smtpd qregex.o rcpthosts.o commands.o timeoutread.o \
       
  2188 + 	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
       
  2189 + 	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
       
  2190 + 	datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
       
  2191 +-	alloc.a substdio.a error.a str.a fs.a auto_qmail.o  `cat \
       
  2192 ++	alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o  `cat \
       
  2193 + 	socket.lib`
       
  2194 + 
       
  2195 + qmail-smtpd.0: \
       
  2196 +@@ -1696,6 +1696,10 @@ compile rcpthosts.c cdb.h uint32.h byte.
       
  2197 + compile rcpthosts.c cdb.h uint32.h byte.h open.h error.h control.h \
       
  2198 + constmap.h stralloc.h gen_alloc.h rcpthosts.h
       
  2199 + 	./compile rcpthosts.c
       
  2200 ++
       
  2201 ++qregex.o: \
       
  2202 ++compile qregex.c qregex.h
       
  2203 ++	./compile qregex.c
       
  2204 + 
       
  2205 + readsubdir.o: \
       
  2206 + compile readsubdir.c readsubdir.h direntry.h fmt.h scan.h str.h \
       
  2207 +diff -r 1510847ae5bf README.qregex
       
  2208 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
       
  2209 ++++ b/README.qregex	Thu Nov 01 16:24:02 2007 +0100
       
  2210 +@@ -0,0 +1,203 @@
       
  2211 ++QREGEX (v2) 20060423 - README April 23, 2006
       
  2212 ++A Regular Expression matching patch for qmail 1.03 and netqmail
       
  2213 ++
       
  2214 ++
       
  2215 ++OVERVIEW:
       
  2216 ++
       
  2217 ++qregex adds the ability to match address evelopes via Regular Expressions (REs)
       
  2218 ++in the qmail-smtpd process. It has the abiltiy to match `helo/ehlo` (host name),
       
  2219 ++`mail from` (envelope sender), and `rcpt to` (envelope recipient) commands.
       
  2220 ++It follows all the base rules that are set out with qmail (ie using control
       
  2221 ++files) so it makes for easy integretion into an existing setup (see the
       
  2222 ++install instructions for more info). The v2 is specified because qregex was
       
  2223 ++re-written to better conform to the security guarantee set forth by the author
       
  2224 ++of qmail. The original version used stdio.h and stdlib.h for reading the
       
  2225 ++control files whereas v2 now uses all stralloc functions which are much more
       
  2226 ++regulated against buffer overruns and the like.
       
  2227 ++See: http://cr.yp.to/qmail/guarantee.html
       
  2228 ++
       
  2229 ++
       
  2230 ++FEATURES:
       
  2231 ++
       
  2232 ++Features of qregex include:
       
  2233 ++
       
  2234 ++1. Performs pattern matching on envelope senders and envelope
       
  2235 ++   recipients against REs in the badmailfrom and badmailto control
       
  2236 ++   files. Two additional control files, badmailfromnorelay and
       
  2237 ++   badmailtonorelay, are used for pattern matching when the 
       
  2238 ++   RELAYCLIENT environment variable is not set.
       
  2239 ++
       
  2240 ++2. Performs pattern matching on the helo/ehlo host name. Setting the
       
  2241 ++   NOBADHELO environment variable prevents the host name from being
       
  2242 ++   compared to the patterns in the badhelo control file.
       
  2243 ++
       
  2244 ++3. Matches to patterns are logged. Setting the LOGREGEX environment
       
  2245 ++   variable causes the matched regex pattern to be included in the log. 
       
  2246 ++
       
  2247 ++4. Matching is case insensitive.
       
  2248 ++
       
  2249 ++5. qregex ignores empty envelope senders. An empty envelope sender is not
       
  2250 ++   compared to the patterns in the badmailfrom and badmailfromnorelay
       
  2251 ++   control files and is always accepted.
       
  2252 ++
       
  2253 ++
       
  2254 ++PLATFORMS:
       
  2255 ++
       
  2256 ++qregex has been built and tested on the following platforms. I'm sure it won't
       
  2257 ++have any problems on any platform that qmail will run on (providing they have
       
  2258 ++a regex interface) but if you run into problems let me know.
       
  2259 ++
       
  2260 ++	- OpenBSD 3.x
       
  2261 ++	- FreeBSD 4.x, 5.x
       
  2262 ++	- Mandrake Linux 9.x
       
  2263 ++	- SuSE Linux 8.x
       
  2264 ++
       
  2265 ++
       
  2266 ++
       
  2267 ++INSTALLATION INSTRUCTIONS:
       
  2268 ++
       
  2269 ++Installation is very simple, there is only one requirement. You need to use the
       
  2270 ++GNU version of the patch utility (http://www.gnu.org/software/patch/patch.html).
       
  2271 ++(For Solaris 8 users it is installed as 'gpatch')
       
  2272 ++
       
  2273 ++- If this is a new setup.
       
  2274 ++Unpack the qmail archive, cd into the qmail-1.03 directory and run
       
  2275 ++"patch < /path/to/qregex-<version>.patch". Follow the instructions as per the
       
  2276 ++included qmail INSTALL file. Once you are done come back to this file and read
       
  2277 ++the section on the control files.
       
  2278 ++
       
  2279 ++If you are using netqmail, then unpack the netqmail archive. Run the collate.sh
       
  2280 ++script and cd into the resulting netqmail-<version> directory. From there, run
       
  2281 ++"patch < /path/to/qregex-<version>.patch". Complete the netqmail installation
       
  2282 ++normally. Once you are done, come back to this file and read the section on the
       
  2283 ++control files.
       
  2284 ++
       
  2285 ++- If this is an existing setup.
       
  2286 ++FIRST: create your control files (see below).
       
  2287 ++cd into your existing qmail or netqmail source directory. Run
       
  2288 ++"patch < /path/to/qregex-<version>.patch" then "make qmail-smtpd". Now run
       
  2289 ++./qmail-smtpd and test your new rules to make sure they work as expected.
       
  2290 ++
       
  2291 ++Install the new binary by cd'ing to /var/qmail/bin and as root (in one command)
       
  2292 ++copy the existing binary to 'qmail-smtpd.old' and copy the new binary from the
       
  2293 ++source directory to 'qmail-smtpd'.
       
  2294 ++(ex. cp qmail-smtpd qmail-smtpd.old && cp ~/qmail-1.03/qmail-smtpd qmail-smtpd)
       
  2295 ++
       
  2296 ++You can also optionally just run "make setup check" as it will install the
       
  2297 ++updated documentation and man pages provided with this patch. Stopping qmail
       
  2298 ++before doing the "make setup check" is always a good idea.
       
  2299 ++
       
  2300 ++
       
  2301 ++LOGGING:
       
  2302 ++
       
  2303 ++qregex will log matches to the patterns in the various control files. Log
       
  2304 ++messages will take these three forms depending on which control file was
       
  2305 ++matched:
       
  2306 ++
       
  2307 ++badhelo
       
  2308 ++qmail-smtpd: badhelo: <host> at <remote IP>
       
  2309 ++
       
  2310 ++badmailfrom and badmailfromnorelay
       
  2311 ++qmail-smtpd: badmailfrom: <sender address> at <remote IP>
       
  2312 ++
       
  2313 ++badmailto and badmailtonorelay
       
  2314 ++qmail-smtpd: badmailto: <rcpt address> at <remote IP>
       
  2315 ++
       
  2316 ++When the LOGREGEX environment variable is set, the matched pattern will
       
  2317 ++be included in the log. Log messages will have the regex pattern appended
       
  2318 ++to them. For example, a badhelo log message will look like this:
       
  2319 ++
       
  2320 ++qmail-smtpd: badhelo: <host> at <remote IP> matches pattern: <regex>
       
  2321 ++
       
  2322 ++
       
  2323 ++CONTROL FILES:
       
  2324 ++
       
  2325 ++qregex provides you with five control files. None of these control files
       
  2326 ++is mandatory and you can use them in any combination you choose in your setup.
       
  2327 ++
       
  2328 ++The "control/badmailfrom" and "control/badmailto" files contain your REs for
       
  2329 ++matching against the 'mail from' (envelope sender) and 'rcpt to' (envelope
       
  2330 ++recipient) smtp commands respectively.
       
  2331 ++The "control/badmailfromnorelay" and "control/badmailtonorelay" match against
       
  2332 ++the same commands but are read only when the RELAYCLIENT environment variable
       
  2333 ++is not set.
       
  2334 ++The "control/badhelo" file matches against the 'helo/ehlo' smtp command.
       
  2335 ++
       
  2336 ++If you prefer you can symlink the badmailfrom and badmailto control files
       
  2337 ++(ln -s badmailfrom badmailto) and maintain fewer sets of rules. Beware
       
  2338 ++this might cause problems in certain setups.
       
  2339 ++        
       
  2340 ++	Here's an example "badhelo" file.
       
  2341 ++	-----------------------------------
       
  2342 ++	# block host strings with no dot (not a FQDN)
       
  2343 ++	!\.
       
  2344 ++	-----------------------------------
       
  2345 ++	
       
  2346 ++	An example "badmailfrom" file.
       
  2347 ++	-----------------------------------
       
  2348 ++	# this will drop everything containing the string
       
  2349 ++	# bad.domain.com or Bad.Domain.Com or BAD.domain.COM
       
  2350 ++	bad\.domain\.com
       
  2351 ++	# force users to fully qualify themselves
       
  2352 ++	# (i.e. deny "user", accept "user@domain")
       
  2353 ++	!@
       
  2354 ++	-----------------------------------
       
  2355 ++
       
  2356 ++	And "badmailto" (a little more interesting)
       
  2357 ++	-----------------------------------
       
  2358 ++	# must not contain invalid characters, brakets or multiple @'s
       
  2359 ++	[!%#:*^(){}]
       
  2360 ++	@.*@
       
  2361 ++	-----------------------------------
       
  2362 ++
       
  2363 ++You can use the non-RE character '!' to start an RE as a signal to qregex to
       
  2364 ++negate the action. As used above in the badmailfrom file, by negating the '@'
       
  2365 ++symbol qregex will signal qmail-smtpd to deny the 'mail from' command whenever
       
  2366 ++the address doesn't contain an @ symbol. When used inside a bracket expression,
       
  2367 ++the '!' character looses this special meaning. This is shown in the badmailto
       
  2368 ++example.
       
  2369 ++
       
  2370 ++The norelay control files follow the same rules as the other control files but
       
  2371 ++are intended to address two specific scenarios.
       
  2372 ++The badmailfromnorelay file can be used to block mail trying to spoof a domain
       
  2373 ++hosted on your mail server. It prevents a mail client that is not allowed to
       
  2374 ++relay email through your server from using one of your hosted domains as its
       
  2375 ++envelope sender.
       
  2376 ++The badmailtonorelay file can be used to create email addresses that cannot
       
  2377 ++receive mail from any source not allowed to relay email through your server.
       
  2378 ++This is handy for creating email addresses for use only within your own 
       
  2379 ++domain(s) that can't receive spam from the world at large.
       
  2380 ++
       
  2381 ++
       
  2382 ++INTERNALS:
       
  2383 ++
       
  2384 ++qregex (or regexmatch as the function is called) will be called during the
       
  2385 ++`helo/ehlo`, `rcpt to` and `mail from` handling routines in "qmail-smtpd.c".
       
  2386 ++When called, it will read the proper control file then one by one compile and
       
  2387 ++execute the regex on the string passed into qmail-smtpd. If the regex matches
       
  2388 ++it returns TRUE (1) and the qmail-smtpd process will deny the user the ability
       
  2389 ++to continue. If you change anything and think it betters this patch please
       
  2390 ++send me a new diff file so I can take a peek.
       
  2391 ++
       
  2392 ++
       
  2393 ++CONTACT:
       
  2394 ++qregex is maintained by:
       
  2395 ++	Andrew St. Jean
       
  2396 ++	andrew@arda.homeunix.net
       
  2397 ++	www.arda.homeunix.net/store/qmail/
       
  2398 ++
       
  2399 ++Contributers to qregex:
       
  2400 ++	Jeremy Kitchen	
       
  2401 ++	kitchen at scriptkitchen dot com
       
  2402 ++	http://www.scriptkitchen.com/qmail
       
  2403 ++
       
  2404 ++	Alex Pleiner
       
  2405 ++	alex@zeitform.de
       
  2406 ++	zeitform Internet Dienste
       
  2407 ++	http://www.zeitform.de/
       
  2408 ++
       
  2409 ++	Thanos Massias
       
  2410 ++
       
  2411 ++Original qregex patch written by:
       
  2412 ++	Evan Borgstrom
       
  2413 ++	evan at unixpimps dot org
       
  2414 +diff -r 1510847ae5bf TARGETS
       
  2415 +--- a/TARGETS	Thu Nov 01 16:23:16 2007 +0100
       
  2416 ++++ b/TARGETS	Thu Nov 01 16:24:02 2007 +0100
       
  2417 +@@ -252,6 +252,7 @@ qmail-qmtpd
       
  2418 + qmail-qmtpd
       
  2419 + qmail-smtpd.o
       
  2420 + qmail-smtpd
       
  2421 ++qregex.o
       
  2422 + sendmail.o
       
  2423 + sendmail
       
  2424 + tcp-env.o
       
  2425 +diff -r 1510847ae5bf hier.c
       
  2426 +--- a/hier.c	Thu Nov 01 16:23:16 2007 +0100
       
  2427 ++++ b/hier.c	Thu Nov 01 16:24:02 2007 +0100
       
  2428 +@@ -76,6 +76,7 @@ void hier()
       
  2429 +   c(auto_qmail,"boot","binm3+df",auto_uido,auto_gidq,0755);
       
  2430 + 
       
  2431 +   c(auto_qmail,"doc","FAQ",auto_uido,auto_gidq,0644);
       
  2432 ++  c(auto_qmail,"doc","README.qregex",auto_uido,auto_gidq,0644);
       
  2433 +   c(auto_qmail,"doc","UPGRADE",auto_uido,auto_gidq,0644);
       
  2434 +   c(auto_qmail,"doc","SENDMAIL",auto_uido,auto_gidq,0644);
       
  2435 +   c(auto_qmail,"doc","INSTALL",auto_uido,auto_gidq,0644);
       
  2436 +diff -r 1510847ae5bf install-big.c
       
  2437 +--- a/install-big.c	Thu Nov 01 16:23:16 2007 +0100
       
  2438 ++++ b/install-big.c	Thu Nov 01 16:24:02 2007 +0100
       
  2439 +@@ -76,6 +76,7 @@ void hier()
       
  2440 +   c(auto_qmail,"boot","binm3+df",auto_uido,auto_gidq,0755);
       
  2441 + 
       
  2442 +   c(auto_qmail,"doc","FAQ",auto_uido,auto_gidq,0644);
       
  2443 ++  c(auto_qmail,"doc","README.qregex",auto_uido,auto_gidq,0644);
       
  2444 +   c(auto_qmail,"doc","UPGRADE",auto_uido,auto_gidq,0644);
       
  2445 +   c(auto_qmail,"doc","SENDMAIL",auto_uido,auto_gidq,0644);
       
  2446 +   c(auto_qmail,"doc","INSTALL",auto_uido,auto_gidq,0644);
       
  2447 +diff -r 1510847ae5bf qmail-control.9
       
  2448 +--- a/qmail-control.9	Thu Nov 01 16:23:16 2007 +0100
       
  2449 ++++ b/qmail-control.9	Thu Nov 01 16:24:02 2007 +0100
       
  2450 +@@ -20,7 +20,11 @@ other hostname-related control files.
       
  2451 + 
       
  2452 + Comments are allowed
       
  2453 + in
       
  2454 ++.IR badhelo ,
       
  2455 + .IR badmailfrom ,
       
  2456 ++.IR badmailfromnorelay ,
       
  2457 ++.IR badmailto ,
       
  2458 ++.IR badmailtonorelay ,
       
  2459 + .IR locals ,
       
  2460 + .IR percenthack ,
       
  2461 + .IR qmqpservers ,
       
  2462 +@@ -40,7 +44,11 @@ See the corresponding man pages for furt
       
  2463 + .ta 5c 10c
       
  2464 + control	default	used by
       
  2465 + 
       
  2466 ++.I badhelo	\fR(none)	\fRqmail-smtpd
       
  2467 + .I badmailfrom	\fR(none)	\fRqmail-smtpd
       
  2468 ++.I badmailfromnorelay	\fR(none)	\fRqmail-smtpd
       
  2469 ++.I badmailto	\fR(none)	\fRqmail-smtpd
       
  2470 ++.I badmailtonorelay	\fR(none)	\fRqmail-smtpd
       
  2471 + .I bouncefrom	\fRMAILER-DAEMON	\fRqmail-send
       
  2472 + .I bouncehost	\fIme	\fRqmail-send
       
  2473 + .I concurrencylocal	\fR10	\fRqmail-send
       
  2474 +diff -r 1510847ae5bf qmail-showctl.c
       
  2475 +--- a/qmail-showctl.c	Thu Nov 01 16:23:16 2007 +0100
       
  2476 ++++ b/qmail-showctl.c	Thu Nov 01 16:24:02 2007 +0100
       
  2477 +@@ -214,7 +214,11 @@ void main()
       
  2478 +     _exit(111);
       
  2479 +   }
       
  2480 + 
       
  2481 +-  do_lst("badmailfrom","Any MAIL FROM is allowed.",""," not accepted in MAIL FROM.");
       
  2482 ++  do_lst("badhelo","Any HELO host name is allowed.",""," HELO host name denied if it matches this pattern.");
       
  2483 ++  do_lst("badmailfrom","Any MAIL FROM is allowed.",""," MAIL FROM denied if it matches this pattern.");
       
  2484 ++  do_lst("badmailfromnorelay","Any MAIL FROM is allowed.",""," MAIL FROM denied if it matches this pattern and RELAYCLIENT is not set.");
       
  2485 ++  do_lst("badmailto","No RCPT TO are specifically denied.",""," RCPT TO denied if it matches this pattern.");
       
  2486 ++  do_lst("badmailtonorelay","No RCPT TO are specifically denied.",""," RCPT TO denied if it matches this pattern and RELAYCLIENT is not set.");
       
  2487 +   do_str("bouncefrom",0,"MAILER-DAEMON","Bounce user name is ");
       
  2488 +   do_str("bouncehost",1,"bouncehost","Bounce host name is ");
       
  2489 +   do_int("concurrencylocal","10","Local concurrency is ","");
       
  2490 +@@ -267,7 +271,11 @@ void main()
       
  2491 +     if (str_equal(d->d_name,"..")) continue;
       
  2492 +     if (str_equal(d->d_name,"bouncefrom")) continue;
       
  2493 +     if (str_equal(d->d_name,"bouncehost")) continue;
       
  2494 ++    if (str_equal(d->d_name,"badhelo")) continue;
       
  2495 +     if (str_equal(d->d_name,"badmailfrom")) continue;
       
  2496 ++    if (str_equal(d->d_name,"badmailfromnorelay")) continue;
       
  2497 ++    if (str_equal(d->d_name,"badmailto")) continue;
       
  2498 ++    if (str_equal(d->d_name,"badmailtonorelay")) continue;
       
  2499 +     if (str_equal(d->d_name,"bouncefrom")) continue;
       
  2500 +     if (str_equal(d->d_name,"bouncehost")) continue;
       
  2501 +     if (str_equal(d->d_name,"concurrencylocal")) continue;
       
  2502 +diff -r 1510847ae5bf qmail-smtpd.8
       
  2503 +--- a/qmail-smtpd.8	Thu Nov 01 16:23:16 2007 +0100
       
  2504 ++++ b/qmail-smtpd.8	Thu Nov 01 16:24:02 2007 +0100
       
  2505 +@@ -37,11 +37,26 @@ even though such messages violate the SM
       
  2506 + even though such messages violate the SMTP protocol.
       
  2507 + .SH "CONTROL FILES"
       
  2508 + .TP 5
       
  2509 ++.I badhelo
       
  2510 ++Unacceptable HELO/EHLO host names.
       
  2511 ++.B qmail-smtpd
       
  2512 ++will reject every recipient address for a message if
       
  2513 ++the host name is listed in, 
       
  2514 ++or matches a POSIX regular expression pattern listed in,
       
  2515 ++.IR badhelo .
       
  2516 ++If the 
       
  2517 ++.B NOBADHELO 
       
  2518 ++environment variable is set, then the contents of 
       
  2519 ++.IR badhelo 
       
  2520 ++will be ignored.
       
  2521 ++For more information, please have a look at doc/README.qregex.
       
  2522 ++.TP 5
       
  2523 + .I badmailfrom
       
  2524 + Unacceptable envelope sender addresses.
       
  2525 + .B qmail-smtpd
       
  2526 + will reject every recipient address for a message
       
  2527 +-if the envelope sender address is listed in
       
  2528 ++if the envelope sender address is listed in, or matches a POSIX regular expression
       
  2529 ++pattern listed in,
       
  2530 + .IR badmailfrom .
       
  2531 + A line in
       
  2532 + .I badmailfrom
       
  2533 +@@ -49,6 +64,32 @@ may be of the form
       
  2534 + .BR @\fIhost ,
       
  2535 + meaning every address at
       
  2536 + .IR host .
       
  2537 ++For more information, please have a look at doc/README.qregex.
       
  2538 ++.TP 5
       
  2539 ++.I badmailfromnorelay
       
  2540 ++Functions the same as the
       
  2541 ++.IR badmailfrom
       
  2542 ++control file but is read only if the 
       
  2543 ++.B RELAYCLIENT 
       
  2544 ++environment variable is not set.
       
  2545 ++For more information, please have a look at doc/README.qregex.
       
  2546 ++.TP 5
       
  2547 ++.I badmailto
       
  2548 ++Unacceptable envelope recipient addresses.
       
  2549 ++.B qmail-smtpd
       
  2550 ++will reject every recipient address for a message if the recipient address
       
  2551 ++is listed in,
       
  2552 ++or matches a POSIX regular expression pattern listed in,
       
  2553 ++.IR badmailto .
       
  2554 ++For more information, please have a look at doc/README.qregex.
       
  2555 ++.TP 5
       
  2556 ++.I badmailtonorelay
       
  2557 ++Functions the same as the
       
  2558 ++.IR badmailto
       
  2559 ++control file but is read only if the
       
  2560 ++.B RELAYCLIENT
       
  2561 ++environment variable is not set.
       
  2562 ++For more information, please have a look at doc/README.qregex.
       
  2563 + .TP 5
       
  2564 + .I databytes
       
  2565 + Maximum number of bytes allowed in a message,
       
  2566 +diff -r 1510847ae5bf qmail-smtpd.c
       
  2567 +--- a/qmail-smtpd.c	Thu Nov 01 16:23:16 2007 +0100
       
  2568 ++++ b/qmail-smtpd.c	Thu Nov 01 16:24:02 2007 +0100
       
  2569 +@@ -23,6 +23,15 @@
       
  2570 + #include "timeoutread.h"
       
  2571 + #include "timeoutwrite.h"
       
  2572 + #include "commands.h"
       
  2573 ++#include "qregex.h"
       
  2574 ++#include "strerr.h"
       
  2575 ++
       
  2576 ++#define BMCHECK_BMF 0
       
  2577 ++#define BMCHECK_BMFNR 1
       
  2578 ++#define BMCHECK_BMT 2
       
  2579 ++#define BMCHECK_BMTNR 3
       
  2580 ++#define BMCHECK_BHELO 4
       
  2581 ++    
       
  2582 + 
       
  2583 + #define MAXHOPS 100
       
  2584 + unsigned int databytes = 0;
       
  2585 +@@ -49,7 +58,9 @@ void die_ipme() { out("421 unable to fig
       
  2586 + void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); }
       
  2587 + void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }
       
  2588 + 
       
  2589 +-void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
       
  2590 ++void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); }
       
  2591 ++void err_bmt() { out("553 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); }
       
  2592 ++void err_bhelo() { out("553 sorry, your HELO host name has been denied (#5.7.1)\r\n"); }
       
  2593 + void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
       
  2594 + void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); }
       
  2595 + void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
       
  2596 +@@ -93,9 +104,24 @@ void dohelo(arg) char *arg; {
       
  2597 + 
       
  2598 + int liphostok = 0;
       
  2599 + stralloc liphost = {0};
       
  2600 ++
       
  2601 + int bmfok = 0;
       
  2602 + stralloc bmf = {0};
       
  2603 +-struct constmap mapbmf;
       
  2604 ++
       
  2605 ++int bmfnrok = 0;
       
  2606 ++stralloc bmfnr = {0};
       
  2607 ++
       
  2608 ++int bmtok = 0;
       
  2609 ++stralloc bmt = {0};
       
  2610 ++
       
  2611 ++int bmtnrok = 0;
       
  2612 ++stralloc bmtnr = {0};
       
  2613 ++
       
  2614 ++int bhelook = 0;
       
  2615 ++stralloc bhelo = {0};
       
  2616 ++
       
  2617 ++int logregex = 0;
       
  2618 ++stralloc matchedregex = {0};
       
  2619 + 
       
  2620 + void setup()
       
  2621 + {
       
  2622 +@@ -114,8 +140,21 @@ void setup()
       
  2623 + 
       
  2624 +   bmfok = control_readfile(&bmf,"control/badmailfrom",0);
       
  2625 +   if (bmfok == -1) die_control();
       
  2626 +-  if (bmfok)
       
  2627 +-    if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
       
  2628 ++
       
  2629 ++  bmfnrok = control_readfile(&bmfnr,"control/badmailfromnorelay",0);
       
  2630 ++  if (bmfnrok == -1) die_control();
       
  2631 ++
       
  2632 ++  bmtok = control_readfile(&bmt,"control/badmailto",0);
       
  2633 ++  if (bmtok == -1) die_control();
       
  2634 ++
       
  2635 ++  bmtnrok = control_readfile(&bmtnr,"control/badmailtonorelay",0);
       
  2636 ++  if (bmtnrok == -1) die_control();
       
  2637 ++
       
  2638 ++  bhelook = control_readfile(&bhelo, "control/badhelo",0);
       
  2639 ++  if (bhelook == -1) die_control();
       
  2640 ++  if (env_get("NOBADHELO")) bhelook = 0;
       
  2641 ++
       
  2642 ++  if (env_get("LOGREGEX")) logregex = 1;
       
  2643 +  
       
  2644 +   if (control_readint(&databytes,"control/databytes") == -1) die_control();
       
  2645 +   x = env_get("DATABYTES");
       
  2646 +@@ -197,14 +236,56 @@ char *arg;
       
  2647 +   return 1;
       
  2648 + }
       
  2649 + 
       
  2650 +-int bmfcheck()
       
  2651 +-{
       
  2652 +-  int j;
       
  2653 +-  if (!bmfok) return 0;
       
  2654 +-  if (constmap(&mapbmf,addr.s,addr.len - 1)) return 1;
       
  2655 +-  j = byte_rchr(addr.s,addr.len,'@');
       
  2656 +-  if (j < addr.len)
       
  2657 +-    if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) return 1;
       
  2658 ++int bmcheck(which) int which;
       
  2659 ++{
       
  2660 ++  int i = 0;
       
  2661 ++  int j = 0;
       
  2662 ++  int x = 0;
       
  2663 ++  int negate = 0;
       
  2664 ++  static stralloc bmb = {0};
       
  2665 ++  static stralloc curregex = {0};
       
  2666 ++
       
  2667 ++  if (which == BMCHECK_BMF) {
       
  2668 ++    if (!stralloc_copy(&bmb,&bmf)) die_nomem();
       
  2669 ++  } else if (which == BMCHECK_BMFNR) {
       
  2670 ++    if (!stralloc_copy(&bmb,&bmfnr)) die_nomem();
       
  2671 ++  } else if (which == BMCHECK_BMT) {
       
  2672 ++    if (!stralloc_copy(&bmb,&bmt)) die_nomem();
       
  2673 ++  } else if (which == BMCHECK_BMTNR) {
       
  2674 ++    if (!stralloc_copy(&bmb,&bmtnr)) die_nomem();
       
  2675 ++  } else if (which == BMCHECK_BHELO) {
       
  2676 ++    if (!stralloc_copy(&bmb,&bhelo)) die_nomem();
       
  2677 ++  } else {
       
  2678 ++    die_control();
       
  2679 ++  }
       
  2680 ++
       
  2681 ++  while (j < bmb.len) {
       
  2682 ++    i = j;
       
  2683 ++    while ((bmb.s[i] != '\0') && (i < bmb.len)) i++;
       
  2684 ++    if (bmb.s[j] == '!') {
       
  2685 ++      negate = 1;
       
  2686 ++      j++;
       
  2687 ++    }
       
  2688 ++    if (!stralloc_copyb(&curregex,bmb.s + j,(i - j))) die_nomem();
       
  2689 ++    if (!stralloc_0(&curregex)) die_nomem();
       
  2690 ++    if (which == BMCHECK_BHELO) {
       
  2691 ++      x = matchregex(helohost.s, curregex.s);
       
  2692 ++    } else {
       
  2693 ++      x = matchregex(addr.s, curregex.s);
       
  2694 ++    }
       
  2695 ++    if ((negate) && (x == 0)) {
       
  2696 ++      if (!stralloc_copyb(&matchedregex,bmb.s + j - 1,(i - j + 1))) die_nomem();
       
  2697 ++      if (!stralloc_0(&matchedregex)) die_nomem();      
       
  2698 ++      return 1;
       
  2699 ++    }
       
  2700 ++    if (!(negate) && (x > 0)) {
       
  2701 ++      if (!stralloc_copyb(&matchedregex,bmb.s + j,(i - j))) die_nomem();
       
  2702 ++      if (!stralloc_0(&matchedregex)) die_nomem();
       
  2703 ++      return 1;
       
  2704 ++    }
       
  2705 ++    j = i + 1;
       
  2706 ++    negate = 0;
       
  2707 ++  }
       
  2708 +   return 0;
       
  2709 + }
       
  2710 + 
       
  2711 +@@ -218,7 +299,9 @@ int addrallowed()
       
  2712 + 
       
  2713 + 
       
  2714 + int seenmail = 0;
       
  2715 +-int flagbarf; /* defined if seenmail */
       
  2716 ++int flagbarfbmf; /* defined if seenmail */
       
  2717 ++int flagbarfbmt;
       
  2718 ++int flagbarfbhelo;
       
  2719 + stralloc mailfrom = {0};
       
  2720 + stralloc rcptto = {0};
       
  2721 + 
       
  2722 +@@ -226,11 +309,13 @@ void smtp_helo(arg) char *arg;
       
  2723 + {
       
  2724 +   smtp_greet("250 "); out("\r\n");
       
  2725 +   seenmail = 0; dohelo(arg);
       
  2726 ++  if (bhelook) flagbarfbhelo = bmcheck(BMCHECK_BHELO);
       
  2727 + }
       
  2728 + void smtp_ehlo(arg) char *arg;
       
  2729 + {
       
  2730 +   smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
       
  2731 +   seenmail = 0; dohelo(arg);
       
  2732 ++  if (bhelook) flagbarfbhelo = bmcheck(BMCHECK_BHELO);
       
  2733 + }
       
  2734 + void smtp_rset()
       
  2735 + {
       
  2736 +@@ -240,7 +325,11 @@ void smtp_mail(arg) char *arg;
       
  2737 + void smtp_mail(arg) char *arg;
       
  2738 + {
       
  2739 +   if (!addrparse(arg)) { err_syntax(); return; }
       
  2740 +-  flagbarf = bmfcheck();
       
  2741 ++  flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */
       
  2742 ++  if ((bmfok) && (addr.len != 1)) flagbarfbmf = bmcheck(BMCHECK_BMF);
       
  2743 ++  if ((!flagbarfbmf) && (bmfnrok) && (addr.len != 1) && (!relayclient)) {
       
  2744 ++    flagbarfbmf = bmcheck(BMCHECK_BMFNR);
       
  2745 ++  }
       
  2746 +   seenmail = 1;
       
  2747 +   if (!stralloc_copys(&rcptto,"")) die_nomem();
       
  2748 +   if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
       
  2749 +@@ -250,7 +339,37 @@ void smtp_rcpt(arg) char *arg; {
       
  2750 + void smtp_rcpt(arg) char *arg; {
       
  2751 +   if (!seenmail) { err_wantmail(); return; }
       
  2752 +   if (!addrparse(arg)) { err_syntax(); return; }
       
  2753 +-  if (flagbarf) { err_bmf(); return; }
       
  2754 ++  if (flagbarfbhelo) {
       
  2755 ++    if (logregex) {
       
  2756 ++      strerr_warn6("qmail-smtpd: badhelo: <",helohost.s,"> at ",remoteip," matches pattern: ",matchedregex.s,0);
       
  2757 ++    } else {
       
  2758 ++      strerr_warn4("qmail-smtpd: badhelo: <",helohost.s,"> at ",remoteip,0);
       
  2759 ++    }
       
  2760 ++    err_bhelo();
       
  2761 ++    return;
       
  2762 ++  }
       
  2763 ++  if (flagbarfbmf) {
       
  2764 ++    if (logregex) {
       
  2765 ++      strerr_warn6("qmail-smtpd: badmailfrom: <",mailfrom.s,"> at ",remoteip," matches pattern: ",matchedregex.s,0);
       
  2766 ++    } else {
       
  2767 ++      strerr_warn4("qmail-smtpd: badmailfrom: <",mailfrom.s,"> at ",remoteip,0);
       
  2768 ++    }
       
  2769 ++    err_bmf();
       
  2770 ++    return;
       
  2771 ++  }
       
  2772 ++  if (bmtok) flagbarfbmt = bmcheck(BMCHECK_BMT);
       
  2773 ++  if ((!flagbarfbmt) && (bmtnrok) && (!relayclient)) {
       
  2774 ++    flagbarfbmt = bmcheck(BMCHECK_BMTNR);
       
  2775 ++  }
       
  2776 ++  if (flagbarfbmt) {
       
  2777 ++    if (logregex) {
       
  2778 ++      strerr_warn6("qmail-smtpd: badmailto: <",addr.s,"> at ",remoteip," matches pattern: ",matchedregex.s,0);
       
  2779 ++    } else {
       
  2780 ++      strerr_warn4("qmail-smtpd: badmailto: <",addr.s,"> at ",remoteip,0);
       
  2781 ++    }
       
  2782 ++    err_bmt();
       
  2783 ++    return;
       
  2784 ++  }
       
  2785 +   if (relayclient) {
       
  2786 +     --addr.len;
       
  2787 +     if (!stralloc_cats(&addr,relayclient)) die_nomem();
       
  2788 +diff -r 1510847ae5bf qregex.c
       
  2789 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
       
  2790 ++++ b/qregex.c	Thu Nov 01 16:24:02 2007 +0100
       
  2791 +@@ -0,0 +1,57 @@
       
  2792 ++/*
       
  2793 ++ * qregex (v2)
       
  2794 ++ * $Id: qregex.c,v 2.1 2001/12/28 07:05:21 evan Exp $
       
  2795 ++ *
       
  2796 ++ * Author  : Evan Borgstrom (evan at unixpimps dot org)
       
  2797 ++ * Created : 2001/12/14 23:08:16
       
  2798 ++ * Modified: $Date: 2001/12/28 07:05:21 $
       
  2799 ++ * Revision: $Revision: 2.1 $
       
  2800 ++ *
       
  2801 ++ * Do POSIX regex matching on addresses for anti-relay / spam control.
       
  2802 ++ * It logs to the maillog
       
  2803 ++ * See the qregex-readme file included with this tarball.
       
  2804 ++ * If you didn't get this file in a tarball please see the following URL:
       
  2805 ++ *  http://www.unixpimps.org/software/qregex
       
  2806 ++ *
       
  2807 ++ * qregex.c is released under a BSD style copyright.
       
  2808 ++ * See http://www.unixpimps.org/software/qregex/copyright.html
       
  2809 ++ *
       
  2810 ++ * Note: this revision follows the coding guidelines set forth by the rest of
       
  2811 ++ *       the qmail code and that described at the following URL.
       
  2812 ++ *       http://cr.yp.to/qmail/guarantee.html
       
  2813 ++ * 
       
  2814 ++ */
       
  2815 ++
       
  2816 ++#include <sys/types.h>
       
  2817 ++#include <regex.h>
       
  2818 ++#include "qregex.h"
       
  2819 ++
       
  2820 ++#define REGCOMP(X,Y)    regcomp(&X, Y, REG_EXTENDED|REG_ICASE)
       
  2821 ++#define REGEXEC(X,Y)    regexec(&X, Y, (size_t)0, (regmatch_t *)0, (int)0)
       
  2822 ++
       
  2823 ++int matchregex(char *text, char *regex) {
       
  2824 ++  regex_t qreg;
       
  2825 ++  int retval = 0;
       
  2826 ++
       
  2827 ++
       
  2828 ++  /* build the regex */
       
  2829 ++  if ((retval = REGCOMP(qreg, regex)) != 0) {
       
  2830 ++    regfree(&qreg);
       
  2831 ++    return(-retval);
       
  2832 ++  }
       
  2833 ++
       
  2834 ++  /* execute the regex */
       
  2835 ++  if ((retval = REGEXEC(qreg, text)) != 0) {
       
  2836 ++    /* did we just not match anything? */
       
  2837 ++    if (retval == REG_NOMATCH) {
       
  2838 ++      regfree(&qreg);
       
  2839 ++      return(0);
       
  2840 ++    }
       
  2841 ++    regfree(&qreg);
       
  2842 ++    return(-retval);
       
  2843 ++  }
       
  2844 ++
       
  2845 ++  /* signal the match */
       
  2846 ++  regfree(&qreg);
       
  2847 ++  return(1);
       
  2848 ++}
       
  2849 +diff -r 1510847ae5bf qregex.h
       
  2850 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
       
  2851 ++++ b/qregex.h	Thu Nov 01 16:24:02 2007 +0100
       
  2852 +@@ -0,0 +1,5 @@
       
  2853 ++/* simple header file for the matchregex prototype */
       
  2854 ++#ifndef _QREGEX_H_
       
  2855 ++#define _QREGEX_H_
       
  2856 ++int matchregex(char *text, char *regex);
       
  2857 ++#endif
       
  2858 diff --git a/source/dietlibc/diet-qmail/queue-fix-dietlibc.patch b/source/dietlibc/diet-qmail/queue-fix-dietlibc.patch
       
  2859 new file mode 100644
       
  2860 index 0000000..6d967ed
       
  2861 --- /dev/null
       
  2862 +++ b/source/dietlibc/diet-qmail/queue-fix-dietlibc.patch
       
  2863 @@ -0,0 +1,18 @@
       
  2864 +Compile with dietlibc
       
  2865 +
       
  2866 +diff -r 6becbe0d87fa conf-cc
       
  2867 +--- a/conf-cc	Thu Nov 01 15:04:39 2007 +0100
       
  2868 ++++ b/conf-cc	Thu Nov 01 15:06:54 2007 +0100
       
  2869 +@@ -1,3 +1,3 @@ gcc -O2
       
  2870 +-gcc -O2
       
  2871 ++diet gcc -O2
       
  2872 + 
       
  2873 + This will be used to compile .c files.
       
  2874 +diff -r 6becbe0d87fa conf-ld
       
  2875 +--- a/conf-ld	Thu Nov 01 15:04:39 2007 +0100
       
  2876 ++++ b/conf-ld	Thu Nov 01 15:06:54 2007 +0100
       
  2877 +@@ -1,3 +1,3 @@ gcc -s
       
  2878 +-gcc -s
       
  2879 ++diet gcc -s -static
       
  2880 + 
       
  2881 + This will be used to link .o files into an executable.
       
  2882 diff --git a/source/dietlibc/diet-qmail/queue-fix-errno.patch b/source/dietlibc/diet-qmail/queue-fix-errno.patch
       
  2883 new file mode 100644
       
  2884 index 0000000..72f9fcd
       
  2885 --- /dev/null
       
  2886 +++ b/source/dietlibc/diet-qmail/queue-fix-errno.patch
       
  2887 @@ -0,0 +1,14 @@
       
  2888 +errno fix
       
  2889 +
       
  2890 +diff -r c045670f36e9 error.h
       
  2891 +--- a/error.h	Thu Nov 01 14:46:11 2007 +0100
       
  2892 ++++ b/error.h	Thu Nov 01 15:02:39 2007 +0100
       
  2893 +@@ -1,7 +1,7 @@
       
  2894 + #ifndef ERROR_H
       
  2895 + #define ERROR_H
       
  2896 + 
       
  2897 +-extern int errno;
       
  2898 ++#include <errno.h>
       
  2899 + 
       
  2900 + extern int error_intr;
       
  2901 + extern int error_nomem;
       
  2902 diff --git a/source/dietlibc/diet-qmail/rc b/source/dietlibc/diet-qmail/rc
       
  2903 new file mode 100644
       
  2904 index 0000000..0f82f9e
       
  2905 --- /dev/null
       
  2906 +++ b/source/dietlibc/diet-qmail/rc
       
  2907 @@ -0,0 +1,7 @@
       
  2908 +#!/bin/sh
       
  2909 +#
       
  2910 +# Using stdout for logging
       
  2911 +# Using control/defaultdelivery from qmail-local to deliver messages by default
       
  2912 +#
       
  2913 +exec env - PATH="/var/qmail/bin:$PATH" \
       
  2914 +  qmail-start "`cat /var/qmail/control/defaultdelivery`"
       
  2915 diff --git a/source/dietlibc/diet-qmail/send_log_run b/source/dietlibc/diet-qmail/send_log_run
       
  2916 new file mode 100644
       
  2917 index 0000000..0c4fd21
       
  2918 --- /dev/null
       
  2919 +++ b/source/dietlibc/diet-qmail/send_log_run
       
  2920 @@ -0,0 +1,20 @@
       
  2921 +#!/bin/sh
       
  2922 +# 
       
  2923 +# Edit this file to match your setup.
       
  2924 +# NOTE: This file is automatically backed-up by pacman, 
       
  2925 +# during updates
       
  2926 +#
       
  2927 +
       
  2928 +# Log size rotate size.
       
  2929 +LOG_SIZE="1048576"
       
  2930 +
       
  2931 +# Number of logs to keep.
       
  2932 +LOGS="5"
       
  2933 +
       
  2934 +# Don't change from this point on, unless
       
  2935 +# you really know what you're doing :).
       
  2936 +
       
  2937 +exec /usr/bin/setuidgid qmaill \
       
  2938 +  /usr/bin/multilog t \
       
  2939 +  n${LOGS} s${LOG_SIZE} \
       
  2940 +  /var/log/qmail/send 2>&1
       
  2941 diff --git a/source/dietlibc/diet-qmail/send_run b/source/dietlibc/diet-qmail/send_run
       
  2942 new file mode 100644
       
  2943 index 0000000..1724b2c
       
  2944 --- /dev/null
       
  2945 +++ b/source/dietlibc/diet-qmail/send_run
       
  2946 @@ -0,0 +1,8 @@
       
  2947 +#!/bin/sh
       
  2948 +#
       
  2949 +# Edit this file to match your setup.
       
  2950 +# NOTE: This file is automatically backed-up by pacman, 
       
  2951 +# during updates
       
  2952 +#
       
  2953 +
       
  2954 +exec /var/qmail/rc
       
  2955 diff --git a/source/dietlibc/diet-qmail/smtpd_log_run b/source/dietlibc/diet-qmail/smtpd_log_run
       
  2956 new file mode 100644
       
  2957 index 0000000..68027b6
       
  2958 --- /dev/null
       
  2959 +++ b/source/dietlibc/diet-qmail/smtpd_log_run
       
  2960 @@ -0,0 +1,20 @@
       
  2961 +#!/bin/sh
       
  2962 +#
       
  2963 +# Edit this file to match your setup.
       
  2964 +# NOTE: This file is automatically backed-up by pacman, 
       
  2965 +# during updates
       
  2966 +#
       
  2967 +
       
  2968 +# Log size rotate size.
       
  2969 +LOG_SIZE="1048576"
       
  2970 +
       
  2971 +# Number of logs to keep.
       
  2972 +LOGS="5"
       
  2973 +
       
  2974 +# Don't change from this point on, unless
       
  2975 +# you really know what you're doing :).
       
  2976 +
       
  2977 +exec /usr/bin/setuidgid qmaill \
       
  2978 +  /usr/bin/multilog t \
       
  2979 +  n${LOGS} s${LOG_SIZE} \
       
  2980 +  /var/log/qmail/smtpd 2>&1
       
  2981 diff --git a/source/dietlibc/diet-qmail/smtpd_run b/source/dietlibc/diet-qmail/smtpd_run
       
  2982 new file mode 100644
       
  2983 index 0000000..ffd4451
       
  2984 --- /dev/null
       
  2985 +++ b/source/dietlibc/diet-qmail/smtpd_run
       
  2986 @@ -0,0 +1,45 @@
       
  2987 +#!/bin/sh
       
  2988 +# 
       
  2989 +# Edit this file to match your setup.
       
  2990 +# NOTE: This file is automatically backed-up by pacman, 
       
  2991 +# during updates
       
  2992 +#
       
  2993 +
       
  2994 +# uid & gid to run qmail-smtpd as.
       
  2995 +# optionally `id -u vpopmail' for vpopmail.
       
  2996 +QMAILDUID=`id -u qmaild`
       
  2997 +
       
  2998 +# optionally `id -g vpopmail` for vpopmail.
       
  2999 +NOFILESGID=`id -g qmaild`
       
  3000 +
       
  3001 +# Password checking program (ie. checkpasswd, vpopmail).
       
  3002 +PASSPROG=""
       
  3003 +
       
  3004 +# FQDN as set in /var/qmail/control/me
       
  3005 +LOCAL=`head -1 /var/qmail/control/me`
       
  3006 +
       
  3007 +# Maximum memory qmail-smtpd is allowed to use.
       
  3008 +MAX_MEM="2000000"
       
  3009 +
       
  3010 +# Maximum allowed concurrent connections.
       
  3011 +MAX_CON=`cat /var/qmail/control/concurrencyincoming`
       
  3012 +
       
  3013 +# Relay control.
       
  3014 +TCP_CDB="/etc/tcp.smtp.cdb"
       
  3015 +
       
  3016 +# Relay denied message for open relays.
       
  3017 +RELAY_DENIED="relays.ordb.org: Your message was rejected because the mail server you use is configured to allow OPEN RELAY - More detailed information regarding this problem is available from http://www.ordb.org/lookup/?%IP% - Please forward this error through to your email server support staff for easy resolution."
       
  3018 +
       
  3019 +# Don't change from this point on, unless
       
  3020 +# you really know what you're doing :).
       
  3021 +SMTPD="/var/qmail/bin/qmail-smtpd"
       
  3022 +PORT="25"
       
  3023 +
       
  3024 +exec /usr/bin/softlimit -m $MAX_MEM \
       
  3025 +  /usr/bin/tcpserver -H -l $LOCAL \
       
  3026 +  -v -x $TCP_CDB \
       
  3027 +  -c $MAX_CON -R 0 $PORT \
       
  3028 +  -u $QMAILUID -g $NOFILESGID \
       
  3029 +  /usr/bin/rblsmtpd -b -C \
       
  3030 +  -r $RELAY_DENIED -t 5 \
       
  3031 +  $SMTPD $PASSPROG /bin/true 2>&1
       
  3032 diff --git a/source/dietlibc/diet-qmail/tcp.pop3 b/source/dietlibc/diet-qmail/tcp.pop3
       
  3033 new file mode 100644
       
  3034 index 0000000..4437128
       
  3035 --- /dev/null
       
  3036 +++ b/source/dietlibc/diet-qmail/tcp.pop3
       
  3037 @@ -0,0 +1,6 @@
       
  3038 +# to update the database after changing this file, run:
       
  3039 +# /etc/rc.d/qmail cdb
       
  3040 +# Allow any client to connect to us via POP3
       
  3041 +# If people are abusing POP3 such as denial-of-service on POP3,
       
  3042 +# you can add their ips here to block them out
       
  3043 +:allow
       
  3044 diff --git a/source/dietlibc/diet-qmail/tcp.smtp b/source/dietlibc/diet-qmail/tcp.smtp
       
  3045 new file mode 100644
       
  3046 index 0000000..a5faa17
       
  3047 --- /dev/null
       
  3048 +++ b/source/dietlibc/diet-qmail/tcp.smtp
       
  3049 @@ -0,0 +1,81 @@
       
  3050 +#------------------------------------------------------
       
  3051 +# DESCRIPTION OF THE RULES TO REMIND ME OF HOW THIS FILE WORKS
       
  3052 +#
       
  3053 +# If you set 'allow', this means that our mail server will allow
       
  3054 +# the specified IP range to make a TCP connection to our server
       
  3055 +#
       
  3056 +# If you set 'deny', this means that our mail server will not allow
       
  3057 +# the specified IP range to make a TCP connection to our server
       
  3058 +#
       
  3059 +# If you set RELAYCLIENT="", this means that the listed IP range is
       
  3060 +# allowed to relay mail through our server
       
  3061 +#
       
  3062 +# If you dont set RELAYCLIENT="", this means that the listed IP range
       
  3063 +# will not be able to relay mail through our server
       
  3064 +#
       
  3065 +# If you set RBLSMTPD="", this means that the listed IP ranges will
       
  3066 +# not be checked against any of the RBL databases
       
  3067 +#
       
  3068 +# If you set RBLSMTPD="some text here", this means that an RBL lookup
       
  3069 +# wont be performed, but the mail will be rejected with the specified
       
  3070 +# text as a 4xx temp error message
       
  3071 +#
       
  3072 +# If you set RBLSMTPD="-some text here", this means that an RBL lookup
       
  3073 +# wont be performed, but the mail will be rejected with the specified
       
  3074 +# text as a 5xx perm error message
       
  3075 +#
       
  3076 +# If you do not set RBLSMTPD="" or ="some text", then an RBL lookup
       
  3077 +# will be performed. If the lookup is successful, then RBLSMTPD will
       
  3078 +# return your custom error message (as specified in the -r parameter
       
  3079 +# in smtpd supervise script)
       
  3080 +#
       
  3081 +#-----------------------------------------------------
       
  3082 +# HERE ARE THE RULES! :
       
  3083 +#-----------------------------------------------------
       
  3084 +# BYPASS OPEN RELAY CHECKING FOR THESE IPS :
       
  3085 +#
       
  3086 +# These IPs are ones that we have setup so that they arent RBL checked.
       
  3087 +# We have done this because these particular servers are RBL listed,
       
  3088 +# and for whatever reason they can't/won't fix their open relay problem,
       
  3089 +# and we still want to be able to receive mail from them.
       
  3090 +#
       
  3091 +# reminder text goes here for this entry so we know the story...
       
  3092 +111.111.111.111:allow,RBLSMTPD=""
       
  3093 +## reminder text goes here for this entry so we know the story...
       
  3094 +222.222.222.222:allow,RBLSMTPD=""
       
  3095 +#
       
  3096 +#-----------------------------------------------------------------
       
  3097 +# DONT ALLOW THESE IPS TO SEND MAIL TO US :
       
  3098 +#
       
  3099 +# mailXX.offermail.net connecting regularly and sending invalid
       
  3100 +# format messages causing exit with status 256 (bare linefeed normally)
       
  3101 +# entry added 15/12/2001
       
  3102 +# after looking at the mail coming from these servers it was found to be spam
       
  3103 +216.242.75.100-116:allow,RBLSMTPD="-Connections from this IP have been banned."
       
  3104 +#
       
  3105 +# heaps of spam from replyto of *@freeamateurhotties.com dec2001
       
  3106 +64.228.127.:allow,RBLSMTPD="-Connections refused due to spam from freeamateurhotties.com"
       
  3107 +154.20.94.:allow,RBLSMTPD="-Connections refused due to spam from freeamateurhotties.com"
       
  3108 +209.151.132.:allow,RBLSMTPD="-Connections refused due to spam from freeamateurhotties.com"
       
  3109 +216.18.85.:allow,RBLSMTPD="-Connections refused due to spam from freeamateurhotties.com"
       
  3110 +#
       
  3111 +#-----------------------------------------------------------------
       
  3112 +# ALLOW THESE IPS TO RELAY MAIL THROUGH OUR SERVER
       
  3113 +#
       
  3114 +# Local class-c's from our LAN are allowed to relay,
       
  3115 +# and we wont bother doing any RBL checking.
       
  3116 +#123.123.123.:allow,RELAYCLIENT="",RBLSMTPD=""
       
  3117 +#123.111.111.:allow,RELAYCLIENT="",RBLSMTPD=""
       
  3118 +#
       
  3119 +# Connections from localhost are allowed to relay
       
  3120 +# (because the WebMail server runs on localhost),
       
  3121 +# and obviously there is no point trying to perform an RBL check.
       
  3122 +127.0.0.1:allow,RELAYCLIENT="",RBLSMTPD=""
       
  3123 +#
       
  3124 +#-----------------------------------------------------------------
       
  3125 +# ALLOW EVERYONE ELSE TO SEND US MAIL
       
  3126 +#
       
  3127 +# Everyone else can make connections to our server,
       
  3128 +# but not allowed to relay
       
  3129 +# RBL lookups are performed
       
  3130 +:allow
       
  3131 -- 
       
  3132 1.5.3.4
       
  3133