devi@27: #!/usr/bin/perl
devi@27: 
devi@27: use strict;
igor@115: use lib '/etc/lilalo/';
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 = <PIDFILE>;
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)>(.*)</\1>@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@<l3cd>(.*?)</l3cd>@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."</$element_name>";
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: }