Development Notes for Novell NetMail Agents
NetMail is designed with modularity in mind. Once a message is received by the STMP agent, it is run though the message queues by NMAP. Agents attached to each queue can then modify, delete, or pass the message to the next queue. As I develop my agents I will be posting notes on this page to assist others in developing their own NetMail agents. I will also be adding small programs to CVS that I have written along the way. These small programs are released under the GNU GPL.
The first problem I ran into when I began this project was with registering my agent with NMAP. Novell's NMAP protocol specification lists the agent registration command as "QWAIT <identifier> <queue> <port>" when the actual command is "QWAIT <queue> <port> <identifier>".
The next problem was a little harder to workaround. As NetMail is heavily multithreaded, any NetMail agent must also be. Since my NetMail servers run on NetWare, I was using NetWare as my development platform. Unfortunately, per the Perl for NetWare readme, the "fork method is not yet implemented on NetWare." Not too big a problem though, I can always use threads. Except "scripts that use the 'Thread' and 'threads' modules may not work as desired." Ok, no problem, guess I'll just have to use non-blocking IO. Unfortunately my tests indicate IO::Select does not work on NetWare either. Bottom line, there is no way I can see to do this in Perl on NetWare. Luckily NetMail is designed so its agents can be on multiple servers. From this point on development was geared toward running SpamAssassin and the agent on a Linux box connecting to NMAP over the network.
Specifically the problem with IO::Select on NetWare, is that for some reason IO::Select->can_read always immediately returns my listen socket, even though nothing has connected to it yet. This causes my IO::Socket->accept to block. The below three line program shows the problem: