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