This commit is contained in:
Graeme Walker 2003-05-18 12:00:00 +00:00
parent ae6c79ec56
commit 7f88cace83
206 changed files with 5749 additions and 3420 deletions

View File

@ -1,6 +1,21 @@
E-MailRelay Change Log
======================
1.0.2 -> 1.1.0
--------------
* In proxy mode unexpected client-side disconnects and timeouts do not leave ".bad" files [see also bug-id 659039].
* By default proxy mode does not interpret addresses for local delivery ("--postmaster").
* Polling option added ("--poll") to rescan the spool directory periodically.
* New special exit code (103) for the pre-processor to trigger immediate polling; 100 to 107 now reserved.
* Orphaned zero-length content files are deleted properly if the server-side dialogue is cut short.
* The "--interface" switch applies to the "--admin" interface too.
* Improved internal event architecture using slot/signal design pattern, and fewer singleton classes.
* Event notification available through the administration interface.
* New "--hidden" switch for Windows.
* Syslog output includes process-id.
* Support for Sun WorkShop 5.0 added.
* Documentation overhaul.
1.0.0 -> 1.0.2
--------------
* Support for trusted IP addresses, allowing certain clients to avoid authentication.
@ -39,7 +54,7 @@ E-MailRelay Change Log
* More flexible logging options ("--verbose" and "--debug" work better).
* File Hierarchy Standard (FHS) option for "configure" ("--enable-fhs").
* FHS-compatible RPMs.
* Spool files writeable by preprocessor when server started as root.
* Spool files writeable by pre-processor when server started as root.
* Default directories in executables and scripts come from "configure".
* The "init.d" script is renamed "emailrelay" (was "emailrelay.sh").
* Man pages are gzipped when installed.
@ -52,7 +67,7 @@ E-MailRelay Change Log
0.9.7 -> 0.9.8
--------------
* Fix for running preprocessor ("--filter") as root.
* Fix for running pre-processor ("--filter") as root.
* Ignore bogus "AUTH=LOGIN" lines in EHLO response.
* Submit utility improved to work with mutt.
* Installation of submit man page.
@ -101,7 +116,7 @@ Windows fixes and improvements...
0.9.2 -> 0.9.3
--------------
* Proxy mode ("--immediate" and "--as-proxy").
* Message preprocessing ("--filter").
* Message pre-processing ("--filter").
* Message store classes better separated using abstract interfaces.
* Improved notification script, with MIME encoding.
* Builds with old 2.91 version of gcc.

36
INSTALL
View File

@ -1,24 +1,30 @@
Introduction
============
What follows are generic installation instructions for doing a standard GNU
"./configure; make; make install" installation from source under Linux, FreeBSD
etc. The Windows installation instructions are in a separate document.
What follows are generic installation instructions for doing a
GNU-style "./configure; make; make install-strip" installation from
source under Linux, FreeBSD etc. The Windows installation instructions
are in a separate document.
A non-standard "configure" switch is available, "--enable-fhs", which overrides
all other directory modifiers, forcing compliance with the File Hierarchy Standard.
This switch is used in building the RPMs, and may become the default in future
releases.
The E-MailRelay "configure" script provides a few extra switches,
which are shown in the output of "./configure --help". The most
important of these is "--enable-fhs", which overrides all other
directory modifiers, forcing compliance with the File Hierarchy
Standard. This switch is used in building the RPMs, and may become the
default in future releases.
There are also a set of variables which can be defined on the "configure" command
line for controlling all the installation directories in more detail, augmenting
the standard command-line switches like "--sbindir" and "--libexecdir". For more
information refer to the E-MailRelay reference document under
"Files and directories".
There are also a set of variables which can be defined on the
"configure" command line for controlling all the installation
directories in more detail, augmenting the standard command-line
switches like "--sbindir" and "--libexecdir". For more information
refer to the E-MailRelay reference document under "Files and directories".
The E-MailRelay user guide describes what needs to be done after the "make
install" in order to get the emailrelay daemon to start up at boot-time,
automatically forward e-mail and bounce failed mail.
If compiling with something other than "gcc" then check for any
compiler-specific help in the relevant lib/<compiler> directory.
The E-MailRelay user guide describes what needs to be done after the
"make install" in order to get the emailrelay daemon to start up at
boot-time, automatically forward e-mail and bounce failed mail.
Basic Installation
==================

View File

@ -1,21 +1,22 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
EXTRA_DIST = emailrelay.spec ChangeLog
SUBDIRS = src bin lib doc
e_doc_DATA = NEWS README changelog.gz

View File

@ -90,24 +90,8 @@ e_sbindir = @e_sbindir@
e_spooldir = @e_spooldir@
install_sh = @install_sh@
#
# Copyright (C) 2001-2003 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.
#
#
#
EXTRA_DIST = emailrelay.spec ChangeLog
SUBDIRS = src bin lib doc
e_doc_DATA = NEWS README changelog.gz

93
README
View File

@ -3,66 +3,69 @@ E-MailRelay Readme
Abstract
--------
E-MailRelay is a simple SMTP store-and-forward message transfer agent (MTA).
It runs as an SMTP server, storing e-mail in a local spool directory, and
then forwarding the stored messages to the next SMTP server on request.
It can also run as a proxy server, forwarding (and optionally pre-processing)
e-mail as soon as it is received. It does not do any message routing, other
than to a local postmaster. Because of this functional simplicity it is
extremely easy to configure, typically only requiring the address of the
next-hop SMTP server to be put on the command line.
E-MailRelay is a simple SMTP proxy and store-and-forward message transfer agent
(MTA). When running as a proxy all e-mail messages can be passed through a
user-defined program, such as a spam filter, which can drop, re-address or edit
messages as they pass through. When running as a store-and-forward MTA incoming
messages are stored in a local spool directory, and then forwarded to the next
SMTP server on request.
C++ source code is available for Linux, FreeBSD (etc) and Windows.
Because of its functional simplicity E-MailRelay is easy to configure, typically
only requiring the address of the target SMTP server to be put on the command
line.
C++ source code is available for Linux, FreeBSD, MacOS X etc, and Windows.
Distribution is under the GNU General Public License.
Quick start
-----------
E-MailRelay can be built and installed from source using the ususal
"./configure ; make ; make install" incantation. The program runs as an SMTP
server daemon using the "emailrelay --as-server" command, and stored mail is
forwarded to the next-hop server by running "emailrelay --as-client <isp-mail-server>:smtp".
To run the program as a proxy use the "--as-proxy" command-line switch, followed by the
address of the target SMTP server. If you want to edit or filter e-mail as it passes
through the proxy then specify your pre-processor program with the "--filter" switch.
You can optionally change the listening port number using "--port" and the
spool directory using "--spool-dir".
The "--as-server" command is typically run automatically at boot time, using
the boot scripts under "/etc/init.d" or "/sbin/init.d", while the "--as-client"
command is normally put into pppd's "ip-up" script ("/etc/ppp/ip-up")
in place of "sendmail -q".
For example, to start up a local proxy which passes messages to some "addsig" script
and then forwards them to an MTA running on "smarthost", use a command like this:
The program can also run as a proxy server ("--as-proxy") so that e-mail
messages are forwarded immediately to the next-hop server -- usually the local
system's default MTA. This can be usefully combined with a mail pre-processor
program by using the "--filter" switch.
emailrelay --as-proxy smarthost:smtp --filter $HOME/bin/addsig --spooldir $HOME/tmp
The program requires a writeable spool directory to store e-mail messages.
The directory defaults to "/usr/local/var/spool/emailrelay", but it
can be changed by using the "--spool-dir" switch.
To use E-MailRelay as a store-and-forward MTA use the "--as-server" switch
to start the storage daemon in the background. And then trigger delivery of
spooled messages by running emailrelay with the "--as-client" switch, followed
by the address of the target SMTP server.
By default the server will try to listen on TCP port 25. If another SMTP
server is running then it will fail to start up, with a "cannot bind" error
message. The port number can be changed by using the "--port" switch.
For example, to start a storage daemon listening on port 10025 use a command
like this:
To test the program out without a full installation:
(1) run the server as "emailrelay --no-daemon --no-syslog --log --spool-dir ${HOME} --port 10025 &"
(2) reconfigure your e-mail client to use port 10025 rather than 25 ("smtp")
(3) send some test messages to addressees on the Internet
(4) connect to the Internet
(5) forward the stored messages using "emailrelay --spool-dir ${HOME} --as-client <your-isp-smtp-host>:smtp"
(6) clean up with "killall emailrelay ; rm ${HOME}/emailrelay.*"
emailrelay --as-server --port 10025 --spooldir $HOME/tmp
And then to forward the spooled mail to "smarthost" run somthing like this:
emailrelay --as-client smarthost:smtp --spooldir $HOME/tmp
By default E-MailRelay will reject connections from remote machines. To
allow connections from anywhere use the "--remote-clients" switch.
For more information on the command-line options refer to the reference guide
or run:
emailrelay --help --verbose
Documentation
-------------
The following documentation is provided in the source distribution:
The following documentation is provided:
* README -- this document
* COPYING -- the GNU General Public License
* INSTALL -- build & install instructions (including the generic GNU text)
* AUTHORS -- authors, credits and additional copyrights
* copyright -- main copyright and GPL reference
* doc/userguide.txt -- user guide
* doc/reference.txt -- reference document
* userguide.txt -- user guide
* reference.txt -- reference document
* ChangeLog -- change log for releases
Additional documents, including source-code documentation generated by
doxygen (www.doxygen.org), is available in a separate package,
"emailrelay-doc".
Source code documentation will be generated when building from source if
"doxygen" is available.
Configurations
--------------
@ -78,21 +81,23 @@ and ported to Windows 98 using:
Recent releases were developed on SuSE Linux 8.0 and
RedHat Linux 8.0 using:
* gcc 2.95.3 and 3.2
* gcc 2.95.3 and gcc 3.2
* autoconf 2.53
The code has also been built successfully on:
* Windows NT 4.0
* MacOS X
* FreeBSD on Intel hardware
* Solaris 8, using gcc, on Sparc hardware
* Linux on Alpha hardware (Debian 2.2)
* Linux on Sparc hardware
* Linux on RS6000 PPC hardware
* Solaris 8 using gcc on Sparc hardware
* Solaris 8 using WorkShop 5.0
* Linux using intel c++ 6.0
* Windows NT 4.0 using MSVC 6.0
Feedback
--------
Please feel free to email the author at
Please feel free to e-mail the author at
"mailto:graeme_walker@users.sourceforge.net".

View File

@ -73,18 +73,64 @@ AC_DEFUN([ACLOCAL_CHECK_LOCALTIME_R],
fi
])
dnl gcc version
dnl buggy ctime
dnl sunpro5 ctime + unistd.h doesnt compile -- fix with time.h first
dnl
AC_DEFUN([ACLOCAL_CHECK_BUGGY_CTIME],
[AC_CACHE_CHECK([for buggy ctime], aclocal_cv_buggy_ctime,
[
AC_TRY_COMPILE(
[#include <ctime>
#include <unistd.h>],
[] ,
aclocal_cv_buggy_ctime=no ,
aclocal_cv_buggy_ctime=yes )
])
if test $aclocal_cv_buggy_ctime = yes; then
AC_DEFINE(HAVE_BUGGY_CTIME,1,[Define if <ctime> requires <time.h>])
else
AC_DEFINE(HAVE_BUGGY_CTIME,0,[Define if <ctime> requires <time.h>])
fi
])
dnl compiler name and version
dnl used for -Ilib/<version> -- only needed for pre 3.0 gcc
dnl
AC_DEFUN([ACLOCAL_COMPILER_VERSION],
[
changequote(<<,>>)
COMPILER_VERSION=`$CXX --version 2>/dev/null | sed q | sed 's/[^0-9 .]*//g;s/\./ /g;s/^ *//;s/ /./;s/ .*//;s/^/gcc/'`
if test -z "${COMPILER_VERSION}"
then
COMPILER_VERSION=`$CXX -V 2>&1 | sed q | grep WorkShop | sed 's/[^0-9]*//;s/[ \.].*//;s/^/sunpro/'`
fi
changequote([,])
AC_SUBST(COMPILER_VERSION)
])
dnl fhs
dnl enable-debug
dnl
AC_DEFUN([ENABLE_DEBUG],
[
if test "$enable_debug" = "yes"
then
AC_DEFINE(_DEBUG,1,[Define to enable extra debug messages at compile-time])
fi
])
dnl with-workshop
dnl
AC_DEFUN([WITH_WORKSHOP],
[
if test "$with_workshop" = "yes"
then
chmod +x lib/sunpro5/xar
AR="`pwd`/lib/sunpro5/xar --cxx \"$CXX\""
AC_SUBST(AR)
fi
])
dnl enable-fhs
dnl
AC_DEFUN([ENABLE_FHS],
[

50
aclocal.m4 vendored
View File

@ -86,18 +86,64 @@ AC_DEFUN([ACLOCAL_CHECK_LOCALTIME_R],
fi
])
dnl gcc version
dnl buggy ctime
dnl sunpro5 ctime + unistd.h doesnt compile -- fix with time.h first
dnl
AC_DEFUN([ACLOCAL_CHECK_BUGGY_CTIME],
[AC_CACHE_CHECK([for buggy ctime], aclocal_cv_buggy_ctime,
[
AC_TRY_COMPILE(
[#include <ctime>
#include <unistd.h>],
[] ,
aclocal_cv_buggy_ctime=no ,
aclocal_cv_buggy_ctime=yes )
])
if test $aclocal_cv_buggy_ctime = yes; then
AC_DEFINE(HAVE_BUGGY_CTIME,1,[Define if <ctime> requires <time.h>])
else
AC_DEFINE(HAVE_BUGGY_CTIME,0,[Define if <ctime> requires <time.h>])
fi
])
dnl compiler name and version
dnl used for -Ilib/<version> -- only needed for pre 3.0 gcc
dnl
AC_DEFUN([ACLOCAL_COMPILER_VERSION],
[
changequote(<<,>>)
COMPILER_VERSION=`$CXX --version 2>/dev/null | sed q | sed 's/[^0-9 .]*//g;s/\./ /g;s/^ *//;s/ /./;s/ .*//;s/^/gcc/'`
if test -z "${COMPILER_VERSION}"
then
COMPILER_VERSION=`$CXX -V 2>&1 | sed q | grep WorkShop | sed 's/[^0-9]*//;s/[ \.].*//;s/^/sunpro/'`
fi
changequote([,])
AC_SUBST(COMPILER_VERSION)
])
dnl fhs
dnl enable-debug
dnl
AC_DEFUN([ENABLE_DEBUG],
[
if test "$enable_debug" = "yes"
then
AC_DEFINE(_DEBUG,1,[Define to enable extra debug messages at compile-time])
fi
])
dnl with-workshop
dnl
AC_DEFUN([WITH_WORKSHOP],
[
if test "$with_workshop" = "yes"
then
chmod +x lib/sunpro5/xar
AR="`pwd`/lib/sunpro5/xar --cxx \"$CXX\""
AC_SUBST(AR)
fi
])
dnl enable-fhs
dnl
AC_DEFUN([ENABLE_FHS],
[

View File

@ -1,21 +1,22 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
EXTRA_DIST = emailrelay-doxygen-filter.sh_ emailrelay-test.sh_ emailrelay-soak.sh_ emailrelay.sh_ txt2html.sh_ txt2mu.sh_ mu2html.sh_ expand.sh_ emailrelay-notify.sh_ emailrelay-resubmit.sh_ emailrelay-deliver.sh_ emailrelay-process.sh_

View File

@ -14,24 +14,8 @@
@SET_MAKE@
#
# Copyright (C) 2001-2003 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.
#
#
#
SHELL = @SHELL@
srcdir = @srcdir@

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
@ -31,18 +31,21 @@
# Once all the servers have been killed the separate log files are
# concatenated into the summary log file "/tmp/emailrelay-test.out".
#
# If this test takes more than a second or two then it has failed.
# If this test takes more a minute then it has failed.
#
# usage: emailrelay-test.sh [-v] [-d] [<exe-dir>]
#
# configuration
#
exe_dir="../src/main"
if test "${1}" != "" ; then exe_dir="${1}" ; fi
use_valgrind="0" ; if test "${1}" = "-v" ; then use_valgrind="1" ; shift ; fi
debug="" ; if test "${1}" = "-d" ; then debug="--debug" ; shift ; fi
exe_dir="../src/main" ; if test "${1}" != "" ; then exe_dir="${1}" ; fi
exe="${exe_dir}/emailrelay"
poke="${exe_dir}/emailrelay-poke"
null_filter="/bin/touch"
content_file="/etc/services"
pp="1001" # port-prefix
pp="201" # port-prefix
# configuration fallback
#
@ -56,16 +59,32 @@ fi
base_dir="/tmp/`basename $0`.$$.tmp"
summary_log="/tmp/`basename $0`.out"
exit_code="1"
watchdog_pid=""
export MALLOC_CHECK_="2"
ulimit -c 1000000
if test "${use_valgrind}" -eq 1
then
exe="valgrind --logfile=${base_dir}/valgrind --trace-children=yes --num-callers=40 --leak-check=yes ${exe} --no-daemon"
fi
Cleanup()
{
${poke} ${pp}11 terminate
${poke} ${pp}12 terminate
${poke} ${pp}13 terminate
${poke} ${pp}14 terminate
${poke} ${pp}15 terminate
${poke} ${pp}16 terminate
sleep 2
kill `cat ${base_dir}/pid-* 2>/dev/null` 2>/dev/null
if test -d ${base_dir}
then
grep "MailRelay-Reason" ${base_dir}/*/*envelope*bad > "${summary_log}" 2>/dev/null
grep "." ${base_dir}/log-? >> "${summary_log}" 2>/dev/null
ls -lR ${base_dir} >> "${summary_log}" 2>/dev/null
diff -w ${base_dir}/store-4/*content "${content_file}" >> "${summary_log}" 2>/dev/null
rm -rf ${base_dir} 2>/dev/null
fi
}
@ -78,14 +97,16 @@ Trap()
RunServer()
{
port_="${1}"
spool_="${2}"
log_="${3}"
pidfile_="${4}"
extra_="${5}"
admin_port_="${2}"
spool_="${3}"
log_="${4}"
pidfile_="${5}"
extra_="${6}"
mkdir -p ${base_dir}/${spool_}
${exe} --log --no-syslog --port ${port_} --spool-dir ${base_dir}/${spool_} \
--pid-file ${base_dir}/${pidfile_} ${extra_} 2> ${base_dir}/${log_}
${exe} ${debug} --log --verbose --no-syslog --port ${port_} --spool-dir ${base_dir}/${spool_} \
--admin ${admin_port_} --admin-terminate \
--pid-file ${base_dir}/${pidfile_} ${extra_} 2> ${base_dir}/${log_} &
}
RunClient()
@ -137,18 +158,21 @@ CrLf()
CheckResults()
{
if test -f ${base_dir}/store-4/*.envelope -a -f ${base_dir}/store-4/*.content
store="${1}"
if test "`ls -1 ${base_dir}/${store}/emailrelay.*.content 2>/dev/null | wc -l`" -eq 2 -a \
"`ls -1 ${base_dir}/${store}/emailrelay.*.envelope 2>/dev/null | wc -l`" -eq 2
then
exit_code="0"
echo `basename $0`: succeeded
else
echo `basename $0`: failed: see ${summary_log} >&2
false
fi
}
StartTimer()
StartWatchdog()
{
( sleep 30 ; Cleanup ) &
sleep 10 && kill `cat ${base_dir}/pid-* 2>/dev/null` 2>/dev/null &
watchdog_pid=$!
}
CreateMessages()
@ -156,6 +180,8 @@ CreateMessages()
mkdir -p ${base_dir}/store-1
Content | CrLf > ${base_dir}/store-1/emailrelay.0.1.content
Envelope | CrLf > ${base_dir}/store-1/emailrelay.0.1.envelope
Content | CrLf > ${base_dir}/store-1/emailrelay.0.2.content
Envelope | CrLf > ${base_dir}/store-1/emailrelay.0.2.envelope
}
CreateAuth()
@ -180,17 +206,48 @@ CreateAuth()
echo "CRAM-MD5 client joe ${key}" >> ${file}
}
CreateFilter()
{
cat <<EOF | sed 's/^_//' > ${base_dir}/filter.sh
_#!/bin/sh
_# filter.sh
_tmp="/tmp/`basename $0`.\$\$.tmp"
_tr 'a-z' 'A-Z' < \$1 > \$tmp && mv \$tmp \$1
_exit 0
EOF
chmod +x ${base_dir}/filter.sh
}
trap "Trap ; exit" 1 2 3 13 15
trap "Trap 0 ; exit" 0
StartTimer
#StartWatchdog
CreateAuth
RunServer ${pp}1 store-2 log-1 pid-1
RunServer ${pp}2 store-2 log-2 pid-2 "--admin ${pp}9 --forward-to localhost:${pp}3 --client-auth ${base_dir}/client-joe.auth"
RunServer ${pp}3 store-3 log-3 pid-3 "--immediate --forward-to localhost:${pp}4 --filter ${null_filter} --client-auth ${base_dir}/client-fred.auth --server-auth ${base_dir}/server.auth"
RunServer ${pp}4 store-4 log-4 pid-4 "--server-auth ${base_dir}/server.auth"
CreateMessages
RunClient localhost:${pp}1 store-1 log-c pid-5
RunPoke ${pp}9 log-p
CheckResults
CreateFilter
RunServer ${pp}01 ${pp}10 store-2 log-1 pid-1
RunServer ${pp}02 ${pp}12 store-2 log-2 pid-2 "--forward-to localhost:${pp}03 --client-auth ${base_dir}/client-joe.auth"
RunServer ${pp}03 ${pp}13 store-3 log-3 pid-3 "--immediate --forward-to localhost:${pp}04 --filter ${null_filter} --client-auth ${base_dir}/client-fred.auth --server-auth ${base_dir}/server.auth"
RunServer ${pp}04 ${pp}14 store-4 log-4 pid-4 "--server-auth ${base_dir}/server.auth"
RunServer ${pp}05 ${pp}15 store-4 log-5 pid-5 "--poll 1 --forward-to localhost:${pp}06"
RunServer ${pp}06 ${pp}16 store-6 log-6 pid-6 "--filter ${base_dir}/filter.sh"
CreateMessages
RunClient localhost:${pp}01 store-1 log-c pid-5
RunPoke ${pp}12 log-p
for i in 0 1 2 3 4 5 6 7 8 9
do
sleep 2
CheckResults store-6
if test $? -eq 0 ; then break ; fi
done
if test "${watchdog_pid}" != ""
then
kill "${watchdog_pid}"
fi
if test ${exit_code} -ne 0
then
echo `basename $0`: failed: see ${summary_log} >&2
fi

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
@ -18,7 +18,7 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# ===
#
#
# emailrelay
#
# A shell-script wrapper for E-MailRelay designed for

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if <ctime> requires <time.h> */
#undef HAVE_BUGGY_CTIME
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
@ -83,3 +86,6 @@
/* Version number of package */
#undef VERSION
/* Define to enable extra debug messages at compile-time */
#undef _DEBUG

108
configure vendored
View File

@ -837,9 +837,15 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-dependency-tracking Speeds up one-time builds
--enable-dependency-tracking Do not reject slow dependency extractors
--enable-debug enable extra debug messages at compile-time
--enable-fhs force FHS-compliant directories, ignoring --prefix
etc
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-workshop use Sun WorkShop 'CC -xar' as the 'ar' tool
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
@ -1453,7 +1459,7 @@ fi
# Define the identity of the package.
PACKAGE=emailrelay
VERSION=1.0.2
VERSION=1.1
cat >>confdefs.h <<_ACEOF
@ -3269,6 +3275,10 @@ fi
COMPILER_VERSION=`$CXX --version 2>/dev/null | sed q | sed 's/[^0-9 .]*//g;s/\./ /g;s/^ *//;s/ /./;s/ .*//;s/^/gcc/'`
if test -z "${COMPILER_VERSION}"
then
COMPILER_VERSION=`$CXX -V 2>&1 | sed q | grep WorkShop | sed 's/[^0-9]*//;s/[ \.].*//;s/^/sunpro/'`
fi
@ -4611,6 +4621,68 @@ _ACEOF
fi
echo "$as_me:$LINENO: checking for buggy ctime" >&5
echo $ECHO_N "checking for buggy ctime... $ECHO_C" >&6
if test "${aclocal_cv_buggy_ctime+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include <ctime>
#include <unistd.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
aclocal_cv_buggy_ctime=no
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
aclocal_cv_buggy_ctime=yes
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $aclocal_cv_buggy_ctime" >&5
echo "${ECHO_T}$aclocal_cv_buggy_ctime" >&6
if test $aclocal_cv_buggy_ctime = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_BUGGY_CTIME 1
_ACEOF
else
cat >>confdefs.h <<\_ACEOF
#define HAVE_BUGGY_CTIME 0
_ACEOF
fi
echo "$as_me:$LINENO: checking for gmtime_r" >&5
echo $ECHO_N "checking for gmtime_r... $ECHO_C" >&6
if test "${aclocal_cv_gmtime_r+set}" = set; then
@ -4734,6 +4806,37 @@ _ACEOF
fi
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
enableval="$enable_debug"
fi;
if test "$enable_debug" = "yes"
then
cat >>confdefs.h <<\_ACEOF
#define _DEBUG 1
_ACEOF
fi
# Check whether --with-workshop or --without-workshop was given.
if test "${with_workshop+set}" = set; then
withval="$with_workshop"
fi;
if test "$with_workshop" = "yes"
then
chmod +x lib/sunpro5/xar
AR="`pwd`/lib/sunpro5/xar --cxx \"$CXX\""
fi
# Check whether --enable-fhs or --disable-fhs was given.
if test "${enable_fhs+set}" = set; then
enableval="$enable_fhs"
@ -4791,7 +4894,7 @@ fi
SET_MAKE=""
ac_config_files="$ac_config_files Makefile src/Makefile src/glib/Makefile src/gnet/Makefile src/gsmtp/Makefile src/main/Makefile src/win32/Makefile lib/Makefile lib/gcc2.95/Makefile lib/msvc6.0/Makefile bin/Makefile doc/Makefile"
ac_config_files="$ac_config_files Makefile src/Makefile src/glib/Makefile src/gnet/Makefile src/gsmtp/Makefile src/main/Makefile src/win32/Makefile lib/Makefile lib/gcc2.95/Makefile lib/msvc6.0/Makefile lib/sunpro5/Makefile bin/Makefile doc/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@ -5290,6 +5393,7 @@ do
"lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
"lib/gcc2.95/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/gcc2.95/Makefile" ;;
"lib/msvc6.0/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/msvc6.0/Makefile" ;;
"lib/sunpro5/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/sunpro5/Makefile" ;;
"bin/Makefile" ) CONFIG_FILES="$CONFIG_FILES bin/Makefile" ;;
"doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;

22
configure.ac Normal file → Executable file
View File

@ -1,4 +1,3 @@
dnl
dnl Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
dnl
dnl This program is free software; you can redistribute it and/or
@ -19,9 +18,10 @@ dnl
dnl ===
dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_INIT(src/gsmtp/gsmtp.h)
AM_INIT_AUTOMAKE(emailrelay,1.0.2)
AM_INIT_AUTOMAKE(emailrelay,1.1)
AM_CONFIG_HEADER(config.h)
dnl ===
@ -57,11 +57,24 @@ AC_CHECK_HEADERS(sys/time.h)
AC_CHECK_FUNCS(glob)
AC_LANG_CPLUSPLUS
ACLOCAL_TYPE_SOCKLEN_T
ACLOCAL_CHECK_BUGGY_CTIME
ACLOCAL_CHECK_GMTIME_R
ACLOCAL_CHECK_LOCALTIME_R
dnl ===
dnl directory tweaking...
dnl "--enable-debug"
dnl
AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[enable extra debug messages at compile-time]))
ENABLE_DEBUG
dnl ===
dnl "--with-workshop"
dnl
AC_ARG_WITH(workshop,AC_HELP_STRING([--with-workshop],[use Sun WorkShop 'CC -xar' as the 'ar' tool]))
WITH_WORKSHOP
dnl ===
dnl directory tweaking and "--enable-fhs" ...
dnl
dnl not AC_PREFIX_DEFAULT([/usr])
AC_ARG_ENABLE(fhs,AC_HELP_STRING([--enable-fhs],[force FHS-compliant directories, ignoring --prefix etc]))
@ -83,10 +96,11 @@ ENABLE_FHS
dnl ===
dnl attempt to fix recursive makes where make is gmake -- may break something else
dnl
SET_MAKE=""
dnl ===
dnl generate files...
dnl
AC_OUTPUT(Makefile src/Makefile src/glib/Makefile src/gnet/Makefile src/gsmtp/Makefile src/main/Makefile src/win32/Makefile lib/Makefile lib/gcc2.95/Makefile lib/msvc6.0/Makefile bin/Makefile doc/Makefile)
AC_OUTPUT(Makefile src/Makefile src/glib/Makefile src/gnet/Makefile src/gsmtp/Makefile src/main/Makefile src/win32/Makefile lib/Makefile lib/gcc2.95/Makefile lib/msvc6.0/Makefile lib/sunpro5/Makefile bin/Makefile doc/Makefile)

View File

@ -1,21 +1,22 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
stylesheet=emailrelay.css
txt_files=developer.txt reference.txt userguide.txt windows.txt

View File

@ -14,24 +14,8 @@
@SET_MAKE@
#
# Copyright (C) 2001-2003 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.
#
#
#
SHELL = @SHELL@
srcdir = @srcdir@

View File

@ -137,12 +137,6 @@ Sometimes only small parts of the implementation are system-specific. In
these cases there are three source files per header. For example, "gsocket.cpp",
"gsocket_win32.cpp" and "gsocket_unix.cpp" in the "src/gnet" directory.
Porting to other compilers
--------------------------
If porting to a good ANSI C++ compiler then start by removing files from the
"lib/gcc2.95" directory (or edit makefiles to remove the include path), and then
review the following header files "src/glib/gdef.h" and "src/gnet/gnet.h".
Compile-time features
---------------------
The following features are available to source-code hackers:
@ -174,7 +168,7 @@ directory.
Style
-----
The commenting style used in header files is compatible with doxygen if passed
through the simple awk-based preprocessor "emailrelay-doxygen-filter.sh". A
through the simple awk-based pre-processor "emailrelay-doxygen-filter.sh". A
"make" in the "doc" directory will run doxygen if it is found on your path.
Patterns
@ -183,7 +177,7 @@ Gang-of-four Design Patterns (ISBN 0-201-63361-2):
+ Factory method
- GNet::EventSources::create()
- GNet::EventLoop::create()
- GNet::Server::newPeer()
- GSmtp::MessageStore::newMessage()
@ -197,8 +191,7 @@ Gang-of-four Design Patterns (ISBN 0-201-63361-2):
- G::LogOutput
- GGui::ApplicationInstance
- GNet::EventSources
- GSmtp::MessageStore
- GNet::EventLoop
+ Facade
@ -226,19 +219,18 @@ Lakos' Large Scale C++ Software Design patterns (ISBN 0-201-63362-0):
- GSmtp::ProtocolMessage
- GSmtp::ServerProtocol::Sender
- GSmtp::ClientProtocol::Sender
- GSmtp::ClientProtocol::Callback
- GSmtp::ProtocolMessage::Callback
- GSmtp::Client::ClientCallback
Meyer's More Effective C++ patterns (ISBN 0-201-63371-X):
+ Reference counting (Item 29)
- GSmtp::MessageStore::Iterator
- G::Slot0
+ Lazy evaluation (Item 17)
- GNet::EventHandlerList::list()
- G::Date::weekday()
Other patterns:
@ -246,6 +238,15 @@ Other patterns:
- GSmtp::ServerProtocol
+ Slot/signal
- G::Slot0
- G::Signal0
+ Exception-safe assignment using swap
- G::Slot0
Idioms
------
The "<<=" operator defined in "src/glib/gmemory.h" is used idiomatically
@ -253,4 +254,5 @@ to reassign a std::auto_ptr<>.
Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>. All rights reserved.

View File

@ -1,4 +1,3 @@
.\"
.\" Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
.\"
.\" This program is free software; you can redistribute it and/or

View File

@ -1,4 +1,3 @@
.\"
.\" Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
.\"
.\" This program is free software; you can redistribute it and/or

View File

@ -1,4 +1,3 @@
.\"
.\" Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
.\"
.\" This program is free software; you can redistribute it and/or
@ -29,7 +28,7 @@ emailrelay-submit \- a submission utility for E-MailRelay
.RI [ to-address \ ...]
.SH DESCRIPTION
.I emailrelay-submit
is a utility which reads an RFC822 email message from the standard
is a utility which reads an RFC822 e-mail message from the standard
input, with SMTP envelope recipient addresses passed on the
command-line, and writes it into the
.B E-MailRelay

View File

@ -1,4 +1,3 @@
.\"
.\" Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
.\"
.\" This program is free software; you can redistribute it and/or
@ -64,7 +63,7 @@ Runs as a client, forwarding spooled mail to <host>: equivalent to \fI--log\fR \
Runs as a proxy: equivalent to \fI--log\fR \fI--close-stderr\fR \fI--immediate\fR \fI--forward-to\fR.
.TP
.B \-d,--as-server
Runs as a server: equivalent to \fI--log\fR \fI--close-stderr\fR.
Runs as a server: equivalent to \fI--log\fR \fI--close-stderr\fR \fI--postmaster\fR.
.TP
.B \-C,--client-auth \fIfile\fR
Enables authentication with remote server, using the given secrets file.
@ -120,9 +119,15 @@ Disables syslog output.
.B \-i,--pid-file \fIpid-file\fR
Records the daemon process-id in the given file.
.TP
.B \-O,--poll \fIperiod\fR
Enables polling with the specified period (requires \fI--forward-to\fR).
.TP
.B \-p,--port \fIport\fR
Specifies the smtp listening port number.
.TP
.B \-P,--postmaster
Deliver to postmaster and reject all other local mailbox addresses.
.TP
.B \-r,--remote-clients
Allows remote clients to connect.
.TP

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -11,7 +11,7 @@
<li><a class="a-href" href="readme.html">Readme</a></li>
<li><a class="a-href" href="changelog.html">Change log</a></li>
<li><a class="a-href" href="userguide.html">User guide</a></li>
<li><a class="a-href" href="reference.html">Reference manual</a></li>
<li><a class="a-href" href="reference.html">Reference</a></li>
<li><a class="a-href" href="windows.html">Windows installation guide</a></li>
<li><a class="a-href" href="developer.html">Notes for developers</a></li>
<li><a class="a-href" href="doxygen/index.html">Source code documentation</a> (generated by <a class="a-href" href="http://www.doxygen.org">doxygen</a>, if available)</li>

View File

@ -23,7 +23,7 @@ where <switch> is:
Runs as a proxy: equivalent to "--log --close-stderr --immediate --forward-to".
# --as-server (-d)
Runs as a server: equivalent to "--log --close-stderr".
Runs as a server: equivalent to "--log --close-stderr --postmaster".
# --client-auth (-C)
Enables authentication with remote server, using the given secrets file.
@ -79,9 +79,15 @@ where <switch> is:
# --pid-file (-i)
Records the daemon process-id in the given file.
# --poll (-O)
Enables polling with the specified period (requires --forward-to).
# --port (-p)
Specifies the smtp listening port number.
# --postmaster (-P)
Deliver to postmaster and reject all other local mailbox addresses.
# --remote-clients (-r)
Allows remote clients to connect.
@ -106,11 +112,14 @@ where <switch> is:
# --version (-V)
Displays version information and exits.
Under Windows there are a few differences. Use "--help --verbose"
to see the complete list.
If no command-line switches are supplied at all then the default
behaviour is:
* to run as a daemon, detached from the terminal
* listen on the standard SMTP port (25)
* store e-mail messages in "/usr/local/var/spool/emailrelay"
* store e-mail messages in "/usr/local/var/spool/emailrelay" or "/var/spool/emailrelay"
* reject connections from remote clients
* disable the administration interface
* generate no logging or diagnostic messages
@ -121,7 +130,7 @@ the standard error stream is closed.
To foward spooled messages to the ISP the command-line switch "--as-client"
is provided to run the program...
* in foreground, exiting when all spooled mail has been processed
* forwarding spooled mail from "/usr/local/var/spool/emailrelay"
* forwarding spooled mail from "/usr/local/var/spool/emailrelay" or "/var/spool/emailrelay"
* without listening on any port
* with error, warning and information messages sent to stderr
* without using syslog
@ -134,9 +143,9 @@ file contains parameters relevant to the SMTP dialogue, and the content file
contains the RFC822 headers and body text.
The filenames used in the message store have a prefix of "emailrelay", followed
by a process-id and sequence number, followed by "envelope" or "content". The
envelope files then have an additional suffix to implement a simple locking
scheme.
by a process-id, timestamp and sequence number, followed by "envelope" or
"content". The envelope files then have an additional suffix to implement a
simple locking scheme.
The envelope suffixes are:
* ".new" -- while the envelope is first being written
@ -159,18 +168,16 @@ SMTP issues
# Local delivery:
Recipient addresses like "postmaster", "postmaster@localhost" and "postmaster@fqdn"
(where "fqdn" is the host's fully qualified domain name) are treated as the local
postmaster, resulting in local delivery rather than mail forwarding.
Recipient addresses (other than "postmaster" addresses) with no "at" sign (@) or
ending in "@localhost" will be rejected at the time the message is submitted by the
e-mail front-end. This is in line with E-MailRelay's intended purpose as a simple
mail relay, rather than a fully-fledged routing MTA.
In server mode (ie. with "--postmaster") recipient addresses like "postmaster",
"postmaster@localhost" and "postmaster@fqdn" (where "fqdn" is the host's fully
qualified domain name) are treated as the local postmaster, resulting in local
delivery rather than mail forwarding. Recipient addresses other than "postmaster"
addresses with no "at" sign (@) or ending in "@localhost" will be rejected at the
time the message is submitted by the client.
Delivery of mail to a local "postmaster" is a feature of E-MailRelay which is
provided for completeness and for comformance to the SMTP specification.
Note that the E-MailRelay daemon does not actually deliver mail to the postmaster
provided for completeness and for comformance to the SMTP specification. But
note that the E-MailRelay daemon does not actually deliver mail to the postmaster
mailbox. All it does is create an envelope and content file in the spool
directory with a ".local" suffix. Some external system, such as a shell
script run from cron calling "procmail", should be used to process the
@ -192,94 +199,43 @@ SMTP issues
re-encode 8-bit messages into 7-bit messages if the next-hop server
does not.
Address validation
------------------
An address supplied to the SMTP commands "RCPT" and "VRFY" is normally accepted
if it contains an at sign, or if it is some sort of local "postmaster" address
(as described above). However, this behaviour can be modified by using an external
verifier program, using the "--verifier" command-line switch.
The verifier program is passed a command-line containing the full address, the
user-name part of the address, the host-name part, the local host's fully
qualified domain name, the current "MAIL" command's "FROM:" address or the
empty string for the "VRFY" command, the IP address of the client connection,
the authentication mechanism used by the client ("NONE" if trusted), and either
the authentication name or the fourth field from authentication secrets file if
a trusted IP address.
For valid local mailbox addresses the verifier is expected to write two lines to
the standard output -- the full name associated with the mailbox, and the
canonical mailbox name -- and then exit with a value of zero. For valid non-local
addresses the first line of output should be empty, the second line should be
copied from the first command-line argument, and the exit value should be one.
For invalid addresses the exit value should be greater than one, and anything
written to the standard output is taken as the failure reason.
(Only the few few thousand characters are read from the verifier's standard
output stream; any more is thrown away.)
In this simple example script all addresses are accepted as long as they contain
an at sign. This has the effect of removing the normal "postmaster" functionality,
which is in any case not very useful when running in proxy mode:
#!/bin/sh
# verifier.sh
# An address verifier script for E-MailRelay.
address="${1}"
user="${2}"
host="${3}"
if test "${address}" != "${user}@${host}" ; then exit 2 ; fi
echo "${address}"
echo "${address}" # again
exit 1 # accept
As another example, the following address verifier script accepts all recipient
addresses by default, but rejects remote addresses if the client has bypassed
authentication by connecting on a trusted IP address:
#!/bin/sh
# verifier.sh
# An address verifier script for E-MailRelay.
host="$3"
local_domain="$4"
auth_mechanism="$7"
if test "${auth_mechanism}" = "NONE" -a "${host}" != "${local_domain}"
then
echo "cannot relay without authentication"
exit 2 # reject the recipient address
fi
echo "${address}"
echo "${address}" # again
exit 1 # accept the recipient address
Administration interface
------------------------
If enabled, the server will provide a network interface for performing
administration tasks. This is a simple command-line interface which is
compatible with "telnet".
If enabled with the "--admin" command line switch, the E-MailRelay server will
provide a network interface for performing administration tasks. This is a
simple command-line interface which is compatible with "telnet":
Currently the only supported commands are "flush" and "info". The "flush" command
is used to forward spooled mail to the configured next-hop SMTP server. The
next-hop server address must have been defined on the "emailrelay" command
line at start-up using the "--forward-to" switch; it cannot be specified through
the administration interface.
$ emailrelay --as-server --port 125 --forward-to localhost:25 --admin 10026
$ telnet localhost 10026
E-MailRelay> help
E-MailRelay> quit
The "flush" command allows you to run a single process which combines the
functionality of storage daemon and forwarding client. This might be useful
in systems which are low on memory: the memory footprint of "telnet" or
"emailrelay-poke" will be much smaller than "emailrelay --as-client".
The "flush" command is used to get the E-MailRelay server to forward spooled
mail to the next SMTP server, as an alternative to running "emailrelay --as-client"
as a separate process. In proxy mode it is a way of getting the proxy
server to scan the spool-directory for new messages.
The utility program "emailrelay-poke" can be used to issue the "flush"
command to an E-MailRelay server. For example:
$ emailrelay --as-server --port 125 --forward-to localhost:25 --admin 10026
$ emailrelay-poke 10026
$ echo $?
To use the "flush" command the next SMTP server address must have been defined
on the "emailrelay" command line at start-up using the "--forward-to" switch.
Also, the "list" command lists the messages in the spool directory, the "info"
command provides network status information and activity statistics, and the
"notify" command enables asynchronous event notification.
Mail processing
---------------
The "--filter" command-line switch allows you to specify a mail processor program
which operates on mail messages as they pass through the E-MailRelay system. The
mail processor program is run as soon as the mail message has been stored in the
spool directory, with the full path of the content file specified on the command
line.
This can be combined with the "--immediate" (or "--as-proxy") switch to implement
personal mail processing, without replacing or reconfiguring the system's
default MTA.
The "--filter" command-line switch allows you to specify a mail pre-processor
program which operates on mail messages as they pass through the E-MailRelay
system. The mail pre-processor program is run as soon as the mail message has been
stored in the spool directory, with the full path of the content file specified
on the command line.
For example, the following command will start a proxy server on port 10025 which
processes mail using the specified filter program, and then forwards the mail on
@ -289,13 +245,26 @@ to the system's default MTA (on port 25):
--filter ${HOME}/.emailrelay/filter \
--spool-dir ${HOME}/.emailrelay/spool
The mail processor program should terminate with an exit code of zero to indicate
success. An exit code of 100 can be used to cancel all further processing of the
message, and any other non-zero exit code is used to indicate an error.
The pre-processor program should terminate with an exit code of zero to indicate
success, or a value between 1 and 99 to indicate failure. Exit codes between
100 and 107 are reserved for special processing: 100 is used to cancel all
further processing of the message, and 103 has the effect of immediately expiring
any "--poll" timer.
For example, the following mail processor shell script examines the client's
IP address and conditionally dumps the message into "sendmail" (using the
sendmail command-line interface rather than SMTP):
The pre-processor program can edit any part of the message's envelope file or
content file: E-MailRelay remembers nothing about the message while the
pre-processor is running, except the filename. But if the message is deleted
by the pre-processor then E-MailRelay will be upset, unless the exit code
is 100.
If the pre-processor program creates new messages in the spool directory then
they may not be processed immediately, or they may be completely ignored. To get
E-MailRelay to pick up new messages in the spool directory use the "--poll"
switch, or run "emailrelay --as-client" from within the pre-processor program.
As an example, the following shell script examines the client's IP address and
conditionally dumps the message into "sendmail" (using the sendmail command-line
interface rather than SMTP):
#!/bin/sh
#
@ -310,15 +279,92 @@ sendmail command-line interface rather than SMTP):
fi
exit 0
An example mail processor script which does simple rot-13 masking of messages is
also provided in the distribution ("share/emailrelay/emailrelay-process.sh").
This could be used as a template for a more sophisticated message encryption
system.
The first thing this script does is convert the path of the content file which
it is given, into the corresponding envelope file. It then extracts the client's
IP address out of the envelope file using "awk". If this matches then it pipes the
message content into sendmail, deletes the message and exits with a value of 100.
The exit value of 100 tells E-MailRelay to forget the message, and not to
complain about the files disappearing.
A more complex example script which does rot-13 masking is also provided in the
distribution ("emailrelay-process.sh"). This does some simple MIME encoding, and
could be used as a template for more sophisticated message encryption.
Some points to note when writing "--filter" programs:
* The standard input and output are not used; the content filename is passed on the command line.
* Programs run with a reduced set of environment variables.
* The E-MailRelay process is completely blocked while the "--filter" program runs.
* E-MailRelay files use CR-LF line terminators, as required by the RFCs.
Address verification
--------------------
In proxy mode all addresses supplied to the SMTP commands "RCPT" and "VRFY" are
accepted by E-MailRelay as valid. In server mode (or more accurately when
"--postmater" is in effect) addresses are accepted if they contain an at sign
or if they are some sort of local "postmaster" address, as described in the SMTP
section above.
However, this behaviour can be modified by using an external verifier program,
using the "--verifier" command-line switch.
The verifier program is passed a command-line containing: (1) the full address,
(2) the user-name part of the address, (3) the host-name part, (4) the local
host's fully qualified domain name, (5) the current "MAIL" command's "FROM:"
address or the empty string for the "VRFY" command, (6) the IP address of the
client connection, (7) the authentication mechanism used by the client ("NONE"
if trusted), and (8) either the authentication name or the fourth field from
authentication secrets file if a trusted IP address.
For valid local mailbox addresses the verifier is expected to write two lines to
the standard output -- the full name associated with the mailbox, and the
canonical mailbox name -- and then exit with a value of zero. For valid non-local
addresses the first line of output should be empty, the second line should be
copied from the first command-line argument, and the exit value should be one.
For invalid addresses the exit value should be greater than one, and anything
written to the standard output is taken as the failure reason. (Only the few
few thousand characters are read from the verifier's standard output stream;
any more is thrown away.)
In this simple example script all addresses are accepted as long as they contain
an at sign. This is equivalent to removing the "--postmaster" command-line
switch:
#!/bin/sh
# verifier.sh
address="${1}"
user="${2}"
host="${3}"
if test "${address}" != "${user}@${host}" ; then exit 2 ; fi
echo "${address}"
echo "${address}" # again
exit 1 # accept
As another example, this verifier script accepts all recipient addresses by
default, but rejects remote addresses if the client has bypassed authentication
by connecting on a trusted IP address:
#!/bin/sh
# verifier.sh
host="$3"
local_domain="$4"
auth_mechanism="$7"
if test "${auth_mechanism}" = "NONE" -a "${host}" != "${local_domain}"
then
echo "cannot relay without authentication"
exit 2 # reject the recipient address
fi
echo "${address}"
echo "${address}" # again
exit 1 # accept the recipient address
If this verifier script is used with a suitable "--server-auth" file then it can
be used to prevent open relay without restricting authenticated clients.
Security issues
---------------
A major security concern is the use of an external mail processor (using the
"--filter" switch), and so the following precautions are taken:
A significant security concern is the use of external mail pre-processors and
address verifiers (using the "--filter" and "--verifier" switches), and so the
following precautions are taken:
# effective userid
@ -332,14 +378,14 @@ A major security concern is the use of an external mail processor (using the
# execution environment
The mail processor runs with an almost empty set of environment variables ("PATH"
and "IFS"), and with no open file descriptors other than "stdin"/"stdout"/"stderr"
The mail pre-processor runs with an almost empty set of environment variables
("PATH" and "IFS"), and with no open file descriptors other than "stdin"/"stdout"/"stderr"
open onto "/dev/null".
# configuration
The mail processor filename has to be configured using a full path, so there is
no dependence on the current working directory or the PATH environment variable.
The mail pre-processor filename has to be configured using a full path, so there
is no dependence on the current working directory or the PATH environment variable.
Security issues which relate to the SMTP protocol itself are beyond the scope of
this document, but RFC2821 makes the following observation: "SMTP mail is
@ -355,7 +401,7 @@ Some other points are:
* Strings are dynamically allocated, so buffer overflow/truncation issues are avoided.
* By default connections to the SMTP and administrative ports will be rejected if they come from remote machines.
* No configuration parameters can be changed through the administrative interface.
* No exec(), system() or popen() calls are used other than execve() to spawn the mail processor and address verifier.
* No exec(), system() or popen() calls are used other than execve() to spawn the mail pre-processor and/or address verifier.
* The submit utility is installed as set-group-id with group ownership of "daemon".
Authentication
@ -375,16 +421,27 @@ fields: "mechanism", "client-or-server", "userid", and "secret". The "mechanism"
field must be "LOGIN" or "CRAM-MD5" (case-insensitive); the "client-or-server"
field must be "client" or "server"; the "userid" field is xtext-encoded user
identifier; and the "secret" field is the xtext-encoded "LOGIN" password or
"CRAM-MD5" key. The "xtext" encoding scheme is defined in RFC1891. The
"CRAM-MD5" keys can be generated using the "emailrelay-passwd" utility.
"CRAM-MD5" key.
A client-side secrets file should contain at least one "LOGIN client" or
"CRAM-MD5 client" entry. A server-side secrets file should contain zero or
more "LOGIN server" or "CRAM-MD5 server" entries. The same secrets file may
be specified for both "--auth-client" and "--auth-server" switches.
The "xtext" encoding scheme is defined properly in RFC1891, but basically it
says that non alphanumeric characters should be represented in hexadecimal as
"+XX".
For example, the following secrets file defines "jsmith" as the username to be
used when E-MailRelay authenticates with a next-hop server, and defines two
The client-side secrets file specified with "--auth-client" is used when
E-MailRelay talks to a remove server. The file should contain at least one
"LOGIN client" or "CRAM-MD5 client" entry.
A server-side secrets file specified with "--auth-server" is used when a remote
client tries to authenticate with E-MailRelay. The file should normally contain
several "LOGIN server" or "CRAM-MD5 server" entries.
The same secrets file may be specified for both "--auth-client" and
"--auth-server" switches.
The "CRAM-MD5" keys can be generated using the "emailrelay-passwd" utility.
As an example, the following secrets file defines "jsmith" as the username to be
used when E-MailRelay authenticates with a remote SMTP server, and defines two
usernames ("user1" and "user2") which can be used by clients when they
authenticate with the E-MailRelay server:
@ -409,18 +466,12 @@ and then send them unencypted over a network. This is a bad thing. You should at
least make sure that the secrets file has tight permissions, and that the
passwords in it are not also used for anything important (such as root access).
On the server side authentication is advertised in the response to the SMTP
"EHLO" command if the "--auth-server" command-line switch is used, and
authentication by the client is mandatory unless the client's IP address is
configured as a trusted address. If the client does authenticate then
the authenticated user-id is stored with the message and then passed on to a
next-hop server using an "AUTH=userid" parameter on the SMTP "MAIL FROM"
command. If the client does not to authenticate then the submitted messages
will be forwarded using "AUTH=<>" on the "MAIL FROM" command. Note that any
"AUTH=userid" information on incoming submitted messages is ignored and
discarded: it is the authorised userid from the AUTH command which is
propagated, not the userid from the incoming "MAIL FROM" command's "AUTH="
parameter.
On the server side authentication is advertised by E-MailRealy in the response
to the SMTP "EHLO" command if the "--auth-server" command-line switch is used.
Authentication by the client is mandatory unless the client's IP address is
configured as a trusted address. If the client does authenticate then the
authenticated user-id is stored with the message and then passed on to the next
SMTP server using an "AUTH=userid" parameter on the SMTP "MAIL FROM" command.
Trusted IP addresses are configured with lines in the secrets file having "NONE"
in the first field, "server" in the second field, a wildcarded IP address in
@ -428,11 +479,21 @@ the third field, and an arbitrary keyword in the fourth field. The keyword
is passed to any external address verifier program specified by the "--verifier"
command-line switch.
On the client side authentication is performed when the client has connected to
For example this secrets file allows any client connecting from the 192.168.0.0
domain to connect without authentication desipte the "--auth-server" switch:
#
# emailrelay secrets file
#
NONE server 192.168.0.* localdomain
LOGIN server user1 secret
LOGIN server user2 e+3Dmc2
On the client side authentication is performed when E-MailRelay has connected to
a server which supports the AUTH extension with the LOGIN or CRAM-MD5 mechanism.
If client authentication is enabled (with the "--auth-client" switch) but the
server does not support the AUTH extension, or does not support the LOGIN or
CRAM-MD5 mechanism, then the client will fail the first message and terminate
CRAM-MD5 mechanism, then E-MailRelay will fail the first message and terminate
with an error message.
Note that some ISPs require separate POP/IMAP authentication before SMTP access
@ -449,21 +510,39 @@ Application notes
set sendmail="/usr/local/libexec/emailrelay-submit"
or
set sendmail="/usr/sbin/emailrelay-submit"
This puts the messages in the E-MailRelay spool-directory, but note that in
proxy mode they will be ignored unless you use "--poll". Or you could use
"--admin" plus "flush"/"emailrelay-poke".
# *Spam Assassin* [http://spamassassin.taint.org]
The E-MailRelay server can use Spam Assasin to mark potential spam by having
The E-MailRelay server can use Spam Assassin to mark potential spam by having
a small shell script which calls spamassassin's "spamc" program installed
as the E-MailRelay mail processor (using the "--filter" command-line switch).
as the E-MailRelay mail pre-processor (using the "--filter" command-line switch).
The shell script would look something like this:
Your "--filter" shell script would look something like this:
#!/bin/sh
tmp="`basename $0`.$$.tmp"
cat ${1} | spamc > ${tmp} && mv ${tmp} ${1}
tmp="/tmp/`basename $0`.$$.tmp"
pre="dos2unix"
post="unix2dos"
${pre} < ${1} | spamc > ${tmp}
if test $? -eq 0 ; then ${post} < ${tmp} > ${1} ; fi
rm -f ${tmp} 2>/dev/null
exit 0
This just pipes the content file into "spamc", using "dos2unix" to remove
carriage-returns. The output is saved in a temporary file, and then put back
into the content file using "unix2dos" to restore the carriage-returns.
Files and directories
---------------------
By default "make install" installs files in the following locations:
Following a normal build from source, a "make install" puts files in the
following locations:
* /usr/local/libexec/emailrelay
* /usr/local/libexec/emailrelay-deliver.sh
* /usr/local/libexec/emailrelay-notify.sh
@ -499,7 +578,8 @@ This directory structure is constrained by the GNU/"autoconf" conventions rather
than the Filesystem Hierarchy Standard (FHS).
To force FHS compliance you can use the "--enable-fhs" switch when running
"configure". This results in the following file locations:
"configure", as is done for the RPMs. This results in the following file
locations:
* /etc/init.d/emailrelay
* /usr/lib/emailrelay/emailrelay-poke
* /usr/sbin/emailrelay
@ -558,15 +638,15 @@ However this will not affect the default spool directory path built into the
scripts and executables; the spool directory path will have to be explicitly
defined at run-time.
For example, building with "configure --enable-fhs ; make ; make install DESTDIR=/root"
would create a spool directory "/root/var/spool/emailrelay", but the server
run as "/root/usr/sbin/emailrelay --as-server" would expect a spool directory
of "/var/spool/emailrelay". This could be fixed by either adding
"--spool-dir /root/var/spool/emailrelay" to the server command-line, or by
creating the "/var/spool/emailrelay" directory manually.
For example, building with "configure --enable-fhs ; make ; make install DESTDIR=/export"
would create a spool directory "/export/var/spool/emailrelay", but the server
run as "/export/usr/sbin/emailrelay --as-server" would expect a spool directory of
"/var/spool/emailrelay". The fix is to add "--spool-dir /export/var/spool/emailrelay"
to the emailrelay command-line.
The "emailrelay" start/stop script in "init.d" creates a pid file in "/var/run"
if the directory exists, or in "/tmp" otherwise.
The "emailrelay" script in "init.d" creates a pid file in "/var/run" if the
directory exists, or in "/tmp" otherwise.

View File

@ -3,112 +3,114 @@ E-MailRelay User Guide
What is it?
-----------
E-MailRelay is a simple store-and-forward e-mail transfer agent. It's a program
which runs in the background and accepts e-mail from front-ends (KMail, Outlook,
Netscape etc.), stores the messages on the hard disk, and when next connected
to the Internet forwards them to a next SMTP server for onward delivery.
E-MailRelay is a simple store-and-forward message transfer agent and proxy server.
It runs on Unix-like operating systems (including Linux), and on Windows.
The E-MailRelay program ("emailrelay") can run in two main modes: a storage
daemon, or a forwarding agent. As a storage daemon it waits for connections
from your e-mail front-end and stores the mail which it receives in a spool
directory. As a forwarding agent it pulls messages out of the spool directory
and passes them on to a remote server -- typically an ISP mail server.
When used as proxy server the E-MailRelay program ("emailrelay") runs in the
background and accepts e-mail from front-ends (KMail, Outlook etc.) or from
the outside world, using the SMTP protocol. As soon as an e-mail message is
received it is forwarded on to the next SMTP server for onward delivery. This
becomes more useful when you add in your own message processing: as each
message is received it can be passed one of your programs for editing,
filtering, encypting etc.
E-MailRelay uses the Simple Message Transfer Protocol (SMTP). When running as a
storage daemon it acts as an SMTP server, and when running as a forwarding
agent it acts as an SMTP client.
The program can also run as a proxy server. In this mode e-mails submitted at
the server interface are passed on to the next server immediately, without
spooling. This can be useful when combined with mail pre-processing to do things
like encryption, message archiving, addition of digital signatures, etc.
E-MailRelay runs on GNU/Linux, FreeBSD, Solaris and Windows.
When used as a store-and-forward transfer agent E-MailRelay runs in two modes:
the storage daemon part, and the forwarding agent. The storage daemon
waits for incoming mail and stores anything it receives in a spool directory.
As a forwarding agent E-MailRelay pulls messages out of the spool directory
and passes them on to a remote server -- perhaps your ISP mail server.
What it's not
-------------
With a dial-up connection E-MailRelay does not get involved in processing
incoming e-mail messages; it only operates on outgoing messages. Incoming e-mail
messages will probably be retrieved from your ISP by your e-mail front-end
program, using the POP3 or IMAP protocols.
E-MailRelay is not a routing MTA. It forwards e-mail to a pre-configured SMTP
server, regardless of any message addressing or DNS redirects.
E-MailRelay is not a routing MTA. It is designed to be used in situations where
all outgoing e-mail message go out over the dial-up connection, so it is not an
appropriate choice if you send e-mail to other people who use the same machine
or to people who are on the same local area network.
E-MailRelay does not do POP3 or IMAP protocols. Many ISPs accept outgoing e-mail
using SMTP, but deliver mail to you using POP3 or IMAP. In this case E-MailRelay
does not get involved in processing incoming e-mail messages; it only operates
on outgoing messages. Incoming e-mail messages will probably be retrieved from
your ISP direcly by your e-mail front-end program.
Also be careful with programs like "fetchmail" which will fetch incoming mail
using POP3 or IMAP, but then use a local SMTP server to deliver to local
mailboxes. E-MailRelay does not act as a delivery agent, so if your local SMTP
server is E-MailRelay then your incoming e-mail will bounce back out.
E-MailRelay is not a delivery agent. Some programs like "fetchmail" send
locally-addressed e-mail to the local SMTP server in order to deliver them to
local mailboxes. E-MailRelay will not normally do this.
Why use it?
-----------
The motivation for developing E-MailRelay is that e-mail store-and-forward
using SMTP is conceptually a very simple thing, but most popular MTAs are
complex. E-MailRelay just stores messages and then forwards them on to your
ISP, whereas a fully-featured MTA does clever things with address re-writing,
message routing, local delivery, loop detection, fancy DNS lookups etc.
E-MailRelay is a simple tool that does SMTP. For simple tasks it is likely
to be easier to understand and configure than a more general purpose MTA.
In particular the configuration of some popular MTAs is notoriously complex
and arcane, whereas the only thing the E-MailRelay system needs is the name of
your ISP's mail server.
E-MailRelay is designed to be policy-free, so that you can implement your own
policies for message retries, bounces, local mailbox delivery, spam filtering
etc. through external scripts.
Because E-MailRelay can act as a proxy server, it may be useful handling
incoming mail from a permanent Internet connection. In this configuration the
pre-processing feature could be used for spam filtering or virus checking.
For outgoing mail pre-processing could be used to compensate for features, such
as encryption, which are not available in your e-mail client program. Or it
could be used to enforce formatting or legal requirements for all outgoing mail.
Typical applications of E-MailRelay include:
* spam filtering and virus checking incoming mail
* adding digital signatures or legal disclaimers to outgoing mail
* doing store-and-forward for outgoing mail across a dial-up internet connection
* adding authentication where the existing infrastructure does not support it
* simple proxying on a firewall host or DMZ
Running E-MailRelay
-------------------
To run E-MailRelay as a storage daemon use the command:
To run the program as a proxy use the "--as-proxy" command-line switch, followed by the
address of the target SMTP server. If you want to edit or filter e-mail as it passes
through the proxy then specify your pre-processor program with the "--filter" switch.
You can optionally change the listening port number using "--port" and the
spool directory using "--spool-dir".
emailrelay --as-server
For example, to start up a local proxy which passes messages to some "addsig" script
and then forwards them to an MTA running on "smarthost", use a command like this:
To run E-MailRelay as a forwarding agent (once connected to the Internet), use
a command like this:
emailrelay --as-proxy smarthost:smtp --filter $HOME/bin/addsig --spooldir $HOME/tmp
emailrelay --as-client mail.myisp.net:smtp
To use E-MailRelay as a store-and-forward MTA use the "--as-server" switch
to start the storage daemon in the background. And then trigger delivery of
spooled messages by running emailrelay with the "--as-client" switch, followed
by the address of the target SMTP server.
where "mail.myisp.net" is replaced with the name of your ISP's SMTP server.
For example, to start a storage daemon listening on port 10025 use a command
like this:
To run E-MailRelay as a personal proxy server (on port 10025) to the system's
default MTA use a command something like this:
emailrelay --as-server --port 10025 --spooldir $HOME/tmp
emailrelay --as-proxy localhost:smtp --no-syslog --port 10025 --filter ${HOME}/.emailrelay/mailfilter --spool-dir ${HOME}/.emailrelay/spool
And then to forward the spooled mail to "smarthost" run somthing like this:
where "mailfilter" is a program which you have written to do the appropriate
mail processing.
emailrelay --as-client smarthost:smtp --spooldir $HOME/tmp
By default E-MailRelay will reject connections from remote machines. To
allow connections from anywhere use the "--remote-clients" switch.
For more information on the command-line options refer to the reference guide
or run:
emailrelay --help
emailrelay --help --verbose
Starting the daemon at boot-time
--------------------------------
The standard installation of E-MailRelay (using "make install") puts most of
the files into the right places, but it does not set things up so that the
daemon starts at boot time, or that e-mail gets forwarded automatically when
you connect to the Internet. You have to do those bits yourself because of the
differences between the various operating systems and distributions.
The standard installation of E-MailRelay (using "make install") puts most of the
files into the right places, but it does not set things up so that the daemon
starts at boot time. You have to do that yourself because of the differences
between the various operating systems and distributions.
Many systems, including the most popular GNU/Linux distributions, use the
System-V mechanism for starting daemons at boot time. The directory
"/etc/init.d" (or "/sbin/init.d") contains a start/stop script for each daemon
process, and then symbolic links in the "rc<N>.d" subdirectories control which
scripts are run when entering or leaving a particular run-level (<N>). The
links point back into the start/stop script in the parent directory, using a
"S" prefix for the starting link, and a "K" prefix for the stopping link. The
numeric part of the link name determines the order in which the links are
called.
Many systems provide GUI programs and command-line tools to make the necessary
links into the boot system: "ksysv" (KDE), "redhat-config-services", "insserv"
(Suse), "chkconfig" (Redhat), "install_initd" (LSB) are examples.
If you cannot use a GUI front-end as provided by GNOME and KDE, or a
command-line utility like "insserv", "chkconfig" or "/usr/lib/lsb/install_initd",
then you can follow the steps below to set up the necessary symbolic links.
If you do not have a suitable configuration tool you can set up the links
manually as described below.
The "System-V" boot system has a base directory "/etc/init.d" (or "/sbin/init.d")
containing a start/stop script for each daemon process, and then symbolic links
in the "rc<N>.d" subdirectories control which scripts are run when entering or
leaving a particular run-level (<N>). The links point back into the start/stop
script in the parent directory, using a "S" prefix for the starting link, and a
"K" prefix for the stopping link. The numeric part of the link name determines
the order in which the links are called.
So the goal is to set up symbolic links to the "emailrelay" start/stop script
(not the binary) which "make install" will have put in "/etc/init.d" or
"/usr/local/libexec".
Before you start you will need to know where your "init.d" directory can be
found and what your default run level is:
@ -117,8 +119,8 @@ found and what your default run level is:
$ runlevel | awk '{print $2}'
Assuming these are "/etc/init.d" and "5" you should (as root) copy the
E-MailRelay start/stop script into "/etc/init.d" (if it is not already
installed there):
E-MailRelay start/stop script into "/etc/init.d" (if it is not already installed
there):
$ cp /usr/local/libexec/emailrelay /etc/init.d
@ -143,6 +145,10 @@ daemons compete for the standard SMTP listening port):
Triggering onward delivery
--------------------------
If you are using E-MailRelay to store and forward e-mail over a dial-up link to
the internet, then you will need to set things up so that the dialler tells
E-MailRelay when to start forwarding.
This section assumes that you are using "pppd" to establish your dial-up
Internet connection. (Note that KDE's "kppp" and Red Hat's "rp3" are graphical
front-ends to the underlying "pppd" daemon.)
@ -162,47 +168,52 @@ If you find "sendmail -q" then it should be sufficient to replace it with this:
where you substitute your ISP's SMTP server address for <myisp>.
Or if your "ip-up" calls out to "ip-up.local" then create a two-line
"ip-up.local" script like this:
"/etc/ppp/ip-up.local" script like this:
$ cd /etc/ppp
$ cat << EOF > ip-up.local
#!/bin/sh
exec /usr/local/sbin/emailrelay --as-client <myisp>:smtp
EOF
$ chmod +x ip-up.local
If you create "ip-up.local" yourself remember to make it executable.
Notification of failed e-mails
------------------------------
If e-mail messages become corrupted or inaccessible within the spool directory
then they will get failed within the E-MailRelay system. In order to get failed
e-mails to 'bounce' back into your in-tray you will need to run the
"emailrelay-notify.sh" script (as "root") periodically. Note that this script
requires that you have "procmail" installed on your system to act as a
"delivery agent".
then they will get failed within the E-MailRelay system, with the envelope files
in the spool directory ending up with a ".bad" suffix.
There are not many ways in which an e-mail can fail within the E-MailRelay
system. If everything is set up correctly then perhaps the most likely case is
that you have run out of disk space. If you are not too worried about getting
failed mail to bounce, or if you do not have a suitable delivery agent, then
a simple check in your ".profile" script for "*.bad" files in the spool
directory may be sufficient:
If you are not too worried about getting failed mail to bounce, or if you do not
have a suitable delivery agent, then a simple check in your ".profile" script
for "*.bad" files in the spool directory may be sufficient:
$ cat <<EOF >> ~/.profile
if test -f /var/spool/emailrelay/*.envelope.bad ; then echo Failed mail >&2 ; fi
EOF
if test -f /var/spool/emailrelay/*.envelope.bad
then
echo Failed mail >&2
fi
If you want failed e-mails to be retried a few times before bouncing back into
your in-tray, you can run the "emailrelay-resubmit.sh" script. This simply
removes the ".bad" suffix from files in the spool directory, as long as they
have not been retried too many times already.
This will warn you that something failed, but you will have to look at the
failure reason written into the envelope files, and at the log files, to
find out what went wrong.
Or you can get failed e-mails to 'bounce' back into your in-tray by running the
"emailrelay-notify.sh" script as "root" periodically. But note that this is
only approporiate if you are using E-MailRelay for outgoing traffic, and it
assumes that you have "procmail" installed on your system to act as a "delivery
agent".
If you want failed e-mails to be retried a few times you can run the
"emailrelay-resubmit.sh" script periodically. This simply removes the ".bad"
suffix from files in the spool directory, as long as they have not been retried
too many times already.
Logging
-------
The E-MailRelay program uses the "syslog" system to issue warnings and error messages,
using the "LOG_MAIL" facility. The "syslog" system is configured through the
"/etc/syslog.conf" file (try "man syslog.conf"), and in most cases you will find
that "LOG_MAIL" warnings and errors are directed to an appropriate log file (perhaps
"/var/log/messages").
If the "--log" switch is used then E-MailRelay program issues warnings and error
messages to the "syslog" system using the "LOG_MAIL" facility. Under Windows NT
it writes to the "Application" event log.
The "syslog" system is configured through the "/etc/syslog.conf" file (try
"man syslog.conf"), and in most cases you will find that "LOG_MAIL" warnings and
errors are directed to an appropriate log file (perhaps "/var/log/messages").
To get a file which will accumulate all E-MailRelay log messages (and messages
from all other mail programs), add a line like this to "/etc/syslog.conf":
@ -297,10 +308,10 @@ from cygwin/bash on Win98 keeps stderr open (albeit with dreadful performance),
whereas the standard command prompt does not. If necessary the environment
variable "GLOGOUTPUT_FILE" can be defined as the name of a log file.
Preventing public mail relay
----------------------------
Preventing open mail relay
--------------------------
If you are running E-MailRelay as a server with a permanent connection to the
Internet it is important to prevent public mail relay. By default public mail
Internet it is important to prevent open mail relay. By default public mail
relaying is not possible because E-MailRelay does not accept IP connections from
remote clients. However, if the "--remote-clients" switch is used then you need
to be more careful. One option is to require all clients to authenticate, by
@ -312,38 +323,11 @@ mechanism of "NONE". Refer to the reference guide for more information.
Taking it one stage further, you may want to allow clients to connect from any
IP address without authentication, but only allow them to send mail to local
users. You can do this by requiring authentication with the "--server-auth"
switch but then exempting all clients from authentication with a "NONE server *.*.*.* x"
switch but then exempt all clients from authentication with a "NONE server *.*.*.* x"
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.
Glossary
--------
# ISP
Internet Service Provider.
# MTA
Message Transfer Agent. Something which accepts incoming e-mail messages
and passes them on either to a local user, or to another MTA. A sophisticated
MTA program, which is widely used on the Internet, is "sendmail".
# SMTP
Simple Message Transfer Protocol. A set of rules which dictate how
e-mail messages are passed from one part of the e-mail system to the next.
The protocol rules are set out in the document "RFC2821".
# POP3
Post Office Protocol 3. A protocol for fetching incoming e-mail messages.
Many e-mail front-ends will fetch messages directly from an ISP using the POP
protocol, or a program like "fetchmail" may do it on their behalf.
# IMAP
Internet Message Access Protocol. A newer alternative to POP3.
# PPP
Point to Point Protocol. A low-level protocol used in dial-up connections
to an ISP. Usually implemented by the "pppd" program on GNU/Linux.

View File

@ -5,7 +5,8 @@ Introduction
------------
E-MailRelay was originally developed on Linux and so most of the documentation
relates to Unix-like operating systems rather than Microsoft Windows. This
document provides some help on Windows installation and setup.
document provides some help on installing and setting up E-MailRelay as a
store-and-forward MTA on Windows.
Quick start
------------
@ -18,7 +19,6 @@ In summary, the Windows installation process is as follows:
* Create a spool directory under "<windir>\spool", eg. "c:\win98\spool\emailrelay".
* Configure your e-mail client (eg. Outlook) to use SMTP on the local machine for outgoing e-mail.
* Run the forwarding client from the taskbar/desktop shortcut once connected to the Internet.
* Optionally register the server as a COM component using the "-regserver" command-line switch.
These steps are explained in more detail below.
@ -105,4 +105,5 @@ taskbar, desktop or "Start->Programs->StartUp" shortcuts.
Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>. All rights reserved.

View File

@ -1,25 +1,27 @@
Summary: Simple e-mail message transfer agent using SMTP
Name: emailrelay
Version: 1.0.2
Version: 1.1
Release: 1
Copyright: GPL
Group: System Environment/Daemons
Source: http://emailrelay.sourceforge.net/.../emailrelay-src-1.0.2.tar.gz
Source: http://emailrelay.sourceforge.net/.../emailrelay-src-1.1.tar.gz
BuildRoot: /tmp/emailrelay-install
%define prefix /usr
%description
E-MailRelay is a simple SMTP store-and-forward message transfer agent (MTA).
It runs as an SMTP server, storing e-mail in a local spool directory, and
then forwarding the stored messages to the next SMTP server on request.
It can also run as a proxy server, forwarding (and optionally pre-processing)
e-mail as soon as it is received. It does not do any message routing, other
than to a local postmaster. Because of this functional simplicity it is
extremely easy to configure, typically only requiring the address of the
next-hop SMTP server to be put on the command line.
E-MailRelay is a simple SMTP proxy and store-and-forward message transfer agent
(MTA). When running as a proxy all e-mail messages can be passed through a
user-defined program, such as a spam filter, which can drop, re-address or edit
messages as they pass through. When running as a store-and-forward MTA incoming
messages are stored in a local spool directory, and then forwarded to the next
SMTP server on request.
C++ source code is available for Linux, FreeBSD (etc) and Windows.
Because of its functional simplicity E-MailRelay is easy to configure, typically
only requiring the address of the target SMTP server to be put on the command
line.
C++ source code is available for Linux, FreeBSD, MacOS X etc, and Windows.
Distribution is under the GNU General Public License.
%prep
@ -30,13 +32,13 @@ Distribution is under the GNU General Public License.
make HAVE_DOXYGEN=no HAVE_MAN2HTML=no
%install
make install destdir=$RPM_BUILD_ROOT DESTDIR=$RPM_BUILD_ROOT HAVE_DOXYGEN=no HAVE_MAN2HTML=no
make install-strip destdir=$RPM_BUILD_ROOT DESTDIR=$RPM_BUILD_ROOT HAVE_DOXYGEN=no HAVE_MAN2HTML=no
%post
test -f /usr/lib/lsb/install_initd && cd /etc/init.d && /usr/lib/lsb/install_initd emailrelay
test -f /usr/lib/lsb/install_initd && cd /etc/init.d && /usr/lib/lsb/install_initd emailrelay || true
%preun
test $1 -eq 0 && test -f /usr/lib/lsb/remove_initd && cd /etc/init.d && /usr/lib/lsb/remove_initd emailrelay
test $1 -eq 0 && test -f /usr/lib/lsb/remove_initd && cd /etc/init.d && /usr/lib/lsb/remove_initd emailrelay || true
%clean
rm -rf $RPM_BUILD_ROOT
@ -75,6 +77,6 @@ rm -rf $RPM_BUILD_ROOT
%changelog
* Wed Jul 3 2003 Graeme Walker <graeme_walker@users.sourceforge.net>
* Wed Jul 3 2002 Graeme Walker <graeme_walker@users.sourceforge.net>
- Initial version.

View File

@ -1,19 +1,20 @@
#
# Copyright (C) 2001-2003 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.
#
SUBDIRS = gcc2.95 msvc6.0
#
## Copyright (C) 2001-2003 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.
##
#
SUBDIRS = gcc2.95 msvc6.0 sunpro5

View File

@ -90,25 +90,9 @@ e_sbindir = @e_sbindir@
e_spooldir = @e_spooldir@
install_sh = @install_sh@
#
# Copyright (C) 2001-2003 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.
#
SUBDIRS = gcc2.95 msvc6.0
#
#
SUBDIRS = gcc2.95 msvc6.0 sunpro5
subdir = lib
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h

View File

@ -1,21 +1,22 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
EXTRA_DIST = iostream limits sstream xlocale

View File

@ -14,24 +14,8 @@
@SET_MAKE@
#
# Copyright (C) 2001-2003 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.
#
#
#
SHELL = @SHELL@
srcdir = @srcdir@

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
@ -30,7 +30,7 @@
namespace std
{
typedef ::ios ios_base ;
} ;
}
#endif

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
@ -27,7 +27,7 @@
namespace std
{
#include <limits.h>
} ;
}
#endif

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
@ -39,7 +39,7 @@ namespace std
std::string str() const ;
} ;
typedef ostringstream stringstream ;
} ;
}
inline
std::ostringstream::ostringstream()

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or

View File

@ -1,20 +1,22 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
EXTRA_DIST = cstdio cstdlib cstring ctime cmath
EXTRA_DIST = cstdio cstdlib cstring ctime

View File

@ -14,24 +14,8 @@
@SET_MAKE@
#
# Copyright (C) 2001-2003 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.
#
#
#
SHELL = @SHELL@
srcdir = @srcdir@
@ -109,7 +93,7 @@ e_sbindir = @e_sbindir@
e_spooldir = @e_spooldir@
install_sh = @install_sh@
EXTRA_DIST = cstdio cstdlib cstring ctime
EXTRA_DIST = cstdio cstdlib cstring ctime cmath
subdir = lib/msvc6.0
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h

43
lib/msvc6.0/cmath Normal file
View File

@ -0,0 +1,43 @@
//
// Copyright (C) 2001-2003 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.
//
// ===
//
// cmath
//
#ifndef G_PORT_CMATH_H
#define G_PORT_CMATH_H
#include <math.h>
namespace std
{
using ::sin ;
using ::cos ;
using ::tan ;
using ::asin ;
using ::acos ;
using ::atan ;
using ::sqrt ;
using ::log ;
using ::log10 ;
}
#endif

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
@ -31,7 +31,7 @@ namespace std
using ::rename ;
using ::sscanf ;
using ::sprintf ;
} ;
}
#endif

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
@ -32,6 +32,6 @@ namespace std
using ::getenv ;
using ::free ;
using ::malloc ;
} ;
}
#endif

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
@ -38,7 +38,7 @@ namespace std
using ::strstr ;
using ::strspn ;
using ::strcspn ;
} ;
}
#endif

View File

@ -1,4 +1,4 @@
//
//
// Copyright (C) 2001-2003 Graeme Walker <graeme_walker@users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or
@ -35,7 +35,7 @@ namespace std
using ::mktime ;
using ::_tzset ;
using ::strftime ;
} ;
}
#endif

20
lib/sunpro5/Makefile.am Normal file
View File

@ -0,0 +1,20 @@
#
## Copyright (C) 2001-2003 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.
##
#
EXTRA_DIST = xar

216
lib/sunpro5/Makefile.in Normal file
View File

@ -0,0 +1,216 @@
# Makefile.in generated by automake 1.6.3 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AR = @AR@
AWK = @AWK@
CC = @CC@
COMPILER_VERSION = @COMPILER_VERSION@
CXX = @CXX@
DEPDIR = @DEPDIR@
GZIP = @GZIP@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_MAN2HTML = @HAVE_MAN2HTML@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
MAKE = @MAKE@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
e_docdir = @e_docdir@
e_examplesdir = @e_examplesdir@
e_initdir = @e_initdir@
e_libexecdir = @e_libexecdir@
e_man1dir = @e_man1dir@
e_sbindir = @e_sbindir@
e_spooldir = @e_spooldir@
install_sh = @install_sh@
#
#
EXTRA_DIST = xar
subdir = lib/sunpro5
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = Makefile.am Makefile.in
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu lib/sunpro5/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
tags: TAGS
TAGS:
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@list='$(DISTFILES)'; for file in $$list; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

16
lib/sunpro5/xar Normal file
View File

@ -0,0 +1,16 @@
#!/bin/sh
#
# xar
#
# A replacement for 'ar' that does 'CC -xar' ignoring
# autoconf's bogus "cru" switches.
#
# For example:
# $ chmod +x lib/sunpro5/xar
# $ ./configure --enable-whatever AR=`pwd`/lib/sunpro5/xar
#
CC="CC"
if test -x "${CXX}" ; then CC="${CXX}" ; fi
if test "${1}" = "--cxx" ; then CC="${2}" ; shift ; shift ; fi
shift # get rid of "cru" flags
exec ${CC} -xar -o "$@"

View File

@ -1,19 +1,20 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
SUBDIRS = glib gnet gsmtp main win32

View File

@ -90,24 +90,8 @@ e_sbindir = @e_sbindir@
e_spooldir = @e_spooldir@
install_sh = @install_sh@
#
# Copyright (C) 2001-2003 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.
#
#
#
SUBDIRS = glib gnet gsmtp main win32
subdir = src
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs

View File

@ -1,21 +1,22 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
EXTRA_DIST=\
garg_win32.cpp \
gcleanup_win32.cpp \
@ -24,6 +25,7 @@ EXTRA_DIST=\
gdirectory_win32.cpp \
gfs_win32.cpp \
glogoutput_win32.cpp \
gmd5_aladdin.cpp \
gprocess_win32.cpp \
gfile_win32.cpp \
gregistry_win32.cpp \
@ -66,7 +68,7 @@ libglib_a_SOURCES = \
glogoutput.cpp \
glogoutput.h \
glogoutput_unix.cpp \
gmd5.cpp \
gmd5_rsa.cpp \
gmd5.h \
gmemory.h \
gnoncopyable.h \
@ -79,6 +81,8 @@ libglib_a_SOURCES = \
groot.cpp \
groot.h \
gsetter.h \
gslot.cpp \
gslot.h \
gstatemachine.h \
gstr.cpp \
gstr.h \

View File

@ -90,24 +90,8 @@ e_sbindir = @e_sbindir@
e_spooldir = @e_spooldir@
install_sh = @install_sh@
#
# Copyright (C) 2001-2003 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.
#
#
#
EXTRA_DIST = \
garg_win32.cpp \
gcleanup_win32.cpp \
@ -116,6 +100,7 @@ EXTRA_DIST = \
gdirectory_win32.cpp \
gfs_win32.cpp \
glogoutput_win32.cpp \
gmd5_aladdin.cpp \
gprocess_win32.cpp \
gfile_win32.cpp \
gregistry_win32.cpp \
@ -159,7 +144,7 @@ libglib_a_SOURCES = \
glogoutput.cpp \
glogoutput.h \
glogoutput_unix.cpp \
gmd5.cpp \
gmd5_rsa.cpp \
gmd5.h \
gmemory.h \
gnoncopyable.h \
@ -172,6 +157,8 @@ libglib_a_SOURCES = \
groot.cpp \
groot.h \
gsetter.h \
gslot.cpp \
gslot.h \
gstatemachine.h \
gstr.cpp \
gstr.h \
@ -193,9 +180,10 @@ am_libglib_a_OBJECTS = garg.$(OBJEXT) garg_unix.$(OBJEXT) \
gdirectory.$(OBJEXT) gdirectory_unix.$(OBJEXT) \
gexception.$(OBJEXT) gfile.$(OBJEXT) gfile_unix.$(OBJEXT) \
gfs_unix.$(OBJEXT) ggetopt.$(OBJEXT) glog.$(OBJEXT) \
glogoutput.$(OBJEXT) glogoutput_unix.$(OBJEXT) gmd5.$(OBJEXT) \
gpath.$(OBJEXT) gpidfile.$(OBJEXT) gprocess_unix.$(OBJEXT) \
groot.$(OBJEXT) gstr.$(OBJEXT) gtime.$(OBJEXT)
glogoutput.$(OBJEXT) glogoutput_unix.$(OBJEXT) \
gmd5_rsa.$(OBJEXT) gpath.$(OBJEXT) gpidfile.$(OBJEXT) \
gprocess_unix.$(OBJEXT) groot.$(OBJEXT) gslot.$(OBJEXT) \
gstr.$(OBJEXT) gtime.$(OBJEXT)
libglib_a_OBJECTS = $(am_libglib_a_OBJECTS)
DEFS = @DEFS@
@ -216,10 +204,12 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@ ./$(DEPDIR)/gfile_unix.Po ./$(DEPDIR)/gfs_unix.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/ggetopt.Po ./$(DEPDIR)/glog.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/glogoutput.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/glogoutput_unix.Po ./$(DEPDIR)/gmd5.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gpath.Po ./$(DEPDIR)/gpidfile.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/glogoutput_unix.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gmd5_rsa.Po ./$(DEPDIR)/gpath.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gpidfile.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gprocess_unix.Po ./$(DEPDIR)/groot.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gstr.Po ./$(DEPDIR)/gtime.Po
@AMDEP_TRUE@ ./$(DEPDIR)/gslot.Po ./$(DEPDIR)/gstr.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gtime.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
@ -275,11 +265,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glog.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glogoutput.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glogoutput_unix.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmd5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmd5_rsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpath.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpidfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gprocess_unix.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/groot.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gslot.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtime.Po@am__quote@

View File

@ -126,7 +126,7 @@ void G::Arg::removeAt( size_t sw_index , size_t sw_args )
G_ASSERT( sw_index > 0U && sw_index < m_array.size() ) ;
if( sw_index > 0U && sw_index < m_array.size() )
{
Array::iterator p = m_array.begin() + sw_index ;
StringArray::iterator p = m_array.begin() + sw_index ;
p = m_array.erase( p ) ;
for( size_t i = 0U ; i < sw_args && p != m_array.end() ; i++ )
p = m_array.erase( p ) ;

View File

@ -25,6 +25,7 @@
#define G_ARG_H
#include "gdef.h"
#include "gstrings.h"
#include <vector>
#include <string>
@ -121,8 +122,7 @@ private:
static bool match( bool , const std::string & , const std::string & ) ;
private:
typedef std::vector<std::string GAllocator(std::string) > Array ;
Array m_array ;
StringArray m_array ;
std::string m_prefix ;
} ;

View File

@ -28,6 +28,12 @@
#include "glog.h"
#include <signal.h>
extern "C"
{
void gcleanup_unix_handler_( int signum ) ;
typedef void (*Handler)( int ) ;
}
namespace G
{
class CleanupImp ;
@ -40,14 +46,13 @@ class G::CleanupImp
{
public:
static void add( void (*fn)(const char*) , const char * ) ;
static void installDefault( int ) ;
static void callHandlers() ;
private:
static void init() ;
static void install( int , void (*fn)(int) ) ;
static void install( int , Handler ) ;
static void installHandler( int ) ;
static void installDefault( int ) ;
static void callHandlers() ;
static void handler_( int ) ;
static bool ignored( int ) ;
private:
@ -104,7 +109,7 @@ void G::CleanupImp::installHandler( int signum )
if( ignored(signum) )
G_DEBUG( "G::CleanupImp::installHandler: signal " << signum << " is ignored" ) ;
else
install( signum , handler_ ) ;
install( signum , gcleanup_unix_handler_ ) ;
}
void G::CleanupImp::installDefault( int signum )
@ -121,7 +126,7 @@ bool G::CleanupImp::ignored( int signum )
return action.sa_handler == SIG_IGN ;
}
void G::CleanupImp::install( int signum , void (*fn)(int) )
void G::CleanupImp::install( int signum , Handler fn )
{
static struct sigaction zero_action ;
struct sigaction action( zero_action ) ;
@ -139,12 +144,13 @@ void G::CleanupImp::callHandlers()
}
}
void G::CleanupImp::handler_( int signum )
extern "C"
void gcleanup_unix_handler_( int signum )
{
try
{
callHandlers() ;
installDefault( signum ) ;
G::CleanupImp::callHandlers() ;
G::CleanupImp::installDefault( signum ) ;
::raise( signum ) ;
}
catch(...)

View File

@ -41,7 +41,7 @@ void G::Daemon::detach()
::_exit( 0 ) ;
setsid() ;
(void) Process::cd( "/" , Process::NoThrow() ) ;
G_IGNORE Process::cd( "/" , Process::NoThrow() ) ;
if( Process::fork() == Process::Parent )
::_exit( 0 ) ;

View File

@ -24,8 +24,7 @@
#include "gdef.h"
#include "gdate.h"
#include "gdebug.h"
#include <sys/types.h>
#include <time.h>
#include <ctime>
#include <iomanip>
//static
@ -45,6 +44,11 @@ G::Date::Date()
init( G::DateTime::utc(G::DateTime::now()) ) ;
}
G::Date::Date( G::DateTime::EpochTime t )
{
init( G::DateTime::utc(t) ) ;
}
G::Date::Date( G::DateTime::EpochTime t , const LocalTime & )
{
init( G::DateTime::local(t) ) ;
@ -88,12 +92,21 @@ std::string G::Date::string( Format format ) const
{
std::ostringstream ss ;
if( format == yyyy_mm_dd_slash )
ss << m_year << "/" << m_month << "/" << m_day ;
{
ss << yyyy() << "/" << mm() << "/" << dd() ;
}
else if( format == yyyy_mm_dd )
{
ss << yyyy() << mm() << dd() ;
}
else if( format == mm_dd )
{
ss << mm() << dd() ;
}
else
ss
<< m_year
<< std::setw(2) << std::setfill('0') << m_month
<< std::setw(2) << std::setfill('0') << m_day ;
{
G_ASSERT( !"enum error" ) ;
}
return ss.str() ;
}
@ -102,10 +115,17 @@ int G::Date::monthday() const
return m_day ;
}
std::string G::Date::monthdayString() const
std::string G::Date::dd() const
{
std::ostringstream ss ;
ss << m_day ;
ss << std::setw(2) << std::setfill('0') << m_day ;
return ss.str() ;
}
std::string G::Date::mm() const
{
std::ostringstream ss ;
ss << std::setw(2) << std::setfill('0') << m_month ;
return ss.str() ;
}
@ -132,7 +152,7 @@ G::Date::Weekday G::Date::weekday() const
return m_weekday ;
}
std::string G::Date::weekdayString( bool brief ) const
std::string G::Date::weekdayName( bool brief ) const
{
if( weekday() == sunday ) return brief ? "Sun" : "Sunday" ;
if( weekday() == monday ) return brief ? "Mon" : "Monday" ;
@ -149,7 +169,7 @@ G::Date::Month G::Date::month() const
return Month(m_month) ;
}
std::string G::Date::monthString( bool brief ) const
std::string G::Date::monthName( bool brief ) const
{
if( month() == january ) return brief ? "Jan" : "January" ;
if( month() == february ) return brief ? "Feb" : "February" ;
@ -171,10 +191,10 @@ int G::Date::year() const
return m_year ;
}
std::string G::Date::yearString() const
std::string G::Date::yyyy() const
{
std::ostringstream ss ;
ss << m_year ;
ss << std::setw(4) << std::setfill('0') << m_year ;
return ss.str() ;
}

View File

@ -27,8 +27,7 @@
#include "gdef.h"
#include "gdatetime.h"
#include "gdebug.h"
#include <sys/types.h>
#include <time.h>
#include <ctime>
#include <string>
namespace G
@ -54,7 +53,7 @@ public:
august , september , october , november , december } ;
enum Format
{ yyyy_mm_dd_slash , yyyy_mm_dd } ;
{ yyyy_mm_dd_slash , yyyy_mm_dd , mm_dd } ;
static int yearUpperLimit() ;
// Returns the smallest supported year value.
@ -73,6 +72,10 @@ public:
Date( const G::DateTime::BrokenDownTime & tm ) ;
// Constructor for the specified date.
explicit Date( G::DateTime::EpochTime t ) ;
// Constructor for the date in the UTC
// timezone as at the given epoch time.
Date( G::DateTime::EpochTime t , const LocalTime & ) ;
// Constructor for the date in the local
// timezone as at the given epoch time.
@ -86,27 +89,34 @@ public:
Weekday weekday() const ;
// Returns the day of the week.
std::string weekdayString( bool brief = false ) const ;
std::string weekdayName( bool brief = false ) const ;
// Returns an english string representation of
// the day of the week.
// (Was weekdayString().)
int monthday() const ;
// Returns the day of the month.
std::string monthdayString() const ;
// Returns a string representation of the day of the month.
std::string dd() const ;
// Returns the day of the month as a two-digit decimal string.
// (Was monthdayString().)
Month month() const ;
// Returns the month.
std::string monthString( bool brief = false ) const ;
std::string monthName( bool brief = false ) const ;
// Returns the month as a string (in english).
// (Was monthString().)
std::string mm() const ;
// Returns the month as a two-digit decimal string.
int year() const ;
// Returns the year.
std::string yearString() const ;
// Returns the year as a string.
std::string yyyy() const ;
// Returns the year as a four-digit decimal string.
// (Was yearString().)
Date & operator++() ;
// Increments the date by one day.

View File

@ -27,9 +27,12 @@
#include "gassert.h"
#include <sstream>
const time_t minute = 60U ;
const time_t hour = 60U * minute ;
const time_t day = 24U * hour ;
namespace
{
const std::time_t minute = 60U ;
const std::time_t hour = 60U * minute ;
const std::time_t day = 24U * hour ;
}
G::DateTime::EpochTime G::DateTime::now()
{
@ -42,8 +45,8 @@ G::DateTime::EpochTime G::DateTime::epochTime( const BrokenDownTime & bdt_in )
BrokenDownTime bdt( bdt_in ) ;
EpochTime start = std::mktime( &bdt ) ; // localtime
// iterate over all timezones
const time_t delta = minute * 30U ;
// iterate over all timezones -- brute force for now
const std::time_t delta = minute * 30U ;
for( EpochTime t = (start-day-delta) ; t <= (start+day+delta) ; t += delta )
{
if( equivalent( t , bdt_in ) )

View File

@ -76,7 +76,7 @@ private:
static bool same( const BrokenDownTime & , const BrokenDownTime & ) ;
static std::tm * gmtime_r( const std::time_t * , std::tm * ) ;
static std::tm * localtime_r( const std::time_t * , std::tm * ) ;
DateTime() ;
DateTime() ; // not implemented
} ;
#endif

View File

@ -38,20 +38,27 @@
#include <config.h>
#if ! HAVE_GMTIME_R
#if HAVE_BUGGY_CTIME
#include <time.h>
#include <ctime>
inline struct tm * gmtime_r( const time_t * tp , struct tm * tm_p )
#endif
#if ! HAVE_GMTIME_R || ! HAVE_LOCALTIME_R
#include <ctime>
#endif
#if ! HAVE_GMTIME_R
inline std::tm * gmtime_r( const std::time_t * tp , std::tm * tm_p )
{
* tm_p = * gmtime( tp ) ;
* tm_p = * std::gmtime( tp ) ;
return tm_p ;
}
#endif
#if ! HAVE_LOCALTIME_R
#include <ctime>
inline struct tm * localtime_r( const time_t * tp , struct tm * tm_p )
inline std::tm * localtime_r( const std::time_t * tp , std::tm * tm_p )
{
* tm_p = * localtime( tp ) ;
* tm_p = * std::localtime( tp ) ;
return tm_p ;
}
#endif
@ -113,14 +120,13 @@
// pre-compilation)
//
#include <cstddef>
#include <iostream>
#include <exception>
#include <fstream>
#include <sstream>
#include <string>
//#include <xlocale>
#include <iostream>
#include <limits>
#include <memory>
#include <exception>
#include <sstream>
#include <string>
// Define fixed-size types
//
@ -142,19 +148,9 @@
typedef unsigned int pid_t ;
#endif
// STL portability macros (no longer necessary)
//
#if 1
#define GAllocator(T)
#define GLessAllocator(T1,T2)
#else
#define GAllocator(T) ,std::allocator<T>
#define GLessAllocator(T1,T2) ,std::allocator<T1>,std::less<T2>
#endif
// Modify compiler error handling
//
#ifdef G_COMPILER_IS_MICROSOFT
#if defined(G_COMPILER_IS_MICROSOFT)
#pragma warning( disable : 4100 ) // unused formal parameter
#pragma warning( disable : 4355 ) // 'this' in initialiser list
#pragma warning( disable : 4511 ) // cannot create default copy ctor
@ -163,5 +159,15 @@
#pragma warning( disable : 4275 ) // dll-interface stuff in <complex>
#endif
// A macro to explicitly ignore a function's return value.
// Some compilers complain when return values are ignored, and
// others complain when using a c-style cast...
//
#if 1
#define G_IGNORE
#else
#define G_IGNORE (void)
#endif
#endif

View File

@ -92,7 +92,7 @@ private:
// Class: G::DirectoryIterator
// Description: An iterator for Directory.
// The iteration model is
/// while(iter.more()) { (void)iter.file() ; }
/// while(iter.more()) { (void)iter.filePath() ; }
//
class G::DirectoryIterator
{

View File

@ -96,7 +96,6 @@ public:
private:
void operator=( const DirectoryIteratorImp & ) ;
DirectoryIteratorImp( const DirectoryIteratorImp & ) ;
static int onError( const char * path , int errno_ ) ;
} ;
// ===
@ -148,8 +147,7 @@ G::DirectoryIterator::~DirectoryIterator()
// ===
//static
int G::DirectoryIteratorImp::onError( const char * , int )
extern "C" int gdirectory_unix_on_error_( const char * , int )
{
const int abort = 1 ;
return abort ;
@ -171,7 +169,7 @@ G::DirectoryIteratorImp::DirectoryIteratorImp( const Directory &dir ,
G_DEBUG( "G::DirectoryIteratorImp::ctor: glob(\"" << wild_path << "\")" ) ;
int flags = 0 | GLOB_ERR ;
int error = ::glob( wild_path.pathCstr() , flags , onError , &m_glob ) ;
int error = ::glob( wild_path.pathCstr() , flags , gdirectory_unix_on_error_ , &m_glob ) ;
if( error || m_glob.gl_pathv == NULL )
{
G_DEBUG( "G::DirectoryIteratorImp::ctor: glob() error: " << error ) ;

View File

@ -39,7 +39,7 @@ bool G::Directory::valid( bool for_creation ) const
DWORD attributes = ::GetFileAttributes( m_path.pathCstr() ) ;
if( attributes == 0xFFFFFFFF )
{
(void)::GetLastError() ;
G_IGNORE ::GetLastError() ;
return false ;
}
return ( attributes & FILE_ATTRIBUTE_DIRECTORY ) != 0 ;

View File

@ -83,7 +83,6 @@ public:
} ;
#define G_EXCEPTION( class_name , description ) class class_name : public G::Exception { public: class_name() { m_what = description ; } public: explicit class_name ( std::ostream & stream ) { m_what = description ; append(stream) ; } public: explicit class_name( const char * more ) { m_what = description ; append(more) ; } public: explicit class_name( const std::string & more ) { m_what = description ; append(more) ; } }
#define G_EXCEPTION_ G_EXCEPTION
#endif

View File

@ -62,9 +62,10 @@ std::string G::File::sizeString( g_uint32_t hi , g_uint32_t lo )
std::string s ;
while( n != 0 )
{
size_t i = n % 10U ;
s.insert( 0U , 1U , '0' + i ) ;
n /= 10U ;
int i = static_cast<int>( n % 10 ) ;
char c = static_cast<char>( '0' + i ) ;
s.insert( 0U , 1U , c ) ;
n /= 10 ;
}
return s ;
}

View File

@ -44,7 +44,6 @@ namespace G
class G::GetOpt
{
public:
typedef std::vector<std::string GAllocator(std::string) > StringArray ;
struct Level // Used by G::GetOpt for extra type safety.
{ unsigned int level ; explicit Level(unsigned int l) : level(l) {} } ;
G_EXCEPTION( InvalidSpecification , "invalid options specification string" ) ;
@ -162,9 +161,9 @@ private:
valued(v_) , hidden(description_.empty()||level_==0U) ,
value_description(vd_) , level(level_) {}
} ;
typedef std::map<std::string,SwitchSpec GLessAllocator(char,SwitchSpec) > SwitchSpecMap ;
typedef std::map<std::string,SwitchSpec> SwitchSpecMap ;
typedef std::pair<bool,std::string> Value ;
typedef std::map<char,Value GLessAllocator(char,Value) > SwitchMap ;
typedef std::map<char,Value> SwitchMap ;
void operator=( const GetOpt & ) ;
GetOpt( const GetOpt & ) ;

View File

@ -31,7 +31,7 @@ namespace G
}
// Class: LogImp
// Description: An implementation class used by Log.
// Description: An implementation class used by G::Log.
//
class G::LogImp
{

View File

@ -61,7 +61,7 @@ public:
// Returns an End object which can be used to close off a quantum
// of logging. (The End::op<<() function calls G::Log::onEnd().)
static Stream &stream() ;
static Stream & stream() ;
// Returns a stream for streaming messages into.
static void onEnd( Severity s ) ;
@ -77,8 +77,7 @@ private:
namespace G
{
inline
std::ostream &operator<<( std::ostream &stream ,
const G::Log::Line & )
std::ostream & operator<<( std::ostream & stream , const G::Log::Line & )
{
return stream ;
}
@ -87,10 +86,9 @@ namespace G
namespace G
{
inline
std::ostream &operator<<( std::ostream &stream ,
const G::Log::End &end )
std::ostream & operator<<( std::ostream & stream , const G::Log::End & end )
{
G::Log::onEnd( end.m_s ) ;
G::Log::onEnd( end.m_s ) ;
return stream ;
}
}
@ -98,7 +96,7 @@ namespace G
namespace G
{
inline
G::Log::Line::Line( const char *file , int line )
G::Log::Line::Line( const char * file , int line )
{
G::Log::setFile( file ) ;
G::Log::setLine( line ) ;
@ -113,7 +111,12 @@ namespace G
// then warning/error messages should also get raised by some another
// independent means.
//
#define G_LOG_OUTPUT( expr , severity ) do { G::Log::stream() << G::Log::Line(__FILE__,__LINE__) << expr << G::Log::end(severity) ; } while(0)
// (The G_LOG_OUTPUT implementation uses separate statements because
// some compilers dont do Koenig lookup with nested classes. They
// look for ::operator<<() or G::X::operator<<() rather than
// G::operator<<().)
//
#define G_LOG_OUTPUT( expr , severity ) do { G::Log::Stream & s_ = G::Log::stream() ; G::operator<<( s_ , G::Log::Line(__FILE__,__LINE__) ) ; s_ << expr ; G::operator<<( s_ , G::Log::end(severity) ) ; } while(0)
#if defined(_DEBUG) && ! defined(G_NO_DEBUG)
#define G_DEBUG( expr ) G_LOG_OUTPUT( expr , G::Log::s_Debug )
#else

View File

@ -30,7 +30,8 @@
G::LogOutput * G::LogOutput::m_this = NULL ;
G::LogOutput::LogOutput( const std::string & prefix , bool enabled , bool summary_log ,
bool verbose_log , bool debug , bool level , bool timestamp , bool strip ) :
bool verbose_log , bool debug , bool level , bool timestamp , bool strip ,
bool use_syslog , SyslogFacility syslog_facility ) :
m_prefix(prefix) ,
m_enabled(enabled) ,
m_summary_log(summary_log) ,
@ -38,7 +39,8 @@ G::LogOutput::LogOutput( const std::string & prefix , bool enabled , bool summar
m_debug(debug) ,
m_level(level) ,
m_strip(strip) ,
m_syslog(false) ,
m_syslog(use_syslog) ,
m_facility(syslog_facility) ,
m_time(0) ,
m_timestamp(timestamp) ,
m_handle(0) ,
@ -57,6 +59,7 @@ G::LogOutput::LogOutput( bool enabled_and_summary , bool verbose_and_debug ) :
m_level(false) ,
m_strip(false) ,
m_syslog(false) ,
m_facility(User) ,
m_time(0) ,
m_timestamp(false) ,
m_handle(0) ,
@ -86,22 +89,6 @@ bool G::LogOutput::enable( bool enabled )
return was_enabled ;
}
void G::LogOutput::timestamp()
{
m_timestamp = true ;
}
void G::LogOutput::syslog()
{
syslog( User ) ;
}
void G::LogOutput::syslog( SyslogFacility facility )
{
m_syslog = true ;
m_facility = facility ;
}
//static
void G::LogOutput::output( Log::Severity severity , const char * file , unsigned int line , const char * text )
{

View File

@ -45,7 +45,8 @@ public:
LogOutput( const std::string & prefix , bool output , bool with_logging ,
bool with_verbose_logging , bool with_debug , bool with_level ,
bool with_timestamp , bool strip_context ) ;
bool with_timestamp , bool strip_context ,
bool use_syslog , SyslogFacility syslog_facility = User ) ;
// Constructor. If there is no LogOutput object,
// or if 'output' is false, then there is no
// output of any sort. Otherwise at least
@ -78,16 +79,6 @@ public:
// Enables or disables output.
// Returns the previous setting.
void syslog() ;
// Enables logging to the syslog system under Unix.
void timestamp() ;
// Enables timestamping.
void syslog( SyslogFacility facility ) ;
// Enables logging to the syslog system under Unix,
// using the specified facility.
static void output( G::Log::Severity s , const char *file , unsigned line , const char *text ) ;
// Generates output if there is an existing
// LogOutput object which is enabled. Uses rawOutput().

View File

@ -28,23 +28,26 @@
namespace
{
int decode( G::LogOutput::SyslogFacility facility )
{
if( facility == G::LogOutput::User ) return LOG_USER ;
if( facility == G::LogOutput::Daemon ) return LOG_DAEMON ;
if( facility == G::LogOutput::Mail ) return LOG_MAIL ;
if( facility == G::LogOutput::Cron ) return LOG_CRON ;
// etc...
return LOG_USER ;
}
int decode( G::Log::Severity severity )
{
if( severity == G::Log::s_Warning ) return LOG_WARNING ;
if( severity == G::Log::s_Error ) return LOG_ERR ;
if( severity == G::Log::s_LogSummary ) return LOG_INFO ;
if( severity == G::Log::s_LogVerbose ) return LOG_INFO ;
return LOG_CRIT ;
}
int mode( G::LogOutput::SyslogFacility facility , G::Log::Severity severity )
{
int m = 0 ;
if( facility == G::LogOutput::User ) m |= LOG_USER ;
else if( facility == G::LogOutput::Daemon ) m |= LOG_DAEMON ;
else if( facility == G::LogOutput::Mail ) m |= LOG_MAIL ;
else if( facility == G::LogOutput::Cron ) m |= LOG_CRON ;
// etc...
if( severity == G::Log::s_Warning ) m |= LOG_WARNING ;
else if( severity == G::Log::s_Error ) m |= LOG_ERR ;
else if( severity == G::Log::s_LogSummary ) m |= LOG_INFO ;
else if( severity == G::Log::s_LogVerbose ) m |= LOG_INFO ;
else m |= LOG_CRIT ;
return m ;
return decode(facility) | decode(severity) ;
}
}
@ -59,9 +62,13 @@ void G::LogOutput::rawOutput( G::Log::Severity severity , const char *message )
void G::LogOutput::init()
{
if( m_syslog )
::openlog( NULL , LOG_PID , decode(m_facility) ) ;
}
void G::LogOutput::cleanup()
{
if( m_syslog )
::closelog() ;
}

View File

@ -65,7 +65,7 @@ void G::LogOutput::rawOutput( G::Log::Severity severity , const char *message )
// (assume suitable string resources of 1001..1003)
DWORD id = 0x400003E9L ;
DWORD type = EVENTLOG_INFORMATION_TYPE ;
WORD type = EVENTLOG_INFORMATION_TYPE ;
if( severity == Log::s_Warning )
{
id = 0x800003EAL ;
@ -78,7 +78,7 @@ void G::LogOutput::rawOutput( G::Log::Severity severity , const char *message )
}
const char * p[] = { message , NULL } ;
(void) ::ReportEvent( m_handle, type, 0, id, NULL, 1, 0, p, NULL ) ;
G_IGNORE ::ReportEvent( m_handle, type, 0, id, NULL, 1, 0, p, NULL ) ;
}
}

192
src/glib/gmd5_aladdin.cpp Normal file
View File

@ -0,0 +1,192 @@
//
// Copyright (C) 2001-2003 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.
//
// ===
//
// gmd5_aladdin.cpp
//
#include "gdef.h"
#include "gmd5.h"
#include "gstr.h"
#include "gstrings.h"
#include "gassert.h"
#include "md5.h"
namespace
{
void init( md5_state_t & context )
{
::md5_init( &context ) ;
}
void update( md5_state_t & context , const std::string & input )
{
char * p = const_cast<char*>(input.c_str()) ;
int size = static_cast<int>( input.size() ) ;
::md5_append( &context , reinterpret_cast<unsigned char*>(p) , size ) ;
}
std::string final( md5_state_t & context )
{
const size_t L = 16U ; // output size
unsigned char buffer[L] ;
::md5_finish( &context , buffer ) ;
const char * buffer_p = reinterpret_cast<char *>(buffer) ;
return std::string( buffer_p , L ) ;
}
std::string writeOut( const md5_state_t & context )
{
G_ASSERT( sizeof context.abcd[0] <= sizeof(unsigned long) ) ;
return
G::Str::fromULong( context.abcd[0] ) + "." +
G::Str::fromULong( context.abcd[1] ) + "." +
G::Str::fromULong( context.abcd[2] ) + "." +
G::Str::fromULong( context.abcd[3] ) ;
}
void readIn( md5_state_t & context , G::Strings & s )
{
static md5_state_t zero_context ;
context = zero_context ;
context.count[0] = 0x200 ; // magic number -- see cyrus sasl lib/md5.c
G_ASSERT( context.count[1] == 0 ) ;
context.abcd[0] = G::Str::toULong(s.front()) ; s.pop_front() ;
context.abcd[1] = G::Str::toULong(s.front()) ; s.pop_front() ;
context.abcd[2] = G::Str::toULong(s.front()) ; s.pop_front() ;
context.abcd[3] = G::Str::toULong(s.front()) ; s.pop_front() ;
G_ASSERT( context.buf[0] == 0 ) ;
}
}
std::string G::Md5::xor_( const std::string & s1 , const std::string & s2 )
{
G_ASSERT( s1.length() == s2.length() ) ;
std::string::const_iterator p1 = s1.begin() ;
std::string::const_iterator p2 = s2.begin() ;
std::string result ;
for( ; p1 != s1.end() ; ++p1 , ++p2 )
{
unsigned char c1 = static_cast<unsigned char>(*p1) ;
unsigned char c2 = static_cast<unsigned char>(*p2) ;
unsigned char c = c1 ^ c2 ;
result.append( 1U , static_cast<char>(c) ) ;
}
return result ;
}
std::string G::Md5::key64( std::string k )
{
const size_t B = 64U ;
if( k.length() > B )
k = digest(k) ;
if( k.length() < B )
k.append( std::string(B-k.length(),'\0') ) ;
G_ASSERT( k.length() == B ) ;
return k ;
}
std::string G::Md5::ipad()
{
const size_t B = 64U ;
return std::string( B , '\066' ) ; // 00110110 = 00,110,110
}
std::string G::Md5::opad()
{
const size_t B = 64U ;
return std::string( B , '\134' ) ; // 01011100 = 01,011,100
}
std::string G::Md5::mask( const std::string & k )
{
std::string k64 = key64( k ) ;
return mask( k64 , ipad() ) + "." + mask( k64 , opad() ) ;
}
std::string G::Md5::mask( const std::string & k64 , const std::string & pad )
{
md5_state_t context ;
init( context ) ;
update( context , xor_(k64,pad) ) ;
return writeOut( context ) ;
}
std::string G::Md5::hmac( const std::string & masked_key , const std::string & input , Masked )
{
G::Strings part_list ;
G::Str::splitIntoTokens( masked_key , part_list , "." ) ;
if( part_list.size() != 8U )
throw InvalidMaskedKey( masked_key ) ;
md5_state_t inner_context ;
md5_state_t outer_context ;
readIn( inner_context , part_list ) ;
readIn( outer_context , part_list ) ;
update( inner_context , input ) ;
update( outer_context , final(inner_context) ) ;
return final( outer_context ) ;
}
std::string G::Md5::hmac( const std::string & k , const std::string & input )
{
std::string k64 = key64( k ) ;
return digest( xor_(k64,opad()) , digest(xor_(k64,ipad()),input) ) ;
}
std::string G::Md5::digest( const std::string & input )
{
return digest( input , NULL ) ;
}
std::string G::Md5::digest( const std::string & input_1 , const std::string & input_2 )
{
return digest( input_1 , &input_2 ) ;
}
std::string G::Md5::digest( const std::string & input_1 , const std::string * input_2 )
{
md5_state_t context ;
init( context ) ;
update( context , input_1 ) ;
if( input_2 != NULL )
update( context , *input_2 ) ;
return final( context ) ;
}
std::string G::Md5::printable( const std::string & input )
{
G_ASSERT( input.length() == 16U ) ;
std::string result ;
const char * hex = "0123456789abcdef" ;
const size_t n = input.length() ;
for( size_t i = 0U ; i < n ; i++ )
{
unsigned char c = static_cast<unsigned char>(input.at(i)) ;
result.append( 1U , hex[(c>>4U)&0x0F] ) ;
result.append( 1U , hex[(c>>0U)&0x0F] ) ;
}
return result ;
}
// Source-file inclusion is not nice, but it means that the "md5.c"
// file can be left in its pristine state but still benefit (?) from
// portability tweaks in "gdef.h" etc.
//
#include "md5.c"

View File

@ -18,7 +18,7 @@
//
// ===
//
// gmd5.cpp
// gmd5_rsa.cpp
//
#include "gdef.h"

View File

@ -52,7 +52,8 @@ void G::PidFile::create( const Path & pid_file )
G_DEBUG( "G::PidFile::create: \"" << pid_file << "\"" ) ;
Process::Umask readable(Process::Umask::Readable) ;
std::ofstream file( pid_file.str().c_str() ) ;
file << Process::Id() << std::endl ;
Process::Id pid ;
file << pid.str() << std::endl ;
if( !file.good() )
throw Error(std::string("cannot create file: ")+pid_file.str()) ;
Cleanup::add( cleanup , strdup_(pid_file.str().c_str()) ) ; // (leaks)

View File

@ -282,8 +282,8 @@ void G::Process::beSpecial( Identity identity , bool change_group )
// gcc requires -D_BSD_SOURCE for seteuid()
//
Identity old_identity ;
(void) ::seteuid( identity.uid ) ;
if( change_group) (void) ::setegid( identity.gid ) ;
G_IGNORE ::seteuid( identity.uid ) ;
if( change_group) G_IGNORE ::setegid( identity.gid ) ;
//G_DEBUG( "G::Process::beSpecial: " << old_identity << " -> " << Identity() ) ;
old_identity.uid = 0 ; // pacify the compiler
}
@ -391,7 +391,7 @@ std::string G::Process::Identity::str() const
// ===
class G::Process::Umask::UmaskImp
class G::Process::Umask::UmaskImp // A private implementation class used by G::Process::Umask.
{
public:
mode_t m_old_mode ;
@ -406,7 +406,7 @@ G::Process::Umask::Umask( Mode mode ) :
G::Process::Umask::~Umask()
{
(void) ::umask( m_imp->m_old_mode ) ;
G_IGNORE ::umask( m_imp->m_old_mode ) ;
delete m_imp ;
}

View File

@ -169,6 +169,11 @@ bool G::Process::cd( const Path & dir , NoThrow )
return 0 == ::_chdir( dir.str().c_str() ) ;
}
int G::Process::errno_()
{
return errno ;
}
int G::Process::spawn( Identity , const Path & exe , const Strings & args_ ,
std::string * pipe_result_p , int error_return )
{
@ -179,7 +184,9 @@ int G::Process::spawn( Identity , const Path & exe , const Strings & args_ ,
Strings args( args_ ) ; // non-const copy
Pipe pipe( pipe_result_p != NULL ) ;
if( pipe_result_p != NULL )
args.push_front( Str::fromInt(pipe.fd()) ) ; // kludge -- child must write on specific fd passed as argv[1]
args.push_front( Str::fromInt(pipe.fd()) ) ; // kludge -- child must write on fd passed as argv[1]
G_DEBUG( "G::Process::spawn: \"" << exe << "\": \"" << Str::join(args,"\",\"") << "\"" ) ;
char ** argv = new char* [ args.size() + 2U ] ;
argv[0U] = const_cast<char*>( exe.pathCstr() ) ;
@ -191,7 +198,9 @@ int G::Process::spawn( Identity , const Path & exe , const Strings & args_ ,
const int mode = _P_WAIT ;
::_flushall() ;
int rc = ::_spawnv( mode , exe.str().c_str() , argv ) ;
int error = errno_() ;
delete [] argv ;
G_DEBUG( "G::Process::spawn: _spawnv(): rc=" << rc << ": errno=" << error ) ;
if( pipe_result_p != NULL )
*pipe_result_p = pipe.read() ;
@ -211,7 +220,6 @@ void G::Process::beSpecial( Identity , bool )
}
// not implemented...
// int G::Process::errno_()
// Who G::Process::fork() {}
// Who G::Process::fork( Id & child ) {}
// void G::Process::exec( const Path & exe , const std::string & arg ) {}

View File

@ -159,6 +159,7 @@ private:
std::pair<g_uint32_t,size_t> getInfo() const ;
std::string getData( g_uint32_t & type , bool & ) const ;
size_t get( char * , size_t ) const ;
void set( g_uint32_t type , const void * p , size_t n ) ;
private:
const RegistryKey & m_hkey ;

View File

@ -259,6 +259,30 @@ std::string G::RegistryValue::getString( const std::string & defolt ,
}
}
g_uint32_t G::RegistryValue::getDword() const
{
DWORD type = 0 ;
bool exists = true ;
std::string data = getData( type , exists ) ;
if( !exists ) throw MissingValue( m_key_name ) ;
if( type != REG_DWORD ) throw InvalidType( m_key_name ) ;
if( data.length() != 4U ) throw ValueError( m_key_name ) ;
g_uint32_t result = 0UL ;
for( int i = 3 ; i >= 0 ; i-- )
{
result *= 256UL ;
result += static_cast<unsigned char>(data[i]) ;
}
return result ;
}
bool G::RegistryValue::getBool() const
{
g_uint32_t n = getDword() ;
if( n != 0UL && n != 1UL ) throw ValueError( m_key_name ) ;
return !!n ;
}
std::string G::RegistryValue::getData( g_uint32_t & type , bool & exists ) const
{
exists = true ;
@ -334,14 +358,25 @@ void G::RegistryValue::set( const char * p )
void G::RegistryValue::set( const std::string & s )
{
DWORD type = REG_SZ ;
set( REG_SZ , reinterpret_cast<const void*>(s.c_str()) , s.length()+1U ) ;
}
LONG rc = ::RegSetValueEx( m_hkey.imp().m_key , m_key_name.c_str() , 0 ,
type , reinterpret_cast<const BYTE*>(s.c_str()) ,
s.length() + 1U ) ;
void G::RegistryValue::set( bool b )
{
g_uint32_t n = b ? 1UL : 0UL ;
set( n ) ;
}
void G::RegistryValue::set( g_uint32_t n )
{
set( REG_DWORD , reinterpret_cast<const void*>(&n) , 4UL ) ;
}
void G::RegistryValue::set( g_uint32_t type , const void * vp , size_t n )
{
const BYTE * p = reinterpret_cast<const BYTE*>(vp) ;
LONG rc = ::RegSetValueEx( m_hkey.imp().m_key , m_key_name.c_str() , 0 , type , p , n ) ;
if( rc != ERROR_SUCCESS )
throw ValueError( "RegSetValueEx" ) ;
}

View File

@ -37,7 +37,7 @@ namespace G
// Description: A class which aquires special privileges.
// The implementation uses G::Process.
//
class G::Root : private noncopyable
class G::Root : private G::noncopyable
{
public:
explicit Root( bool change_group = true ) ;

View File

@ -33,10 +33,10 @@ namespace G
}
// Class: G::Setter
// Description: A class to Manage a boolean flag
// Description: A class to manage a boolean flag
// while in scope.
//
class G::Setter : public G:: noncopyable
class G::Setter : public G::noncopyable
{
public:
explicit Setter( bool & b ) ;

54
src/glib/gslot.cpp Normal file
View File

@ -0,0 +1,54 @@
//
// Copyright (C) 2001-2003 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.
//
// ===
//
// gslot.cpp
//
#include "gdef.h"
#include "gslot.h"
G::SlotBase::~SlotBase()
{
}
G::SlotBase::SlotBase() : m_ref_count(1UL)
{
}
void G::SlotBase::up()
{
m_ref_count++ ;
}
void G::SlotBase::down()
{
m_ref_count-- ;
if( m_ref_count == 0UL )
delete this ;
}
// ===
void G::SignalImp::check( const SlotBase * p )
{
if( p != NULL )
throw AlreadyConnected() ;
}

415
src/glib/gslot.h Normal file
View File

@ -0,0 +1,415 @@
//
// Copyright (C) 2001-2003 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.
//
// ===
//
// gslot.h
//
// Inspired by libsigc++, but simplified by:
// * not doing multicast
// * not detecting dangling references
// * not supporting global function callbacks
// * using only void returns
//
// The key to the implementation is that SlotImp<> is
// templated on the callback parameter P and the callback
// sink class T, but Slot<> is templated only on P, so
// the event-source class does not need to know the type
// of the event-sink. The SlotOp<> classes are used to
// resolve this mismatch, by downcasting to the T-specific
// SlotImp<> class. The Slot<> classes are reference-counting
// handles to SlotImp<> (via SlotBase), with an additional
// function pointer for the relevant SlotOp<> downcasting
// method.
//
// The overloaded template function slot<>() creates
// a Slot<> handle, passing it a suitable SlotBase body
// and casting function. The dynamic type of the SlotBase
// reference is a SlotImp<> class which knows about the
// specific sink class T, and the casting function knows
// how to access the derived class. The combination of
// SlotBase polymorphism and casting function isolates the
// slot class from the sink class.
//
// Usage:
/// class Source
/// {
/// public:
/// Signal1<int> m_signal ;
/// private:
/// void Source::raiseEvent()
/// {
/// int n = 123 ;
/// m_signal.emit( n ) ;
/// }
/// } ;
///
/// class Sink
/// {
/// public:
/// void onEvent( int n ) ;
/// Sink( Source & source )
/// {
/// source.m_signal.connect( slot(*this,&Sink::onEvent) ) ;
/// }
/// } ;
//
#ifndef G_SLOT_H
#define G_SLOT_H
#include "gdef.h"
#include "gexception.h"
#include "gnoncopyable.h"
namespace G
{
// Class: SlotBase
// Description: Part of the slot/signal system.
// Used as a base class to all SlotImp<> classes
// allowing them to be used as bodies to the
// Slot<> reference-counting handle.
//
class SlotBase
{
public:
virtual ~SlotBase() ;
// Destructor.
SlotBase() ;
// Default constuctor.
void up() ;
// Increments the reference count.
void down() ;
// Decrements the reference count
// and does "delete this" on zero.
private:
SlotBase( const SlotBase & ) ; // not implemented
void operator=( const SlotBase & ) ; // not implemented
private:
unsigned long m_ref_count ;
} ;
// Class: SignalImp
// Description: Part of the slot/signal system.
// A static helper class used by Signal<> classes.
//
class SignalImp
{
public:
G_EXCEPTION( AlreadyConnected , "signal already connected to a slot" ) ;
static void check( const SlotBase * p ) ;
private:
SignalImp() ; // not implemented
} ;
template <class T>
inline
void swap_( T & t1 , T & t2 ) // no std::swap in gcc2.95
{
T temp( t1 ) ;
t1 = t2 ;
t2 = temp ;
}
// ===
// Class: SlotImp0
// Description: Part of the slot/signal system.
// An implementation class for Slot0<>. An instance
// is created by the slot<>()
//
template <class T>
class SlotImp0 : public SlotBase
{
T & m_object ;
void (T::*m_fn)() ;
public:
SlotImp0( T & object , void (T::*fn)() ) : m_object(object) , m_fn(fn) {}
void callback() { (m_object.*m_fn)() ; }
} ;
// Class: SlotOp0
// Description: Part of the slot/signal system.
//
template <class T>
class SlotOp0
{
public:
static void callback( SlotBase * imp )
{ static_cast<SlotImp0<T>*>(imp)->callback() ; }
} ;
// Class: Slot0
// Description: Part of the slot/signal system.
//
class Slot0
{
SlotBase * m_imp ;
void (*m_op)( SlotBase * ) ;
public:
Slot0() : m_imp(0) , m_op(0) {}
Slot0( SlotBase * imp , void (*op)(SlotBase*) ) : m_imp(imp) , m_op(op) {}
~Slot0() { if( m_imp ) m_imp->down() ; }
void callback() { if( m_imp ) (*m_op)( m_imp ) ; }
Slot0( const Slot0 & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
void swap( Slot0 & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
void operator=( const Slot0 & rhs ) { Slot0 tmp(rhs) ; swap(tmp) ; }
const SlotBase * base() const { return m_imp ; }
} ;
// Class: Signal0
// Description: Part of the slot/signal system.
//
class Signal0 : public noncopyable
{
Slot0 m_slot ;
public:
Signal0() {}
void emit() { m_slot.callback() ; }
void connect( Slot0 slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
void disconnect() { m_slot = Slot0() ; }
} ;
// Function: slot
// Description: Part of the slot/signal system.
//
template <class T>
inline
Slot0 slot( T & object , void (T::*fn)() )
{
return Slot0( new SlotImp0<T>(object,fn) , SlotOp0<T>::callback ) ;
}
// ===
// Class: SlotImp1
// Description: Part of the slot/signal system.
//
template <class T, class P>
class SlotImp1 : public SlotBase
{
T & m_object ;
void (T::*m_fn)( P ) ;
public:
SlotImp1( T & object , void (T::*fn)(P) ) : m_object(object) , m_fn(fn) {}
void callback( P p ) { (m_object.*m_fn)(p) ; }
} ;
// Class: SlotOp1
// Description: Part of the slot/signal system.
//
template <class T, class P>
class SlotOp1
{
public:
static void callback( SlotBase * imp , P p )
{ static_cast<SlotImp1<T,P>*>(imp)->callback( p ) ; }
} ;
// Class: Slot1
// Description: Part of the slot/signal system.
//
template <class P>
class Slot1
{
SlotBase * m_imp ;
void (*m_op)( SlotBase * , P ) ;
public:
Slot1() : m_imp(0) , m_op(0) {}
Slot1( SlotBase * imp , void (*op)(SlotBase*,P) ) : m_imp(imp) , m_op(op) {}
~Slot1() { if( m_imp ) m_imp->down() ; }
void callback( P p ) { if( m_imp ) (*m_op)( m_imp , p ) ; }
Slot1( const Slot1<P> & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
void swap( Slot1<P> & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
void operator=( const Slot1<P> & rhs ) { Slot1 tmp(rhs) ; swap(tmp) ; }
const SlotBase * base() const { return m_imp ; }
} ;
// Class: Signal1
// Description: Part of the slot/signal system.
//
template <class P>
class Signal1 : public noncopyable
{
Slot1<P> m_slot ;
public:
Signal1() {}
void emit( P p ) { m_slot.callback( p ) ; }
void connect( Slot1<P> slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
void disconnect() { m_slot = Slot1<P>() ; }
} ;
// Function: slot
// Description: Part of the slot/signal system.
//
template <class T,class P>
inline
Slot1<P> slot( T & object , void (T::*fn)(P) )
{
return Slot1<P>( new SlotImp1<T,P>(object,fn) , SlotOp1<T,P>::callback ) ;
}
// ===
// Class: SlotImp2
// Description: Part of the slot/signal system.
//
template <class T, class P1, class P2>
class SlotImp2 : public SlotBase
{
T & m_object ;
void (T::*m_fn)( P1 , P2 ) ;
public:
SlotImp2( T & object , void (T::*fn)(P1,P2) ) : m_object(object) , m_fn(fn) {}
void callback( P1 p1 , P2 p2 ) { (m_object.*m_fn)(p1,p2) ; }
} ;
// Class: SlotOp2
// Description: Part of the slot/signal system.
//
template <class T, class P1 , class P2>
class SlotOp2
{
public:
static void callback( SlotBase * imp , P1 p1 , P2 p2 )
{ static_cast<SlotImp2<T,P1,P2>*>(imp)->callback( p1 , p2 ) ; }
} ;
// Class: Slot2
// Description: Part of the slot/signal system.
//
template <class P1, class P2>
class Slot2
{
SlotBase * m_imp ;
void (*m_op)( SlotBase * , P1 , P2 ) ;
public:
Slot2() : m_imp(0) , m_op(0) {}
Slot2( SlotBase * imp , void (*op)(SlotBase*,P1,P2) ) : m_imp(imp) , m_op(op) {}
~Slot2() { if( m_imp ) m_imp->down() ; }
void callback( P1 p1 , P2 p2 ) { if( m_imp ) (*m_op)( m_imp , p1 , p2 ) ; }
Slot2( const Slot2<P1,P2> & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
void swap( Slot2<P1,P2> & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
void operator=( const Slot2<P1,P2> & rhs ) { Slot2 tmp(rhs) ; swap(tmp) ; }
const SlotBase * base() const { return m_imp ; }
} ;
// Class: Signal2
// Description: Part of the slot/signal system.
//
template <class P1, class P2>
class Signal2 : public noncopyable
{
Slot2<P1,P2> m_slot ;
public:
Signal2() {}
void emit( P1 p1 , P2 p2 ) { m_slot.callback( p1 , p2 ) ; }
void connect( Slot2<P1,P2> slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
void disconnect() { m_slot = Slot2<P1,P2>() ; }
} ;
// Function: slot
// Description: Part of the slot/signal system.
//
template <class T, class P1, class P2>
inline
Slot2<P1,P2> slot( T & object , void (T::*fn)(P1,P2) )
{
return Slot2<P1,P2>( new SlotImp2<T,P1,P2>(object,fn) , SlotOp2<T,P1,P2>::callback ) ;
}
// ===
// Class: SlotImp3
// Description: Part of the slot/signal system.
//
template <class T, class P1, class P2, class P3>
class SlotImp3 : public SlotBase
{
T & m_object ;
void (T::*m_fn)( P1 , P2 , P3 ) ;
public:
SlotImp3( T & object , void (T::*fn)(P1,P2,P3) ) : m_object(object) , m_fn(fn) {}
void callback( P1 p1 , P2 p2 , P3 p3 ) { (m_object.*m_fn)(p1,p2,p3) ; }
} ;
// Class: SlotOp3
// Description: Part of the slot/signal system.
//
template <class T, class P1 , class P2, class P3>
class SlotOp3
{
public:
static void callback( SlotBase * imp , P1 p1 , P2 p2 , P3 p3 )
{ static_cast<SlotImp3<T,P1,P2,P3>*>(imp)->callback( p1 , p2 , p3 ) ; }
} ;
// Class: Slot3
// Description: Part of the slot/signal system.
//
template <class P1, class P2, class P3>
class Slot3
{
SlotBase * m_imp ;
void (*m_op)( SlotBase * , P1 , P2 , P3 ) ;
public:
Slot3() : m_imp(0) , m_op(0) {}
Slot3( SlotBase * imp , void (*op)(SlotBase*,P1,P2,P3) ) : m_imp(imp) , m_op(op) {}
~Slot3() { if( m_imp ) m_imp->down() ; }
void callback( P1 p1 , P2 p2 , P3 p3 ) { if( m_imp ) (*m_op)( m_imp , p1 , p2 , p3 ) ; }
Slot3( const Slot3<P1,P2,P3> & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
void swap( Slot3<P1,P2,P3> & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
void operator=( const Slot3<P1,P2,P3> & rhs ) { Slot3 tmp(rhs) ; swap(tmp) ; }
const SlotBase * base() const { return m_imp ; }
} ;
// Class: Signal3
// Description: Part of the slot/signal system.
//
template <class P1, class P2, class P3>
class Signal3 : public noncopyable
{
Slot3<P1,P2,P3> m_slot ;
public:
Signal3() {}
void emit( P1 p1 , P2 p2 , P3 p3 ) { m_slot.callback( p1 , p2 , p3 ) ; }
void connect( Slot3<P1,P2,P3> slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
void disconnect() { m_slot = Slot3<P1,P2,P3>() ; }
} ;
// Function: slot
// Description: Part of the slot/signal system.
//
template <class T, class P1, class P2, class P3>
inline
Slot3<P1,P2,P3> slot( T & object , void (T::*fn)(P1,P2,P3) )
{
return Slot3<P1,P2,P3>( new SlotImp3<T,P1,P2,P3>(object,fn) , SlotOp3<T,P1,P2,P3>::callback ) ;
}
} // namespace
#endif

View File

@ -152,7 +152,7 @@ private:
Transition(State s1,State s2,Action a,State s3) :
from(s1) , to(s2) , alt(s3) , action(a) {}
} ;
typedef std::multimap<Event,Transition GLessAllocator(Event,Transition) > Map ;
typedef std::multimap<Event,Transition> Map ;
Map m_map ;
State m_state ;
State m_end ;

View File

@ -115,7 +115,7 @@ bool G::Str::isUShort( const std::string & s )
{
try
{
(void) toUShort(s) ;
G_IGNORE toUShort(s) ;
}
catch( Overflow & )
{
@ -132,7 +132,7 @@ bool G::Str::isUInt( const std::string & s )
{
try
{
(void) toUInt(s) ;
G_IGNORE toUInt(s) ;
}
catch( Overflow & )
{
@ -149,7 +149,7 @@ bool G::Str::isULong( const std::string & s )
{
try
{
(void) toULong(s) ;
G_IGNORE toULong(s) ;
}
catch( Overflow & )
{
@ -238,7 +238,7 @@ void G::Str::toLower( std::string &s )
{
for( std::string::iterator p = s.begin() ; p != s.end() ; ++p )
{
*p = ::tolower( *p ) ;
*p = static_cast<char>( ::tolower(*p) ) ;
}
}
@ -253,7 +253,7 @@ void G::Str::toUpper( std::string &s )
{
for( std::string::iterator p = s.begin() ; p != s.end() ; ++p )
{
*p = ::toupper( *p ) ;
*p = static_cast<char>( ::toupper(*p) ) ;
}
}

View File

@ -45,7 +45,6 @@ class G::Str
public:
G_EXCEPTION( Overflow , "conversion error: over/underflow" ) ;
G_EXCEPTION( InvalidFormat, "conversion error: invalid format" ) ;
typedef std::vector<std::string GAllocator(std::string) > StringArray ;
static bool replace( std::string &s ,
const std::string &from , const std::string &to ,
@ -207,7 +206,7 @@ public:
bool discard_bogus_escapes = true ) ;
// Overload for vector<string>.
static std::string join( const G::Strings & strings , const std::string & sep ) ;
static std::string join( const Strings & strings , const std::string & sep ) ;
// Concatenates a set of strings.
static std::string join( const StringArray & strings , const std::string & sep ) ;

View File

@ -24,8 +24,10 @@
#ifndef G_STRINGS_H
#define G_STRINGS_H
#include "gdef.h"
#include <string>
#include <list>
#include <vector>
namespace G
{
@ -34,7 +36,12 @@ namespace G
// Description: A std::list of std::strings.
// See also: Str
//
typedef std::list<std::string GAllocator(std::string) > Strings ;
typedef std::list<std::string> Strings ;
// Typedef: StringArray
// Description: A std::vector of std::strings.
//
typedef std::vector<std::string> StringArray ;
}

View File

@ -80,7 +80,7 @@ unsigned int G::Time::seconds() const
return m_ss ;
}
std::string G::Time::hhmmss( const char * sep )
std::string G::Time::hhmmss( const char * sep ) const
{
if( sep == NULL ) sep = "" ;
std::ostringstream ss ;
@ -88,7 +88,7 @@ std::string G::Time::hhmmss( const char * sep )
return ss.str() ;
}
std::string G::Time::hhmm( const char * sep )
std::string G::Time::hhmm( const char * sep ) const
{
if( sep == NULL ) sep = "" ;
std::ostringstream ss ;
@ -96,3 +96,11 @@ std::string G::Time::hhmm( const char * sep )
return ss.str() ;
}
std::string G::Time::ss() const
{
std::ostringstream ss ;
ss << (m_ss/10U) << (m_ss%10U) ;
return ss.str() ;
}

View File

@ -44,17 +44,17 @@ public:
class LocalTime // An overload discriminator class for Time constructors.
{} ;
Time() ;
// Constructor, using UTC, for now.
explicit Time( const G::DateTime::BrokenDownTime & tm ) ;
// Constructor for the given broken-down time.
explicit Time( G::DateTime::EpochTime t ) ;
// Constructor for the given epoch time.
Time() ;
// Constructor for now.
// Constructor, using UTC, for the given epoch time.
Time( G::DateTime::EpochTime t , const LocalTime & ) ;
// Localtime constructor for the given epoch time.
// Constructor, using the local timezone, for the given epoch time.
explicit Time( const LocalTime & ) ;
// Localtime constructor for now.
@ -68,12 +68,15 @@ public:
unsigned int seconds() const ;
// Returns the seconds (0 <= s <= 61 [sic]).
std::string hhmmss( const char * sep = NULL ) ;
std::string hhmmss( const char * sep = NULL ) const ;
// Returns a hhmmss string.
std::string hhmm( const char * sep = NULL ) ;
std::string hhmm( const char * sep = NULL ) const ;
// Returns a hhmm string.
std::string ss() const ;
// Returns the seconds as a two-digit decimal seconds.
private:
unsigned int m_hh ;
unsigned int m_mm ;

View File

@ -1,22 +1,23 @@
//
// Copyright (C) 2001-2003 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.
//
// ===
/*
Copyright (C) 2001-2003 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.
*/
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/

View File

@ -1,21 +1,22 @@
#
# Copyright (C) 2001-2003 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.
#
#
## Copyright (C) 2001-2003 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.
##
#
EXTRA_DIST=\
gclient_win32.cpp \
@ -24,7 +25,9 @@ EXTRA_DIST=\
glocal_win32.cpp \
grequest.cpp \
gresolve_win32.cpp \
gsocket_win32.cpp
gsocket_win32.cpp \
gaddress_ipv6.cpp \
gresolve_ipv6.cpp
INCLUDES = -I$(top_srcdir)/lib/$(COMPILER_VERSION) -I$(top_srcdir)/src/glib
noinst_LIBRARIES = libgnet.a
libgnet_a_SOURCES = gaddress_ipv4.cpp \

Some files were not shown because too many files have changed in this diff Show More