diff options
Diffstat (limited to 'FICS/network.c.orig')
-rw-r--r-- | FICS/network.c.orig | 657 |
1 files changed, 0 insertions, 657 deletions
diff --git a/FICS/network.c.orig b/FICS/network.c.orig deleted file mode 100644 index eed60c8..0000000 --- a/FICS/network.c.orig +++ /dev/null @@ -1,657 +0,0 @@ -/* network.c - * - */ - -#include "stdinclude.h" - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/telnet.h> - -#include "common.h" -#include "utils.h" -#include "playerdb.h" -#include "network.h" -#include "rmalloc.h" -#ifdef TIMESEAL -#include "timeseal.h" -#endif - -extern int errno; - -/* grimm */ -#if defined(SGI) -#else -/* -int send(int s, char *msg, int len, int flags); -int recv(int s, char *buf, int len, int flags); -char *memset(char *s, int c, int n); -int setsockopt( int s, int level, int optname, char *optval, int optlen); -int accept(int s, struct sockaddr *addr, size_t *addrlen); -void *memmove(void *dst0, const void *src0, register size_t length); -int bind(int s, struct sockaddr *name, int namelen); -int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout); -int listen(int s, int level); -*/ -#endif -/* added for warning */ - -PRIVATE int sockfd = 0; /* The socket */ -PRIVATE int numConnections = 0; -/* Sparse array */ -PUBLIC connection con[256]; - -PUBLIC int no_file; -PUBLIC int max_connections; - -/* Index == fd, for sparse array, quick lookups! wasted memory :( */ -PUBLIC int findConnection(int fd) -{ - if (con[fd].status == NETSTAT_EMPTY) - return -1; - else - return fd; -} - -PUBLIC int net_addConnection(int fd, unsigned int fromHost) -{ - int noblock = 1; - - if (findConnection(fd) >= 0) { - fprintf(stderr, "FICS: FD already in connection table!\n"); - return -1; - } - if (numConnections == max_connections) - return -1; - if (ioctl(fd, FIONBIO, &noblock) == -1) { - fprintf(stderr, "Error setting nonblocking mode errno=%d\n", errno); - } - con[fd].fd = fd; - if (fd != 0) - con[fd].outFd = fd; - else - con[fd].outFd = 1; - con[fd].fromHost = fromHost; - con[fd].status = NETSTAT_CONNECTED; -#ifdef TIMESEAL - con[fd].user[0]='\0'; - con[fd].sys[0]='\0'; - con[fd].timeseal = 0; - con[fd].time = 0; -#endif - con[fd].numPending = 0; - con[fd].processed = 0; - con[fd].outPos = 0; - if (con[fd].sndbuf == NULL) { -#ifdef DEBUG - fprintf(stderr, "FICS: nac(%d) allocating sndbuf.\n", fd); -#endif - con[fd].sndbufpos = 0; - con[fd].sndbufsize = MAX_STRING_LENGTH; - con[fd].sndbuf = rmalloc(MAX_STRING_LENGTH); - } else { -#ifdef DEBUG - fprintf(stderr, "FICS: nac(%d) reusing old sndbuf size %d pos %d.\n", fd, con[fd].sndbufsize, con[fd].sndbufpos); -#endif - } - con[fd].state = 0; - numConnections++; - -#ifdef DEBUG - fprintf(stderr, "FICS: fd: %d connections: %d descriptors: %d \n", fd, numConnections, getdtablesize()); /* sparky 3/13/95 */ -#endif - - return 0; -} - -PRIVATE int remConnection(int fd) -{ - int which; - if ((which = findConnection(fd)) < 0) { - return -1; - } - numConnections--; - con[fd].status = NETSTAT_EMPTY; - if (con[fd].sndbuf == NULL) { - fprintf(stderr, "FICS: remcon(%d) totally screwed, this shouldn't happen.\n", fd); - } else { - if (con[fd].sndbufsize > MAX_STRING_LENGTH) { - con[fd].sndbufsize = MAX_STRING_LENGTH; - con[fd].sndbuf = rrealloc(con[fd].sndbuf, MAX_STRING_LENGTH); - } - if (con[fd].sndbufpos) { /* didn't send everything, bummer */ - con[fd].sndbufpos = 0; - } - } - return 0; -} - -PRIVATE void net_flushme(int which) -{ - int sent; - - sent = send(con[which].outFd, con[which].sndbuf, con[which].sndbufpos, 0); - if (sent == -1) { - if (errno != EPIPE) /* EPIPE = they've disconnected */ - fprintf(stderr, "FICS: net_flushme(%d) couldn't send, errno=%d.\n", which, errno); - con[which].sndbufpos = 0; - } else { - con[which].sndbufpos -= sent; - if (con[which].sndbufpos) - memmove(con[which].sndbuf, con[which].sndbuf + sent, con[which].sndbufpos); - } - if (con[which].sndbufsize > MAX_STRING_LENGTH && con[which].sndbufpos < MAX_STRING_LENGTH) { - /* time to shrink the buffer */ - con[which].sndbuf = rrealloc(con[which].sndbuf, MAX_STRING_LENGTH); - con[which].sndbufsize = MAX_STRING_LENGTH; - } -} - -PRIVATE void net_flush_all_connections(void) -{ - int which; - fd_set writefds; - struct timeval to; - - FD_ZERO(&writefds); - for (which = 0; which < max_connections; which++) - if (con[which].status == NETSTAT_CONNECTED && con[which].sndbufpos) - FD_SET(con[which].outFd, &writefds); - - to.tv_usec = 0; - to.tv_sec = 0; - select(no_file, NULL, &writefds, NULL, &to); - for (which = 0; which < max_connections; which++) { - if (FD_ISSET(con[which].outFd, &writefds)) { - net_flushme(which); - } - } -} - -PRIVATE void net_flush_connection(int fd) -{ - int which; - fd_set writefds; - struct timeval to; - - if (((which = findConnection(fd)) >= 0) && (con[which].sndbufpos)) { - FD_ZERO(&writefds); - FD_SET(con[which].outFd, &writefds); - to.tv_usec = 0; - to.tv_sec = 0; - select(no_file, NULL, &writefds, NULL, &to); - if (FD_ISSET(con[which].outFd, &writefds)) { - net_flushme(which); - } - } - return; -} - -PRIVATE int sendme(int which, char *str, int len) -{ - int i, count; - fd_set writefds; - struct timeval to; - count = len; - - while ((i = ((con[which].sndbufsize - con[which].sndbufpos) < len) ? (con[which].sndbufsize - con[which].sndbufpos) : len) > 0) { - memmove(con[which].sndbuf + con[which].sndbufpos, str, i); - con[which].sndbufpos += i; - if (con[which].sndbufpos == con[which].sndbufsize) { - - FD_ZERO(&writefds); - FD_SET(con[which].outFd, &writefds); - to.tv_usec = 0; - to.tv_sec = 0; - select(no_file, NULL, &writefds, NULL, &to); - if (FD_ISSET(con[which].outFd, &writefds)) { - net_flushme(which); - } else { - /* time to grow the buffer */ - con[which].sndbufsize += MAX_STRING_LENGTH; - con[which].sndbuf = rrealloc(con[which].sndbuf, con[which].sndbufsize); - } - } - str += i; - len -= i; - } - return count; -} - -/* - * -1 for an error other than EWOULDBLOCK. - * Put <lf> after every <cr> and put \ at the end of overlength lines. - * Doesn't send anything unless the buffer fills, output waits until - * flushed -*/ -PUBLIC int net_send_string(int fd, char *str, int format) -{ - int which, i, j; - - if ((which = findConnection(fd)) < 0) { - return -1; - } - while (*str) { - for (i = 0; str[i] >= ' '; i++); - if (i) { - if (format && (i >= (j = LINE_WIDTH - con[which].outPos))) { /* word wrap */ - i = j; - while (i > 0 && str[i - 1] != ' ') - i--; - while (i > 0 && str[i - 1] == ' ') - i--; - if (i == 0) - i = j - 1; - sendme(which, str, i); - sendme(which, "\n\r\\ ", 6); - con[which].outPos = 4; - while (str[i] == ' ') /* eat the leading spaces after we wrap */ - i++; - } else { - sendme(which, str, i); - con[which].outPos += i; - } - str += i; - } else { /* non-printable stuff handled here */ - switch (*str) { - case '\t': - sendme(which, " ", 8 - (con[which].outPos & 7)); - con[which].outPos &= ~7; - if (con[which].outPos += 8 >= LINE_WIDTH) - con[which].outPos = 0; - break; - case '\n': - sendme(which, "\n\r", 2); - con[which].outPos = 0; - break; - case '\033': - con[which].outPos -= 3; - default: - sendme(which, str, 1); - } - str++; - } - } - return 0; -} - -/* if we get a complete line (something terminated by \n), copy it to com - and return 1. - if we don't get a complete line, but there is no error, return 0. - if some error, return -1. - */ -PUBLIC int readline2(char *com, int who) -{ - unsigned char *start, *s, *d; - int howmany, state, fd, pending; - - static unsigned char will_tm[] = {IAC, WILL, TELOPT_TM, '\0'}; - static unsigned char will_sga[] = {IAC, WILL, TELOPT_SGA, '\0'}; - static unsigned char ayt[] = "[Responding to AYT: Yes, I'm here.]\n"; - - state = con[who].state; - if ((state == 2) || (state > 4)) { - fprintf(stderr, "FICS: state screwed for con[%d], this is a bug.\n", who); - state = 0; - } - s = start = con[who].inBuf; - pending = con[who].numPending; - fd = con[who].fd; - - howmany = recv(fd, start + pending, MAX_STRING_LENGTH - 1 - pending, 0); - if (howmany == 0) /* error: they've disconnected */ - return (-1); - else if (howmany == -1) { - if (errno != EWOULDBLOCK) { /* some other error */ - return (-1); - } else if (con[who].processed) { /* nothing new and nothing old */ - return (0); - } else { /* nothing new, but some unprocessed old */ - howmany = 0; - } - } - if (con[who].processed) - s += pending; - else - howmany += pending; - d = s; - - for (; howmany-- > 0; s++) { - switch (state) { - case 0: /* Haven't skipped over any control chars or - telnet commands */ - if (*s == IAC) { - d = s; - state = 1; - } else if (*s == '\n') { - *s = '\0'; - strcpy(com, start); - if (howmany) - bcopy(s + 1, start, howmany); - con[who].state = 0; - con[who].numPending = howmany; - con[who].processed = 0; - con[who].outPos = 0; - return (1); - } else if ((*s > (0xff - 0x20)) || (*s < 0x20)) { - d = s; - state = 2; - } - break; - case 1: /* got telnet IAC */ - if (*s == IP) - return (-1); /* ^C = logout */ - else if (*s == DO) - state = 4; - else if ((*s == WILL) || (*s == DONT) || (*s == WONT)) - state = 3; /* this is cheesy, but we aren't using em */ - else if (*s == AYT) { - send(fd, (char *) ayt, strlen((char *) ayt), 0); - state = 2; - } else if (*s == EL) { /* erase line */ - d = start; - state = 2; - } else /* dunno what it is, so ignore it */ - state = 2; - break; - case 2: /* we've skipped over something, need to - shuffle processed chars down */ - if (*s == IAC) - state = 1; - else if (*s == '\n') { - *d = '\0'; - strcpy(com, start); - if (howmany) - memmove(start, s + 1, howmany); - con[who].state = 0; - con[who].numPending = howmany; - con[who].processed = 0; - con[who].outPos = 0; - return (1); - } else if (*s >= ' ') - *(d++) = *s; - break; - case 3: /* some telnet junk we're ignoring */ - state = 2; - break; - case 4: /* got IAC DO */ - if (*s == TELOPT_TM) - send(fd, (char *) will_tm, strlen((char *) will_tm), 0); - else if (*s == TELOPT_SGA) - send(fd, (char *) will_sga, strlen((char *) will_sga), 0); - state = 2; - break; - } - } - if (state == 0) - d = s; - else if (state == 2) - state = 0; - con[who].state = state; - con[who].numPending = d - start; - con[who].processed = 1; - if (con[who].numPending == MAX_STRING_LENGTH - 1) { /* buffer full */ - *d = '\0'; - strcpy(com, start); - con[who].state = 0; - con[who].numPending = 0; - con[who].processed = 0; - return (1); - } - return (0); -} - -/* -PRIVATE int readline(int who) -{ - int e, fd = con[who].fd; - char *t = con[who].inBuf; - int recvCount; - int totalCount = 0; - unsigned char c; - static unsigned char will_tm[] = {IAC, WILL, TELOPT_TM, '\0'}; - static unsigned char will_sga[] = {IAC, WILL, TELOPT_SGA, '\0'}; - - t += con[who].numPending; - - while ((recvCount = recv(fd, (char *) &c, 1, 0)) == 1) { - totalCount += recvCount; - if (c == IAC) { - recvCount = recv(fd, (char *) &c, 1, 0); - if (recvCount == 1) { - totalCount += recvCount; - switch (c) { - case IP: - c = '\3'; - break; - case DO: - recvCount = recv(fd, (char *) &c, 1, 0); - if (recvCount == 1) { - totalCount += recvCount; - if (c == TELOPT_TM) { - send(fd, (char *) will_tm, strlen((char *) will_tm), 0); - } else if (c == TELOPT_SGA) { - send(fd, (char *) will_sga, strlen((char *) will_sga), 0); - } - } - c = '\0'; - break; - case DONT: - recvCount = recv(fd, (char *) &c, 1, 0); - break; - c = '\0'; - default: - recvCount = recv(fd, (char *) &c, 1, 0); - c = '\0'; - break; - } - } - } - if (c != '\r' && c > 2) { - if (isprint(c) || (c == '\n')) { - *t++ = c; - con[who].numPending++; - } - } - if (c == '\n' || con[who].numPending >= MAX_STRING_LENGTH - 1) { - *--t = '\0'; - con[who].numPending = 0; - con[fd].outPos = 0; - return 1; - } - } - - *t = '\0'; - e = ((totalCount == 0) || (errno != EWOULDBLOCK)) ? -1 : 0; - return (e); -} -*/ - -PUBLIC int net_init(int port) -{ - int i; - int opt; - struct sockaddr_in serv_addr; - struct linger lingeropt; - - no_file = getdtablesize(); -/* Although we have 256 descriptors to work with for opening sockets, - * we can only use 126 maximum of them for some reason... built in - * limitation of the socket libs? Sparky 3/13/95 - */ - if (no_file > MAX_PLAYER + 10) - no_file = MAX_PLAYER + 10; - max_connections = no_file - 10; - for (i = 0; i < no_file; i++) { - con[i].status = NETSTAT_EMPTY; - con[i].sndbuf = NULL; - con[i].sndbufsize = con[i].sndbufpos = 0; - } - /* Open a TCP socket (an Internet stream socket). */ - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - fprintf(stderr, "FICS: can't open stream socket\n"); - return -1; - } - /* Bind our local address so that the client can send to us */ - memset((char *) &serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_port = htons(port); - - /** added in an attempt to allow rebinding to the port **/ - - opt = 1; - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)); - opt = 1; - setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt)); - lingeropt.l_onoff = 0; - lingeropt.l_linger = 0; - setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *) &lingeropt, sizeof(lingeropt)); - -/* -#ifdef DEBUG - opt = 1; - setsockopt(sockfd, SOL_SOCKET, SO_DEBUG, (char *)&opt, sizeof(opt)); -#endif -*/ - - if (bind(sockfd, (struct sockaddr *) & serv_addr, sizeof(serv_addr)) < 0) { - fprintf(stderr, "FICS: can't bind local address. errno=%d\n", errno); - return -1; - } - opt = 1; - ioctl(sockfd, FIONBIO, &opt); - listen(sockfd, 5); - return 0; -} - -PUBLIC void net_close(void) -{ - int i; - for (i = 0; i < no_file; i++) { - if (con[i].status != NETSTAT_EMPTY) - net_close_connection(con[i].fd); - } -} - -PUBLIC void net_close_connection(int fd) -{ - if (con[fd].status == NETSTAT_CONNECTED) - net_flush_connection(fd); - if (!remConnection(fd)) { - if (fd > 2) - close(fd); - } -} - -PUBLIC void turn_echo_on(int fd) -{ - static unsigned char wont_echo[] = {IAC, WONT, TELOPT_ECHO, '\0'}; - - send(fd, (char *) wont_echo, strlen((char *) wont_echo), 0); -} - -PUBLIC void turn_echo_off(int fd) -{ - static unsigned char will_echo[] = {IAC, WILL, TELOPT_ECHO, '\0'}; - - send(fd, (char *) will_echo, strlen((char *) will_echo), 0); -} - -PUBLIC unsigned int net_connected_host(int fd) -{ - int which; - - if ((which = findConnection(fd)) < 0) { - fprintf(stderr, "FICS: FD not in connection table!\n"); - return -1; - } - return con[which].fromHost; -} - -PUBLIC void ngc2(char *com, int timeout) -{ - struct sockaddr_in cli_addr; - size_t cli_len = sizeof(struct sockaddr_in); - - int fd, loop, nfound, lineComplete; - fd_set readfds; - struct timeval to; - - while ((fd = accept(sockfd, (struct sockaddr *) & cli_addr, &cli_len)) != -1) { - if (net_addConnection(fd, cli_addr.sin_addr.s_addr)) { - char *woo = -"FICS is currently full. Please try one of the following sites:\n\r\n\r" -"E-FICS: krypton.daimi.aau.dk 5000 (130.225.18.157 5000) Main EURO server\n\r" -"D-FICS: dds.hacktic.nl 5000 (193.78.33.69 5000) Dutch server\n\r" -"B-FICS: holly.csv.warwick.ac.uk 5000 (137.205.192.12 5000) British server\n\r" -"?-FICS: chess.unix-ag.uni-kl.de 5000 (131.246.89.3 5000) German server\n\r" -"M-FICS: wisdom.weizmann.ac.il 5000 (132.76.80.77 5000) Mid-east server\n\r\n\r"; - fprintf(stderr, "FICS is full. fd = %d\n"); - write (fd, woo, strlen(woo)); - sleep(1); - close(fd); - } else { -/* int opt, optlen; - - opt = 1024; - setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&opt, sizeof(opt)); - opt = 8192; - setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &opt, sizeof(opt)); - optlen = sizeof(opt); - getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&opt, &optlen); - fprintf(stderr, "%d sndbuf: %d", fd, opt); - optlen = sizeof(opt); - getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &optlen); - fprintf(stderr, " rcvbuf: %d\n", opt); -*/ - process_new_connection(fd, net_connected_host(fd)); - } - } - if (errno != EWOULDBLOCK) - fprintf(stderr, "FICS: Problem with accept(). errno=%d\n", errno); - - net_flush_all_connections(); - - FD_ZERO(&readfds); - for (loop = 0; loop < no_file; loop++) - if (con[loop].status != NETSTAT_EMPTY) - FD_SET(con[loop].fd, &readfds); - - to.tv_usec = 0; - to.tv_sec = timeout; - nfound = select(no_file, &readfds, NULL, NULL, &to); - for (loop = 0; loop < no_file; loop++) { - if (con[loop].status != NETSTAT_EMPTY) { - fd = con[loop].fd; - lineComplete = readline2(com, fd); - if (lineComplete == 0) /* partial line: do nothing with it */ - continue; - if (lineComplete > 0) { /* complete line: process it */ -#ifdef TIMESEAL - if (!(parseInput(com, &con[loop]))) continue; -#endif - if (process_input(fd, com) != COM_LOGOUT) { - net_flush_connection(fd); - continue; - } - } - /* Disconnect anyone who gets here */ - process_disconnection(fd); - net_close_connection(fd); - } - } -} - -PUBLIC int net_consize(void) -{ - int i, total; - - total = sizeof(con); - for (i=0; i < no_file; i++) - total += con[i].sndbufsize; - - return(total); -} |