--- /dev/null
+#include "scd_init_listener.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_in_connector.h"
+
+
+scd_init_listener::scd_init_listener(scd_simulator &sim, uint16_t port):
+ _sim(sim), _host(""), _port(port), _handler(false) {}
+
+
+scd_init_listener::scd_init_listener(scd_simulator &sim,
+ const std::string &host, uint16_t port):
+ _sim(sim), _host(host), _port(port), _handler(false) {}
+
+
+scd_init_listener::~scd_init_listener()
+{
+ cleanup(true);
+ close();
+}
+
+
+void scd_init_listener::listen()
+{
+ if (!_socket.is_valid())
+ {
+ // create listening socket
+ if (!_socket.create())
+ throw scd_exception("creating listening socket failed");
+ if (!_socket.bind(_host, _port))
+ throw scd_exception("binding listening socket failed");
+ if (!_socket.listen())
+ throw scd_exception("listening to socket failed");
+
+ // register socket
+ if (!_handler)
+ {
+ _sim.get_poller().register_handler(*this,
+ SOCK_EV_READ | SOCK_EV_CLOSE);
+ _handler = true;
+ }
+
+ scd_debug("socket listening");
+ }
+ else
+ scd_warn("socket is already listening");
+
+} // listen()
+
+
+void scd_init_listener::close()
+{
+ if (_handler)
+ {
+ _sim.get_poller().remove_handler(*this);
+ _handler = false;
+ }
+
+ if (_socket.is_valid())
+ {
+ _socket.close();
+ scd_debug("listener socket closed");
+ }
+
+} // close()
+
+
+void scd_init_listener::cleanup(bool hard)
+{
+ std::list<scd_in_connector*>::iterator iter;
+
+ for( iter=_connectors.begin(); iter!=_connectors.end();)
+ {
+ if ( hard || !(*iter)->is_connecting() )
+ {
+ delete *iter;
+ iter = _connectors.erase(iter);
+ }
+ else
+ iter++;
+ }
+} // cleanup()
+
+
+void scd_init_listener::handle_sock_ev(sock_ev events)
+{
+ if (events & SOCK_EV_READ)
+ {
+ scd_debug("incomming connection");
+
+ scd_socket* newconn = new scd_socket();
+
+ if (_socket.accept(*newconn))
+ {
+ /* create a new connector that handles the connection
+ * and store it in the list of connectors */
+ scd_in_connector* connector;
+ connector = new scd_in_connector(_sim, newconn);
+ _connectors.push_back(connector);
+ }
+ else
+ {
+ // connection could not be accepted
+ scd_debug("accepting connection failed");
+ delete newconn;
+ }
+ }
+
+ if (events & SOCK_EV_CLOSE)
+ {
+ throw scd_exception("init_listener: experienced an error");
+ }
+
+ if (!_socket.is_valid())
+ {
+ throw scd_exception("init_listener: unexpectedly closed");
+ }
+
+} // sock_ev_handler()
+
+
+const scd_socket& scd_init_listener::get_sock()
+{
+ return _socket;
+}