Помогите разобраться.
Под систему мониторинга zabbix был содран, а потом подпилен скрипт на perl для рассылки sms.
Скрипт запускает слушателя на порту, а потом клиент из zabbix скармливает ему сообщение которое необходимо отправить через smstools3
Вот "оригинал" статьи https://www.ylsoftware.com/news/639
На одном серваке все работает как нужно, перенес скрипт на другой сервер и он не работает, при запуске ругается.
В rc.d лежит это:
Код: Выделить всё
# REQUIRE: NETWORKING SERVERS
# BEFORE: smsd
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable sysadmd:
#
# smsdpl_enable="YES"
#
# smsdpl_ip=""
# smsdpl_port=""
# smsdpl_user=""
# smsdpl_group=""
# smsdpl_log=""
# smsdpl_outdir=""
. /etc/rc.subr
name=smsdpl
rcvar=${name}_enable
start_cmd="smsdpl_start"
stop_cmd="smsdpl_stop"
load_rc_config $name
: ${smsdpl_enable:=NO}
: ${smsdpl_pidfile:="/var/run/smsd/smsdpl.pid"}
: ${smsdpl_ip:="192.168.1.9"}
: ${smsdpl_port:="32767"}
: ${smsdpl_user:="root"}
: ${smsdpl_group:="wheel"}
: ${smsdpl_log:="/var/log/smsd/send-smsd.log"}
: ${smsdpl_outdir:="/var/spool/sms/outgoing/"}
pidfile=${smsdpl_pidfile}
command_interpreter="/usr/local/bin/perl"
command="/usr/local/sbin/${name}.pl"
command_args="&"
smsdpl_start(){
echo "Starting smsdpl"
$command_interpreter $command ${smsdpl_ip} ${smsdpl_port} ${smsdpl_user} ${smsdpl_group} ${smsdpl_log} ${smsdpl_outdir} ${smsdpl_pidfile} $command_args
}
smsdpl_stop(){
echo "Stopping spsdpl"
/bin/kill -s HUP `/bin/cat $pidfile`
/bin/rm $pidfile
}
run_rc_command "$1"
Код: Выделить всё
#!/usr/local/bin/perl
use strict;
use warnings;
use diagnostics;
use POSIX;
use IO::Socket;
use XML::Simple;
use Text::Iconv;
use Data::Dumper;
# Права, с которыми будет работать скрипт
# Важно понимать что файлы он так же будет создавать с этими правами
# Так что эти настройки должны учитывать аналогичные настройки для smsd
my $settings = {
'user' => "root",
'group' => "wheel",
'port' => "32767",
'ipaddr' => "192.168.1.9",
'outgoing_dir' => '/var/spool/sms/outgoing/',
'logfile' => '/var/log/smsd/send-smsd.log',
};
# my $PIDFILE = '/var/run/smsd/smsdpl.pid';
my $PIDFILE = $ARGV[6];
# Резолвим идентификаторы пользователя и группы
# my $d_uid = getpwnam($settings->{'user'});
# my $d_gid = getgrnam($settings->{'group'});
my $d_uid = getpwnam($ARGV[2]);
my $d_gid = getgrnam($ARGV[3]);
# Урезаем права
setuid($d_uid);
setgid($d_gid);
# Создаём сокет
my $sock = new IO::Socket::INET (
LocalAddr => $ARGV[0],
LocalPort => $ARGV[1],
Proto => 'tcp',
Listen => 1,
Reuse => 1,
);
# Станем демоном
my $pid = fork ();
exit (0) if $pid;
die "Can't fork: $!" unless defined $pid;
setsid() or die "Can't start a new session: $!";
# Демон должен быть один
if (-s $PIDFILE) {
open (FILE, $PIDFILE) or die "Can't open $PIDFILE: $!";
chomp ($pid = <FILE>);
close (FILE);
if (kill (0, $pid)) {
die "Daemon already works";
}
}
open (FILE, "> $PIDFILE") or die "Can't open $PIDFILE: $!";
print FILE $$, "\n";
close (FILE);
# Обрабатываем входящие соединения
while (my $client = $sock->accept()) {
# IP-адрес клиента
my $client_ip = $client->peerhost;
# Считываем данные с клиента
my $xml_data = "";
while (<$client>) {
$xml_data .= $_;
}
# Пытаемся распарсить данные
eval {
my $data = XMLin($xml_data);
# Если данные указаны
if (defined($data->{'number'}) && defined($data->{'message'})) {
# Имя файла для записи SMS
my $uniq_name = time();
# my $sms_file_name = $settings->{'outgoing_dir'} . $uniq_name;
my $sms_file_name = $ARGV[5] . $uniq_name;
# Перекодируем сообщение
my $converter = Text::Iconv->new('UTF-8', 'UCS-2BE');
my $message = $converter->convert($data->{'message'});
# Извлекаем номер
my $number = $data->{'number'};
# Формируем SMS-сообщение
my $sms_data = "To: $number\nAlphabet: UCS2\n\n$message";
# Печатаем сообщение в файл
open SMSFILE, '>', $sms_file_name;
print SMSFILE $sms_data;
close SMSFILE;
# Формируем сообщение для записи в лог
my $logtime = strftime("%Y-%m-%d %H:%M:%S", localtime());
my $logline = "$logtime $client_ip $number $uniq_name\n";
# Пишем в лог
# open LOGFILE, '>>', $settings->{'logfile'};
open LOGFILE, '>>', $ARGV[4];
flock LOGFILE, 2;
print LOGFILE $logline;
close LOGFILE;
}
};
# Если произошла ошибка то не расстраиваемся
if (my $error = $@) {
}
}
# Закрываем сокет
close($sock);
Код: Выделить всё
# /usr/local/etc/rc.d/smsdpl start
Starting smsdpl
Can't call method "accept" on an undefined value at /usr/local/sbin/smsdpl.pl
line 79 (#1)
(F) You used the syntax of a method call, but the slot filled by the
object reference or package name contains an undefined value. Something
like this will reproduce the error:
$BADREF = undef;
process $BADREF 1,2,3;
$BADREF->process(1,2,3);
Uncaught exception from user code:
Can't call method "accept" on an undefined value at /usr/local/sbin/smsdpl.pl line 79.
IO::Socket,XML::Simple,use Text::Iconv,use Data::Dumper заинсталил ...