v1.3.1
This commit is contained in:
parent
333cb6f46b
commit
c1992c3def
@ -1,6 +1,13 @@
|
||||
E-MailRelay Change Log
|
||||
======================
|
||||
|
||||
1.3 -> 1.3.1
|
||||
------------
|
||||
* Windows resource leak from CreateProcess() fixed.
|
||||
* Windows dialog box double-close fix.
|
||||
* Some documentation for the "--scanner" switch.
|
||||
* New usage patterns section in the user guide.
|
||||
|
||||
1.2 -> 1.3
|
||||
----------
|
||||
* Client protocol waits for a greeting from the server on startup [bug-id 842156].
|
||||
|
5
README
5
README
@ -79,7 +79,7 @@ The code was originally developed on SuSE Linux 7.1 using:
|
||||
* glibc 2.2.4 (libc.so.6)
|
||||
* autoconf 2.52
|
||||
|
||||
and ported to Windows 98 using:
|
||||
and to Windows 98 using:
|
||||
* MSVC 6.0
|
||||
|
||||
Recent releases were developed on SuSE Linux 9.0 using:
|
||||
@ -87,6 +87,9 @@ Recent releases were developed on SuSE Linux 9.0 using:
|
||||
* gcc 3.3.1
|
||||
* autoconf 2.57
|
||||
|
||||
and on Windows NT4 SP6 using:
|
||||
* MSVC 6.0 SP3
|
||||
|
||||
The code has also been built successfully on:
|
||||
* MacOS X
|
||||
* FreeBSD on Intel hardware
|
||||
|
2
configure
vendored
2
configure
vendored
@ -1557,7 +1557,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE=emailrelay
|
||||
VERSION=1.3
|
||||
VERSION=1.3.1
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
dnl
|
||||
|
||||
AC_INIT(src/gsmtp/gsmtp.h)
|
||||
AM_INIT_AUTOMAKE(emailrelay,1.3)
|
||||
AM_INIT_AUTOMAKE(emailrelay,1.3.1)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl ===
|
||||
|
@ -97,7 +97,7 @@ Enables authentication with remote server, using the given secrets file.
|
||||
<DT><B>-Y,--client-filter </B><I>program</I>
|
||||
|
||||
<DD>
|
||||
Defines a mail processor program for when forwarding.
|
||||
Specifies an external program to process messages when they are forwarded.
|
||||
<DT><B>-e,--close-stderr </B>
|
||||
|
||||
<DD>
|
||||
@ -117,15 +117,15 @@ Sets an override for the host's fully qualified domain name.
|
||||
<DT><B>-X,--dont-listen </B>
|
||||
|
||||
<DD>
|
||||
Dont listen for smtp connections (usually used with <I>--admin</I>).
|
||||
Disables listening for smtp connections (usually used with <I>--admin</I>).
|
||||
<DT><B>-x,--dont-serve </B>
|
||||
|
||||
<DD>
|
||||
Dont act as a server (usually used with <I>--forward</I>).
|
||||
Disables acting as a server (usually used with <I>--forward</I>).
|
||||
<DT><B>-z,--filter </B><I>program</I>
|
||||
|
||||
<DD>
|
||||
Defines a mail processor program for when storing.
|
||||
Specifies an external program to process messages as they are stored.
|
||||
<DT><B>-f,--forward </B>
|
||||
|
||||
<DD>
|
||||
@ -141,11 +141,11 @@ Displays help text and exits.
|
||||
<DT><B>-m,--immediate </B>
|
||||
|
||||
<DD>
|
||||
Forwards each message as soon as it is received (requires <I>--forward-to</I>).
|
||||
Enables immediating forwarding of messages as soon as they are received (requires <I>--forward-to</I>).
|
||||
<DT><B>-I,--interface </B><I>ip-address</I>
|
||||
|
||||
<DD>
|
||||
Listen on a specific interface.
|
||||
Defines the listening interface for new connections.
|
||||
<DT><B>-l,--log </B>
|
||||
|
||||
<DD>
|
||||
@ -165,7 +165,7 @@ Disables syslog output.
|
||||
<DT><B>-i,--pid-file </B><I>pid-file</I>
|
||||
|
||||
<DD>
|
||||
Records the daemon process-id in the given file.
|
||||
Defines a file for storing the daemon process-id.
|
||||
<DT><B>-O,--poll </B><I>period</I>
|
||||
|
||||
<DD>
|
||||
@ -177,7 +177,7 @@ Specifies the smtp listening port number.
|
||||
<DT><B>-P,--postmaster </B>
|
||||
|
||||
<DD>
|
||||
Allow delivery to postmaster but reject all other local mailbox addresses.
|
||||
Allows delivery to the postmaster but rejects all other local mailbox addresses.
|
||||
<DT><B>-r,--remote-clients </B>
|
||||
|
||||
<DD>
|
||||
@ -186,6 +186,10 @@ Allows remote clients to connect.
|
||||
|
||||
<DD>
|
||||
Sets the response timeout (in seconds) when talking to a remote server (default is 1800).
|
||||
<DT><B>-R,--scanner </B><I>host:port</I>
|
||||
|
||||
<DD>
|
||||
Specifies an external network server to process messages when they are stored.
|
||||
<DT><B>-S,--server-auth </B><I>file</I>
|
||||
|
||||
<DD>
|
||||
@ -205,7 +209,7 @@ Generates more verbose output (works with <I>--help</I> and <I>--log</I>).
|
||||
<DT><B>-Z,--verifier </B><I>program</I>
|
||||
|
||||
<DD>
|
||||
Defines an external address verifier program.
|
||||
Specifies an external program for address verification.
|
||||
<DT><B>-V,--version </B>
|
||||
|
||||
<DD>
|
||||
@ -464,7 +468,7 @@ Graeme Walker, mailto:<A HREF="mailto:graeme_walker@users.sourceforge.net">graem
|
||||
This document was created by
|
||||
<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>,
|
||||
using the manual pages.<BR>
|
||||
Time: 20:53:37 GMT, February 26, 2004
|
||||
Time: 15:37:43 GMT, May 09, 2004
|
||||
</BODY>
|
||||
</HTML>
|
||||
<!-- Copyright (C) 2001-2004 Graeme Walker <graeme_walker@users.sourceforge.net>. All rights reserved. -->
|
||||
|
@ -75,7 +75,7 @@ Runs as a server: equivalent to \fI--log\fR \fI--close-stderr\fR \fI--postmaster
|
||||
Enables authentication with remote server, using the given secrets file.
|
||||
.TP
|
||||
.B \-Y,--client-filter \fIprogram\fR
|
||||
Defines a mail processor program for when forwarding.
|
||||
Specifies an external program to process messages when they are forwarded.
|
||||
.TP
|
||||
.B \-e,--close-stderr
|
||||
Closes the standard error stream after start-up.
|
||||
@ -90,13 +90,13 @@ Generates debug-level logging (if compiled-in).
|
||||
Sets an override for the host's fully qualified domain name.
|
||||
.TP
|
||||
.B \-X,--dont-listen
|
||||
Dont listen for smtp connections (usually used with \fI--admin\fR).
|
||||
Disables listening for smtp connections (usually used with \fI--admin\fR).
|
||||
.TP
|
||||
.B \-x,--dont-serve
|
||||
Dont act as a server (usually used with \fI--forward\fR).
|
||||
Disables acting as a server (usually used with \fI--forward\fR).
|
||||
.TP
|
||||
.B \-z,--filter \fIprogram\fR
|
||||
Defines a mail processor program for when storing.
|
||||
Specifies an external program to process messages as they are stored.
|
||||
.TP
|
||||
.B \-f,--forward
|
||||
Forwards stored mail on startup (requires \fI--forward-to\fR).
|
||||
@ -108,10 +108,10 @@ Specifies the remote smtp server (required by \fI--forward\fR, \fI--poll\fR, \fI
|
||||
Displays help text and exits.
|
||||
.TP
|
||||
.B \-m,--immediate
|
||||
Forwards each message as soon as it is received (requires \fI--forward-to\fR).
|
||||
Enables immediating forwarding of messages as soon as they are received (requires \fI--forward-to\fR).
|
||||
.TP
|
||||
.B \-I,--interface \fIip-address\fR
|
||||
Listen on a specific interface.
|
||||
Defines the listening interface for new connections.
|
||||
.TP
|
||||
.B \-l,--log
|
||||
Writes log information on standard error and syslog.
|
||||
@ -126,7 +126,7 @@ Does not detach from the terminal.
|
||||
Disables syslog output.
|
||||
.TP
|
||||
.B \-i,--pid-file \fIpid-file\fR
|
||||
Records the daemon process-id in the given file.
|
||||
Defines a file for storing the daemon process-id.
|
||||
.TP
|
||||
.B \-O,--poll \fIperiod\fR
|
||||
Enables polling with the specified period (requires \fI--forward-to\fR).
|
||||
@ -135,7 +135,7 @@ Enables polling with the specified period (requires \fI--forward-to\fR).
|
||||
Specifies the smtp listening port number.
|
||||
.TP
|
||||
.B \-P,--postmaster
|
||||
Allow delivery to postmaster but reject all other local mailbox addresses.
|
||||
Allows delivery to the postmaster but rejects all other local mailbox addresses.
|
||||
.TP
|
||||
.B \-r,--remote-clients
|
||||
Allows remote clients to connect.
|
||||
@ -143,6 +143,9 @@ Allows remote clients to connect.
|
||||
.B \-T,--response-timeout \fItime\fR
|
||||
Sets the response timeout (in seconds) when talking to a remote server (default is 1800).
|
||||
.TP
|
||||
.B \-R,--scanner \fIhost:port\fR
|
||||
Specifies an external network server to process messages when they are stored.
|
||||
.TP
|
||||
.B \-S,--server-auth \fIfile\fR
|
||||
Enables authentication of remote clients, using the given secrets file.
|
||||
.TP
|
||||
@ -156,7 +159,7 @@ Names the effective user to switch to when started as root (default is \fIdaemon
|
||||
Generates more verbose output (works with \fI--help\fR and \fI--log\fR).
|
||||
.TP
|
||||
.B \-Z,--verifier \fIprogram\fR
|
||||
Defines an external address verifier program.
|
||||
Specifies an external program for address verification.
|
||||
.TP
|
||||
.B \-V,--version
|
||||
Displays version information and exits.
|
||||
|
@ -1,4 +1,5 @@
|
||||
E-MailRelay Reference
|
||||
|
||||
=====================
|
||||
|
||||
Introduction
|
||||
@ -35,7 +36,7 @@ where <switch> is:
|
||||
Enables authentication with remote server, using the given secrets file.
|
||||
|
||||
# --client-filter (-Y)
|
||||
Defines a mail processor program for when forwarding.
|
||||
Specifies an external program to process messages when they are forwarded.
|
||||
|
||||
# --close-stderr (-e)
|
||||
Closes the standard error stream after start-up.
|
||||
@ -50,13 +51,13 @@ where <switch> is:
|
||||
Sets an override for the host's fully qualified domain name.
|
||||
|
||||
# --dont-listen (-X)
|
||||
Dont listen for smtp connections (usually used with --admin).
|
||||
Disables listening for smtp connections (usually used with --admin).
|
||||
|
||||
# --dont-serve (-x)
|
||||
Dont act as a server (usually used with --forward).
|
||||
Disables acting as a server (usually used with --forward).
|
||||
|
||||
# --filter (-z)
|
||||
Defines a mail processor program for when storing.
|
||||
Specifies an external program to process messages as they are stored.
|
||||
|
||||
# --forward (-f)
|
||||
Forwards stored mail on startup (requires --forward-to).
|
||||
@ -68,10 +69,10 @@ where <switch> is:
|
||||
Displays help text and exits.
|
||||
|
||||
# --immediate (-m)
|
||||
Forwards each message as soon as it is received (requires --forward-to).
|
||||
Enables immediating forwarding of messages as soon as they are received (requires --forward-to).
|
||||
|
||||
# --interface (-I)
|
||||
Listen on a specific interface.
|
||||
Defines the listening interface for new connections.
|
||||
|
||||
# --log (-l)
|
||||
Writes log information on standard error and syslog.
|
||||
@ -86,7 +87,7 @@ where <switch> is:
|
||||
Disables syslog output.
|
||||
|
||||
# --pid-file (-i)
|
||||
Records the daemon process-id in the given file.
|
||||
Defines a file for storing the daemon process-id.
|
||||
|
||||
# --poll (-O)
|
||||
Enables polling with the specified period (requires --forward-to).
|
||||
@ -95,7 +96,7 @@ where <switch> is:
|
||||
Specifies the smtp listening port number.
|
||||
|
||||
# --postmaster (-P)
|
||||
Allow delivery to postmaster but reject all other local mailbox addresses.
|
||||
Allows delivery to the postmaster but rejects all other local mailbox addresses.
|
||||
|
||||
# --remote-clients (-r)
|
||||
Allows remote clients to connect.
|
||||
@ -103,6 +104,9 @@ where <switch> is:
|
||||
# --response-timeout (-T)
|
||||
Sets the response timeout (in seconds) when talking to a remote server (default is 1800).
|
||||
|
||||
# --scanner (-R)
|
||||
Specifies an external network server to process messages when they are stored.
|
||||
|
||||
# --server-auth (-S)
|
||||
Enables authentication of remote clients, using the given secrets file.
|
||||
|
||||
@ -116,7 +120,7 @@ where <switch> is:
|
||||
Generates more verbose output (works with --help and --log).
|
||||
|
||||
# --verifier (-Z)
|
||||
Defines an external address verifier program.
|
||||
Specifies an external program for address verification.
|
||||
|
||||
# --version (-V)
|
||||
Displays version information and exits.
|
||||
@ -346,6 +350,17 @@ Bear in mind the following points when writing "--filter" programs:
|
||||
* Windows JScript and VBScript programs must be run using "cscript".
|
||||
* Windows Perl programs must be run from a batch file, or from a JScript/VBScript wrapper.
|
||||
|
||||
It is also possible to run a separate server process to pre-process messages by
|
||||
using the "--scanner" switch, which has the advantage of not blocking the main
|
||||
E-MailRelay process during message pre-processing. The "--scanner" switch is
|
||||
used to specify the IP address and port that the scanner server is listening on.
|
||||
E-MailRelay connects to this address and then uses a simple line-based dialog as
|
||||
each e-mail message is received. E-MailRelay sends the full path of the message
|
||||
content file, and the scanner is expected to respond with "ok" if the message is
|
||||
to be accepted, or an error message. No source code is provided for a scanner
|
||||
process in this release, but *Python's* [http://python.org] support for threads
|
||||
and sockets would make it a good choice of language.
|
||||
|
||||
Address verification
|
||||
--------------------
|
||||
In proxy mode all addresses supplied to the SMTP commands "RCPT" and "VRFY" are
|
||||
|
@ -334,6 +334,39 @@ line in the secrets file. To complete the solution you must have an address
|
||||
verifier script ("--verifier") which rejects remote addresses if the client has
|
||||
not authenticated. Again, refer to the reference guide for further details.
|
||||
|
||||
Usage patterns
|
||||
--------------
|
||||
The simplest ways of using E-MailRelay are as a proxy or as a store-and-forward
|
||||
MTA, but other configurations are possible. For example, you could use the
|
||||
E-MailRelay server to do message storing, but use something else to do the
|
||||
forwarding. Or you could implement simple routing by having a "--filter" program
|
||||
that moves message files into the spool directory of another E-MailRelay
|
||||
process. Or you could have multiple forwarding E-MailRelay processes running off
|
||||
the same spool directory, but trigger them at different times of the day.
|
||||
|
||||
Remember that messages can be introduced directly into the E-MailRelay spool
|
||||
directory using the "emailrelay-submit" utility, and they can be moved out again
|
||||
at any time as long as the envelope file is not "locked" with a ".busy" filename
|
||||
extension. Your "--filter" program can edit messages in any way you want, and it
|
||||
can even remove the current message from the spool directory as long as it lets
|
||||
E-MailRelay know by terminating with an exit code of 100.
|
||||
|
||||
Another important technique is to run E-MailRelay as a server, but use the
|
||||
"--poll" switch so that the server process will also do periodic forwarding.
|
||||
With a short "--poll" period this behaves rather like a proxy, but the
|
||||
submitting client program does not have to wait for the message to be delivered
|
||||
to the remote server. A normal proxy only responds with OK after the SMTP DATA
|
||||
transfer phase once the message has been sucessfully transfered to the next
|
||||
server, but by using the "--poll" mechanism the client gets an OK response
|
||||
immediately. If you don't like the idea of polling the spool directory, you can
|
||||
use a "--filter" program to force the "--poll" timer to expire as soon as a new
|
||||
message is received by exiting with a value of 103.
|
||||
|
||||
For more ideas check out the "--client-filter", "--poll" and "--scanner"
|
||||
switches, and don't overlook the administration interface ("--admin") which you
|
||||
can use to receive notification of message arrival or force message forwarding
|
||||
at any time.
|
||||
|
||||
SpamAssassin
|
||||
------------
|
||||
The E-MailRelay server can use *Spam Assassin* [http://spamassassin.org] to mark
|
||||
@ -386,6 +419,31 @@ Try an E-MailRelay command line like this:
|
||||
But note that you may have to add explicit paths if perl or spamassassin are not
|
||||
on your path.
|
||||
|
||||
If you have a problem with long SpamAssassin processing times causing the
|
||||
submitting program to time-out then you should try moving the spam processing
|
||||
out of the storing server and into the forwarding process. You can do this by
|
||||
replacing the "--filter" switch on the "--as-server" command with a
|
||||
"--client-filter" switch on the "--as-client" command.
|
||||
|
||||
So this:
|
||||
|
||||
emailrelay --as-server --filter /usr/local/bin/myfilter.sh
|
||||
emailrelay --as-client smarthost:smtp
|
||||
|
||||
becomes this:
|
||||
|
||||
emailrelay --as-server
|
||||
emailrelay --as-client smarthost:smtp --client-filter /usr/local/bin/myfilter.sh
|
||||
|
||||
To avoid having to run the "--as-client" forwarding processes repeatedly (eg.
|
||||
from "cron") you can start a long-lived forwarding process that polls the spool
|
||||
directory itself, like this:
|
||||
|
||||
emailrelay --log --close-stderr --dont-listen --poll 30 --forward-to smarthost:smtp ...
|
||||
|
||||
You could then try running several forwarding processes in parallel in order to
|
||||
maximise throughput.
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
Summary: Simple e-mail message transfer agent using SMTP
|
||||
Name: emailrelay
|
||||
Version: 1.3
|
||||
Version: 1.3.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
Source: http://emailrelay.sourceforge.net/.../emailrelay-src-1.3.tar.gz
|
||||
Source: http://emailrelay.sourceforge.net/.../emailrelay-src-1.3.1.tar.gz
|
||||
BuildRoot: /tmp/emailrelay-install
|
||||
|
||||
%description
|
||||
|
@ -51,7 +51,9 @@ int G::LogImp::m_line = 0 ;
|
||||
std::ostringstream & G::LogImp::s()
|
||||
{
|
||||
if( m_ss == NULL )
|
||||
{
|
||||
m_ss = new std::ostringstream ;
|
||||
}
|
||||
return *m_ss ;
|
||||
}
|
||||
|
||||
@ -59,7 +61,6 @@ void G::LogImp::empty()
|
||||
{
|
||||
delete m_ss ;
|
||||
m_ss = NULL ;
|
||||
m_ss = new std::ostringstream ;
|
||||
}
|
||||
|
||||
bool G::LogImp::active()
|
||||
|
@ -33,7 +33,6 @@ namespace
|
||||
typedef md5::big_t big_t ;
|
||||
typedef md5::digest_stream md5_state_t ;
|
||||
typedef md5::digest::state_type state_type ;
|
||||
typedef md5::message message ;
|
||||
typedef md5::format format ;
|
||||
|
||||
void init( md5_state_t & )
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "gstr.h"
|
||||
#include "gdebug.h"
|
||||
#include "glog.h"
|
||||
#include "gassert.h"
|
||||
#include <cstring>
|
||||
|
||||
G::Path::Path() :
|
||||
@ -47,6 +48,7 @@ G::Path::Path( const std::string & path )
|
||||
|
||||
G::Path::Path( const char * path )
|
||||
{
|
||||
G_ASSERT( path != NULL ) ;
|
||||
set( std::string(path) ) ;
|
||||
validate( "ctor(cstr)" ) ;
|
||||
}
|
||||
@ -408,7 +410,9 @@ G::Strings G::Path::split( bool no_dot ) const
|
||||
|
||||
bool G::Path::operator==( const Path & other ) const
|
||||
{
|
||||
return m_str == other.m_str ;
|
||||
return
|
||||
( m_str.empty() && other.m_str.empty() ) ||
|
||||
( m_str == other.m_str ) ;
|
||||
}
|
||||
|
||||
bool G::Path::operator!=( const Path & other ) const
|
||||
|
@ -336,7 +336,15 @@ HANDLE G::ProcessImp::createProcess( const std::string & exe , const std::string
|
||||
process_attributes , thread_attributes , inherit ,
|
||||
flags , env , cwd , &start , &info ) ;
|
||||
|
||||
return rc ? info.hProcess : HNULL ;
|
||||
if( rc )
|
||||
{
|
||||
::CloseHandle( info.hThread ) ;
|
||||
return info.hProcess ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HNULL ;
|
||||
}
|
||||
}
|
||||
|
||||
std::string G::ProcessImp::commandLine( std::string exe , Strings args )
|
||||
@ -364,6 +372,7 @@ std::string G::ProcessImp::commandLine( std::string exe , Strings args )
|
||||
|
||||
DWORD G::ProcessImp::waitFor( HANDLE hprocess , DWORD default_exit_code )
|
||||
{
|
||||
// waits for the process to end and closes the handle
|
||||
DWORD timeout_ms = 30000UL ;
|
||||
if( WAIT_TIMEOUT == ::WaitForSingleObject( hprocess , timeout_ms ) )
|
||||
{
|
||||
@ -372,6 +381,7 @@ DWORD G::ProcessImp::waitFor( HANDLE hprocess , DWORD default_exit_code )
|
||||
}
|
||||
DWORD exit_code = default_exit_code ;
|
||||
BOOL rc = ::GetExitCodeProcess( hprocess , &exit_code ) ;
|
||||
::CloseHandle( hprocess ) ;
|
||||
if( rc == 0 ) exit_code = default_exit_code ;
|
||||
return exit_code ;
|
||||
}
|
||||
|
@ -20,12 +20,21 @@
|
||||
//
|
||||
// gslot.h
|
||||
//
|
||||
// Inspired by libsigc++, but simplified by:
|
||||
// Slots and signals provide a typesafe callback mechanism
|
||||
// that separates event source classes from event sinks.
|
||||
// The slot/signal pattern is used in several C++ libraries
|
||||
// including libsigc++, Qt and boost.
|
||||
//
|
||||
// This implementation was inspired by libsigc++,
|
||||
// but simplified by:
|
||||
// * not doing multicast
|
||||
// * not detecting dangling references
|
||||
// * not supporting global function callbacks
|
||||
// * using only void returns
|
||||
//
|
||||
// Note that 'signals' in this context are not related
|
||||
// to ANSI-C or POSIX signals (signal(), sigaction(2)).
|
||||
//
|
||||
// Event-generating classes expose a "signal" object which
|
||||
// client objects can connect() to in order to receive events.
|
||||
// The client receives events through a "slot" member function.
|
||||
|
@ -58,15 +58,15 @@ md5::digest::state_type md5::digest::state() const
|
||||
md5::digest::digest( const std::string & s )
|
||||
{
|
||||
init() ;
|
||||
small_t blocks = message::blocks( s.length() ) ;
|
||||
for( small_t block = 0U ; block < blocks ; ++block )
|
||||
small_t n = block::blocks( s.length() ) ;
|
||||
for( small_t i = 0U ; i < n ; ++i )
|
||||
{
|
||||
message m( s , block , message::end(s.length()) ) ;
|
||||
add( m ) ;
|
||||
block b( s , i , block::end(s.length()) ) ;
|
||||
add( b ) ;
|
||||
}
|
||||
}
|
||||
|
||||
void md5::digest::add( const message & m )
|
||||
void md5::digest::add( const block & m )
|
||||
{
|
||||
digest old( *this ) ;
|
||||
round1( m ) ;
|
||||
@ -100,7 +100,7 @@ void md5::digest::add( const digest & other )
|
||||
d += other.d ;
|
||||
}
|
||||
|
||||
void md5::digest::round1( const message & m )
|
||||
void md5::digest::round1( const block & m )
|
||||
{
|
||||
digest & d = *this ;
|
||||
d(m,F,ABCD, 0, 7, 1); d(m,F,DABC, 1,12, 2); d(m,F,CDAB, 2,17, 3); d(m,F,BCDA, 3,22, 4);
|
||||
@ -109,7 +109,7 @@ void md5::digest::round1( const message & m )
|
||||
d(m,F,ABCD,12, 7,13); d(m,F,DABC,13,12,14); d(m,F,CDAB,14,17,15); d(m,F,BCDA,15,22,16);
|
||||
}
|
||||
|
||||
void md5::digest::round2( const message & m )
|
||||
void md5::digest::round2( const block & m )
|
||||
{
|
||||
digest & d = *this ;
|
||||
d(m,G,ABCD, 1, 5,17); d(m,G,DABC, 6, 9,18); d(m,G,CDAB,11,14,19); d(m,G,BCDA, 0,20,20);
|
||||
@ -118,7 +118,7 @@ void md5::digest::round2( const message & m )
|
||||
d(m,G,ABCD,13, 5,29); d(m,G,DABC, 2, 9,30); d(m,G,CDAB, 7,14,31); d(m,G,BCDA,12,20,32);
|
||||
}
|
||||
|
||||
void md5::digest::round3( const message & m )
|
||||
void md5::digest::round3( const block & m )
|
||||
{
|
||||
digest & d = *this ;
|
||||
d(m,H,ABCD, 5, 4,33); d(m,H,DABC, 8,11,34); d(m,H,CDAB,11,16,35); d(m,H,BCDA,14,23,36);
|
||||
@ -127,7 +127,7 @@ void md5::digest::round3( const message & m )
|
||||
d(m,H,ABCD, 9, 4,45); d(m,H,DABC,12,11,46); d(m,H,CDAB,15,16,47); d(m,H,BCDA, 2,23,48);
|
||||
}
|
||||
|
||||
void md5::digest::round4( const message & m )
|
||||
void md5::digest::round4( const block & m )
|
||||
{
|
||||
digest & d = *this ;
|
||||
d(m,I,ABCD, 0, 6,49); d(m,I,DABC, 7,10,50); d(m,I,CDAB,14,15,51); d(m,I,BCDA, 5,21,52);
|
||||
@ -136,7 +136,7 @@ void md5::digest::round4( const message & m )
|
||||
d(m,I,ABCD, 4, 6,61); d(m,I,DABC,11,10,62); d(m,I,CDAB, 2,15,63); d(m,I,BCDA, 9,21,64);
|
||||
}
|
||||
|
||||
void md5::digest::operator()( const message & m , aux_fn_t aux , Permutation p , small_t k , small_t s , small_t i )
|
||||
void md5::digest::operator()( const block & m , aux_fn_t aux , Permutation p , small_t k , small_t s , small_t i )
|
||||
{
|
||||
if( p == ABCD ) a = op( m , aux , a , b , c , d , k , s , i ) ;
|
||||
if( p == DABC ) d = op( m , aux , d , a , b , c , k , s , i ) ;
|
||||
@ -145,7 +145,7 @@ void md5::digest::operator()( const message & m , aux_fn_t aux , Permutation p ,
|
||||
}
|
||||
|
||||
//static
|
||||
md5::big_t md5::digest::op( const message & m , aux_fn_t aux , big_t a , big_t b , big_t c , big_t d ,
|
||||
md5::big_t md5::digest::op( const block & m , aux_fn_t aux , big_t a , big_t b , big_t c , big_t d ,
|
||||
small_t k , small_t s , small_t i )
|
||||
{
|
||||
return b + rot32( s , ( a + (*aux)( b , c , d ) + m.X(k) + T(i) ) ) ;
|
||||
@ -327,7 +327,7 @@ std::string md5::format::str1( small_t n )
|
||||
|
||||
// ===
|
||||
|
||||
md5::message::message( const std::string & s , small_t block , big_t end_value ) :
|
||||
md5::block::block( const std::string & s , small_t block , big_t end_value ) :
|
||||
m_s(s) ,
|
||||
m_block(block) ,
|
||||
m_end_value(end_value)
|
||||
@ -335,7 +335,7 @@ md5::message::message( const std::string & s , small_t block , big_t end_value )
|
||||
}
|
||||
|
||||
//static
|
||||
md5::big_t md5::message::end( small_t length )
|
||||
md5::big_t md5::block::end( small_t length )
|
||||
{
|
||||
big_t result = length ;
|
||||
result *= 8UL ;
|
||||
@ -343,20 +343,20 @@ md5::big_t md5::message::end( small_t length )
|
||||
}
|
||||
|
||||
//static
|
||||
md5::small_t md5::message::rounded( small_t raw_byte_count )
|
||||
md5::small_t md5::block::rounded( small_t raw_byte_count )
|
||||
{
|
||||
small_t n = raw_byte_count + 64U ;
|
||||
return n - ( ( raw_byte_count + 8U ) % 64U ) ;
|
||||
}
|
||||
|
||||
//static
|
||||
md5::small_t md5::message::blocks( small_t raw_byte_count )
|
||||
md5::small_t md5::block::blocks( small_t raw_byte_count )
|
||||
{
|
||||
small_t byte_count = rounded(raw_byte_count) + 8U ;
|
||||
return byte_count / 64UL ;
|
||||
}
|
||||
|
||||
md5::big_t md5::message::X( small_t dword_index ) const
|
||||
md5::big_t md5::block::X( small_t dword_index ) const
|
||||
{
|
||||
small_t byte_index = ( m_block * 64U ) + ( dword_index * 4U ) ;
|
||||
big_t result = x( byte_index + 3U ) ;
|
||||
@ -366,7 +366,7 @@ md5::big_t md5::message::X( small_t dword_index ) const
|
||||
return result ;
|
||||
}
|
||||
|
||||
md5::small_t md5::message::x( small_t i ) const
|
||||
md5::small_t md5::block::x( small_t i ) const
|
||||
{
|
||||
small_t length = m_s.length() ;
|
||||
if( i < length )
|
||||
@ -414,7 +414,7 @@ void md5::digest_stream::add( const std::string & s )
|
||||
|
||||
while( m_buffer.length() >= 64U )
|
||||
{
|
||||
message m( m_buffer , 0U , 0UL ) ;
|
||||
block m( m_buffer , 0U , 0UL ) ;
|
||||
m_digest.add( m ) ;
|
||||
m_buffer.erase( 0U , 64U ) ;
|
||||
}
|
||||
@ -422,7 +422,7 @@ void md5::digest_stream::add( const std::string & s )
|
||||
|
||||
void md5::digest_stream::close()
|
||||
{
|
||||
m_digest.add( message(m_buffer,0U,message::end(m_length)) ) ;
|
||||
m_digest.add( block(m_buffer,0U,block::end(m_length)) ) ;
|
||||
m_buffer.erase() ;
|
||||
}
|
||||
|
||||
|
116
src/glib/md5.h
116
src/glib/md5.h
@ -41,14 +41,27 @@ namespace md5
|
||||
typedef unsigned long big_t ; ///< To hold at least 32 bits, maybe more.
|
||||
typedef unsigned int small_t ; ///< To hold at least a size_t.
|
||||
typedef char assert_big_t_is_big_enough[sizeof(big_t)>=4U?1:-1] ; ///< A static assertion check.
|
||||
typedef char assert_small_t_is_big_enough[sizeof(big_t)>=sizeof(size_t)?1:-1] ; ///< A static assertion check.
|
||||
class digest ;
|
||||
class digest_stream ;
|
||||
class format ;
|
||||
class message ;
|
||||
class block ;
|
||||
}
|
||||
|
||||
/// \class md5::digest
|
||||
/// An md5 digest class. See RFC 1321.
|
||||
/// A class that calculates an md5 digest from one or more 64-byte blocks of
|
||||
/// data using the algorithm described by RFC 1321.
|
||||
///
|
||||
/// Digests are made up of four integers which can be formatted into more
|
||||
/// usable forms using the md5::format class.
|
||||
///
|
||||
/// A digest can be calculated in one go from an arbitrarily-sized block of
|
||||
/// data, or incrementally from a series of 64-byte blocks. The 64-byte
|
||||
/// blocks must be passed as md5::block objects.
|
||||
///
|
||||
/// In practice the requirement for 64-byte blocks of input data may be
|
||||
/// inconvenient, so the md5::digest_stream class is provided to allow
|
||||
/// calculation of digests from a stream of arbitrarily-sized data blocks.
|
||||
///
|
||||
class md5::digest
|
||||
{
|
||||
@ -56,24 +69,29 @@ public:
|
||||
struct state_type ///< Holds the md5 algorithm state. Used by md5::digest.
|
||||
{ big_t a ; big_t b ; big_t c ; big_t d ; } ;
|
||||
|
||||
explicit digest( const std::string & s ) ;
|
||||
///< Constuctor. Calculates a digest for the
|
||||
///< given message string.
|
||||
|
||||
explicit digest( state_type ) ;
|
||||
///< Constructor taking the result of an
|
||||
///< earlier call to state().
|
||||
|
||||
state_type state() const ;
|
||||
///< Returns the internal state. Typically
|
||||
///< passed to the md5::format class.
|
||||
|
||||
digest() ;
|
||||
///< Default constructor. The message to
|
||||
///< be digested should be add()ed
|
||||
///< in 64-byte blocks.
|
||||
|
||||
void add( const message & block ) ;
|
||||
explicit digest( const std::string & s ) ;
|
||||
///< Constuctor. Calculates a digest for the
|
||||
///< given message string. Do not use add()
|
||||
///< with this constructor.
|
||||
|
||||
explicit digest( state_type ) ;
|
||||
///< Constructor taking the result of an
|
||||
///< earlier call to state(). This allows
|
||||
///< calculation of a digest from a stream
|
||||
///< of 64-byte blocks to be suspended
|
||||
///< mid-stream and then resumed using a
|
||||
///< new digest object.
|
||||
|
||||
state_type state() const ;
|
||||
///< Returns the internal state. Typically
|
||||
///< passed to the md5::format class.
|
||||
|
||||
void add( const block & ) ;
|
||||
///< Adds a 64-byte block of the message.
|
||||
|
||||
private:
|
||||
@ -85,19 +103,19 @@ private:
|
||||
big_t d ;
|
||||
|
||||
private:
|
||||
explicit digest( const message & m ) ;
|
||||
explicit digest( const block & ) ;
|
||||
digest( const digest & ) ;
|
||||
void add( const digest & ) ;
|
||||
void init() ;
|
||||
void calculate( const message & ) ;
|
||||
void calculate( const block & ) ;
|
||||
static big_t T( small_t i ) ;
|
||||
static big_t rot32( small_t places , big_t n ) ;
|
||||
void operator()( const message & , aux_fn_t , Permutation , small_t , small_t , small_t ) ;
|
||||
static big_t op( const message & , aux_fn_t , big_t , big_t , big_t , big_t , small_t , small_t , small_t ) ;
|
||||
void round1( const message & ) ;
|
||||
void round2( const message & ) ;
|
||||
void round3( const message & ) ;
|
||||
void round4( const message & ) ;
|
||||
void operator()( const block & , aux_fn_t , Permutation , small_t , small_t , small_t ) ;
|
||||
static big_t op( const block & , aux_fn_t , big_t , big_t , big_t , big_t , small_t , small_t , small_t ) ;
|
||||
void round1( const block & ) ;
|
||||
void round2( const block & ) ;
|
||||
void round3( const block & ) ;
|
||||
void round4( const block & ) ;
|
||||
static big_t F( big_t x , big_t y , big_t z ) ;
|
||||
static big_t G( big_t x , big_t y , big_t z ) ;
|
||||
static big_t H( big_t x , big_t y , big_t z ) ;
|
||||
@ -105,8 +123,10 @@ private:
|
||||
} ;
|
||||
|
||||
/// \class md5::format
|
||||
/// A static string-formatting class for the output
|
||||
/// of md5::digest.
|
||||
/// A static string-formatting class for the output of md5::digest.
|
||||
/// Various static methods are prodived to convert the
|
||||
/// md5::digest::state_type structure into more useful formats,
|
||||
/// including the printable format defined by RFC 1321.
|
||||
///
|
||||
class md5::format
|
||||
{
|
||||
@ -130,39 +150,45 @@ private:
|
||||
format() ; // not implemented
|
||||
} ;
|
||||
|
||||
/// \class md5::message
|
||||
/// A helper class for md5::digest representing a
|
||||
/// \class md5::block
|
||||
/// A helper class used by the md5::digest implementation to represent a
|
||||
/// 64-character data block.
|
||||
///
|
||||
class md5::message
|
||||
class md5::block
|
||||
{
|
||||
public:
|
||||
message( const std::string & s , small_t block_offset , big_t end_value ) ;
|
||||
block( const std::string & s , small_t block_offset , big_t end_value ) ;
|
||||
///< Constructor. Unusually, the string reference is
|
||||
///< kept, so beware of temporaries.
|
||||
///< kept, so beware of binding temporaries.
|
||||
///<
|
||||
///< The 'block-offset' indicates, in units of 64-character
|
||||
///< blocks, how far down 's' the current block's data is.
|
||||
///<
|
||||
///< The string must hold at least 64 bytes beyond the
|
||||
///< 'block-offset' point, except for the last block in
|
||||
///< a message sequence. Note that this is the number
|
||||
///< of blocks, not the number of bytes.
|
||||
///<
|
||||
///< The 'end-value' is derived from the length of the
|
||||
///< full string (not just the current block). It is only
|
||||
///< full message (not just the current block). It is only
|
||||
///< used for the last block. See end().
|
||||
|
||||
static big_t end( small_t data_length ) ;
|
||||
///< Takes the total number of bytes in the input data and
|
||||
///< Takes the total number of bytes in the input message and
|
||||
///< returns a value which can be passed to the constructor's
|
||||
///< third parameter.
|
||||
///< third parameter. This is used for the last block in
|
||||
///< the sequence of blocks that make up a complete message.
|
||||
|
||||
static small_t blocks( small_t data_length ) ;
|
||||
///< Takes the total number of bytes in the input data and
|
||||
///< Takes the total number of bytes in the input message and
|
||||
///< returns the number of 64-byte blocks, allowing for
|
||||
///< padding. In practice 0..55 maps to 1, 56..119 maps to
|
||||
///< 2, etc.
|
||||
|
||||
private:
|
||||
friend class digest ;
|
||||
message( const message & ) ; // not implemented
|
||||
void operator=( const message & ) ; // not implemented
|
||||
block( const block & ) ; // not implemented
|
||||
void operator=( const block & ) ; // not implemented
|
||||
big_t X( small_t ) const ;
|
||||
small_t x( small_t ) const ;
|
||||
static small_t rounded( small_t n ) ;
|
||||
@ -174,10 +200,14 @@ private:
|
||||
} ;
|
||||
|
||||
/// \class md5::digest_stream
|
||||
/// A class that calculates an md5 digest from a data stream
|
||||
/// using the algorithm described by RFC 1321.
|
||||
///
|
||||
/// An md5 digest class with buffering. The buffering allows
|
||||
/// incremental calculation of an md5 digest, without requiring either
|
||||
/// the complete input string or precise 64-byte blocks.
|
||||
/// The implementation is layered on top of the block-oriented
|
||||
/// md5::digest by adding an element of buffering. The buffering
|
||||
/// allows incremental calculation of an md5 digest without
|
||||
/// requiring either the complete input string or precise
|
||||
/// 64-byte blocks.
|
||||
///
|
||||
class md5::digest_stream
|
||||
{
|
||||
@ -189,9 +219,11 @@ public:
|
||||
///< Default constructor.
|
||||
|
||||
digest_stream( digest::state_type d , small_t n ) ;
|
||||
///< Constructor taking state(). The "state_type::s" string
|
||||
///< is implicitly empty, so 'n' must be a multiple
|
||||
///< of sixty-four.
|
||||
///< Constructor taking state() allowing digest
|
||||
///< calculation to be suspended and resumed. The
|
||||
///< 'n' parameter must be a multiple of sixty-four
|
||||
///< (since "state_type::s" string is implicitly
|
||||
///< empty).
|
||||
|
||||
void add( const std::string & ) ;
|
||||
///< Adds more message data.
|
||||
|
@ -38,7 +38,7 @@ class GNet::AddressImp
|
||||
{
|
||||
public:
|
||||
typedef sockaddr_in address_type ;
|
||||
union Sockaddr // Used by GNet::AddressImp to casting between sockaddr and sockaddr_in.
|
||||
union Sockaddr // Used by GNet::AddressImp to cast between sockaddr and sockaddr_in.
|
||||
{ address_type specific ; struct sockaddr general ; } ;
|
||||
|
||||
explicit AddressImp( unsigned int port ) ; // (not in_port_t -- see validPort(), setPort() etc)
|
||||
|
@ -38,7 +38,7 @@ class GNet::AddressImp
|
||||
{
|
||||
public:
|
||||
typedef sockaddr_in6 address_type ;
|
||||
union Sockaddr // Used by GNet::AddressImp to casting between sockaddr and sockaddr_in6.
|
||||
union Sockaddr // Used by GNet::AddressImp to cast between sockaddr and sockaddr_in6.
|
||||
{ address_type specific ; struct sockaddr general ; } ;
|
||||
|
||||
explicit AddressImp( unsigned int port ) ; // (not in_port_t -- see validPort(), setPort() etc)
|
||||
|
@ -39,6 +39,7 @@ EXTRA_DIST=\
|
||||
passwd.dsp \
|
||||
poke.dsp \
|
||||
resource.h \
|
||||
scanner.cpp \
|
||||
submit.dsp \
|
||||
winapp.cpp \
|
||||
winapp.h \
|
||||
|
@ -150,6 +150,7 @@ EXTRA_DIST = \
|
||||
passwd.dsp \
|
||||
poke.dsp \
|
||||
resource.h \
|
||||
scanner.cpp \
|
||||
submit.dsp \
|
||||
winapp.cpp \
|
||||
winapp.h \
|
||||
|
@ -58,9 +58,9 @@ std::string Main::CommandLine::switchSpec( bool is_windows )
|
||||
<< "e!close-stderr!closes the standard error stream after start-up!0!!3|"
|
||||
<< "a!admin!enables the administration interface and specifies its listening port number!"
|
||||
<< "1!admin-port!3|"
|
||||
<< "x!dont-serve!dont act as a server (usually used with --forward)!0!!3|"
|
||||
<< "X!dont-listen!dont listen for smtp connections (usually used with --admin)!0!!3|"
|
||||
<< "z!filter!defines a mail processor program for when storing!1!program!3|"
|
||||
<< "x!dont-serve!disables acting as a server (usually used with --forward)!0!!3|"
|
||||
<< "X!dont-listen!disables listening for smtp connections (usually used with --admin)!0!!3|"
|
||||
<< "z!filter!specifies an external program to process messages as they are stored!1!program!3|"
|
||||
<< "D!domain!sets an override for the host's fully qualified domain name!1!fqdn!3|"
|
||||
<< "f!forward!forwards stored mail on startup (requires --forward-to)!0!!3|"
|
||||
<< "o!forward-to!specifies the remote smtp server (required by --forward, --poll, --immediate and --admin)!1!host:port!3|"
|
||||
@ -68,15 +68,15 @@ std::string Main::CommandLine::switchSpec( bool is_windows )
|
||||
<< "(default is 1800)!1!time!3|"
|
||||
<< "U!connection-timeout!sets the timeout (in seconds) when connecting to a remote server "
|
||||
<< "(default is 40)!1!time!3|"
|
||||
<< "m!immediate!forwards each message as soon as it is received (requires --forward-to)!0!!3|"
|
||||
<< "I!interface!listen on a specific interface!1!ip-address!3|"
|
||||
<< "i!pid-file!records the daemon process-id in the given file!1!pid-file!3|"
|
||||
<< "m!immediate!enables immediating forwarding of messages as soon as they are received (requires --forward-to)!0!!3|"
|
||||
<< "I!interface!defines the listening interface for new connections!1!ip-address!3|"
|
||||
<< "i!pid-file!defines a file for storing the daemon process-id!1!pid-file!3|"
|
||||
<< "O!poll!enables polling with the specified period (requires --forward-to)!1!period!3|"
|
||||
<< "P!postmaster!allow delivery to postmaster but reject all other local mailbox addresses!0!!3|"
|
||||
<< "Z!verifier!defines an external address verifier program!1!program!3|"
|
||||
<< "Y!client-filter!defines a mail processor program for when forwarding!1!program!3|"
|
||||
<< "P!postmaster!allows delivery to the postmaster but rejects all other local mailbox addresses!0!!3|"
|
||||
<< "Z!verifier!specifies an external program for address verification!1!program!3|"
|
||||
<< "Y!client-filter!specifies an external program to process messages when they are forwarded!1!program!3|"
|
||||
<< "R!scanner!specifies an external network server to process messages when they are stored!1!host:port!3|"
|
||||
<< "Q!admin-terminate!enables the terminate command on the admin interface!0!!3|"
|
||||
<< "R!scanner!!1!host:port!0|"
|
||||
<< "A!anonymous!disables the smtp vrfy command and sends less verbose smtp responses!0!!3|"
|
||||
;
|
||||
return ss.str() ;
|
||||
|
@ -23,7 +23,7 @@ PROJECT_NAME = E-MailRelay
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.3
|
||||
PROJECT_NUMBER = 1.3.1
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
@ -122,8 +122,8 @@ RFC 1321 MD5 algorithm that is independent of the rest of
|
||||
the E-MailRelay library code.
|
||||
|
||||
Key classes are:
|
||||
- digest
|
||||
- digest_stream
|
||||
- digest
|
||||
|
||||
*/
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
//static
|
||||
std::string Main::Run::versionNumber()
|
||||
{
|
||||
return "1.3" ;
|
||||
return "1.3.1" ;
|
||||
}
|
||||
|
||||
Main::Run::Run( Main::Output & output , const G::Arg & arg , const std::string & switch_spec ) :
|
||||
|
183
src/main/scanner.cpp
Normal file
183
src/main/scanner.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
//
|
||||
// Copyright (C) 2001-2004 Graeme Walker <graeme_walker@users.sourceforge.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// ===
|
||||
//
|
||||
// scanner.cpp
|
||||
//
|
||||
// A dummy scanner process for testing "emailrelay --scanner"
|
||||
// (eg. "emailrelay --as-proxy localhost:10025 --scanner localhost:10010")
|
||||
//
|
||||
// usage: scanner [<sleep-time>]
|
||||
//
|
||||
// Listens on port 10010. Reports messages as infected if the content
|
||||
// included the string "cough". Sleeps for <sleep-time> (default 30s)
|
||||
// if the message contains the string "sleep".
|
||||
//
|
||||
|
||||
#include "gdef.h"
|
||||
#include "gnet.h"
|
||||
#include "gserver.h"
|
||||
#include "glinebuffer.h"
|
||||
#include "gstr.h"
|
||||
#include "gevent.h"
|
||||
#include "gmemory.h"
|
||||
#include "garg.h"
|
||||
#include "gsleep.h"
|
||||
#include "gdebug.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
static int sleep_time = 30 ;
|
||||
|
||||
class ScannerPeer : public GNet::ServerPeer
|
||||
{
|
||||
public:
|
||||
explicit ScannerPeer( GNet::Server::PeerInfo info ) ;
|
||||
private:
|
||||
virtual void onDelete() ;
|
||||
virtual void onData( const char * , size_t ) ;
|
||||
void process() ;
|
||||
void processFile( std::string ) ;
|
||||
private:
|
||||
GNet::LineBuffer m_buffer ;
|
||||
} ;
|
||||
|
||||
ScannerPeer::ScannerPeer( GNet::Server::PeerInfo info ) :
|
||||
ServerPeer( info )
|
||||
{
|
||||
}
|
||||
|
||||
void ScannerPeer::onDelete()
|
||||
{
|
||||
process() ;
|
||||
}
|
||||
|
||||
void ScannerPeer::onData( const char * p , size_t n )
|
||||
{
|
||||
std::string s( p , n ) ;
|
||||
m_buffer.add( s ) ;
|
||||
process() ;
|
||||
}
|
||||
|
||||
void ScannerPeer::process()
|
||||
{
|
||||
if( m_buffer.more() )
|
||||
{
|
||||
std::string s = m_buffer.line() ;
|
||||
if( !s.empty() )
|
||||
{
|
||||
std::string path( s ) ;
|
||||
G::Str::trim( path , " \r\n\t" ) ;
|
||||
processFile( path ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScannerPeer::processFile( std::string path )
|
||||
{
|
||||
G_LOG( "ScannerPeer::processFile: file: \"" << path << "\"" ) ;
|
||||
bool infected = false ;
|
||||
bool do_sleep = false ;
|
||||
{
|
||||
std::ifstream file( path.c_str() ) ;
|
||||
while( file.good() )
|
||||
{
|
||||
std::string line = G::Str::readLineFrom( file ) ;
|
||||
G_LOG( "ScannerPeer::processFile: line: \"" << G::Str::toPrintableAscii(line) << "\"" ) ;
|
||||
if( line.find("cough") != std::string::npos )
|
||||
infected = true ;
|
||||
if( line.find("sleep") != std::string::npos )
|
||||
do_sleep = true ;
|
||||
}
|
||||
}
|
||||
G_LOG( "ScannerPeer::processFile: infected=" << infected ) ;
|
||||
|
||||
if( do_sleep && ::sleep_time )
|
||||
{
|
||||
G_LOG( "ScannerPeer::processFile: sleeping..." ) ;
|
||||
::sleep( ::sleep_time ) ;
|
||||
G_LOG( "ScannerPeer::processFile: done sleeping" ) ;
|
||||
}
|
||||
|
||||
std::ostringstream ss ;
|
||||
if( infected )
|
||||
{
|
||||
ss << "the message \"" << path << "\" is infected by flu\n" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "ok\n" ;
|
||||
}
|
||||
std::string s = ss.str() ;
|
||||
socket().write( s.data() , s.length() ) ;
|
||||
doDelete() ;
|
||||
}
|
||||
|
||||
// ===
|
||||
|
||||
class Scanner : public GNet::Server
|
||||
{
|
||||
public:
|
||||
Scanner( unsigned int port ) ;
|
||||
virtual GNet::ServerPeer * newPeer( GNet::Server::PeerInfo ) ;
|
||||
} ;
|
||||
|
||||
Scanner::Scanner( unsigned int port ) :
|
||||
GNet::Server( port )
|
||||
{
|
||||
}
|
||||
|
||||
GNet::ServerPeer * Scanner::newPeer( GNet::Server::PeerInfo info )
|
||||
{
|
||||
return new ScannerPeer( info ) ;
|
||||
}
|
||||
|
||||
// ===
|
||||
|
||||
static int run()
|
||||
{
|
||||
unsigned int port = 10010 ;
|
||||
std::auto_ptr<GNet::EventLoop> loop( GNet::EventLoop::create() ) ;
|
||||
Scanner scanner( port ) ;
|
||||
loop->run() ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int main( int argc , char * argv [] )
|
||||
{
|
||||
try
|
||||
{
|
||||
G::Arg arg( argc , argv ) ;
|
||||
if( arg.c() > 1U )
|
||||
::sleep_time = G::Str::toInt( arg.v(1U) ) ;
|
||||
bool debug = true ;
|
||||
G::LogOutput log_output( debug , debug ) ;
|
||||
return run() ;
|
||||
}
|
||||
catch( std::exception & e )
|
||||
{
|
||||
std::cerr << "exception: " << e.what() << std::endl ;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "exception\n" ;
|
||||
}
|
||||
return 1 ;
|
||||
}
|
||||
|
@ -85,7 +85,6 @@ void Main::WinForm::onCommand( unsigned int id )
|
||||
if( id == IDOK && ( !m_confirm || m_app.confirm() ) )
|
||||
{
|
||||
m_app.formOk() ;
|
||||
end() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,15 @@
|
||||
#include "winapp.h"
|
||||
#include "commandline.h"
|
||||
#include "run.h"
|
||||
#include <clocale>
|
||||
|
||||
int WINAPI WinMain( HINSTANCE hinstance , HINSTANCE previous ,
|
||||
LPSTR command_line , int show )
|
||||
{
|
||||
try
|
||||
{
|
||||
::setlocale( LC_ALL , "" ) ;
|
||||
|
||||
G::Arg arg ;
|
||||
arg.parse( hinstance , command_line ) ;
|
||||
Main::WinApp app( hinstance , previous , "E-MailRelay" ) ;
|
||||
|
@ -30,7 +30,7 @@ mk_rc=$(mk_bin)windres
|
||||
mk_rm_f=rm -f
|
||||
mk_objects=$(mk_sources:.cpp=.o)
|
||||
mk_gcc=$(mk_bin)g++
|
||||
mk_gcc_flags=-mno-cygwin -g
|
||||
mk_gcc_flags=-mno-cygwin -g -mwindows
|
||||
mk_defines=-DG_WIN32 -DG_MINGW
|
||||
mk_includes=-I../glib -I../gnet -I../gsmtp -I../win32
|
||||
mk_cpp_flags=$(mk_defines) $(mk_includes)
|
||||
|
Loading…
x
Reference in New Issue
Block a user