The DejaVU Framework -- hush 3.0
[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?

source: csserverimp.c hush-3.0b4/auxiliary/net/cs


[.] - [up] [top] - index README make include source scripts configure
  // 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;
  }
  
  

[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?
Hush Online Technology
hush@cs.vu.nl
09/09/98