1. Introduction
2. What are Simscan, ClamAV and Chkuser?
4.2. ClamAV recommended packages
4.3. Simscan required packages
4.4. Simscan recommended packages
4.5. Chkuser required packages
5. Applying the patches over Netqmail
5.1. Applying Chkuser
5.2. Applying qmail-queue-custom-error.patch
5.3. Recompiling Netqmail
6. Activating chkuser antispam features
7.1. Installing ClamAV prerequisites
7.2. Installing ClamAV
7.3. Setting up ClamAV startup
7.4. Activating the virus definitions update
8.1. Installing Simscan prerequisites
8.2. Installing Simscan
8.3. Creating Simscan control files
8.4. Testing Simscan
8.5. Activating Simscan
This is a quick guide to install Simscan, ClamAV and Chkuser setting up an antivirus/antispam[1] solution to your Qmail server.
By following this guide you’ll end up with a running installation of these products. The goal here is to not miss any detail needed to set them up. If you see that something is missing, contact me – see contact info in About this guide section.
It’s assumed you already know how to manage a Qmail server, and you know how to compile products from the source. By following this installation process we’re going to apply 2 patches over netqmail, so you have to understand what you’re doing.
This installation was tested only in a RedHat 9.0 but it should work for other systems too.
We use these three packages to implement an antivirus/antispam[1] solution to our Qmail/Vpopmail mail server.
[1] Currently the antispam capabilities of the presented installation are limited to those added by the Chkuser package. For a more complete antispam solution we should add Spamassassin to this installation. Simscan was written with Spamassassin in mind, but we’re still not using it here. A future version of this guide will include the Spamassassin integration with Simscan. More info about it, look up in http://www.qmailwiki.org/Simscan/Guide.
Simscan is a simple program that enables qmail-smtpd to reject viruses, spam, and block attachments during the SMTP conversation so the email never makes it into your computers. It is completely open source and uses other open source components. Very efficient and written in C. Simscan can apply 4 different types of scanners: 1 – virus scanner, 2 - attachment extension scanner (searches for .pif, .scr, … attachments), 3 - regular expression scanner, 4 - spam content scanner.
More info about it in:
http://www.inter7.com/?page=simscan
http://www.qmailwiki.org/index.php?title=Simscan
Clam AntiVirus is a GPL anti-virus toolkit for UNIX. The main purpose of this software is the integration with mail servers (attachment scanning). The package provides a flexible and scalable multi-threaded daemon, a command line scanner, and a tool for automatic updating via Internet. The programs are based on a shared library distributed with the Clam AntiVirus package, which you can use with your own software. Most importantly, the virus database is kept up to date.
More info about it in:
Chkuser is a patch to qmail-smtpd executable adding to it a lot of new features, specially, the capability of refusing to receive messages for e-mail accounts that doesn’t exist. The original qmail-smtpd accepts by default all messages, checking later for the existence of recipients. So, if the message is delivered to not existing recipients, a lot of additional system work and network traffic are generated, with multiple expensive bouncing if the sender is a fake one. Chkuser also enables qmail-smtpd to respond to settings passed by a bunch of new environment variables, like CHKUSER_RCPTLIMIT and CHKUSER_WRONGRCPTLIMIT.
More info about it in:
http://www.interazioni.it/opensource/chkuser
How they work together
In summary, when a new SMTP connection begins, qmail-smtpd will first execute the Chkuser tests to know if it will accept or reject the message, if it accepts, qmail-smtpd will trigger Simscan that will trigger ClamAV for virus scanning, and after it, if the message was considered clean, Simscan triggers qmail-queue to deliver the message to its destination, otherwise it blocks the message by returning an error code to qmail-smtpd.
This guide assumes that you already have a mail server running with these three products:
· netqmail-1.05: http://www.qmail.org. Note: If you’re using the standard qmail-1.03 package, it should suffice, but you need to patch it with QMAILQUEUE patch to enable Simscan to scan the mail messages.
· ucspi-tcp: http://cr.yp.to/ucspi-tcp.html.
· vpopmail: http://www.inter7.com.br.
We won’t cover the installation of these packages in this document. Refer to http://www.flounder.net/qmail/qmail-howto.html and http://www.inter7.com/vpopmail/install.txt to get installation instructions.
This is the list of the packages necessary to make Simscan, ClamAV and Chkuser work. For each package listed, go to its website and download the latest stable version of it. There are required and recommended packages. You can choose not to install the recommended packages, but you will lose the features they add.
NOTE: We’re listing here the packages names in the versions that were used in our installation, but you should use the most recent versions.
TIP: Download all the packages to a directory called /root/packages/simscan so you can better follow the commands we’re going to use later.
· ClamAV-0.85.1.tar.gz:This is the package with the antivirus. Download its latest version from http://www.ClamAV.net/.
· zlib and zlib-devel packages: They provide the ability of working with .zip files. These already come installed in Redhat 9.0, so we won’t cover their installations.
· gcc compiler suite: (both 2.9x and 3.x are supported) this already come installed in Redhat 9.0, so we won’t cover its installation.
·
gmp-4.1.4.tar.gz: It's very important to install the GMP package because it allows freshclam
(a ClamAV component) to verify the digital
signatures of the virus databases. Download its latest version from http://www.swox.com/gmp/.
·
curl-7.13.2.tar.gz: ClamAV uses curl version >= 7.10.0 to follow the links inside a mail
message and check if they are pointing to viruses. We’re not currently enabling
this feature here, but we want to be able to use it eventually. Download the
latest version from http://curl.haxx.se/.
·
bzip2 and bzip2-devel library: To install them in your Redhat, run ‘up2date bzip2 bzip2-devel’ and you’re done.
· simscan-1.1.tar.gz: The Simscan package. Download its latest version from http://www.inter7.com/?page=simscan.
· pcre-5.0.tar.gz: the Perl Compatible Regular Expressions libraries. Needed to enable simscan’s ‘regex’ scanner. Download its latest version from http://www.pcre.org.
· qmail-queue-custom-error.patch: Enables Simscan to return the appropriate message for each e-mail it refuses to deliver. It is bundled with Simscan source, in the ~/contrib directory, so you don’t have to download it from elsewhere.
· ClamAV: ClamAV is required for the antivirus function of Simscan. You should have already downloaded ClamAV at this point.
· chkuser-2.0.8b-release.tar.gz: The Chkuser package. Download it from http://www.interazioni.it/opensource/chkuser/download
· netqmail-1.05: Chkuser can be applied over netqmail-1.05, which already contains some patches applied. To know which other Qmail versions Chkuser is compatible with, look up in http://www.interazioni.it/opensource/chkuser/documentation/installation/automatic.html
Before we install ClamAV and Simscan, we’ll install the Qmail patches. Let’s begin with Chkuser.
Untar chkuser-2.0.8b-release.tar.gz to /usr/local/src directory:
cd /usr/local/src
tar –xvzf /root/packages/simscan/chkuser-2.0.8b-release.tar.gz
Now go to netqmail source directory and apply the netqmail-1.05_chkuser-2.0.8.patch:
cd /usr/local/src/netqmail-1.05/netqmail-1.05
patch < /usr/local/src/chkuser-2.0.8b-release/netqmail-1.05_chkuser-2.0.8.patch
The patch command will return the lines bellow:
patching file Makefile
patching file TARGETS
patching file chkuser.c
patching file chkuser.h
patching file chkuser_settings.h
patching file conf-cc
patching file qmail-smtpd.c
Fixing the path to vpopmail home in the
source files
Chkuser believes the default home directory for the vpopmail user is /home/vpopmail, which is not true for most of vpopmail installations. Here vpopmail is installed under /var/vpopmail, so let’s edit the files Makefile and conf-cc to fix the path to vpopmail home directory.
Edit Makefile:
vi Makefile
Substitute the line with the wrong path by this one bellow:
VPOPMAIL_HOME=/var/vpopmail
Edit conf-cc
vi conf-cc
Substitute the line with the wrong path by this one bellow:
cc -O2 -I/var/vpopmail/include
Setting qmail-smtpd to run under vpopmail
UID and GID
To verify the existence of the email accounts, qmail-smtpd will need to read vpopmail files and directories. The standard qmail installation sets qmail-smtpd to run under ‘qmaild’ UID and GID, we need to change it to vpopmail user UID and GID.
Bellow is an example of a /service/qmail-smtpd/run script to run qmail-smtpd as Vpopmail UID and GID:
#!/bin/sh
VPOPMAILUID=`id -u vpopmail`
VPOPMAILGID=`id -g vpopmail`
VpopmailHome=`grep vpopmail /etc/passwd|cut -d':' -f6`
exec /usr/local/bin/softlimit -m 10000000 \
/usr/local/bin/tcpserver -v -p -x $VpopmailHome/etc/tcp.smtp.cdb \
-u $VPOPMAILUID -g $VPOPMAILGID 0 smtp rblsmtpd -b -rbl.spamcop.net /var/qmail/bin/qmail-smtpd 2>&1
NOTE: the softlimit we’re using here is 10,000,000 bytes instead of the usual 2,000,000 bytes. This bigger softlimit exists to give room for simscan and clamav execution under the qmail-smtpd process.
Untar simscan to /usr/local/src:
cd /usr/local/src
tar –xvzf /root/packages/simscan/simscan-1.1.tar.gz
Patch netqmail:
cd /usr/local/src/netqmail-1.05/netqmail-1.05
patch < /usr/local/src/simscan-1.1/contrib/qmail-queue-custom-error.patch
The patch command will return the following lines:
patching file qmail.c
Hunk #1 FAILED at 14.
Hunk #2 succeeded at 56 (offset 11 lines).
Hunk #4 succeeded at 152 (offset 11 lines).
1 out of 4 hunks FAILED -- saving rejects to file qmail.c.rej
patching file qmail.h
As you can see, the patch to qmail.h was successful, but the patch for qmail.c was unsuccessful. This is because this patch is not prepared to be installed after the QMAILQUEUE patch that comes installed with netqmail.
To solve this or you edit qmail.c and add
manually the rejected hunk saved in qmail.c.rej, or you can use the qmail.c
file bellow that was previously edited by Darrel (don’t know his lastname) and
posted in the simscan’s mailling in http://article.gmane.org/gmane.mail.qmail.simscan/1395.
The thread subject was ‘qmail-queue patch isn't compatible
withqmail-queue-custom-error.patch’.
For convenience, the contents of this file are also in APPENDIX A. qmail.c source for netqmail-1.05 with QMAILQUEUE patch plus qmail-queue-custom-error.patch in this document.
So, if you are using netqmail-1.05 and the same qmail-queue-custom-error.patch we’re using, you can cut and paste the contents posted in that link and save it in a file called qmail.c.
Time to compile qmail with the patches we just applied:
cd /usr/local/src/netqmail-1.05/netqmail-1.05
make
For precaution, backup your actual qmail binaries, just in case something goes wrong:
tar –cvzf /root/qmail_bin.tar.gz /var/qmail/bin
Stop qmail execution
svc –d /service/qmail*
Install the new binaries:
make setup check
Start qmail daemons again:
svc –u /service/qmail*
Check to see if everything is fine. If chkuser is already working, you’re going to see a lot of CHKUSER messages for each new SMTP connection inside qmail-smtpd logfile, usually in /var/log/qmail-smtpd/current.
Try to send an e-mail for a user that doesn’t exist in your domain, and see what chkuser will answer to you. It’ll be something like:
<asdfasdfasdf@mydomain.com.br>:
200.195.39.13
said: 511 sorry, no mailbox here by that name (#5.1.1 -
chkuser)
It also logs when an existing user is found.
If everything was ok, just because of chkuser you now have a mail server much nicer than you used to have ;-)
Among all the new features Chkuser introduces into qmail-smtpd, we picked up these two that we believe are essential:
· CHKUSER_RCPTLIMIT: A qmail-smtpd environment variable that enables defining a limit for the maximum number of recipients permitted in 1 SMTP connection.
· CHKUSER_WRONGRCPTLIMIT: A qmail-smtpd environment variable that permits defining a limit for the maximum number of wrong recipients (recipients that don’t exist) permitted in 1 SMTP connection
To enable these variables, edit the file /var/vpopmail/etc/tcp.smtp and add the following line:
:allow,CHKUSER_RCPTLIMIT="15",CHKUSER_WRONGRCPTLIMIT="3"
NOTE: The limits where setting here make sense to our needs adjust them to fit yours.
Recompile the tcp.smtp.cdb file:
tcprules /var/vpopmail/etc/tcp.smtp.cdb \
/var/vpopmail/etc/tcp.smtp.tmp < /var/vpopmail/etc/tcp.smtp
Soon you’ll see in qmail-smtpd logfile chkuser blocking the spammers.
To install gmp-4.1.4.tar.gz, untar it to /usr/local/src and compile it with the commands bellow:
cd /usr/local/src
tar –xvzf /root/packages/simscan/gmp-4.1.4.tar.gz
cd gmp-4.1.4
./configure
make
make install
To install curl-7.13.2.tar.gz,
first remove the existing curl and curl-devel rpm packages, if they are
installed
rpm –e curl curl-devel
Untar curl-7.13.2.tar.gz to /usr/local/src and compile it with the following commands:
cd /usr/local/src
tar –xvzf /root/packages/simscan/curl-7.13.2.tar.gz
cd curl-7.13.2
./configure
make
make install
Create clamav user and group:
groupadd clamav
useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav
Untar clamav:
cd /usr/local/src
tar -xvzf /root/packages/simscan/clamav-0.85.1.tar.gz
Compile it, setting /etc as its “sysconfdir” directory:
./configure --sysconfdir=/etc
make
make install-strip
Now it’s time to start clamd daemon and set it to start whenever the system boots.
If you try to to start it now by hand, you’ll see the following error messages
clamd
ERROR: Please edit the example config file /etc/clamd.conf.
ERROR: Can't open/parse the config file /etc/clamd.conf
In enforces you to read the /etc/clamd.conf and edit it. So edit it and do the following modifications:
# Comment or remove the line below.
#Example
Change the path to the logfile to /var/log:
LogFile /var/log/clamd.log
Add it to initialization script /etc/rc.d/rc.local:
vi /etc/rc.d/rc.local
/usr/local/sbin/clamd
Start it manually now
clamd
To activate the automatic download of the virus definitions database, you have to schedule a utility called /usr/local/bin/freshclam in your crontab.
Before you try to run freshclam, edit its configuration file /etc/freshclam.conf and comment the line “Example” just like you did in /etc/clamd.conf. Or freshclam won’t execute and will print an error message.
After editing this file, add the freshclam command line to an hourly execution in your crontab:
Open the root crontab:
crontab -e
Add the line bellow
N * * * * /usr/local/bin/freshclam –quiet
Where “N” is a number between 0 and 59 defining a minute to start the job execution. The ClamAV website asks for people not to use the multiple of 10 time slots because a lot of freshclam clients are connecting at those time slots.
You can execute freshclam by hand right now and see it updating the virus database:
/usr/local/bin/freshclam
To install pcre-5.0.tar.gz, untar it to /usr/local/src and compile it with the commands bellow:
cd /usr/local/src
tar –xvzf /root/packages/simscan/pcre-5.0.tar.gz
cd pcre-5.0
./configure
make
make install
The other prerequisites, ClamAV and qmail-queue-custom-error.patch, where already installed at this point.
Adding simscan user and group:
useradd -g clamav -s /bin/false -c \
"Simscan - a qmail-queue substitute" simscan
Untar it to /usr/local/src:
cd /usr/local/src
tar –xvzf /root/packages/simscan/simscan-1.1.tar.gz
cd simscan-1.1
Configuring simscan installation:
./configure --enable-per-domain=y \
--enable-attach=y --enable-clamav=y \
--enable-regex --enable-received \
--enable-clamavdb-path=/usr/local/share/clamav --disable-ripmime \
--enable-custom-smtp-reject
The command above will print the following lines:
Current settings
---------------------------------------
user = simscan
qmail directory = /var/qmail
work directory = /var/qmail/simscan
control directory = /var/qmail/control
qmail queue program = /var/qmail/bin/qmail-queue
clamdscan program = /usr/local/bin/clamdscan
clamav scan = ON
trophie scanning = OFF
attachement scan = ON
ripmime program = /usr/local/bin/ripmime
custom smtp reject = ON
drop message = OFF
regex scanner = ON
quarantine processing = OFF
domain based checking = ON
add received header = ON
spam scanning = OFF
Compile and install it:
make
make install-strip
Since we compiled Simscan with the --enable-per-domain option, simscan will be able to do “per domain scanning”. Per domain scanning allows the administrator to explicitly state what scanning occurs for what domain. In addition, attachment scanning can be enabled or disabled for each domain.
Simscan will read its scanning rules from /var/qmail/control/simcontrol.cdb. This .cdb file is generated by running /var/qmail/bin/simscanmk. This command will create that .cdb file based in a text file called /var/qmail/control/simcontrol, this is the file where we’ll define the per domain scanning rules.
Edit /var/qmail/control/simcontrol:
vi /var/qmail/control/simcontrol
Add the following rule to disable the spam scanner, enable clam and attach scanners, setting the attach scanner to unconditionally block every e-mail containing .pif, .bat, .com and .exe attachments:
:clam=yes,spam=no,attach=.scr:.bat:.com:.pif:.exe
NOTE: The syntax above is for a ‘default rule’, a rule valid for all domains in the machine. Observe that there is no domain name before the initial colon “:” sign. To add a rule valid only for a specific domain, put the domain name before the colon, Example.: somedomain.com:clam=yes,attach=no. Read the README file from simscan source for additional help with the syntax.
Generate ~/simcontrol.cdb file:
/var/qmail/bin/simscanmk
There is another .cdb file simscan reads, /var/qmail/control/simversions.cdb, from where it gets the “scanner versions” information. This information is used by simscan to add a “Received: by simscan...” header to each scanned message containing the appropriate version of each of its scanners. The added header will look like this one bellow:
Received: by simscan 1.1.0 ppid: 8053, pid: 8054, t: 1.7363s
scanners: regex: 1.1.0 attach: 1.1.0 clamav: 0.85.1/m:31/d:858
To create the /var/qmail/control/simversions.cdb file simply run simscanmk with the ‘-g’ option:
/var/qmail/bin/simscanmk -g
This command will discover the proper scanner versions and add them to the .cdb file. Remember to rerun this command every time you update one of the scanners, say after you update clamav to a newer version.
Before definitely activating simscan, test if from the command line, enabling the DEBUG messages.
Create a draft text file used to be a mail body:
echo “hi, testing.” > mailtest.txt
Then, send this file as an e-mail message with the following command:
QMAILQUEUE=/var/qmail/bin/simscan
SIMSCAN_DEBUG=2 qmail-inject \
somercpt@somedomain < mailtest.txt
NOTE: remember to put a valid e-mail in place of ‘somercpt@somedomain’.
This will print a lot of debugging info, and if everything was ok, the last few lines will look like these:
simscan: cdb looking up version regex
simscan: cdb looking up version attach
simscan: calling clamdscan
simscan: cdb looking up version clamav
simscan: normal clamdscan return code: 0
simscan: done, execing qmail-queue
simscan: qmail-queue exited 0
Now that (hopefully) simscan is running fine, lets inform of its existence to qmail-smtpd process, by setting the QMAILQUEUE environment variable.
You can do this by adding this variable to the tcp.smtp.cdb file, from where tcpserver will get the environment variables to pass for qmail-smtpd.
So, edit /var/vpopmail/etc/tcp.smtp and add the following line:
:allow,CHKUSER_RCPTLIMIT="15",CHKUSER_WRONGRCPTLIMIT="3",QMAILQUEUE="/var/qmail/bin/simscan"
Regenerate the tcp.smtp.cdb file:
tcprules /var/vpopmail/etc/tcp.smtp.cdb \
/var/vpopmail/etc/tcp.smtp.tmp < /var/vpopmail/etc/tcp.smtp
You should see simscan activity in /var/qmail/qmail-smtp/current logfile.
Author: Bruno Negrão
Modified: 2005/05/25
Contact: vpopmail at engepel dot com dot br
!!!!!!!!!!!!!!!!!!!
BELLOW STARTS QMAIL.C !!!!!!!!!!!!!!!!!!!!!!!!!
#include "substdio.h"
#include "readwrite.h"
#include "wait.h"
#include "exit.h"
#include "fork.h"
#include "fd.h"
#include "qmail.h"
#include "auto_qmail.h"
#include "env.h"
static char *binqqargs[2] = { 0, 0 } ;
static void setup_qqargs()
{
if(!binqqargs[0])
binqqargs[0] = env_get("QMAILQUEUE");
if(!binqqargs[0])
binqqargs[0] = "bin/qmail-queue";
}
int qmail_open(qq)
struct qmail *qq;
{
int pim[2];
int pie[2];
int pierr[2];
setup_qqargs();
if (pipe(pim) == -1) return -1;
if (pipe(pie) == -1) { close(pim[0]); close(pim[1]); return -1; }
if (pipe(pierr) == -1) {
close(pim[0]); close(pim[1]);
close(pie[0]); close(pie[1]);
close(pierr[0]); close(pierr[1]);
return -1;
}
switch(qq->pid = vfork()) {
case -1:
close(pierr[0]); close(pierr[1]);
close(pim[0]); close(pim[1]);
close(pie[0]); close(pie[1]);
return -1;
case 0:
close(pim[1]);
close(pie[1]);
close(pierr[0]); /* we want to receive data */
if (fd_move(0,pim[0]) == -1) _exit(120);
if (fd_move(1,pie[0]) == -1) _exit(120);
if (fd_move(4,pierr[1]) == -1) _exit(120);
if (chdir(auto_qmail) == -1) _exit(61);
execv(*binqqargs,binqqargs);
_exit(120);
}
qq->fdm = pim[1]; close(pim[0]);
qq->fde = pie[1]; close(pie[0]);
qq->fderr = pierr[0]; close(pierr[1]);
substdio_fdbuf(&qq->ss,write,qq->fdm,qq->buf,sizeof(qq->buf));
qq->flagerr = 0;
return 0;
}
unsigned long qmail_qp(qq) struct qmail *qq;
{
return qq->pid;
}
void qmail_fail(qq) struct qmail *qq;
{
qq->flagerr = 1;
}
void qmail_put(qq,s,len) struct qmail *qq; char *s; int len;
{
if (!qq->flagerr) if (substdio_put(&qq->ss,s,len) == -1)
qq->flagerr = 1;
}
void qmail_puts(qq,s) struct qmail *qq; char *s;
{
if (!qq->flagerr) if (substdio_puts(&qq->ss,s) == -1)
qq->flagerr = 1;
}
void qmail_from(qq,s) struct qmail *qq; char *s;
{
if (substdio_flush(&qq->ss) == -1) qq->flagerr = 1;
close(qq->fdm);
substdio_fdbuf(&qq->ss,write,qq->fde,qq->buf,sizeof(qq->buf));
qmail_put(qq,"F",1);
qmail_puts(qq,s);
qmail_put(qq,"",1);
}
void qmail_to(qq,s) struct qmail *qq; char *s;
{
qmail_put(qq,"T",1);
qmail_puts(qq,s);
qmail_put(qq,"",1);
}
char *qmail_close(qq)
struct qmail *qq;
{
int wstat;
int exitcode;
int match;
char ch;
static char errstr[256];
int len = 0;
qmail_put(qq,"",1);
if (!qq->flagerr) if (substdio_flush(&qq->ss) == -1)
qq->flagerr = 1;
close(qq->fde);
substdio_fdbuf(&qq->ss,read,qq->fderr,qq->buf,sizeof(qq->buf));
while( substdio_bget(&qq->ss,&ch,1) && len < 255){
errstr[len]=ch;
len++;
}
if (len > 0) errstr[len]='\0'; /* add str-term */
close(qq->fderr);
if (wait_pid(&wstat,qq->pid) != qq->pid)
return "Zqq waitpid surprise (#4.3.0)";
if (wait_crashed(wstat))
return "Zqq crashed (#4.3.0)";
exitcode = wait_exitcode(wstat);
switch(exitcode) {
case 115: /* compatibility */
case 11: return "Denvelope address too long for qq
(#5.1.3)";
case 31: return "Dmail server permanently rejected
message (#5.3.0)";
case 51: return "Zqq out of memory (#4.3.0)";
case 52: return "Zqq timeout (#4.3.0)";
case 53: return "Zqq write error or disk full
(#4.3.0)";
case 0: if (!qq->flagerr) return ""; /* fall
through */
case 54: return "Zqq read error (#4.3.0)";
case 55: return "Zqq unable to read configuration
(#4.3.0)";
case 56: return "Zqq trouble making network connection
(#4.3.0)";
case 61: return "Zqq trouble in home directory
(#4.3.0)";
case 63:
case 64:
case 65:
case 66:
case 62: return "Zqq trouble creating files in queue
(#4.3.0)";
case 71: return "Zmail server temporarily rejected
message (#4.3.0)";
case 72: return "Zconnection to mail server timed out
(#4.4.1)";
case 73: return "Zconnection to mail server rejected
(#4.4.1)";
case 74: return "Zcommunication with mail server failed
(#4.4.2)";
case 91: /* fall through */
case 81: return "Zqq internal bug (#4.3.0)";
case 120: return "Zunable to exec qq (#4.3.0)";
default:
if (exitcode == 82 && len > 2){
return errstr;
}
if ((exitcode >= 11) && (exitcode
<= 40))
return "Dqq permanent problem
(#5.3.0)";
return "Zqq temporary problem
(#4.3.0)";
}
}
!!!!!!!!!!!!!!!!!!! STOP ABOVE THIS LINE !!!!!!!!!!!!!!!!!!!!!!!!!