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) {

Reply via email to