// socket.cpp #include "socket.h" Socket::Socket() { optval = 1; port = MUDPORT; backlog = SOCKET_CONNECTION_BACKLOG; fdmax = getdtablesize(); if(fdmax < 1) { sil_log::log("Socket: call to getdtablesize() failed"); fdmax = MAX_PROCESS_OPEN_DESCRIPTORS; } FD_ZERO(&fdset); start_time = time(NULL); } Socket::~Socket() { sil_log::log("Socket: closing down port %d", port); close(socket_fd); } BOOL Socket::initialize(INT listen_port) { port = listen_port; return initialize(); } BOOL Socket::initialize(void) { INT error = 0; socket_fd = socket(AF_INET, SOCK_STREAM, 0); // 0 stands for IP protocol if(socket_fd == -1) { sil_log::log("Socket: call to socket() failed"); return false; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); error = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); if(error == -1) { sil_log::log("Socket: call to setsockopt() failed"); return false; } error = bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)); if(error == -1) { sil_log::log("Socket: call to bind() failed"); return false; } error = listen(socket_fd, backlog); if(error == -1) { sil_log::log("Socket: call to listen() failed, make sure socket is free"); return false; } FD_SET(socket_fd, &fdset); return true; } const STRING Socket::get_uptime(void) { std::stringstream s; // this gives us number of seconds since driver start time_t now = time(NULL) - start_time; s << "Up: " << convert_time(now); return s.str(); } const INT Socket::open_connection(void) { INT temp_fd = 0; struct sockaddr_in sock; socklen_t socklen = sizeof(sock); temp_fd = accept(socket_fd, (struct sockaddr *)&sock, &socklen); if(temp_fd == -1) { sil_log::log("Socket: call to accept() failed"); return temp_fd; } FD_SET(temp_fd, &fdset); return temp_fd; } const INT Socket::open_connection(struct sockaddr_in *sock) { // this overrided function is for when we need to INT temp_fd = 0; socklen_t socklen = sizeof(struct sockaddr_in); temp_fd = accept(socket_fd, (struct sockaddr *)sock, &socklen); if(temp_fd == -1) { sil_log::log("Socket: call to accept() with sock failed"); return temp_fd; } FD_SET(temp_fd, &fdset); return temp_fd; } void Socket::close_connection(const INT& fd) { sil_log::log("Socket: request to close descriptor %d", fd); // make sure we don't accidentally close the server if(fd != socket_fd && FD_ISSET(fd, &fdset)) { FD_CLR(fd, &fdset); close(fd); } } const STRING Socket::convert_time(time_t tSeconds) { std::stringstream s; INT days = 0, hours = 0, minutes = 0; if(tSeconds > 86400) { // number of seconds in a day days = tSeconds / 86400; tSeconds %= 86400; s << days << (days > 1 ? " days, " : " day, "); } if(tSeconds > 3600) { // number of seconds in an hour hours = tSeconds / 3600; tSeconds %= 3600; s << hours << ( (hours > 1 || hours == 0) ? " hours, " : " hour, "); } if(tSeconds > 60) { // number of seconds in a minute minutes = tSeconds / 60; tSeconds %= 60; s << minutes << ( (minutes > 1 || minutes == 0) ? " minutes, " : " minute, "); } s << tSeconds << ( (tSeconds > 1 || tSeconds == 0) ? " seconds." : " second."); return s.str(); }