######
#
# EASY-SERV.PL
# Copyright : Software Research Associates, Inc. 1990
# Written by Hiroshi Sakoh (
[email protected]) 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;