// csserverimp.cc include <net/cs/csserverimp.h> include <net/cs/csaddress.h> include <net/cs/dataconn.h> include <net/cs/listenconn.h> include <net/cs/cs.h> include <net/cs/samlib.h> include <stdio.h> include <string.h> include <sys/time.h> include <unistd.h> if defined(HUSH) include <hush/kit.h> //#include <hush/globe.h> // for kit, jrvosse endif const int maxclients = 32; //---------------------------- csserverimp implementation --------------------- csserverimp::csserverimp() { int i; _connected = 0; _clients = new (data_connection*)[maxclients]; if (_clients == NULL) { warn("csserverimp::csserverimp : couldn't allocate connection array"); } else { for (i = 0; i < maxclients; i++) _clients[i] = NULL; } _address = NULL; _listen = NULL; } int csserverimp::init_imp(csaddress* addr) { _address = addr; _listen = createlisten(_address); if (!_listen -> connected()) { warn("csserverimp::init_imp : couldn't create listen connection"); return -1; } if (_listen == NULL) { warn("csserverimp::init_imp : couldn't create listen connection"); return -1; } _connected = 1; return 0; } csserverimp::~csserverimp() { closeall_imp(); delete[] _clients; delete _listen; _connected = 0; _address = NULL; close(_listen -> fd()); } int csserverimp::connected_imp() const { return _connected; } void csserverimp::bind_imp(handler* h) const { if defined(HUSH) kit *tk = kit::_default; if (tk) tk-> bind(_listen -> fd(), h); else warn("csserverimp::bind_imp : no kit"); else warn("csserverimp::bind_imp : binding only supported in hush"); endif } void csserverimp::unbind_imp() const { if defined(HUSH) thekit() -> unbind(_listen -> fd()); else warn("csserverimp::bind_imp : binding only supported in hush"); endif } listen_connection* csserverimp::listenconn_imp() const { return _listen; } data_connection* csserverimp::conn_imp(int fd) const { int i; for (i = 0; i < maxclients; i++) { if ((_clients[i] != NULL) && (_clients[i] -> fd() == fd)) return _clients[i]; } // not found return NULL; } void csserverimp::closeall_imp() { int i; if (_clients == NULL) { warn("csserverimp::closeall_imp : _clients = NULL"); return; } for (i = 0; i < maxclients; i++) { if (_clients[i] != NULL) { delete _clients[i]; _clients[i] = NULL; } } } data_connection* csserverimp::checkconnections_imp() { int i; for (i = 0; i < maxclients; i++) { if ((_clients[i] != NULL) && (_clients[i] -> ready())) { return _clients[i]; } } return NULL; // on of the filedescriptors given by user has data, // so there's no connection to return } data_connection* csserverimp::select_imp(fd_set* fds) { fd_set readfds; int max_fd; int i; if (!_connected) { warn("csserverimp::select_imp : no listen connection present"); return NULL; } while (1) { // build fdset FD_ZERO(&readfds); if (fds != NULL) readfds = *fds; // very dangerous, but I know of no other way... FD_SET(_listen -> fd(), &readfds); max_fd = _listen -> fd(); for (i = 0; i < maxclients; i++) { if (_clients[i] != NULL) { int fd = _clients[i] -> fd(); if (fd >= 0) { FD_SET(fd, &readfds); if (fd > max_fd) max_fd = fd; } } } if (::select(max_fd + 1, &readfds, NULL, NULL, NULL) > 0) { if (_listen -> ready()) { newconnection_imp(); continue; } return checkconnections_imp(); } else { return NULL; // interrupted select, let calling program // figure out what to do } } } void csserverimp::close_imp(data_connection* conn) { int i; if (!_connected) { warn("csserverimp::close_imp : not connected"); return; } for (i = 0; i < maxclients; i++) { if ((_clients[i] != NULL) && (_clients[i] == conn)) close_imp(i); } } void csserverimp::close_imp(int clientnr) { if (cs_trace) printf("csserverimp::close_imp : closing client %d\n", clientnr); if ((clientnr < 0) || (clientnr >= maxclients) || (_clients[clientnr] == NULL)) { warn("csserverimp::close_imp : invalid clientnr %d", clientnr); return; } delete _clients[clientnr]; _clients[clientnr] = NULL; } int csserverimp::broadcast_imp(const char* buffer, int nrbytes) { int i; int result = 0; if (!_connected) { warn("csserverimp::broadcast_imp : not connected"); return -1; } for (i = 0; i < maxclients; i++) { if (_clients[i] != NULL) { int retval = write_imp(_clients[i], buffer, nrbytes); if (retval <= 0) result = retval; // it's possible _clients[i] is now removed, so check again if ((_clients[i] != NULL) && (!_clients[i] -> connected())) { write_to_log("csserverimp::broadcast_imp : deleting connection %d\n", i); delete _clients[i]; _clients[i] = NULL; } } } return result; } int csserverimp::broadcastmsg_imp(const char* buffer, int nrbytes) { int i; int result = 0; if (!_connected) { warn("csserverimp::broadcastmsg : not connected"); return -1; } for (i = 0; i < maxclients; i++) { if (_clients[i] != NULL) { int retval = writemsg_imp(_clients[i], buffer, nrbytes); if (retval <= 0) result = retval; // it's possible _clients[i] is now removed, so check again if ((_clients[i] != NULL) && (!_clients[i] -> connected())) { write_to_log("csserverimp::broadcast_imp : deleting connection %d\n", i); delete _clients[i]; _clients[i] = NULL; } } } return result; } data_connection* csserverimp::newconnection_imp() { data_connection* new_conn; int i; int newclient = -1; if (!_connected) { warn("csserverimp::newconnection_imp : not connected"); return NULL; } if (_clients == NULL) { warn("csserverimp::newconnection_imp : _clients = NULL"); return NULL; } for (i = 0; i < maxclients; i++) { if (_clients[i] == NULL) { newclient = i; break; } } if (newclient < 0) { warn("csserverimp::newconnection_imp : too many clients"); return NULL; } new_conn = _listen -> waitconnect(); if (new_conn == NULL) { warn("csserverimp::newconnection_imp : couldn't create new connection"); return NULL; } _clients[newclient] = new_conn; return new_conn; } int csserverimp::read_imp(data_connection* conn, char* buffer, int maxnrbytes) { int retval; if (conn == NULL) { warn("csserverimp::read_imp : conn = NULL"); return -1; } retval = conn -> read(buffer, maxnrbytes); // some clients may require to close the connection themselves, so don't // remove the connection here /* if (!conn -> connected()) close_imp(conn); */ return retval; } int csserverimp::readmsg_imp(data_connection* conn, char* buffer, int maxnrbytes) { int retval; if (conn == NULL) { warn("csserverimp::readmsg_imp : conn = NULL"); return -1; } retval = conn -> readmsg(buffer, maxnrbytes); // some clients may require to close the connection themselves, so don't // remove the connection here /* if (!conn -> connected()) close_imp(conn); */ return retval; } int csserverimp::write_imp(data_connection* conn, const char* buffer, int nrbytes) { int retval; if (conn == NULL) { warn("csserverimp::write_imp : conn = NULL"); return -1; } retval = conn -> write(buffer, nrbytes); // some clients may require to close the connection themselves, so don't // remove the connection here /* if (!conn -> connected()) close_imp(conn); */ return retval; } int csserverimp::writemsg_imp(data_connection* conn, const char* buffer, int nrbytes) { int retval; if (conn == NULL) { warn("csserverimp::writemsg_imp : conn = NULL"); return -1; } retval = conn -> writemsg(buffer, nrbytes); // some clients may require to close the connection themselves, so don't // remove the connection here /* if (!conn -> connected()) close_imp(conn); */ return retval; }
Hush Online Technology
hush@cs.vu.nl
09/09/98 |
![]() |
![]() |