Linux biogene 3.16.0-11-amd64 #1 SMP Debian 3.16.84-1 (2020-06-09) x86_64
Apache
: 46.101.124.208 | : 18.117.170.203
Cant Read [ /etc/named.conf ]
5.6.40-0+deb8u12
www-data
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
usr /
sbin /
[ HOME SHELL ]
Name
Size
Permission
Action
a2disconf
13.84
KB
-rwxr-xr-x
a2dismod
13.84
KB
-rwxr-xr-x
a2dissite
13.84
KB
-rwxr-xr-x
a2enconf
13.84
KB
-rwxr-xr-x
a2enmod
13.84
KB
-rwxr-xr-x
a2ensite
13.84
KB
-rwxr-xr-x
a2query
9.66
KB
-rwxr-xr-x
accessdb
10.13
KB
-rwxr-xr-x
accton
10.2
KB
-rwxr-xr-x
acpid
46.8
KB
-rwxr-xr-x
add-shell
695
B
-rwxr-xr-x
addgnupghome
3.05
KB
-rwxr-xr-x
addgroup
33.66
KB
-rwxr-xr-x
adduser
33.66
KB
-rwxr-xr-x
amavis-mc
18.73
KB
-rwxr-xr-x
amavis-services
33.4
KB
-rwxr-xr-x
amavisd-agent
13.11
KB
-rwxr-xr-x
amavisd-nanny
11.72
KB
-rwxr-xr-x
amavisd-new
1.46
MB
-rwxr-xr-x
amavisd-new-cronjob
825
B
-rwxr-xr-x
amavisd-release
12.32
KB
-rwxr-xr-x
amavisd-signer
36.85
KB
-rwxr-xr-x
amavisd-snmp-subagent
52.97
KB
-rwxr-xr-x
amavisd-snmp-subagent-zmq
52.42
KB
-rwxr-xr-x
amavisd-status
14
KB
-rwxr-xr-x
amavisd-submit
9.09
KB
-rwxr-xr-x
apache2
650.93
KB
-rwxr-xr-x
apache2ctl
6.25
KB
-rwxr-xr-x
apachectl
6.25
KB
-rwxr-xr-x
applygnupgdefaults
2.21
KB
-rwxr-xr-x
arp
54.38
KB
-rwxr-xr-x
arpd
39.11
KB
-rwxr-xr-x
arping
30.48
KB
-rwxr-xr-x
aspell-autobuildhash
13.09
KB
-rwxr-xr-x
atd
21.88
KB
-rwxr-xr-x
biosdecode
18.76
KB
-rwxr-xr-x
check_forensic
952
B
-rwxr-xr-x
chgpasswd
57.3
KB
-rwxr-xr-x
chpasswd
49.36
KB
-rwxr-xr-x
chroot
34.6
KB
-rwxr-xr-x
cpgr
51.48
KB
-rwxr-xr-x
cppw
51.48
KB
-rwxr-xr-x
cron
43.36
KB
-rwxr-xr-x
dbconfig-generate-include
11.63
KB
-rwxr-xr-x
dbconfig-load-include
5.57
KB
-rwxr-xr-x
delgroup
15.43
KB
-rwxr-xr-x
deluser
15.43
KB
-rwxr-xr-x
dmidecode
98.43
KB
-rwxr-xr-x
dovecot
82.05
KB
-rwxr-xr-x
dpkg-divert
135.23
KB
-rwxr-xr-x
dpkg-preconfigure
3.52
KB
-rwxr-xr-x
dpkg-reconfigure
4.23
KB
-rwxr-xr-x
dpkg-statoverride
58.84
KB
-rwxr-xr-x
dump-acct
18.46
KB
-rwxr-xr-x
dump-utmp
14.4
KB
-rwxr-xr-x
e2freefrag
10.18
KB
-rwxr-xr-x
e4defrag
26.47
KB
-rwxr-xr-x
fdformat
10.21
KB
-rwxr-xr-x
filefrag
14.25
KB
-rwxr-xr-x
groupadd
57.36
KB
-rwxr-xr-x
groupdel
53.23
KB
-rwxr-xr-x
groupmod
67.73
KB
-rwxr-xr-x
grpck
53.35
KB
-rwxr-xr-x
grpconv
49.23
KB
-rwxr-xr-x
grpunconv
49.23
KB
-rwxr-xr-x
grub-bios-setup
751.6
KB
-rwxr-xr-x
grub-install
943.7
KB
-rwxr-xr-x
grub-macbless
739.26
KB
-rwxr-xr-x
grub-mkconfig
7.78
KB
-rwxr-xr-x
grub-mkdevicemap
188.83
KB
-rwxr-xr-x
grub-probe
749.2
KB
-rwxr-xr-x
grub-reboot
4.01
KB
-rwxr-xr-x
grub-set-default
3.48
KB
-rwxr-xr-x
httxt2dbm
9.96
KB
-rwxr-xr-x
iconvconfig
30.46
KB
-rwxr-xr-x
install-sgmlcatalog
4.44
KB
-rwxr-xr-x
invoke-rc.d
15.01
KB
-rwxr-xr-x
ip6tables-apply
6.85
KB
-rwxr-xr-x
iptables-apply
6.85
KB
-rwxr-xr-x
irqbalance
43.07
KB
-rwxr-xr-x
ispell-autobuildhash
15.25
KB
-rwxr-xr-x
laptop-detect
2.53
KB
-rwxr-xr-x
ldattach
22.35
KB
-rwxr-xr-x
locale-gen
1.5
KB
-rwxr-xr-x
logrotate
62.92
KB
-rwxr-xr-x
logwatch
57.19
KB
-rwxr-xr-x
make-ssl-cert
3.69
KB
-rwxr-xr-x
mkinitramfs
9.15
KB
-rwxr-xr-x
mklost+found
10.2
KB
-rwxr-xr-x
mount.davfs
123.61
KB
-rwsr-xr-x
mysqld
11.32
MB
-rwxr-xr-x
newusers
77.86
KB
-rwxr-xr-x
nfacct
14.2
KB
-rwxr-xr-x
nfnl_osf
14.18
KB
-rwxr-xr-x
nologin
5.87
KB
-rwxr-xr-x
ownership
10.13
KB
-rwxr-xr-x
p0f-analyzer
23.34
KB
-rwxr-xr-x
pam-auth-update
19.02
KB
-rwxr-xr-x
pam_getenv
2.82
KB
-rwxr-xr-x
pam_timestamp_check
10.2
KB
-rwxr-xr-x
paperconfig
4.07
KB
-rwxr-xr-x
php5dismod
6.21
KB
-rwxr-xr-x
php5enmod
6.21
KB
-rwxr-xr-x
php5query
5.05
KB
-rwxr-xr-x
pma-configure
299
B
-rwxr-xr-x
pma-secure
157
B
-rwxr-xr-x
postalias
17.87
KB
-rwxr-xr-x
postcat
17.94
KB
-rwxr-xr-x
postconf
163.38
KB
-rwxr-xr-x
postdrop
13.99
KB
-r-xr-sr-x
postfix
13.95
KB
-rwxr-xr-x
postfix-add-filter
4.88
KB
-rwxr-xr-x
postfix-add-policy
3.81
KB
-rwxr-xr-x
postkick
9.87
KB
-rwxr-xr-x
postlock
9.87
KB
-rwxr-xr-x
postlog
10.05
KB
-rwxr-xr-x
postmap
17.87
KB
-rwxr-xr-x
postmulti
30.26
KB
-rwxr-xr-x
postqueue
13.95
KB
-r-xr-sr-x
postsuper
26.26
KB
-rwxr-xr-x
posttls-finger
33.95
KB
-rwxr-xr-x
pwck
49.3
KB
-rwxr-xr-x
pwconv
45.17
KB
-rwxr-xr-x
pwunconv
36.36
KB
-rwxr-xr-x
qmqp-sink
13.87
KB
-rwxr-xr-x
qmqp-source
17.88
KB
-rwxr-xr-x
qshape
12.55
KB
-rwxr-xr-x
readprofile
14.33
KB
-rwxr-xr-x
remove-default-ispell
2.86
KB
-rwxr-xr-x
remove-default-wordlist
2.86
KB
-rwxr-xr-x
remove-shell
749
B
-rwxr-xr-x
rmail
13.87
KB
-rwxr-xr-x
rmt
54.91
KB
-rwxr-xr-x
rmt-tar
54.91
KB
-rwxr-xr-x
rsyslogd
563.81
KB
-rwxr-xr-x
rtcwake
26.42
KB
-rwxr-xr-x
sa
35.39
KB
-rwxr-xr-x
safe_finger
10.3
KB
-rwxr-xr-x
select-default-ispell
1.83
KB
-rwxr-xr-x
select-default-wordlist
1.82
KB
-rwxr-xr-x
sendmail
26.05
KB
-rwxr-xr-x
service
9.37
KB
-rwxr-xr-x
setvesablank
10.07
KB
-rwxr-xr-x
slapacl
1.21
MB
-rwxr-xr-x
slapadd
1.21
MB
-rwxr-xr-x
slapauth
1.21
MB
-rwxr-xr-x
slapcat
1.21
MB
-rwxr-xr-x
slapd
1.21
MB
-rwxr-xr-x
slapdn
1.21
MB
-rwxr-xr-x
slapindex
1.21
MB
-rwxr-xr-x
slappasswd
1.21
MB
-rwxr-xr-x
slapschema
1.21
MB
-rwxr-xr-x
slaptest
1.21
MB
-rwxr-xr-x
smtp-sink
30.8
KB
-rwxr-xr-x
smtp-source
21.89
KB
-rwxr-xr-x
spamd
127.49
KB
-rwxr-xr-x
split-logfile
2.36
KB
-rwxr-xr-x
sshd
760.63
KB
-rwxr-xr-x
tarcat
936
B
-rwxr-xr-x
tcpd
10.12
KB
-rwxr-xr-x
tcpdchk
22.42
KB
-rwxr-xr-x
tcpdmatch
18.33
KB
-rwxr-xr-x
tcptraceroute
1.45
KB
-rwxr-xr-x
tcptraceroute.db
1.45
KB
-rwxr-xr-x
traceroute
67.37
KB
-rwxr-xr-x
try-from
10.06
KB
-rwxr-xr-x
tunelp
14.22
KB
-rwxr-xr-x
tzconfig
106
B
-rwxr-xr-x
umount.davfs
10.21
KB
-rwxr-xr-x
update-alternatives
46.43
KB
-rwxr-xr-x
update-ca-certificates
4.85
KB
-rwxr-xr-x
update-catalog
9.15
KB
-rwxr-xr-x
update-default-aspell
1
KB
-rwxr-xr-x
update-default-ispell
9.68
KB
-rwxr-xr-x
update-default-wordlist
7.5
KB
-rwxr-xr-x
update-dictcommon-aspell
1
KB
-rwxr-xr-x
update-dictcommon-hunspell
782
B
-rwxr-xr-x
update-grub
64
B
-rwxr-xr-x
update-grub2
64
B
-rwxr-xr-x
update-icon-caches
617
B
-rwxr-xr-x
update-info-dir
1.65
KB
-rwxr-xr-x
update-initramfs
8.76
KB
-rwxr-xr-x
update-locale
2.99
KB
-rwxr-xr-x
update-mime
8.84
KB
-rwxr-xr-x
update-passwd
30.31
KB
-rwxr-xr-x
update-pciids
2.84
KB
-rwxr-xr-x
update-python-modules
19.33
KB
-rwxr-xr-x
update-rc.d
11.72
KB
-rwxr-xr-x
update-xmlcatalog
16.28
KB
-rwxr-xr-x
upgrade-from-grub-legacy
1.49
KB
-rwxr-xr-x
useradd
118.69
KB
-rwxr-xr-x
userdel
81.92
KB
-rwxr-xr-x
usermod
122.5
KB
-rwxr-xr-x
validlocale
1.73
KB
-rwxr-xr-x
vcstime
6.06
KB
-rwxr-xr-x
vigr
59.73
KB
-rwxr-xr-x
vipw
59.73
KB
-rwxr-xr-x
visudo
2.2
MB
-rwxr-xr-x
vpddecode
14.26
KB
-rwxr-xr-x
vsftpd
156.32
KB
-rwxr-xr-x
zabbix_agentd
527.59
KB
-rwxr-xr-x
zic
42.36
KB
-rwxr-xr-x
Delete
Unzip
Zip
${this.title}
Close
Code Editor : amavis-services
#!/usr/bin/perl -T #------------------------------------------------------------------------------ # This is amavis-services, a set of supervisor processes for amavisd-new. # # Author: Mark Martinec <Mark.Martinec@ijs.si> # # Copyright (c) 2012-2014, Mark Martinec # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # The views and conclusions contained in the software and documentation are # those of the authors and should not be interpreted as representing official # policies, either expressed or implied, of the Jozef Stefan Institute. # (the above license is the 2-clause BSD license, also known as # a "Simplified BSD License", and pertains to this program only) # # Patches and problem reports are welcome. # The latest version of this program is available at: # http://www.ijs.si/software/amavisd/ #------------------------------------------------------------------------------ use strict; use re 'taint'; use warnings; use warnings FATAL => qw(utf8 void); no warnings 'uninitialized'; use vars qw($VERSION); $VERSION = 2.008002; use Errno qw(ESRCH ENOENT); use POSIX qw(strftime); use Time::HiRes (); use Unix::Syslog qw(:macros :subs); use vars qw($myproduct_name $myversion_id $myversion_date $myversion); use vars qw($MYHOME $idle_ttl $active_ttl $log_level); use vars qw($syslog_ident $syslog_facility); use vars qw($inner_sock_specs $outer_sock_specs $snmp_sock_specs); BEGIN { $myproduct_name = 'amavis-services'; $myversion_id = '2.9.0'; $myversion_date = '20140506'; $myversion = "$myproduct_name-$myversion_id ($myversion_date)"; } ### USER CONFIGURABLE: $log_level = 0; # 0..5 $syslog_facility = LOG_MAIL; $syslog_ident = $myproduct_name; $MYHOME = '/var/lib/amavis'; # A socket to which amavisd child processes report their data. # should match one of the sockets in @zmq_sockets in amavisd.conf $inner_sock_specs = "ipc://$MYHOME/amavisd-zmq.sock"; # A socket to which we forward summarized amavisd data. # should match a socket of the same name in amavis-status $outer_sock_specs = "tcp://127.0.0.1:23232"; # A socket on which we accept SNMP queries and respond to. # should match a socket of the same name in amavisd-snmp-subagent-zmq $snmp_sock_specs = "tcp://127.0.0.1:23233"; # tcp://*:23233 $idle_ttl = 4*60*60; # idle children are sent a SIGTERM # after this many seconds $active_ttl = 15*60; # stuck active children are sent a SIGTERM # after this many seconds ### END OF USER CONFIGURABLE use vars qw(@age_slots); BEGIN { @age_slots = ( 0.1, 0.2, 0.5, 1, 2, 4, 8, 15, 30, # seconds 1*60, 2*60, 4*60, 8*60, 15*60, 30*60, # minutes 1*3600, 2*3600, 4*3600, 8*3600, 15*3600, 30*3600); # hours } use vars qw($zmq_mod_name $zmq_mod_version $zmq_lib_version); BEGIN { my($zmq_major, $zmq_minor, $zmq_patch); if (eval { require ZMQ::LibZMQ3 && require ZMQ::Constants }) { $zmq_mod_name = 'ZMQ::LibZMQ3'; # new interface module to zmq v3 or libxs import ZMQ::LibZMQ3; import ZMQ::Constants qw(:all); ($zmq_major, $zmq_minor, $zmq_patch) = ZMQ::LibZMQ3::zmq_version(); # *zmq_sendmsg [native] # (socket,msgobj,flags) # *zmq_recvmsg [native] # (socket,flags) -> msgobj *zmq_sendstr = sub { # (socket,string,flags) my $rv = zmq_send($_[0], $_[1], length $_[1], $_[2]||0); $rv == -1 ? undef : $rv; }; } elsif (eval { require ZMQ::LibZMQ2 && require ZMQ::Constants }) { $zmq_mod_name = 'ZMQ::LibZMQ2'; # new interface module to zmq v2 import ZMQ::LibZMQ2; import ZMQ::Constants qw(:all); ($zmq_major, $zmq_minor, $zmq_patch) = ZMQ::LibZMQ2::zmq_version(); # zmq v2/v3 incompatibile renaming *zmq_sendmsg = \&ZMQ::LibZMQ2::zmq_send; # (socket,msgobj,flags) *zmq_recvmsg = \&ZMQ::LibZMQ2::zmq_recv; # (socket,flags) -> msgobj *zmq_sendstr = sub { # (socket,string,flags) my $rv = zmq_send(@_); $rv == -1 ? undef : $rv; }; } elsif (eval { require ZeroMQ::Constants && require ZeroMQ::Raw }) { $zmq_mod_name = 'ZeroMQ'; # old interface module to zmq v2 import ZeroMQ::Raw; import ZeroMQ::Constants qw(:all); ($zmq_major, $zmq_minor, $zmq_patch) = ZeroMQ::version(); # zmq v2/v3 incompatibile renaming *zmq_sendmsg = \&ZeroMQ::Raw::zmq_send; # (socket,msgobj,flags) *zmq_recvmsg = \&ZeroMQ::Raw::zmq_recv; # (socket,flags) -> msgobj *zmq_sendstr = sub { # (socket,string,flags) my $rv = zmq_send(@_); $rv == -1 ? undef : $rv; }; } else { die "Perl modules ZMQ::LibZMQ3 or ZMQ::LibZMQ2 or ZeroMQ not available\n"; } $zmq_mod_version = $zmq_mod_name->VERSION; $zmq_lib_version = join('.', $zmq_major, $zmq_minor, $zmq_patch); 1; } sub zmq_version { sprintf("%s %s, lib %s", $zmq_mod_name, $zmq_mod_version, $zmq_lib_version); }; sub zmq_recvstr { # (socket,buffer,offset) -> (len,more) my $sock = $_[0]; my $offset = $_[2] || 0; my $zm = zmq_recvmsg($sock); # a copy of a received msg obj if (!$zm) { substr($_[1],$offset) = ''; return } ($offset ? substr($_[1],$offset) : $_[1]) = zmq_msg_data($zm); my $len = length($_[1]) - $offset; zmq_msg_close($zm); return $len if !wantarray; my $more = zmq_getsockopt($sock, ZMQ_RCVMORE); if ($more == -1) { substr($_[1],$offset) = ''; return } ($len, $more); }; my($interrupted, $syslog_open, $foreground); my($zmq_ctx, $inner_sock, $outer_sock, $snmp_sock); my $zmq_poll_units = 1000; # milliseconds since zmq v3 $zmq_poll_units *= 1000 if $zmq_lib_version =~ /^[012]\./; # microseconds # Return untainted copy of a string (argument can be a string or a string ref) # sub untaint($) { return undef if !defined $_[0]; # must return undef even in a list context! no re 'taint'; local $1; # avoids Perl taint bug: tainted global $1 propagates taintedness (ref($_[0]) ? ${$_[0]} : $_[0]) =~ /^(.*)\z/s; $1; } sub ll($) { my($level) = @_; $level <= $log_level; } sub do_log($$;@) { # my($level,$errmsg,@args) = @_; my $level = shift; if ($level <= $log_level) { my $errmsg = shift; # treat $errmsg as sprintf format string if additional arguments provided $errmsg = sprintf($errmsg,@_) if @_; if (!$syslog_open) { $errmsg .= "\n"; print STDERR $errmsg; # print ignoring I/O status, except SIGPIPE } else { my $prio = $level >= 3 ? LOG_DEBUG # most frequent first : $level >= 1 ? LOG_INFO : $level >= 0 ? LOG_NOTICE : $level >= -1 ? LOG_WARNING : LOG_ERR; syslog($prio, "%s", $errmsg); } } } sub process_message($$) { my($process_states_ref,$msgstr_ref) = @_; if (!$msgstr_ref || !defined $$msgstr_ref) { # should not happen (except on a failure of zmq_recvmsg) } elsif ($$msgstr_ref =~ /^am\.st \d+\s+/s) { my($subscription_chan, $pid, $time, $state, $task_id) = split(' ', $$msgstr_ref); if ($state eq 'FLUSH') { do_log(0, "childproc_minder: FLUSH process states"); %$process_states_ref = (); # flush all kept state (e.g. on a restart) } elsif ($state eq 'exiting' || $state eq 'purged') { delete $process_states_ref->{$pid}; # may or may not exist } else { $state = ' ' if $state eq '-'; my $p = $process_states_ref->{$pid}; if ($p) { $p->{state} = $state; $p->{task_id} = $task_id; } else { # new process appeared $process_states_ref->{$pid} = $p = { state => $state, task_id => $task_id, timestamp => undef, base_timestamp => undef, }; } my $now = Time::HiRes::time; if ($time > 1e9) { # Unix time in seconds with fraction (> Y2000) $p->{base_timestamp} = $p->{timestamp} = $time; } elsif (!$p->{base_timestamp}) { # delta time but no base $p->{timestamp} = $now; $p->{base_timestamp} = $p->{timestamp} - $time/1000; # estimate } else { # delta time since base_timestamp in ms $p->{timestamp} = $p->{base_timestamp} + $time/1000; } $p->{tick} = $now; } } 1; } sub check_proc($) { my($process_states_ref) = @_; do_log(2, "CHECK"); my $cnt_gone = 0; my $cnt_terminated = 0; while (my($pid,$p) = each %$process_states_ref) { my $now = Time::HiRes::time; my $age = $now - $p->{base_timestamp}; my $idling = $p->{task_id} eq '' && $p->{state} =~ /^[. ]\z/s; my $overdue = $age > ($idling ? $idle_ttl : $active_ttl); my $n; # number of checked processes (0 or 1) if (!$overdue && $now - $p->{tick} < 10) { $n = 1; # recently heard from it, assume it is still there do_log(2, "PID %d skipped, recently heared from\n", $pid); } elsif (!$overdue && $idling && $p->{last_checked_timestamp} && $now - $p->{last_checked_timestamp} < 20) { $n = 1; # recently checked, idle, assume it is still there do_log(2, "PID %d skipped, recently checked\n", $pid); } elsif (!$overdue && $p->{last_checked_timestamp} && $now - $p->{last_checked_timestamp} < 10) { $n = 1; # recently checked, busy, assume it is still there do_log(2, "PID %d skipped, recently checked\n", $pid); } else { do_log(2, "PID %d checking\n", $pid); $p->{last_checked_timestamp} = $now; $n = kill(0,$pid); # test if the process is still there if ($n == 0) { # ESRCH means there is no such process if ($! != ESRCH) { do_log(-1, "Can't check the process %s: %s", $pid,$!); } elsif (defined $p->{sig_sent}) { $cnt_terminated++; do_log(2, "PID %d sucessfully terminated by SIG%s, %s\n", $pid, $p->{sig_sent}, $p->{task_id} || $p->{state}); } else { $cnt_gone++; do_log(0, "PID %d went away, %s\n", $pid, $p->{task_id} || $p->{state} ); } delete $process_states_ref->{$pid}; defined zmq_sendstr($inner_sock, sprintf('am.st %s %014.3f purged', $pid,$now)) or die "zmq_sendstr failed: $!" } } if ($n == 0) { # already dealt with } elsif (!$overdue) { # life is good do_log(2, "PID %d: %s\n", $pid, $p->{task_id} || $p->{state} ); } elsif (!$p->{sig_sent} || $p->{sig_sent_timestamp} + $p->{sig_sent_retry_in} >= $now) { # overdue, terminate or kill, or retry the killing if (!$p->{sig_sent}) { $p->{sig_sent} = 'TERM'; $p->{sig_sent_retry_in} = 20; } else { $p->{sig_sent} = 'KILL'; $p->{sig_sent_retry_in} *= 1.5; # increase the wait time for a retry } $p->{sig_sent_timestamp} = $now; if (kill($p->{sig_sent},$pid)) { do_log(2, "PID %d SIG%s, %s\n", $pid, $p->{sig_sent}, $p->{task_id} || $p->{state}); } elsif ($! == ESRCH) { # already gone by now, no fuss } else { warn "Can't $p->{sig_sent} the [$pid]: $!"; } if ($p->{sig_sent_retry_in} > 600) { do_log(2, "Giving up on PID %d, %s\n", $pid, $p->{task_id} || $p->{state}); delete $process_states_ref->{$pid}; defined zmq_sendstr($inner_sock, sprintf('am.st %s %014.3f purged', $pid,$now)) or die "zmq_sendstr failed: $!" } } } ($cnt_gone, $cnt_terminated); } # The childproc_minder process receives information about amavisd child # processes from an outer socket, forwarded there by a forwarding process. # Based on updates received, and based on its own processes sanity checks, # it maintains a state in memory of each amavisd child process. # # It must run on the same host as amavisd child processes in order to be # able to check for lost or crashed processes. # # It kills amavisd child processes which are active longer than $active_ttl # seconds, or are idling for more than $idle_ttl seconds. For killed or lost # processes it sends 'purged' messages to the inner socket, and periodically # sends a list of amavisd child process PIDs to the inner socket for the # benefit of more ephemeral clients. # sub childproc_minder() { do_log(5, "childproc-minder: zmq_init"); $zmq_ctx = zmq_init(1); $zmq_ctx or die "Can't create ZMQ context: $!"; do_log(5, "childproc-minder: creating outer ZMQ_SUB socket"); $outer_sock = zmq_socket($zmq_ctx, ZMQ_SUB); $outer_sock or die "Can't create outer ZMQ socket: $!"; do_log(5, "childproc-minder: zmq_setsockopt on outer socket"); zmq_setsockopt($outer_sock, ZMQ_LINGER, 2000) != -1 # milliseconds or die "zmq_setsockopt LINGER failed: $!"; my $outer_sock_ipv4only = 1; # a ZMQ default if (defined &ZMQ_IPV4ONLY && $outer_sock_specs =~ /:[0-9a-f]*:/i) { zmq_setsockopt($outer_sock, ZMQ_IPV4ONLY(), 0) != -1 or die "zmq_setsockopt failed: $!"; $outer_sock_ipv4only = 0; } zmq_setsockopt($outer_sock, ZMQ_SUBSCRIBE, 'am.st ') != -1 or die "zmq_setsockopt SUBSCRIBE failed: $!"; do_log(5, "childproc-minder: connecting to outer zmq socket %s%s", $outer_sock_specs, $outer_sock_ipv4only ? '' : ', IPv6 enabled'); zmq_connect($outer_sock, $outer_sock_specs) != -1 or die "zmq_connect to $outer_sock_specs failed: $!"; do_log(5, "childproc-minder: creating inner ZMQ_PUB socket"); $inner_sock = zmq_socket($zmq_ctx, ZMQ_PUB); $inner_sock or die "Can't create inner ZMQ socket: $!"; do_log(5, "childproc-minder: zmq_setsockopt on inner socket"); zmq_setsockopt($inner_sock, ZMQ_LINGER, 2000) != -1 # milliseconds or die "zmq_setsockopt LINGER failed: $!"; my $inner_sock_ipv4only = 1; # a ZMQ default if (defined &ZMQ_IPV4ONLY && $inner_sock_specs =~ /:[0-9a-f]*:/i) { zmq_setsockopt($inner_sock, ZMQ_IPV4ONLY(), 0) != -1 or die "zmq_setsockopt IPV4ONLY failed: $!"; $inner_sock_ipv4only = 0; } my $hwm = defined &ZMQ_SNDHWM ? ZMQ_SNDHWM() : defined &ZMQ_HWM ? ZMQ_HWM() : undef; if (defined $hwm) { zmq_setsockopt($inner_sock, $hwm, 100) != -1 or die "zmq_setsockopt HWM failed: $!"; } do_log(5, "childproc-minder: connecting to inner zmq socket %s%s", $inner_sock_specs, $inner_sock_ipv4only ? '' : ', IPv6 enabled'); zmq_connect($inner_sock, $inner_sock_specs) != -1 or die "zmq_connect to $inner_sock_specs failed: $!"; sleep 1; # a crude way to avoid a "slow joiner" syndrome #*** my $last_checked = 0; my $last_proclist_sent = 0; my %process_states; # associative array on pid do_log(5, "childproc-minder: sending FLUSH to inner zmq socket"); my $now = Time::HiRes::time; defined zmq_sendstr($inner_sock, sprintf('am.st %s %014.3f FLUSH', $$, $now)) or die "zmq_sendstr failed: $!"; do_log(5, "childproc-minder: entering event loop"); for (;;) { zmq_poll( [ { socket => $outer_sock, events => ZMQ_POLLIN, callback => sub { my($msgstr, $msgstr_l, $more); for (;;) { ($msgstr_l,$more) = zmq_recvstr($outer_sock,$msgstr); defined $msgstr_l or die "zmq_recvstr failed: $!"; do_log(5, "childproc-minder: got %s", $msgstr); process_message(\%process_states,\$msgstr); last if !$more; } }, }, ], 1 * $zmq_poll_units ) != -1 or die "zmq_poll failed: $!"; $now = Time::HiRes::time; if ($last_checked + 1 < $now && $last_proclist_sent + 2 < $now) { my($cnt_gone, $cnt_terminated) = check_proc(\%process_states); $last_checked = $now; my(@proc_idle_list, @proc_busy_list); my(@num_proc_busy_by_age, %num_proc_busy_by_activity); my $now = Time::HiRes::time; for my $pid (sort { $a <=> $b } keys %process_states) { my $p = $process_states{$pid}; my $s = $p->{state}; if ($p->{task_id} eq '' && $s =~ /^[. ]\z/s) { push(@proc_idle_list, $pid); } else { push(@proc_busy_list, $pid); $num_proc_busy_by_age[0]++; if (defined $p->{base_timestamp}) { my $age = $now - $p->{base_timestamp}; my $j = 1; for my $t (@age_slots) { if ($age >= $t) { $num_proc_busy_by_age[$j]++ } $j++; } } if ($s eq 'm' || $s eq 'd' || $s eq 'F') { $s = 'm' } elsif ($s eq 'D' || $s eq 'V' || $s eq 'S') { } else { $s = ' ' } $num_proc_busy_by_activity{$s}++; } } for my $j (0..@age_slots) { # age_slots start at 1, zero is extra send_gauge("ProcBusy$j", $num_proc_busy_by_age[$j] || 0, 1); } send_gauge('ProcBusyTransfer', $num_proc_busy_by_activity{'m'}||0, 1); send_gauge('ProcBusyDecode', $num_proc_busy_by_activity{'D'}||0, 1); send_gauge('ProcBusyVirus', $num_proc_busy_by_activity{'V'}||0, 1); send_gauge('ProcBusySpam', $num_proc_busy_by_activity{'S'}||0, 1); send_gauge('ProcBusyOther', $num_proc_busy_by_activity{' '}||0, 1); send_count('ProcGone', $cnt_gone, 1) if $cnt_gone; send_gauge('ProcAll', @proc_busy_list + @proc_idle_list, 1); send_gauge('ProcBusy', scalar @proc_busy_list, 1); send_gauge('ProcIdle', scalar @proc_idle_list, 0); # last chunk # must not mix different subscription prefixes # within the same multi-part message my $msg = 'am.proc.busy ' . join(' ',@proc_busy_list); do_log(5, "childproc-minder: sending %s", $msg); defined zmq_sendstr($inner_sock, $msg) or die "zmq_sendstr failed: $!"; $msg = 'am.proc.idle ' . join(' ',@proc_idle_list); do_log(5, "childproc-minder: sending %s", $msg); defined zmq_sendstr($inner_sock, $msg) or die "zmq_sendstr failed: $!"; $last_proclist_sent = $now; } } # forever # not reached } sub send_gauge($$;$) { my($name,$value,$more) = @_; defined zmq_sendstr($inner_sock, sprintf('am.nanny %s G32 %d', $name,$value), $more ? ZMQ_SNDMORE : 0) or die "zmq_sendstr (send_gauge $name) failed: $!"; } sub send_count($$;$) { my($name,$value,$more) = @_; defined zmq_sendstr($inner_sock, sprintf('am.nanny %s C32 %d', $name,$value), $more ? ZMQ_SNDMORE : 0) or die "zmq_sendstr (send_count $name) failed: $!"; } # snmp_responder listens to am.snmp and am.nanny messages reporting the # SNMP variable updates (as broadcast to the outer socket by a forwarding # process and child_minder), keeps evidence of a current value of each # SNMP variable, and also listens on a $snmp_sock_specs socket for queries # from amavisd-snmp-subagent-zmq, responding to each query by current values # of SNMP variables. # sub snmp_responder() { do_log(5, "snmp-responder: zmq_init"); $zmq_ctx = zmq_init(1); $zmq_ctx or die "Can't create ZMQ context: $!"; do_log(5, "snmp-responder: creating outer ZMQ_SUB socket"); $outer_sock = zmq_socket($zmq_ctx, ZMQ_SUB); $outer_sock or die "Can't create outer ZMQ socket: $!"; do_log(5, "snmp-responder: zmq_setsockopt on outer socket"); zmq_setsockopt($outer_sock, ZMQ_LINGER, 2000) != -1 # milliseconds or die "zmq_setsockopt LINGER failed: $!"; my $outer_sock_ipv4only = 1; # a ZMQ default if (defined &ZMQ_IPV4ONLY && $outer_sock_specs =~ /:[0-9a-f]*:/i) { zmq_setsockopt($outer_sock, ZMQ_IPV4ONLY(), 0) != -1 or die "zmq_setsockopt IPV4ONLY failed: $!"; $outer_sock_ipv4only = 0; } zmq_setsockopt($outer_sock, ZMQ_SUBSCRIBE, 'am.snmp ') != -1 or die "zmq_setsockopt SUBSCRIBE failed: $!"; zmq_setsockopt($outer_sock, ZMQ_SUBSCRIBE, 'am.nanny ') != -1 or die "zmq_setsockopt SUBSCRIBE failed: $!"; do_log(5, "snmp-responder: connecting to outer zmq socket %s%s", $outer_sock_specs, $outer_sock_ipv4only ? '' : ', IPv6 enabled'); zmq_connect($outer_sock, $outer_sock_specs) != -1 or die "zmq_connect to $outer_sock_specs failed: $!"; do_log(5, "snmp-responder: creating snmp ZMQ_REP socket"); $snmp_sock = zmq_socket($zmq_ctx, ZMQ_REP); $snmp_sock or die "Can't create ZMQ socket: $!"; do_log(5, "snmp-responder: zmq_setsockopt LINGER on snmp socket"); zmq_setsockopt($snmp_sock, ZMQ_LINGER, 2000) != -1 # milliseconds or die "zmq_setsockopt LINGER failed: $!"; my $snmp_sock_ipv4only = 1; # a ZMQ default if (defined &ZMQ_IPV4ONLY && $snmp_sock_specs =~ /:[0-9a-f]*:/i) { do_log(5, "snmp-responder: zmq_setsockopt IPV4ONLY on snmp socket"); zmq_setsockopt($snmp_sock, ZMQ_IPV4ONLY(), 0) != -1 or die "zmq_setsockopt IPV4ONLY failed: $!"; $snmp_sock_ipv4only = 0; } # my $hwm = defined &ZMQ_SNDHWM ? ZMQ_SNDHWM() # : defined &ZMQ_HWM ? ZMQ_HWM() : undef; # if (defined $hwm) { # do_log(5, "snmp-responder: zmq_setsockopt SNDHWM on snmp socket"); # zmq_setsockopt($inner_sock, $hwm, 2000) != -1 # or die "zmq_setsockopt HWM failed: $!"; # } do_log(5, "snmp-responder: binding to snmp zmq socket %s%s", $snmp_sock_specs, $snmp_sock_ipv4only ? '' : ', IPv6 enabled'); zmq_bind($snmp_sock, $snmp_sock_specs) != -1 or die "zmq_bind to $snmp_sock_specs failed: $!"; my(%snmp_var, %snmp_type); $snmp_var{'sysUpTime'} = int(time); # to be converted to TIM $snmp_type{'sysUpTime'} = 'INT'; $snmp_var{'sysObjectID'} = '1.3.6.1.4.1.15312.2'; $snmp_type{'sysObjectID'} = 'OID'; $snmp_var{'sysServices'} = 64; $snmp_type{'sysServices'} = 'INT'; do_log(5, "snmp-responder: entering event loop"); for (;;) { zmq_poll( [ { socket => $snmp_sock, events => ZMQ_POLLIN, callback => sub { # listen to queries # fetch a query of a form: "am.snmp?" or "am.nanny?" for (;;) { my($msgstr, $msgstr_l, $more); ($msgstr_l,$more) = zmq_recvstr($snmp_sock,$msgstr); defined $msgstr_l or die "zmq_recvstr failed: $!"; do_log(5, 'snmp-responder: %sgot "%s"', $more?'M':' ', $msgstr); if ($msgstr ne 'am.snmp?' && $msgstr ne 'am.nanny?') { do_log(2, 'snmp-responder: ignored "%s"', $msgstr); } else { my $chan = $msgstr; $chan =~ s/\?\z//; my $query_nanny = $chan eq 'am.nanny'; my $response; while (my($key,$val) = each(%snmp_var)) { next if $query_nanny ? $key !~ /^Proc/ : $key =~ /^Proc/; my $type = $snmp_type{$key}; if (!defined $val) { $type = $val = '?' } if (defined $response) { # previous do_log(2, 'snmp-responder: sending "%s"', $response); defined zmq_sendstr($snmp_sock,$response, ZMQ_SNDMORE) or die "zmq_sendstr failed: $!"; } $response = join(' ', $chan, $key, $type, $val); } if (defined $response) { defined zmq_sendstr($snmp_sock,$response) or die "zmq_sendstr failed: $!"; } } last if !$more; } }, }, { socket => $outer_sock, events => ZMQ_POLLIN, callback => sub { # listen to information updates for (;;) { my($msgstr, $msgstr_l, $more, $chan, $key, $type, $rest); ($msgstr_l,$more) = zmq_recvstr($outer_sock,$msgstr); defined $msgstr_l or die "zmq_recvstr failed: $!"; ($chan,$key,$type,$rest) = split(' ',$msgstr,4); if ($chan ne 'am.snmp' && $chan ne 'am.nanny') { do_log(5, "snmp_responder: ignored: %s", $msgstr); } elsif (!defined $key) { do_log(5, "snmp_responder: ignored, no key: %s", $msgstr); } elsif ($key eq 'FLUSH') { # amavisd cold start, flush SNMP variables do_log(0, "snmp_responder: FLUSH snmp data"); %snmp_var = (); %snmp_type = (); $snmp_var{'sysUpTime'} = int(time); # to be converted to TIM $snmp_type{'sysUpTime'} = 'INT'; $snmp_var{'sysObjectID'} = '1.3.6.1.4.1.15312.2'; $snmp_type{'sysObjectID'} = 'OID'; $snmp_var{'sysServices'} = 64; $snmp_type{'sysServices'} = 'INT'; } elsif (!$snmp_var{$key}) { $snmp_var{$key} = $rest; $snmp_type{$key} = $type; } elsif ($type =~ /^(C32|C64|TIM)\z/) { # a counter $snmp_var{$key} += $rest; } else { $snmp_var{$key} = $rest; # string, gauge, absolute value } last if !$more; } }, }, ], -1, # blocking (no timeout) ) != -1 or die "zmq_poll failed: $!"; } # not reached } # msg_forwarder forwards messages from inner ZMQ socket to outer ZMQ socket. # Binding (not connecting) to both sockets provides a single stable point # in the system. # # Amavisd child processes are dynamic and connect to the inner socket, # supplying information. Similarly the childproc_minder process occasionally # feeds its supplementaty information updates to this inner socket. # # Dynamic clients like amavisd-nanny, amavisd-snmp-subagent, amavisd-agent, # and a childproc_minder process connect to the outer socket to receive # information from there. # sub msg_forwarder() { do_log(5, "msg-forwarder: zmq_init"); $zmq_ctx = zmq_init(1); $zmq_ctx or die "Can't create a ZMQ context"; # receive from amavisd child processes do_log(5, "msg-forwarder: creating inner ZMQ_SUB socket"); $inner_sock = zmq_socket($zmq_ctx, ZMQ_SUB); $inner_sock or die "Error creating inner ZMQ_SUB socket: $!"; do_log(5, "msg-forwarder: zmq_setsockopt on inner socket"); zmq_setsockopt($inner_sock, ZMQ_LINGER, 2000) != -1 # milliseconds or die "zmq_setsockopt LINGER failed: $!"; my $inner_sock_ipv4only = 1; # a ZMQ default if (defined &ZMQ_IPV4ONLY && $inner_sock_specs =~ /:[0-9a-f]*:/i) { zmq_setsockopt($inner_sock, ZMQ_IPV4ONLY(), 0) != -1 or die "zmq_setsockopt IPV4ONLY failed: $!"; $inner_sock_ipv4only = 0; } zmq_setsockopt($inner_sock, ZMQ_SUBSCRIBE, '') != -1 or die "zmq_setsockopt SUBSCRIBE failed: $!"; # zmq_setsockopt($inner_sock, ZMQ_SUBSCRIBE, 'am.log.') != -1 # or die "zmq_setsockopt SUBSCRIBE failed: $!"; # zmq_setsockopt($inner_sock, ZMQ_SUBSCRIBE, 'am.proc.') != -1 # or die "zmq_setsockopt SUBSCRIBE failed: $!"; # zmq_setsockopt($inner_sock, ZMQ_SUBSCRIBE, 'am.st ') != -1 # or die "zmq_setsockopt SUBSCRIBE failed: $!"; # zmq_setsockopt($inner_sock, ZMQ_SUBSCRIBE, 'am.snmp ') != -1 # or die "zmq_setsockopt SUBSCRIBE failed: $!"; # zmq_setsockopt($inner_sock, ZMQ_SUBSCRIBE, 'am.nanny ') != -1 # or die "zmq_setsockopt SUBSCRIBE failed: $!"; do_log(5, "msg-forwarder: binding to inner zmq socket %s%s", $inner_sock_specs, $inner_sock_ipv4only ? '' : ', IPv6 enabled'); zmq_bind($inner_sock, $inner_sock_specs) != -1 or die "zmq_bind to $inner_sock_specs failed: $!"; # forward to a public outer socket # to clients like amavisd-nanny, amavisd-agent, amavisd-snmp-subagent do_log(5, "msg-forwarder: creating outer ZMQ_PUB socket"); $outer_sock = zmq_socket($zmq_ctx, ZMQ_PUB); $outer_sock or die "Error creating outer ZMQ_PUB socket: $!"; do_log(5, "msg-forwarder: zmq_setsockopt on outer socket"); zmq_setsockopt($outer_sock, ZMQ_LINGER, 2000) != -1 # milliseconds or die "zmq_setsockopt LINGER failed: $!"; my $outer_sock_ipv4only = 1; # a ZMQ default if (defined &ZMQ_IPV4ONLY && $outer_sock_specs =~ /:[0-9a-f]*:/i) { zmq_setsockopt($outer_sock, ZMQ_IPV4ONLY(), 0) != -1 or die "zmq_setsockopt IPV4ONLY failed: $!"; $outer_sock_ipv4only = 0; } do_log(5, "msg-forwarder: binding to outer zmq socket %s%s", $outer_sock_specs, $outer_sock_ipv4only ? '' : ', IPv6 enabled'); zmq_bind($outer_sock, $outer_sock_specs) != -1 or die "zmq_bind to $outer_sock_specs failed: $!"; # start forwarding # if (0) { if ($zmq_mod_name eq 'ZeroMQ' || $zmq_mod_name eq 'ZMQ::LibZMQ2') { do_log(5, "msg_forwarder: using a built-in zmq_device for forwarding"); zmq_device(ZMQ_FORWARDER, $inner_sock, $outer_sock); } else { # ZMQ_FORWARDER device is no longer available in 3.1 # 0MQ 3.2.1: zmq_device() deprecated and replaced by zmq_proxy() do_log(5, "msg_forwarder: start forwarding"); my $debug = $foreground && ll(5); if ($debug) { $| = 1; print "starting\n" } my $cnt = 0; for (;;) { # pass messages $cnt++; for (;;) { # pass one multi-part message my $zmsg = zmq_recvmsg($inner_sock); # a copy of a received msg obj $zmsg or die "zmq_recvmsg failed: $!"; my $more = zmq_getsockopt($inner_sock, ZMQ_RCVMORE); $more != -1 or die "zmq_getsockopt RCVMORE failed: $!"; # if ($debug && $zmsg) { # my $str = zmq_msg_data($zmsg); # copy and return as a perl scalar # printf("%s %s\n", $more?'M':' ', $str) if 1 || $str =~ /^am\.st /; # } # the zmq_sendmsg nullifies a message in a $zmsg object zmq_sendmsg($outer_sock, $zmsg, $more ? ZMQ_SNDMORE : 0) != -1 or die "zmq_sendmsg failed: $!"; zmq_msg_close($zmsg); # declares a msg obj as no longer required last if !$more; } if ($debug) { print '.'; printf(" %d\n", $cnt) if $cnt % 100 == 0; } } } # not reached } sub usage() { my $me = $0; local $1; $me =~ s{([^/]*)\z}{$1}s; "Usage: $me [-f] [-d log_level] (msg-forwarder|childproc-minder|snmp-responder)"; } # main program starts here my $normal_termination = 0; $SIG{'__DIE__' } = sub { if (!$^S) { my($m) = @_; chomp($m); do_log(-1,"_DIE: %s", $m) } }; $SIG{'__WARN__'} = sub { my($m) = @_; chomp($m); do_log(0,"_WARN: %s",$m) }; my $task_name; $foreground = 0; my(@argv) = @ARGV; # preserve @ARGV, may modify @argv while (@argv >= 2 && $argv[0] =~ /^-[d]\z/ || @argv >= 1 && $argv[0] =~ /^-/) { my($opt,$val); $opt = shift @argv; $val = shift @argv if $opt !~ /^-[hVf-]\z/; # these take no arguments if ($opt eq '--') { last; } elsif ($opt eq '-h') { # -h (help) printf STDERR ("%s\n\n%s\n", $myversion, usage()); } elsif ($opt eq '-V') { # -V (version) printf STDERR ("%s\n", $myversion); } elsif ($opt eq '-f') { $foreground = 1; } elsif ($opt eq '-d') { # -d log_level or -d SAdbg1,SAdbg2,..,SAdbg3 $val =~ /^\d+\z/ or die "Bad value for option -d: $val\n"; $log_level = untaint($val) if $val =~ /^\d+\z/; } else { printf STDERR ("Error in command line options: %s\n\n%s\n", $opt, usage()); exit 1; } } if (@argv == 1 && $argv[0] =~ /^(?:msg-forwarder|childproc-minder|snmp-responder)\z/) { $task_name = $argv[0]; } else { printf STDERR ("Error parsing a command line %s\n\n%s\n", join(' ',@ARGV), usage()); exit 1; } if (!$foreground) { openlog($syslog_ident, LOG_PID | LOG_NDELAY, $syslog_facility); $syslog_open = 1; } do_log(0, "%s task '%s' [%d] started. %s\n", $myversion, $task_name, $$, zmq_version()); eval { # catch TERM and INT signals for a controlled shutdown my $h = sub { $interrupted = $_[0]; die "\n" }; local $SIG{INT} = $h; local $SIG{TERM} = $h; if ($task_name eq 'msg-forwarder') { msg_forwarder(); } elsif ($task_name eq 'childproc-minder') { childproc_minder(); } elsif ($task_name eq 'snmp-responder') { snmp_responder(); } else { die "Unrecognized task name: $task_name"; } }; # until interrupted do_log(0, "Task '%s' [%d] shutting down", $task_name, $$); if ($inner_sock) { do_log(0, "%s closing inner socket", $task_name); zmq_setsockopt($inner_sock, ZMQ_LINGER, 0); # ignoring status zmq_close($inner_sock); # ignoring status } if ($outer_sock) { do_log(0, "%s closing outer socket", $task_name); zmq_setsockopt($outer_sock, ZMQ_LINGER, 0); # ignoring status zmq_close($outer_sock); # ignoring status } if ($snmp_sock) { do_log(0, "%s closing SNMP socket", $task_name); zmq_setsockopt($snmp_sock, ZMQ_LINGER, 0); # ignoring status zmq_close($snmp_sock); # ignoring status } if ($zmq_ctx) { do_log(0, "%s closing context", $task_name); zmq_term($zmq_ctx); # ignoring status } END { do_log(0, "Task '%s' [%d] exiting: %s", $task_name, $$, $interrupted) if !$normal_termination; if ($syslog_open) { closelog(); $syslog_open = 0 } }
Close