40 #include "EST_system.h"
41 #include "EST_socket.h"
45 #include "EST_ServiceTable.h"
46 #include "EST_Server.h"
47 #include "EST_Pathname.h"
48 #include "EST_error.h"
49 #include "EST_Token.h"
53 static EST_Regex ipnum(
"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+");
57 static EST_String command_term =
"\n//End//\n";
63 EST_Server::RequestHandler::RequestHandler()
67 EST_Server::RequestHandler::~RequestHandler()
71 EST_Server::ResultHandler::ResultHandler()
75 EST_Server::ResultHandler::~ResultHandler()
79 EST_Server::BufferedSocket::BufferedSocket(
int socket)
84 buffer=walloc(
char, 100);
87 EST_Server::BufferedSocket::~BufferedSocket()
96 void EST_Server::BufferedSocket::ensure(
int n)
100 buffer= wrealloc(buffer,
char, n+100);
105 int EST_Server::BufferedSocket::read_data(
void)
107 return ::read(s, buffer+bpos, blen-bpos);
114 initClient(name, type, trace);
116 initServer(mode, name, type, trace);
122 initClient(name, type, trace);
129 initClient(name, type, NULL);
131 initServer(mode, name, type, NULL);
137 initClient(name, type, NULL);
143 initClient(hostname, port, trace);
149 initClient(hostname, port, NULL);
158 if (p_buffered_socket)
159 delete p_buffered_socket;
162 void EST_Server::zero()
176 EST_error(
"no %s called '%s' listed",
177 (
const char *)type, (
const char *)name);
179 initClient(entry, trace);
186 tmp.
name=
"<UNKNOWN>";
198 initClient(tmp, trace);
201 void EST_Server::init(ostream *trace)
206 if (!socket_initialise())
207 EST_sys_error(
"Can't Initialise Network Code");
212 if (p_serv_addr != NULL)
226 struct sockaddr_in *serv_addr =
new sockaddr_in;
228 p_serv_addr = serv_addr;
229 struct hostent *serverhost;
231 memset(serv_addr, 0,
sizeof(*serv_addr));
236 *p_trace <<
"Using address "
240 serv_addr->sin_addr.s_addr = inet_addr(entry.
address);
245 *p_trace <<
"Using domain name "
249 serverhost = gethostbyname(entry.
hostname);
251 if (serverhost == (
struct hostent *)0)
252 EST_error(
"lookup of host '%s' failed", (
const char *)entry.
hostname);
254 memmove(&(serv_addr->sin_addr),serverhost->h_addr, serverhost->h_length);
258 *p_trace <<
"Server is at "
259 << inet_ntoa(serv_addr->sin_addr)
262 serv_addr->sin_family = AF_INET;
263 serv_addr->sin_port = htons(entry.
port);
272 int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
275 EST_sys_error(
"Can't create socket");
277 struct sockaddr_in serv_addr;
279 memset(&serv_addr, 0,
sizeof(serv_addr));
281 serv_addr.sin_family = AF_INET;
282 serv_addr.sin_port = htons(0);
283 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
286 if (bind(s, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) != 0)
287 EST_sys_error(
"bind failed");
289 if (listen(s, 5) != 0)
290 EST_sys_error(
"listen failed");
298 {
return p_entry.
name; }
301 {
return p_entry.
type; }
313 else if (p_entry.
address !=
"")
316 return "<UNKNOWN HOST>";
320 {
return p_entry.
port; }
325 EST_error(
"Already Connected");
328 EST_error(
"Connect is not a legal action on server end connections");
330 struct sockaddr_in *serv_addr = (
struct sockaddr_in *) p_serv_addr;
332 p_socket = socket(serv_addr->sin_family, SOCK_STREAM, IPPROTO_TCP);
334 if (NOT_A_SOCKET(p_socket))
335 return connect_system_error;
338 *p_trace <<
"Connect to "
339 << inet_ntoa(serv_addr->sin_addr)
341 << ntohs(serv_addr->sin_port)
344 if (::
connect(p_socket, (
struct sockaddr *)serv_addr,
sizeof(*serv_addr)) != 0)
351 #
if !defined(SYSTEM_IS_WIN32)
352 t_errno == ECONNREFUSED ||
356 return connect_not_allowed_error;
358 #
if !defined(SYSTEM_IS_WIN32)
359 t_errno == ENETUNREACH ||
360 t_errno == EADDRNOTAVAIL ||
364 return connect_not_found_error;
370 write(*p_buffered_socket,
"//"+p_entry.
cookie, cookie_term);
383 EST_error(
"Not Connected");
388 *p_trace <<
"Disconnect from "
392 *p_trace <<
"Close down service "
397 if (p_buffered_socket)
399 delete p_buffered_socket;
400 p_buffered_socket = NULL;
409 bool EST_Server::parse_command(
const EST_String command,
431 bool EST_Server::parse_result(
const EST_String resultString,
434 res.
set(
"STRING", resultString);
446 bool EST_Server::execute(
const EST_String package,
452 EST_String command = build_command(package, operation, args);
454 return execute(command, handler);
457 static int server_died;
458 static void server_died_fn(
int x)
485 #if !defined(SYSTEM_IS_WIN32)
486 void (*old)(int) = signal(SIGPIPE, server_died_fn);
490 if ((n=::write(s.s, data+p, l))>0)
493 *p_trace <<
"wrote " << n <<
" chars\n";
499 #if !defined(SYSTEM_IS_WIN32)
500 signal(SIGPIPE, old);
502 EST_sys_error(
"Failed while writing to %s", (
const char *)p_entry.
type);
505 #if !defined(SYSTEM_IS_WIN32)
506 signal(SIGPIPE, old);
510 EST_error(
"Failed while writing to %s", (
const char *)p_entry.
type);
521 while ((endpos=result.index(end, 0))<0 && 1==1)
523 int n=sock.read_data();
532 EST_sys_error(
"Failed to read from %s %d", (
const char *)p_entry.
type, errno);
537 *p_trace <<
"read " << n <<
" chars '" << bit <<
"'\n";
544 sock.ensure(result.length()-endpos);
547 (
const char *)result+endpos+end.
length(),
548 result.length()-endpos-end.
length());
550 sock.bpos=result.length()-endpos-end.
length();
552 result=result.at(0, endpos);
565 bool EST_Server::execute(
const EST_String command,
569 EST_error(
"Must connect to %s before calling execute.", (
const char *)p_entry.
type);
572 Result &res = handler.res;
575 *p_trace <<
"Sending command "
581 write(*p_buffered_socket, command, command_term);
585 EST_String result = read_data(*p_buffered_socket, result_term, eof);
588 res.set(
"ERROR",
"server closed connection");
589 handler.resString=result;
594 EST_String status = read_data(*p_buffered_socket, status_term, eof);
597 res.set(
"ERROR",
"server closed connection");
598 handler.resString=result;
604 if (status ==
"ERROR")
606 res.set(
"ERROR", result);
607 handler.resString=result;
611 else if (!parse_result(result, res))
613 res.set(
"ERROR",
"Server returned bad result '"+result+
"'");
614 handler.resString=result;
619 handler.resString=result;
627 EST_error(
"Server disconnected", (
const char *)p_entry.
type);
634 run_sequential(handler);
638 EST_error(
"Server type %d not yet implemented", (
int)p_mode);
647 struct sockaddr_in sin;
648 socklen_t sin_size =
sizeof(sin);
651 (csocket = accept(p_socket, (
struct sockaddr *) &sin,
655 *p_trace <<
"connection " << csocket <<
"\n";
657 BufferedSocket bs(csocket);
659 if (!check_cookie(bs))
665 handle_client(bs, handler);
669 *p_trace <<
"Client " << csocket <<
" disconnected\n";
672 EST_sys_error(
"error accepting connections");
675 bool EST_Server::check_cookie(BufferedSocket &socket)
682 EST_String cookie = read_data(socket, cookie_term, eof);
684 if (eof || cookie.
at(0, 2) !=
"//" || cookie.
after(0,2) != p_entry.
cookie)
686 EST_warning(
"Bad cookie '%s'", (
const char *)cookie.
after(0,2));
693 bool EST_Server::process_command(BufferedSocket &socket,
EST_String command, RequestHandler &handler)
695 handler.requestString=command;
697 if (!parse_command(command,
702 EST_warning(
"Bad Command '%s'", (
const char *)command);
708 if (error_message !=
"")
709 return_error(socket, error_message);
711 return_value(socket, handler.res, TRUE);
716 void EST_Server::handle_client(BufferedSocket &socket, RequestHandler &handler)
721 EST_String command=read_data(socket, command_term, eof);
727 *p_trace <<
"Got command " << command <<
"\n";
729 if (!process_command(socket, command, handler))
734 void EST_Server::return_error(BufferedSocket &socket,
EST_String err)
738 *p_trace <<
"error in processing: " << err <<
"\n";
739 write(socket, err, result_term);
740 write(socket,
"ERROR", status_term);
743 void EST_Server::return_value(BufferedSocket &socket, Result &res,
bool final)
748 *p_trace <<
"Result: " << resultString <<
"\n";
750 write(socket, resultString, result_term);
751 write(socket,
final?
"OK":
"VAL", status_term);