#!/usr/local/bin/perl -Tw
#-*- perl -*-
#--------------------------------------------------------------------
# SUFARY module Υѥ饤֥ꥵѥɲ
#--------------------------------------------------------------------
BEGIN{
    $LIB = '/home/tatuo-y/work/sufary/sufary192/perl/SUFARY';
    unshift(@INC, $LIB, "$LIB/blib/lib", "$LIB/blib/arch");
    $ENV{PATH} = '/usr/ucb:/bin';
}
#--------------------------------------------------------------------
# 
#--------------------------------------------------------------------
use SUFARY;
use Socket;
use Carp;
use FileHandle;
#--------------------------------------------------------------------
# եΥץ
#--------------------------------------------------------------------
STDOUT->autoflush();
#$suf = SUFARY->new("../../README");
$suf = SUFARY->new("/home/daiti-m/dep/ejd/ejdic");
#--------------------------------------------------------------------
# å
#--------------------------------------------------------------------
sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n"; }
#--------------------------------------------------------------------
# åȤ̿
#--------------------------------------------------------------------
sub SetupSocket {
    ($port) = @_;
    $port = 2345 unless $port;	# ǥեȤΥݡֹ


    my $proto = getprotobyname('tcp');
    # åȤ
    socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
    setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
	|| die "setsockopt: $!";
    # Х
    bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
    # դ
    listen(Server, SOMAXCONN);

    select(Server); $| = 1; select(STDOUT);  # Хåե
}
#--------------------------------------------------------------------
# ᥤץ
#--------------------------------------------------------------------
sub MainProcess {
    while (<Client>) {
	chomp $_;
	$key = $_;
	logmsg "($PNUM) REQ [$key]";
	my $nx = $suf->search($key);
	print Client "[$key] --- matched $nx\n";
	my $tmp = $suf->get_all_line;
	foreach (@$tmp) {
	    print Client "$_\n";
	}
	print Client "SUF_END_OF_RESULT\n";
    }
}
#--------------------------------------------------------------------
# Multi-Thread Manager
#--------------------------------------------------------------------
sub spawn {
    my $coderef = shift;
    unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
	confess "usage: spawn CODEREF";
    }
    my $pid;
    if (!defined ($pid = fork)) {
	logmsg "cannot fork: $!";
	return;
    } elsif ($pid) {
	logmsg "begat $pid";
	return;			# parent process
    }
    # child process
#    open(STDIN, "<&Client") || die "can't dup client to stdin";
#    open(STDOUT, ">&Client") || die "can't dup client to stdout";
#    STDOUT->autoflush();
    Client->autoflush();
    exit &$coderef();
}
#--------------------------------------------------------------------
# ᥤ롼
#--------------------------------------------------------------------
&SetupSocket;

my $waitedpid = 0;
my $addr;

logmsg "server started on port $port";

sub PEAPER {
    $waitedpid = wait;
    $SIG{CHLD} = \&PEAPER;
    logmsg "reaped $waitedpid" . ($? ? " with exit $?" : "");
}
$SIG{CHLD} = \&PEAPER;

for (; $addr = accept(Client, Server); close Client) {
    my ($port, $iaddr) = sockaddr_in($addr);
    my $name = gethostbyaddr($iaddr, AF_INET);

    $PNUM++;
    logmsg "($PNUM) connection from $name [", inet_ntoa($iaddr), "] at port $port";

    spawn \&MainProcess;
}
