Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 709 lines (606 sloc) 21.457 kB
3837fab Ask and ye shall receive
John Peacock authored
1 #!/usr/bin/perl -Tw
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
2 # High performance pre-forking qpsmtpd daemon, Copyright (C) 2006 SoftScan
3 # http://www.softscan.co.uk
4 #
5 # Based on qpsmtpd-forkserver Copyright (C) 2001 Ask Bjoern Hansen
6 # See the LICENSE file for details.
7 #
8 # For more information see http://develooper.com/code/qpsmtpd/
9
10 # safety guards
11 use strict;
12
13 # includes
14 use IO::Socket;
15 use POSIX;
16 use IPC::Shareable(':all');
17 use lib 'lib';
18 use Qpsmtpd::TcpServer::Prefork;
19 use Qpsmtpd::Constants;
20 use Getopt::Long;
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
21
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
22 my $has_ipv6 = Qpsmtpd::TcpServer::has_ipv6;
23
24 if ($has_ipv6) {
25 use Socket6;
26 }
27
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
28 #use Time::HiRes qw(gettimeofday tv_interval);
29
30 # secure shell
31 $ENV{'PATH'} = '/bin:/usr/bin';
32 delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
33
34 # version
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
35 my $VERSION = "1.0";
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
36
85cd1aa @vetinari prefork: clear a previously running instance by cloning the base inst…
vetinari authored
37 # qpsmtpd instances
38 my ($qpsmtpd, $qpsmtpd_base);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
39
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
40 # cmd's needed by IPC
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
41 my $ipcrm = '/usr/bin/ipcrm';
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
42 my $ipcs = '/usr/bin/ipcs';
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
43 my $xargs = '/usr/bin/xargs';
44
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
45 # vars we need
46 my $chld_shmem; # shared mem to keep track of children (and their connections)
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
47 my %children;
48 my $chld_pool;
49 my $chld_busy;
e4f0cb0 Inside the main loop skip the sleep when children have exited. Instea…
Radu Greab authored
50 my @children_term; # terminated children, their death pending processing
51 # by the main loop
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
52 my $d; # socket
53
54 # default settings
f0a27f8 @vetinari prefork: --pid-file option now works
vetinari authored
55 my $pid_file;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
56 my $d_port = 25;
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
57 my $d_addr;
58 if ($has_ipv6) {
59 $d_addr = "[::]";
60 }
61 else {
62 $d_addr = "0.0.0.0";
63 }
64
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
65 my $debug = 0;
66 my $max_children = 15; # max number of child processes to spawn
67 my $idle_children = 5; # number of idle child processes to spawn
68 my $maxconnip = 10;
69 my $child_lifetime = 100; # number of times a child may be reused
70 my $loop_sleep = 30; # seconds main_loop sleeps before checking children
71 my $re_nice = 5; # substracted from parents current nice level
72 my $d_start = 0;
73 my $quiet = 0;
74 my $status = 0;
75 my $signal = '';
b7f4684 Fixup qpsmtpd-prefork, et al, to correctly load Constants.
John Peacock authored
76 my $pretty = 0;
502e1d2 @vetinari prefork: - add --detach option to daemonize like forkserver
vetinari authored
77 my $detach = 0;
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
78 my $user;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
79
80 # help text
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
81 sub usage {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
82 print <<"EOT";
83 Usage: qpsmtpd-prefork [ options ]
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
84 --quiet : Be quiet (even errors are suppressed)
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
85 --version : Show version information
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
86 --debug : Enable debug output
87 --interface addr : Interface daemon should listen on (default: $d_addr)
88 --port int : TCP port daemon should listen on (default: $d_port)
89 --max-from-ip int : Limit number of connections from single IP (default: $maxconnip, 0 to disable)
90 --children int : Max number of children that can be spawned (default: $max_children)
91 --idle-children int : Number of idle children to spawn (default: $idle_children, 0 to disable)
b7f4684 Fixup qpsmtpd-prefork, et al, to correctly load Constants.
John Peacock authored
92 --pretty-child : Change child process name (default: 0)
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
93 --user username : User the daemon should run as
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
94 --pid-file path : Path to pid file
95 --renice-parent int : Subtract value from parent process nice level (default: $re_nice)
502e1d2 @vetinari prefork: - add --detach option to daemonize like forkserver
vetinari authored
96 --detach : detach from controlling terminal (daemonize)
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
97 --help : This message
98 EOT
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
99 exit 0;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
100 }
101
102 # get arguments
103 GetOptions(
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
104 'quiet' => \$quiet,
105 'version' => sub { print "Qpsmtpd Daemon - version $VERSION\n"; exit 0; },
106 'debug' => \$debug,
107 'interface=s' => \$d_addr,
108 'port=i' => \$d_port,
109 'max-from-ip=i' => \$maxconnip,
110 'children=i' => \$max_children,
111 'idle-children=i' => \$idle_children,
b7f4684 Fixup qpsmtpd-prefork, et al, to correctly load Constants.
John Peacock authored
112 'pretty-child' => \$pretty,
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
113 'user=s' => \$user,
114 'renice-parent=i' => \$re_nice,
502e1d2 @vetinari prefork: - add --detach option to daemonize like forkserver
vetinari authored
115 'detach' => \$detach,
f0a27f8 @vetinari prefork: --pid-file option now works
vetinari authored
116 'pid-file=s' => \$pid_file,
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
117 'help' => \&usage,
118 ) || &usage;
119
502e1d2 @vetinari prefork: - add --detach option to daemonize like forkserver
vetinari authored
120 if ($user =~ /^([\w\-]+)$/) { $user = $1 } else { &usage }
aa802e6 Untaint the value of the --interface option.
Radu Greab authored
121 if ($d_addr =~ /^(\[.*\]|[\w\-.]+)$/) { $d_addr = $1 } else { &usage }
3837fab Ask and ye shall receive
John Peacock authored
122
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
123 # set max from ip to max number of children if option is set to disabled
124 $maxconnip = $max_children if ($maxconnip == 0);
125
126 #to fix limit counter error in plugin <hosts_allow>
127 $maxconnip++;
128
129 #ensure that idle_children matches value given to max_children
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
130 $idle_children = $max_children
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
131 if (!$idle_children || $idle_children > $max_children || $idle_children < -1);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
132 $chld_pool = $idle_children;
133
f0a27f8 @vetinari prefork: --pid-file option now works
vetinari authored
134 if ($pid_file) {
135 if ($pid_file =~ m#^(/[\w\d/\-.]+)$#) { $pid_file = $1 } else { &usage }
136 if (-e $pid_file) {
137 open PID, "+<$pid_file"
138 or die "open pid_file: $!\n";
139 my $running_pid = <PID> || ''; chomp $running_pid;
140 if ($running_pid =~ /(\d+)/) {
141 $running_pid = $1;
142 die "Found an already running qpsmtpd with pid $running_pid.\n"
143 if (kill 0, $running_pid);
144 }
145 seek PID, 0, 0
146 or die "Could not seek back to beginning of $pid_file: $!\n";
147 truncate PID, 0
148 or die "Could not truncate $pid_file at 0: $!";
149 }
150 else {
151 open PID, ">$pid_file"
152 or die "open pid_file: $!\n";
153 }
154 }
155
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
156 run();
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
157
158 #start daemon
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
159 sub run {
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
160 # get UUID/GUID
502e1d2 @vetinari prefork: - add --detach option to daemonize like forkserver
vetinari authored
161 my ($quid, $qgid, $groups);
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
162 if ($user) {
502e1d2 @vetinari prefork: - add --detach option to daemonize like forkserver
vetinari authored
163 (undef, undef, $quid, $qgid) = getpwnam $user
164 or die "unable to determine uid/gid for $user\n";
165 $groups = "$qgid $qgid";
166 while (my ($name,$passwd,$gid,$members) = getgrent()) {
167 my @m = split(/ /, $members);
168 if (grep {$_ eq $user} @m) {
169 $groups .= " $gid";
170 }
171 }
172 endgrent;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
173 }
174
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
175 my @Socket_opts = (
176 LocalPort => $d_port,
177 LocalAddr => $d_addr,
178 Proto => 'tcp',
179 Listen => SOMAXCONN,
180 Reuse => 1,
181 );
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
182 # create new socket (used by clients to communicate with daemon)
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
183 if ($has_ipv6) {
184 $d = IO::Socket::INET6->new(@Socket_opts);
185 }
186 else {
f1281af @vetinari prefork: fix missing "->new" after IO::Socket::INET
vetinari authored
187 $d = IO::Socket::INET->new(@Socket_opts);
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
188 }
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
189 die "FATAL: Failed to start daemon.\nReason: $!\n(It may be nessesary to "
190 . "wait 20 secs before starting daemon again)\n"
191 unless $d;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
192
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
193 info("qpsmtpd-prefork daemon, version: $VERSION, staring on host: " .
194 "$d_addr, port: $d_port (user: $user [$<])");
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
195
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
196 # reset priority
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
197 my $old_nice = getpriority(0, 0);
198 my $new_nice = $old_nice - $re_nice;
199 if ($new_nice < 20 && $new_nice > -20) {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
200 setpriority(0, 0, $1) if ($new_nice =~ /(\-?\d+)/);
201 info("parent daemon nice level: $1");
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
202 }
203 else {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
204 die "FATAL: new nice level: $new_nice is not between -19 and 19 "
205 . "(old level = $old_nice, renice value = $re_nice)";
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
206 }
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
207
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
208 if ($user) {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
209 # change UUID/UGID
502e1d2 @vetinari prefork: - add --detach option to daemonize like forkserver
vetinari authored
210 $) = $groups;
211 POSIX::setgid($qgid) or die "unable to change gid: $!\n";
212 POSIX::setuid($quid) or die "unable to change uid: $!\n";
213 $> = $quid;
214 die "FATAL: failed to setuid to user: $user, uid: $quid\n"
215 if ($> != $quid and $> != ($quid - 2**32));
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
216 }
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
217
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
218 # setup shared memory
2a5c554 @vetinari prefork: support two or more parallel running instances (on different…
vetinari authored
219 $chld_shmem = shmem($d_port."qpsmtpd", 1);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
220 untie $chld_shmem;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
221
222 # Interrupt handler
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
223 $SIG{INT} = $SIG{TERM} = sub {
224 # terminate daemon (and children)
225 my $sig = shift;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
226
227 # prevent another signal and disable reaper
228 $SIG{$sig} = $SIG{CHLD} = $SIG{HUP} = 'IGNORE';
f0a27f8 @vetinari prefork: --pid-file option now works
vetinari authored
229 unlink($pid_file) if $pid_file;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
230
231 # close socket
232 $d->close();
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
233 my $cnt = kill 'INT' => keys %children;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
234
235 # cleanup shared memory
236 IPC::Shareable->clean_up;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
237 info("shutdown of daemon (and $cnt children)");
238 exit;
239 };
240
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
241 # Hup handler
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
242 $SIG{HUP} = sub {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
243 # reload qpmstpd plugins
a64742c @vetinari prefork, forkserver: restart on SIGHUP: * reset to defaults * clear c…
vetinari authored
244 $qpsmtpd = $qpsmtpd_base = qpsmtpd_instance('restart' => 1); # reload plugins...
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
245 $qpsmtpd->load_plugins;
246 kill 'HUP' => keys %children;
247 info("reload daemon requested");
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
248 };
249
85cd1aa @vetinari prefork: clear a previously running instance by cloning the base inst…
vetinari authored
250 # setup qpsmtpd_instance(s), _base is for resetting to a known state
251 # after each connection
252 $qpsmtpd = $qpsmtpd_base = qpsmtpd_instance();
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
253
18d1b9f Detach and daemonize only after reading the configuration and loading…
Diego d'Ambra authored
254 if ($detach) {
255 open STDIN, '/dev/null' or die "/dev/null: $!";
256 open STDOUT, '>/dev/null' or die "/dev/null: $!";
257 open STDERR, '>&STDOUT' or die "open(stderr): $!";
258 defined (my $pid = fork) or die "fork: $!";
259 exit 0 if $pid;
260 POSIX::setsid or die "setsid: $!";
261 }
262
263 if ($pid_file) {
264 print PID $$,"\n";
265 close PID;
266 }
267
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
268 # child reaper
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
269 $SIG{CHLD} = \&reaper;
270 spawn_children();
271 main_loop();
272 exit;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
273 }
274
275 # initialize children (only done at daemon startup)
276 sub spawn_children {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
277 # block signals while new children are being spawned
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
278 my $sigset = block_signal(SIGCHLD);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
279 for (1 .. $chld_pool) {
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
280 new_child();
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
281 }
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
282
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
283 # reset block signals
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
284 unblock_signal($sigset);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
285 }
286
287 # cleanup after child dies
288 sub reaper {
289 my $stiff;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
290 while (($stiff = waitpid(-1, &WNOHANG)) > 0) {
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
291 my $res = WEXITSTATUS($?);
292 info("child terminated, pid: $stiff (status $?, res: $res)");
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
293 delete $children{$stiff}; # delete pid from children
294 # add pid to array so it later can be removed from shared memory
e4f0cb0 Inside the main loop skip the sleep when children have exited. Instea…
Radu Greab authored
295 push @children_term, $stiff;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
296 }
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
297
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
298 $SIG{CHLD} = \&reaper;
299 }
300
e4f0cb0 Inside the main loop skip the sleep when children have exited. Instea…
Radu Greab authored
301 #main_loop: main loop. Either processes children that have exited or
302 # periodically scans the shared memory for children that are not longer
303 # alive. Spawns new children when necessary.
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
304 #arg0: void
305 #ret0: void
306 sub main_loop {
307 while (1) {
e4f0cb0 Inside the main loop skip the sleep when children have exited. Instea…
Radu Greab authored
308 # if there is no child death to process, then sleep EXPR seconds
309 # or until signal (i.e. child death) is received
310 sleep $loop_sleep unless @children_term;
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
311
e4f0cb0 Inside the main loop skip the sleep when children have exited. Instea…
Radu Greab authored
312 # block CHLD signals to avoid race
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
313 my $sigset = block_signal(SIGCHLD);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
314
e4f0cb0 Inside the main loop skip the sleep when children have exited. Instea…
Radu Greab authored
315 # get number of busy children
316 if (@children_term) {
317 # remove dead children info from shared memory
318 $chld_busy = shmem_opt(undef, \@children_term, undef, undef);
319 @children_term = ();
320 }
321 else {
322 # just check the shared memory
323 $chld_busy = shmem_opt(undef, undef, undef, undef, 1);
324 }
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
325
326 # calculate children in pool (if valid busy children number)
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
327 if (defined($chld_busy)) {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
328 info("busy children: $chld_busy");
329 $chld_pool = $chld_busy + $idle_children;
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
330
331 # ensure pool limit is max_children
332 $chld_pool = $max_children if ($chld_pool > $max_children);
333 info( "children pool: $chld_pool, spawned: "
334 . scalar(keys %children)
335 . ", busy: $chld_busy");
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
336 }
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
337 else {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
338
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
339 # reset shared memory
340 warn("unable to access shared memory - resetting it");
341 IPC::Shareable->clean_up;
342 my $shmem = shmem($d_port . "qpsmtpd", 1);
343 untie $shmem;
344 }
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
345
346 # spawn children
347 for (my $i = scalar(keys %children) ; $i < $chld_pool ; $i++) {
348 new_child(); # add to the child pool
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
349 }
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
350
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
351 # unblock signals
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
352 unblock_signal($sigset);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
353 }
354 }
355
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
356 # block_signal: block signals
357 # arg0..n: int with signal(s) to block
358 # ret0: ref str with sigset (used to later unblock signal)
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
359 sub block_signal {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
360 my @signal = @_; #arg0..n
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
361
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
362 my ($sigset, $blockset);
363
364 $sigset = POSIX::SigSet->new();
365 $blockset = POSIX::SigSet->new(@signal);
366 sigprocmask(SIG_BLOCK, $blockset, $sigset)
367 or die "Could not block @signal signals: $!\n";
368
369 return ($sigset);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
370 }
371
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
372 # unblock_signal: unblock/reset and receive pending signals
373 # arg0: ref str with sigset
374 # ret0: void
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
375 sub unblock_signal {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
376 my $sigset = shift; # arg0
377 sigprocmask(SIG_SETMASK, $sigset)
378 or die "Could not restore signals: $!\n";
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
379 }
380
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
381 # new_child: initialize new child
382 # arg0: void
383 # ret0: void
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
384 sub new_child {
385 # daemonize away from the parent process
386 my $pid;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
387 die "Cannot fork child: $!\n" unless defined($pid = fork);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
388 if ($pid) {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
389 # in parent
390 $children{$pid} = 1;
391 info("new child, pid: $pid");
392 return;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
393 }
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
394
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
395 # in child
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
396
397 # reset priority
398 setpriority 0, 0, getpriority(0, 0) + $re_nice;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
399
400 # reset signals
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
401 my $sigset = POSIX::SigSet->new();
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
402 my $blockset = POSIX::SigSet->new(SIGCHLD);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
403 sigprocmask(SIG_UNBLOCK, $blockset, $sigset)
404 or die "Could not unblock SIGHUP signal: $!\n";
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
405 $SIG{CHLD} = $SIG{INT} = $SIG{TERM} = $SIG{ALRM} = 'DEFAULT';
406
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
407 # child should exit if it receives HUP signal (note: blocked while child
408 # is busy, but restored once done)
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
409 $SIG{HUP} = sub {
410 info("signal HUP received, going to exit");
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
411 exit 1;
412 };
413
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
414 # continue to accept connections until "old age" is reached
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
415 for (my $i = 0 ; $i < $child_lifetime ; $i++) {
416 # accept a connection
b7f4684 Fixup qpsmtpd-prefork, et al, to correctly load Constants.
John Peacock authored
417 if ( $pretty ) {
418 $ENV{PROCESS} = $0 if not defined $ENV{PROCESS}; # 1st time only
419 $0 = 'qpsmtpd child'; # set pretty child name in process listing
420 }
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
421 my ($client, $iinfo) = $d->accept()
422 or die
423 "failed to create new object - $!"; # wait here until client connects
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
424 info("connect from: " . $client->peerhost . ":" . $client->peerport);
85cd1aa @vetinari prefork: clear a previously running instance by cloning the base inst…
vetinari authored
425
426 # clear a previously running instance by cloning the base:
427 $qpsmtpd = $qpsmtpd_base;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
428
429 # set STDIN/STDOUT and autoflush
0be3400 @vetinari prefork: using POSIX::dup2 failed after a few million connections, so
vetinari authored
430 # ... no longer use POSIX::dup2: it failes after a few
431 # million connections
432 close(STDIN);
433 open(STDIN, "+<&".fileno($client))
434 or die "unable to duplicate filehandle to STDIN - $!";
435
436 close(STDOUT);
437 open(STDOUT, "+>&".fileno($client))
438 or die "unable to duplicate filehandle to STDOUT - $!";
439 select(STDOUT);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
440 $| = 1;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
441
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
442 # connection recieved, block signals
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
443 my $sigset = block_signal(SIGHUP);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
444
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
445 # start a session if connection looks valid
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
446 qpsmtpd_session($client, $iinfo, $qpsmtpd) if ($iinfo);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
447
448 # close connection and cleanup
449 $client->shutdown(2);
450
451 # unset block and receive pending signals
452 unblock_signal($sigset);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
453 }
454 exit; # this child has reached its end-of-life
455 }
456
457 # respond to client
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
458 # arg0: ref to socket object (client)
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
459 # arg1: int with SMTP reply code
460 # arg2: arr with message
461 # ret0: int 0|1 (0 = failure, 1 = success)
462 sub respond_client {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
463 my ($client, $code, @message) = @_;
464 $client->autoflush(1);
465 while (my $msg = shift @message) {
466 my $line = $code . (@message ? "-" : " ") . $msg;
467 info("reply to client: <$line>");
468 print $client "$line\r\n"
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
469 or (info("Could not print [$line]: $!"), return 0);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
470 }
471 return 1;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
472 }
473
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
474 # qpsmtpd_instance: setup qpsmtpd instance
475 # arg0: void
476 # ret0: ref to qpsmtpd_instance
85cd1aa @vetinari prefork: clear a previously running instance by cloning the base inst…
vetinari authored
477 sub qpsmtpd_instance {
a64742c @vetinari prefork, forkserver: restart on SIGHUP: * reset to defaults * clear c…
vetinari authored
478 my %args = @_;
479 my $qpsmtpd = Qpsmtpd::TcpServer::Prefork->new(%args);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
480 $qpsmtpd->load_plugins;
481 $qpsmtpd->spool_dir;
482 $qpsmtpd->size_threshold;
483
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
484 return ($qpsmtpd);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
485 }
486
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
487 # shmem: tie to shared memory hash
488 # arg0: str with glue
489 # arg1: int 0|1 (0 = don't create shmem, 1 = create shmem)
490 # ret0: ref to shared hash
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
491 sub shmem {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
492 my $glue = shift; #arg0
493 my $create = shift || 0; #arg1
494
495 my %options = (
496 create => $create,
497 exclusive => 0,
498 mode => 0640,
499 destroy => 0,
500 );
501
502 my %shmem_hash;
503 eval {
504 tie %shmem_hash, 'IPC::Shareable', $glue, {%options}
505 || die "unable to tie to shared memory - $!";
506 };
507 if ($@) {
508 info("$@");
509 return;
510 }
511
512 return (\%shmem_hash);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
513 }
514
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
515 # shmem_opt: connect to shared memory and perform options
516 # arg0: ref to hash where shared memory should be copied to
517 # arg1: ref to arr with pid(s) to delete
518 # arg2: int with pid to add (key)
519 # arg3: str with packed iaddr to add (value)
520 # arg4: int 0|1 check and cleanup shared memory (0 = no, 1 = yes - default 0)
521 # ret0: int with number of busy children (undef if error)
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
522 sub shmem_opt {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
523 my $ref_shmem = shift; #arg0
524 my $ref_pid_del = shift; #arg1
525 my $pid_add_key = shift; #arg2
526 my $pid_add_value = shift; #arg3
527 my $check = shift || 0; #arg4
528
529 # check arguments
530 if ( (defined($pid_add_key) && !defined($pid_add_value))
531 || (!defined($pid_add_key) && defined($pid_add_value)))
532 {
533 return;
534 }
535
536 my ($chld_shmem, $chld_busy);
537 eval {
2a5c554 @vetinari prefork: support two or more parallel running instances (on different…
vetinari authored
538 $chld_shmem = &shmem($d_port."qpsmtpd", 0); #connect to shared memory hash
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
539
540 if (tied %{$chld_shmem}) {
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
541
542 # lock shared memory
543 eval {
544 # ensure that hung shared memory is noticed
545 local $SIG{ALRM} = sub {
546 die "locking timed out\n";
547 };
548 alarm 15;
549
550 (tied %{$chld_shmem})->shlock(LOCK_EX);
551
552 alarm 0;
553 };
554 die $@ if $@;
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
555
556 # delete
557 if ($ref_pid_del) {
558 foreach my $pid_del (@{$ref_pid_del}) {
559 delete $$chld_shmem{$pid_del};
560 }
561 }
562 # add
563 $$chld_shmem{$pid_add_key} = $pid_add_value if ($pid_add_key);
564 # copy
565 %{$ref_shmem} = %{$chld_shmem} if ($ref_shmem);
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
566
567 # check
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
568 if ($check) {
569 # loop through pid list and delete orphaned processes
570 foreach my $pid (keys %{$chld_shmem}) {
571 if (!kill 0, $pid) {
572 delete $$chld_shmem{$pid};
573 warn("orphaned child, pid: $pid removed from memory");
574 }
575 }
576 }
577
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
578 # number of busy children
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
579 $chld_busy = scalar(keys %{$chld_shmem});
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
580
581 # unlock shared memory
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
582 (tied %{$chld_shmem})->shunlock;
583
584 # untie from shared memory
585 untie $chld_shmem || die "unable to untie from shared memory";
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
586 }
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
587 else {
588 die "failed to connect to shared memory";
589 }
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
590 };
591
592 # check for error
593 if ($@) {
594 undef($chld_busy);
595 warn("$@");
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
596 }
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
597
598 return ($chld_busy);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
599 }
600
601 # info: write info
602 # arg0: str with debug text
603 sub info {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
604 my $text = shift; #arg0
605 return if (!$debug);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
606
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
607 my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
608 my $nowtime = sprintf "%02d/%02d/%02d %02d:%02d:%02d", $mday, $mon + 1,
609 $year + 1900, $hour, $min, $sec;
610
611 chomp($text);
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
612 print STDERR "$nowtime:$$: $text\n";
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
613 }
614
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
615 # start qpmstpd session
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
616 # arg0: ref to socket object
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
617 # arg1: ref to socket object
618 # arg2: ref to qpsmtpd instance
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
619 # ret0: void
620 sub qpsmtpd_session {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
621 my $client = shift; #arg0
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
622 my $iinfo = shift; #arg1
623 my $qpsmtpd = shift; #arg2
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
624
625 # get local/remote hostname, port and ip address
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
626 my ($port, $iaddr, $lport, $laddr, $nto_iaddr, $nto_laddr) = Qpsmtpd::TcpServer::lrpip($d, $client, $iinfo);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
627
628 # get current connected ip addresses (from shared memory)
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
629 my %children;
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
630 shmem_opt(\%children, undef, $$, $iaddr);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
631
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
632 my ($rc, @msg) =
633 $qpsmtpd->run_hooks(
634 "pre-connection",
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
635 remote_ip => $nto_iaddr,
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
636 remote_port => $port,
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
637 local_ip => $nto_laddr,
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
638 local_port => $lport,
639 max_conn_ip => $maxconnip,
640 child_addrs => [values %children],
641 );
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
642 if ( $rc == DENYSOFT
643 || $rc == DENYSOFT_DISCONNECT
644 || $rc == DENY
645 || $rc == DENY_DISCONNECT)
646 {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
647 #smtp return code to reply client with (seed with soft deny)
648 my $rc_reply = 451;
649 unless ($msg[0]) {
650 if ($rc == DENYSOFT || $rc == DENYSOFT_DISCONNECT) {
651 @msg = ("Sorry, try again later");
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
652 }
653 else {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
654 @msg = ("Sorry, service not available to you");
655 $rc_reply = 550;
656 }
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
657 }
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
658 respond_client($client, $rc_reply, @msg);
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
659
660 # remove pid from shared memory
661 shmem_opt(undef, [$$], undef, undef);
662
663 # retur so child can be reused
664 return;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
665 }
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
666
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
667 # all children should have different seeds, to prevent conflicts
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
668 srand(time ^ ($$ + ($$ << 15)));
669
670 # ALRM handler
671 $SIG{ALRM} = sub {
672 print $client "421 Connection Timed Out\n";
e9e95dd Patch to qpsmtpd-prefork from Matt Sergeant:
John Peacock authored
673 info("Connection Timed Out");
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
674
675 # kill the child
676 exit 1;
677 };
678
679 # set enviroment variables
ccf990e IPv6 support from issue #7.
Matt Sergeant authored
680 ($ENV{TCPLOCALIP}, $ENV{TCPREMOTEIP}, $ENV{TCPREMOTEHOST}) = Qpsmtpd::TcpServer::tcpenv($nto_laddr, $nto_iaddr);
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
681
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
682 # run qpmsptd functions
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
683 $SIG{__DIE__} = 'DEFAULT';
684 eval {
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
685 $qpsmtpd->start_connection(
686 local_ip => $ENV{TCPLOCALIP},
687 local_port => $lport,
688 remote_ip => $ENV{TCPREMOTEIP},
689 remote_port => $client->peerport,
690 );
691 $qpsmtpd->run();
692 $qpsmtpd->run_hooks("post-connection");
ea243c2 @vetinari add reset() to Qpsmtpd::Connection to clear the connection notes after
vetinari authored
693 $qpsmtpd->connection->reset;
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
694 };
9bb950d Additional patch to qpsmtpd-prefork from Lars Roland:
John Peacock authored
695 if ($@ !~ /^(disconnect_tcpserver|died while reading from STDIN)/) {
696 warn("$@");
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
697 }
698
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
699 # child is now idle again
700 info("disconnect from: $nto_iaddr:$port");
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
701
409372c Detect and reset locked shared memory.
Diego d'Ambra authored
702 # remove pid from shared memory
703 unless (defined(shmem_opt(undef, [$$], undef, undef))) {
704 # exit because parent is down or shared memory is corrupted
705 info("parent seems to be down, going to exit");
706 exit 1;
707 }
67dc86e New pre-forking qpsmtpd daemon, courtesy of Lars Roland at SoftScan.
John Peacock authored
708 }
Something went wrong with that request. Please try again.