Hi,
attached are 2 patches. The first one (qp.pm.diff) adds to Qpsmtpd.pm
a) a check for $ENV{QPSMTP_CONFIG} in config_dir() and the use of that
directory if the wanted config file is in there. All qpsmtpds should
be able to use this.
b) if load_plugins() gets an argument and it's a directory, the plugins
are loaded from this directory The second diff adds --config-dir,
--plugin-dir and --pid-file as command line options to
qpsmtpd-forkserver. Except for pid-file they have no defaults
(pid-file: /var/run/qpsmtpd.pid).
(I hope this helps the DD who filed an ITP for qpsmtpd to release the
debian package [earlier] .))
Hanno
--- Qpsmtpd.pm.orig Sat Nov 27 07:46:21 2004
+++ Qpsmtpd.pm Tue Dec 14 10:18:48 2004
@@ -65,13 +65,16 @@
sub config_dir {
my ($self, $config) = @_;
my $configdir = ($ENV{QMAIL} || '/var/qmail') . '/control';
- my ($name) = ($0 =~ m!(.*?)/([^/]+)$!);
+ my ($name) = ($0 =~ m#(.*?)/([^/]+)$#);
$configdir = "$name/config" if (-e "$name/config/$config");
+ if (exists $ENV{QPSMTP_CONFIG}) {
+ $configdir = $ENV{QPSMTP_CONFIG} if (-e "$ENV{QPSMTP_CONFIG}/$config");
+ }
return $configdir;
}
sub plugin_dir {
- my ($name) = ($0 =~ m!(.*?)/([^/]+)$!);
+ my ($name) = ($0 =~ m#(.*?)/([^/]+)$#);
my $dir = "$name/plugins";
}
@@ -122,6 +125,7 @@
sub load_plugins {
my $self = shift;
+ my $plugin_dir = shift;
$self->log(LOGERROR, "Plugins already loaded") if $self->{hooks};
$self->{hooks} = {};
@@ -129,6 +133,9 @@
my @plugins = $self->config('plugins');
my $dir = $self->plugin_dir;
+ if (defined $plugin_dir && -d $plugin_dir) {
+ $dir = $plugin_dir;
+ }
$self->log(LOGNOTICE, "loading plugins from $dir");
@plugins = $self->_load_plugins($dir, @plugins);
--- qpsmtpd-forkserver.orig Mon Dec 13 18:10:26 2004
+++ qpsmtpd-forkserver Wed Dec 15 18:52:23 2004
@@ -25,6 +22,9 @@
my $LOCALADDR = '0.0.0.0'; # ip address to bind to
my $USER = 'smtpd'; # user to suid to
my $MAXCONNIP = 5; # max simultaneous connections from one IP
+my $PLUGIN_DIR = undef; # load plugins from this dir
+my $CONFIG_DIR = undef; # load config (also) from this dir
+my $PID_FILE = '/var/run/qpsmtpd.pid';
sub usage {
print <<"EOT";
@@ -34,6 +34,9 @@
-c, --limit-connections N : limit concurrent connections to N; default 15
-u, --user U : run as a particular user (defualt 'smtpd')
-m, --max-from-ip M : limit connections from a single IP; default 5
+ -P, --plugin-dir D : load plugins from directory D
+ -C, --config-dir C : load plugins from directory C
+ --pid-file P : print main servers PID to file P
EOT
exit 0;
}
@@ -43,13 +46,33 @@
'c|limit-connections=i' => \$MAXCONN,
'm|max-from-ip=i' => \$MAXCONNIP,
'p|port=i' => \$PORT,
- 'u|user=s' => \$USER) || &usage;
+ 'u|user=s' => \$USER,
+ 'P|plugin-dir=s' => \$PLUGIN_DIR,
+ 'C|config-dir=s' => \$CONFIG_DIR,
+ 'pid-file=s',) || &usage;
# detaint the commandline
if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { &usage }
if ($LOCALADDR =~ /^([\d\w\-.]+)$/) { $LOCALADDR = $1 } else { &usage }
if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { &usage }
if ($MAXCONN =~ /^(\d+)$/) { $MAXCONN = $1 } else { &usage }
+if (defined $PLUGIN_DIR) {
+ if ($PLUGIN_DIR =~ m#^(/[\w\-/.]+)$#) { $PLUGIN_DIR = $1 } else { &usage }
+}
+if (exists $ENV{QPSMTP_CONFIG}) {
+ if ($ENV{QPSMTP_CONFIG} =~ m#^(/[\w\-/.]+)$#) {
+ $ENV{QPSMTP_CONFIG} = $1;
+ } else {
+ ::log(LOGWARN,"unclean ENV QPSMTP_CONFIG, ignoring...");
+ delete $ENV{QPSMTP_CONFIG};
+ }
+}
+if (defined $CONFIG_DIR) {
+ if ($CONFIG_DIR =~ m#^(/[\w\-/.]+)$#) {
+ $ENV{QPSMTP_CONFIG} = $1;
+ } else { &usage }
+}
+if ($PID_FILE =~ m#^(/[\w\d/\-]+)$#) { $PID_FILE = $1 } else { &usage }
delete $ENV{ENV};
$ENV{PATH} = '/bin:/usr/bin:/var/qmail/bin';
@@ -84,10 +107,26 @@
or die "Creating TCP socket $LOCALADDR:$PORT: $!\n";
::log(LOGINFO,"Listening on port $PORT");
+if (-e $PID_FILE) {
+ open PID, "+<$PID_FILE"
+ or die "open pid_file: $!\n";
+ my $running_pid = <PID>; chomp $running_pid;
+ if (kill 0, $running_pid) {
+ die "Found an already running qpsmtpd with pid $running_pid.\n";
+ }
+ seek PID, 0, 0
+ or die "Could not seek back to beginning of $PID_FILE: $!\n";
+} else {
+ open PID, ">$PID_FILE"
+ or die "open pid_file: $!\n";
+}
+print PID $$,"\n";
+close PID;
+
# Drop priviledges
my (undef, undef, $quid, $qgid) = getpwnam $USER or
die "unable to determine uid/gid for $USER\n";
-$) = "";
+$) = "$qgid $qgid";
POSIX::setgid($qgid) or
die "unable to change gid: $!\n";
POSIX::setuid($quid) or
@@ -101,7 +140,7 @@
# Load plugins here
my $plugin_loader = Qpsmtpd::TcpServer->new();
-$plugin_loader->load_plugins;
+$plugin_loader->load_plugins($PLUGIN_DIR);
while (1) {