Страница 1 из 1

Демон на перл не содает файл

Добавлено: 2015-07-30 16:50:45
kharkov_max
День добрый

По данной статье https://www.ylsoftware.com/news/639
Создал демон на перл для формирования файла для демона smsd на отправку sms сообщений.
Сам скрипт немного модифицировал под себя.

После обновлления perl до perl5.20 что то перестало работать, не могу разобраться что, прошу помощи.
Сам демон запускается и слушает порт, но по итогу отработки скрипта файл в нужном каталоге не появляется ...
И ошибок ни каких ...

Вот сами скрипты:
rc.d для запуска smsdpl

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

#!/bin/sh

# PROVIDE: smsdpl
# 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:="127.0.0.1"}
: ${smsdpl_port:="32767"}
: ${smsdpl_user:="smsd"}
: ${smsdpl_group:="dialer"}
: ${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"
Сам демон smsdpl.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' => "smsd",
    'group' => "dialer",
    'port' => "32767",
    'ipaddr' => "192.168.10.250",
    '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 => $settings->{'ipaddr'},
#    LocalPort => $settings->{'port'},
#    Proto => 'tcp',
#    Listen => 1,
#    Reuse => 1,
#);

# Создаём сокет
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);
И скрипт который кидает данные на порт send-smsd.pl:

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

#!/usr/local/bin/perl

use strict;
use warnings;
use diagnostics;

use IO::Socket;
use XML::Simple;

use Data::Dumper;

# Настройки
my $settings = {
    'host' => '192.168.10.250',
    'port' => 32767,
};

# Если количество аргументов не равняется трём:
exit 1 if @ARGV != 3;

# Извлекаем данные
my $number = shift @ARGV;
my $subject = shift @ARGV;
my $body = shift @ARGV;

# Создаём структуру данных
my $data = {
    'number' => $number,
    'message' => $body,
};

# Создаём строку данных
my $data_line = XMLout(
    $data,
    'RootName' => 'xml',
    'NoAttr' => 1
);

# Создаём сокет
my $sock = new IO::Socket::INET (
    PeerAddr => $settings->{'host'},
    PeerPort => $settings->{'port'},
    Proto => 'tcp',
);

# Пишем строку данных в сокет
print $sock $data_line;

# Закрываем сокет
close $sock;

Демон на перл не содает файл

Добавлено: 2015-07-31 15:23:26
kharkov_max
Сделал portupgrade -f 'p5-*' и все заработало.
Видимо нужно было все модули после обновления perl пересобрать ...