#!/usr/local/bin/jperl
################################################################
# pskkserv(perl4) version 4.0                         1996.12.18
#
# This software is placed in the public domain.
#
# pskkserv version 0.1                          1995.6.15
#         Written by Masaaki Sato <msatoh@mrit.mei.co.jp>
#               Matsushita Research Institute Tokyo, Inc. 
#                      Human Interface Research Laboratry
#                                     Tel    044-911-6351
#                                     Fax    044-911-8760
#
# pskkserv version 0.2                          1996.9.27
#  Modified by Mikio Nakajima <GY2M-NKJM@asahi-net.or.jp>
#   skk-server-version бǤƤʤäΤǡ
#   skkserv ȥץμ碌
#   ɽޥåѤʤȤѤĽ
#   ¾٤Ŭ
#
# pskkserv version 0.5	                         1996.10.16
#  Modified by Masaaki Sato
#   zombie process ޻ߡ
#   setsockopt ɲá
#   
#
# pskkserv version 4.0	                         1996.12.18
#  Modified by Masaaki Sato
#   -p ꤻ /etc/services  skkserv 
#     ܤʤϥǥեȤȤ 1178 ѡ
#   NOT FOUND ư skkserv ˹碌롣
#   deamon like ư˹碌롣
#	    thanks to @ʳز<ymmt@is.s.u-tokyo.ac.jp>
#   sys/socket.ph Фѡ
#     ʤSolaris ˤĤƤ㳰
#   ޥɤӤͤʸѹ
#	    thanks to <tokuya@crab.fuji-ric.co.jp>
################################################################

require "getopts.pl";
&Getopts('p:d');

$version="pskkserv-4.0 of 1996.12.18";

# check sys/socket.ph
$ph = 0;
foreach $dir (@INC){
	if (-r "$dir/sys/socket.ph"){
		$ph = 1;
		last;
	}
}

if ($ph == 1){
	require "sys/socket.ph";
	$AF_INET = &AF_INET;
	$SOCK_STREAM = &SOCK_STREAM;
	$SO_REUSEADDR = &SO_REUSEADDR;
}else{
	chop ($os_name = `uname -s`);
	chop ($os_version = `uname -r`);
 
	if ($os_name eq 'SunOS' && $os_version =~ /^5/) {
		$AF_INET = 2;
		$SOCK_STREAM = 2;
		$SO_REUSEADDR = 4;
	}else{
		$AF_INET = 2;
		$SOCK_STREAM = 1;
		$SO_REUSEADDR = 2;
	}
}

$port = "skkserv" unless $opt_p;
($dicname) = @ARGV;
$dicname = $ENV{'SKK_JISYO'} unless $dicname;
die "Usage: pskkserv [-p port] [-d] dic-file-name\n" unless $dicname;

$sockaddr = 'S n a4 x8';

($name, $aliases, $proto) = getprotobyname('tcp');

if ($port !~ /^\d+$/){
  ($name, $aliases, $port) = getservbyname($port, 'tcp');
  $port = 1178 unless defined $port;
}

$hostname=$ENV{"HOST"};
if ( $hostname ){
  ($hostname, $haliases, $haddrtype, $hlength,@haddr) = gethostbyname($hostname);
  ($a,$b,$c,$d)=unpack('C4',$haddr[0]);
  $hostaddr="$hostname:$a.$b.$c.$d:";
}

$local = pack($sockaddr, $AF_INET, $port, "\0\0\0\0");

if ($opt_d) {
  print "\npskkserv version ", substr($version, 9), " by msatoh@mrit.mei.co.jp\n";
  print "and GY2M-NKJM@asahi-net.or.jp\n\n";
  print "Host: ", $hostaddr, "\nPort: ", $port, "\nDic: ", $dicname, "\n\n";
}

select(NS); $| = 1; select(stdout);

socket(S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!";
setsockopt(S,$proto, $SO_REUSEADDR,1);
bind(S, $local) || die "bind: $!";
listen(S, 5) || die "listen: $!";

select(S); $| = 1; select(stdout);

dbmopen(%DIC,$dicname,0444);

unless ($opt_d){
  if ( fork() != 0 ){
  	exit;
  }
}

for ($con = 1;  ; $con++){
  printf("Listening for connection %d ...\n", $con) if $opt_d;
  ($addr = accept(NS, S)) || die $!;
  
  if (($mid = fork()) == 0){
   if (($child = fork()) == 0){
    print "accept OK\n" if $opt_d;
    ($af, $port, $inetaddr) = unpack($sockaddr, $addr);
    @inetaddr = unpack('C4', $inetaddr);
    print $con, ": ", $af, $port, @inetaddr, "\n" if $opt_d;
    
    while(read(NS, $command, 1) != 0){
      print "Command received: ", $command, " --\n" if $opt_d;
      if ($command eq '1'){
        $char="";
        $key="";
        while(read(NS, $char, 1) != 0){
          last if ($char eq " ");
          $key .= $char;
        }
        print "<<", $key, ">>\n" if $opt_d;
        $ans=$DIC{$key};
        if (defined($ans)){
            print "-- ", $ans, " --\n" if $opt_d;
            print NS "1", $ans, "\n";
          }else{
            print "-- Not found --\n" if $opt_d;
            print NS "4",$key,"\n";
          }
      }
      elsif ($command eq '2'){
        print NS $version, " ";
      }
      elsif ($command eq '3'){
        print NS $hostaddr, " ";
      }
      elsif ($command eq '0'){
        close(NS);
        exit;
      }
      else {
        print NS "0";
      }
    }
   }
   exit;
  }
  wait;
  close(NS);
}

dbmclose(%DIC);

