Проблема со скриптом perl

И всё прочее, что касается HTML
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
kharkov_max
капитан
Сообщения: 1862
Зарегистрирован: 2008-10-03 14:56:40

Проблема со скриптом perl

Непрочитанное сообщение kharkov_max » 2017-10-28 19:55:26

Добрый день.

Помогите разобраться.
Под систему мониторинга 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/sbin/${name}.pl лежит этот скрипт:

Код: Выделить всё

#!/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.
Не могу разобраться в чем проблема, возможно что то не добавлено в cpan.
IO::Socket,XML::Simple,use Text::Iconv,use Data::Dumper заинсталил ...

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/


Аватара пользователя
kharkov_max
капитан
Сообщения: 1862
Зарегистрирован: 2008-10-03 14:56:40

Проблема со скриптом perl

Непрочитанное сообщение kharkov_max » 2017-10-31 6:51:11

PYO, Спасибо, разобрался ...