// client_socket.cpp #include "client_socket.h" ClientSocket::ClientSocket() { fd = -1; conn_state = Closed; prompt = false; compress = false; colorblind = false; logonTime = time(NULL); lastCommandTime = time(NULL); name = "Idle Login"; password = ""; hostname = ""; next_command = ""; if(pthread_mutex_init(&busy, NULL) != 0) { perror("ClientScoket::ClientSocket(): mutex initialization error"); exit(MUTEX_INIT_ERROR); } } ClientSocket::~ClientSocket() { fd = -1; conn_state = Closed; } BOOL ClientSocket::read_socket() { CHAR buffer[kMaxSocketInputBufferLength] = {0}; INT bytes_read = 0, total_read = 0; BOOL ret = false; bytes_read = read(fd, buffer, kMaxSocketInputBufferLength); total_read += bytes_read; while(bytes_read == kMaxSocketInputBufferLength) { sil_log::log("ClientSocket::read_socket(): read full buffer size"); if(this->lock()) { in_buffer += buffer; this->unlock(); } bytes_read = read(fd, buffer, kMaxSocketInputBufferLength); total_read += bytes_read; } if(total_read > 0) { if(this->lock()) { in_buffer += buffer; sil_log::log("in_buffer so far is '%s', strlen %d", in_buffer.c_str(), in_buffer.length()); // if we got a full command, re-prompt the user if(buffer[bytes_read - 1] == '\n'/* || buffer[bytes_read - 1] == '\r'*/) prompt = true; this->unlock(); ret = true; } else { // couldn't lock? sil_log::log("ClientSocket::read_socket(): failed to lock client %d's mutex", fd); ret = false; } } else if(bytes_read == 0) { sil_log::log("ClientSocket::read_socket(): read EOF from client %d", fd); ret = false; } else { // this happens sometimes when telnet window is closed sil_log::log("ClientSocket::read_socket(): Error reading from client %d", fd); ret = false; } return ret; } BOOL ClientSocket::write_socket() { if(out_buffer.empty() && !(prompt && conn_state == Playing)) return true; // TODO:this is going to have to change sometime if(prompt && conn_state == Playing) { out_buffer += "\r\nSILd:>"; prompt = false; } INT write_size = 0, written = 0; if(this->lock()) { // write data to socket for(INT i = 0; iunlock(); } else { // couldn't lock sil_log::log("ClientSocket::write_socket(): failed to lock client %d's mutex", fd); return false; } return true; } BOOL ClientSocket::lock() { BOOL success; if(pthread_mutex_lock(&busy) != 0) success = false; else success = true; return success; } BOOL ClientSocket::unlock() { BOOL success; if(pthread_mutex_unlock(&busy) != 0) success = false; else success = true; return success; } void ClientSocket::to_client(const STRING text) { if(this->lock()) { // lock ok out_buffer += text; this->unlock(); } } void ClientSocket::from_client(const STRING text) { if(this->lock()) { in_buffer += text; this->unlock(); } } BOOL ClientSocket::hasPublicIP() { if(hostname.empty()) return false; const char ipsep = '.'; INT quad1 = 0, quad2 = 0; char address[16] = {0}; strncpy(address, hostname.c_str(), 16); quad1 = atoi(strtok(address, &ipsep)); quad2 = atoi(strtok(NULL, &ipsep)); // weed out local loopback and private ip classes a, b, and c: 10.x.x.x, 172.(16-31).x.x, and 192.168.x.x if(hostname == "127.0.0.1" || (quad1 == 10 || (quad1 == 172 && (quad2 > 15 && quad2 < 32)) || (quad1 == 192 && quad2 == 168) ) ) return false; else return true; }