#!/usr/bin/perl use strict; use lib '.'; use l3config; use IO::Socket; use POSIX qw(:sys_wait_h); sub main; main(); sub REAPER { 1 until (-1 == waitpid(-1, WNOHANG)); $SIG{CHLD} = \&REAPER; } sub process_was_killed { # Здесь должна быть красивая процедура # завершения демона unlink $Config{backend_pidfile}; exit(0); } sub main { init_config(); # Проверяем, возможно демон уже запущен # Если он работает, просто завершаемся if (open(PIDFILE, $Config{backend_pidfile})) { my $pid = ; close(PIDFILE); if ( ! -e "/proc/$pid" || !`grep $Config{"l3-backend"} /proc/$pid/cmdline && grep "uid:.*\b$<\b" /proc/$pid/status`) { print "Removing stale pidfile\n"; unlink $Config{backend_pidfile} or die "Can't remove stale pidfile ". $Config{backend_pidfile}. " : $!"; } else { print "l3-backend is already running\n"; exit(0); } } # Уходим в background, если необходимо if ($Config{detach} =~ /^y/i) { #$Config{verbose} = "no"; my $pid = fork; exit if $pid; die "Couldn't fork: $!" unless defined ($pid); open(PIDFILE, ">", $Config{backend_pidfile}) or die "Can't open pidfile ". $Config{backend_pidfile}. " for wrting: $!"; print PIDFILE $$; close(PIDFILE); for my $handle (*STDIN, *STDOUT, *STDERR) { open ($handle, "+<", "/dev/null") or die "can't reopen $handle to /dev/null: $!" } POSIX::setsid() or die "Can't start a new session: $!"; $0 = $Config{"l3-backend"}; $SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&process_was_killed; } # Открываем сетевой сокет и слушаем my $server = IO::Socket::INET->new( LocalPort => $Config{backend_port}, Type => SOCK_STREAM, Reuse => 1, Listen => 10 ); if (!$server) { die "Couldn't bind to socket ".$Config{backend_port}."\n"; } $SIG{CHLD} = 'IGNORE'; # При получении новых соединенений, # порождаем дочерние процессы while (my $client = $server->accept()) { my $pid; next if $pid = fork; die "fork: $!" unless defined $pid; # Это наш ответвлённый клиент close($server); my $saved_data = ""; # Считываем данные и передаём их в точку получения open(OUT, ">>", $Config{"backend_datafile"}); select OUT; $|=1; while(<$client>) { print OUT $_; $saved_data .= $_; } close(OUT); #open(LOG, ">>", "/tmp/l3-backend.log"); #print LOG "Saved data:$saved_data\n"; #close(LOG); while ($saved_data =~ m@<(session|command)>(.*)@sg) { #open(LOG, ">>", "/tmp/l3-backend.log"); #print LOG "Found element $1\n"; #close(LOG); my $element_name = $1; my $element = $2; if ($element =~ m@(.*?)@msg) { # Обнаружен элемент l3cd # Информация должна быть сохранена в соответствующий каталог my $l3cd = $1; # Путь l3cd должен быть не пуст, # и в нём могут быть только символы латинского алфавита, цифры и знаки _ и - if ($l3cd && $l3cd =~ /^[a-zA-Z_\/0-9-]*/) { system("mkdir -p $Config{backend_datadir}/$l3cd"); if (open(OUT, ">>", $Config{"backend_datadir"}."/$l3cd/data.xml")) { print OUT "<$element_name>".$element.""; close(OUT); }; } } } } continue { # Наш родитель close ($client); } }