###### # # EASY-SERV.PL # Copyright : Software Research Associates, Inc. 1990 # Written by Hiroshi Sakoh (sakoh@sra.co.jp) on 11-01-90 # Please distribute widely, but leave my name here. # require "sys/fcntl.ph"; require "easy-ipc.pl"; # # ®ister_serv($name, $port) # # Registers a service port. # sub register_serv { &defserver($_[0], $_[1]); fcntl($_[0], &F_SETFL, &FNDELAY) || die "fcntl: $!\n"; $_eserv_generic{$_[0]} = $_[0]; # define generic socket $_eserv_sockets{$_[0]} = $_[0]; } # # ®ister_client($name, $host, $port) # # Registers a client port. # sub register_client { &defclient($_[0], $_[1], $_[2]); fcntl($_[0], &F_SETFL, &FNDELAY) || die "fcntl: $!\n"; $_eclient_sockets{$_[0]} = $_[0]; } # # &run_serv() # # Wait for a request, dispatch it. # Sends back a reply to the requester. # sub run_serv { local($bytestoread, $packet, $actualread, $request, $reply); local($bytestowrite, $actualwrite); local($try); local($MAXTRY) = 1000; for (;;) { @avails = &selectsock(keys(_eserv_sockets)); # wait for a request nextavail: for(@avails) { if (defined($_eserv_generic{$_})) { # got a request for connection &acceptsock($_eserv_newsock, $_); $_eserv_sockets{$_eserv_newsock} = $_eserv_newsock; } else { if (!eof($_)) { # got an usual request chop($bytestoread = <$_>); # The first packet should contain bytes to be read. for ( $request = "" ; $bytestoread > 0 ; $bytestoread -= $actualread) { for ($actualread = $try = 0; ($actualread == 0) && ($try < $MAXTRY); $try++) { $actualread = read($_, $packet, $bytestoread); } if ($actualread == 0) { print STDERR "Unexpected EOF\n"; close($_); delete $_eserv_sockets{$_}; next nextavail; } $request .= $packet; } $reply = &serv_body($request, $_); # I'd really like to use syswrite() below to # avoid to be blocked. But it doesn't work. Why?????? print $_ length($reply) . "\n"; for ($bytestowrite = length($reply) ; $bytestowrite > 0 ; $bytestowrite -= 1024) { print $_ substr($reply, 0, 1024); $reply = substr($reply, 1024); } } else { # got an eof message close($_); delete $_eserv_sockets{$_}; } } } } } # # &send_request($socket, $request) # # Sends a request to a server, waits a reply from the server # and returns it. # sub send_request { local($sock, $request) = @_; local($reply, $packet, $bytestoread, $actualread); local($bytestowrite); local($try); local($MAXTRY) = 1000; # I'd really like to use syswrite() below to # avoid to be blocked. But it doesn't work. Why?????? print $_ length($request) . "\n"; # write length of data for ($bytestowrite = length($request) # write data packets ; $bytestowrite > 0 ; $bytestowrite -= 1024) { print $sock substr($request, 0, 1024); $reply = substr($request, 1024); } chop($bytestoread = <$sock>); # The first packet should contain bytes to read. for ( $reply = "" ; $bytestoread > 0 ; $bytestoread -= $actualread) { for ($actualread = $try = 0; ($actualread == 0) && ($try < $MAXTRY); $try++) { $actualread = read($_, $packet, $bytestoread); } if ($actualread == 0) { print STDERR "Unexpected EOF\n"; close($sock); return ""; } $reply .= $packet; } $reply; } # # &cleanup_serv() # # Closes down all server sockets and exits. # sub cleanup_serv { for(keys(_eserv_sockets)) { close($_); } exit; } 1;