int ioctl ( int fd, int cmd, int flags ) /******************************************************************************/ { int retVal = -1; struct _reent tmp; if (is_fd_valid(&tmp, fd)) { int devop = fdTable[fd]; retVal = devlist[devoptab[devop].maj].ioctl(&devoptab[devop],cmd,flags); } return retVal; }
long _read ( int fd, void *buf, size_t cnt ) #endif /******************************************************************************/ { long retVal = -1; if (is_fd_valid(ptr, fd)) { int devop = fdTable[fd]; retVal = devlist[devoptab[devop].maj].read_r (ptr, &devoptab[devop], buf, cnt); } return retVal; }
int _close ( int fd ) #endif /******************************************************************************/ { int retVal = -1; if (fd > FD_STDERR) { /* Don't allow the stdio streams to be closed */ if (is_fd_valid(ptr, fd)) { int devop = fdTable[fd]; retVal = devlist[devoptab[devop].maj].close_r(ptr,&devoptab[devop]); if (!retVal) { fdTable[fd] = -1; } } } return retVal; }
/** * This checks the sockets for input and exceptions, does the right * thing. * * There are 2 lists we need to look through - init_sockets is a list */ void doeric_server() { int i, pollret, rr; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); player *pl, *next; #if CS_LOGSTATS if ((time(NULL) - cst_lst.time_start) >= CS_LOGTIME) { write_cs_stats(); } #endif FD_ZERO(&tmp_read); FD_ZERO(&tmp_write); FD_ZERO(&tmp_exceptions); for (i = 0; i < socket_info.allocated_sockets; i++) { if (init_sockets[i].status == Ns_Add && !is_fd_valid(init_sockets[i].fd)) { LOG(llevDebug, "doeric_server(): Invalid waiting fd %d\n", i); init_sockets[i].status = Ns_Dead; } if (init_sockets[i].status == Ns_Dead) { FREE_SOCKET(i); } else if (init_sockets[i].status == Ns_Zombie) { if (init_sockets[i].login_count++ >= 1000000 / MAX_TIME) { init_sockets[i].status = Ns_Dead; } } else if (init_sockets[i].status != Ns_Avail) { if (init_sockets[i].status > Ns_Wait) { /* Kill this socket after being 3 minutes idle */ if (init_sockets[i].login_count++ >= 60 * 4 * (1000000 / MAX_TIME)) { FREE_SOCKET(i); continue; } } FD_SET((uint32) init_sockets[i].fd, &tmp_read); FD_SET((uint32) init_sockets[i].fd, &tmp_write); FD_SET((uint32) init_sockets[i].fd, &tmp_exceptions); } } /* Go through the players. Let the loop set the next pl value, since * we may remove some. */ for (pl = first_player; pl != NULL; ) { if (pl->socket.status != Ns_Dead && !is_fd_valid(pl->socket.fd)) { LOG(llevDebug, "doeric_server(): Invalid file descriptor for player %s [%s]: %d\n", (pl->ob && pl->ob->name) ? pl->ob->name : "(unnamed player?)", (pl->socket.host) ? pl->socket.host : "(unknown ip?)", pl->socket.fd); pl->socket.status = Ns_Dead; } if (pl->socket.status == Ns_Dead) { player *npl = pl->next; remove_ns_dead_player(pl); pl = npl; } else if (pl->socket.status == Ns_Zombie) { if (pl->socket.login_count++ >= 1000000 / MAX_TIME) { pl->socket.status = Ns_Dead; } } else { FD_SET((uint32) pl->socket.fd, &tmp_read); FD_SET((uint32) pl->socket.fd, &tmp_write); FD_SET((uint32) pl->socket.fd, &tmp_exceptions); pl = pl->next; } } socket_info.timeout.tv_sec = 0; socket_info.timeout.tv_usec = 0; pollret = select(socket_info.max_filedescriptor, &tmp_read, &tmp_write, &tmp_exceptions, &socket_info.timeout); if (pollret == -1) { LOG(llevDebug, "DEBUG: doeric_server(): select failed: %s\n", strerror_local(errno)); return; } /* Following adds a new connection */ if (pollret && FD_ISSET(init_sockets[0].fd, &tmp_read)) { int newsocknum = 0; /* If this is the case, all sockets are currently in use */ if (socket_info.allocated_sockets <= socket_info.nconns) { init_sockets = realloc(init_sockets, sizeof(socket_struct) * (socket_info.nconns + 1)); if (!init_sockets) { LOG(llevError, "ERROR: doeric_server(): Out of memory\n"); } newsocknum = socket_info.allocated_sockets; socket_info.allocated_sockets++; init_sockets[newsocknum].status = Ns_Avail; } else { int j; for (j = 1; j < socket_info.allocated_sockets; j++) { if (init_sockets[j].status == Ns_Avail) { newsocknum = j; break; } } } init_sockets[newsocknum].fd = accept(init_sockets[0].fd, (struct sockaddr *) &addr, &addrlen); if (init_sockets[newsocknum].fd == -1) { LOG(llevDebug, "doeric_server(): accept failed: %s\n", strerror_local(errno)); } else { char buf[MAX_BUF]; long ip = ntohl(addr.sin_addr.s_addr); snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld", (ip >> 24) & 255, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); if (checkbanned(NULL, buf)) { LOG(llevInfo, "BAN: Banned IP tried to connect. [%s]\n", buf); #ifndef WIN32 close(init_sockets[newsocknum].fd); #else shutdown(init_sockets[newsocknum].fd, SD_BOTH); closesocket(init_sockets[newsocknum].fd); #endif init_sockets[newsocknum].fd = -1; } else { init_connection(&init_sockets[newsocknum], buf); socket_info.nconns++; } } }