/* INet Socket Code by Johnson Earls version 1.0 created 9-Dec-90 changed by cknight version 1.1 [changed it to fit in with SpiderBot, also made it a linked-list implementation] 2-Mar-91 */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <ctype.h> #include <sys/time.h> #include "stringops.h" #include "socket.h" sockrec *socket_allocate(sockrec *s, long data) { sockrec *new; #ifdef FUNCTIONS puts ("**socket_allocate"); #endif new = allocate (sockrec); new->data = data; new->next = s; return new; } sockrec *socket_deallocate(sockrec *s, sockrec *d) { sockrec *list; #ifdef FUNCTIONS puts ("**socket_deallocate"); #endif if (s == d) { list = s->next; free (s); return list; } else { sockrec *temp; for (list = s; (list->next != s) && (list->next != NULL); list = list->next); if (list->next != NULL) { temp = list->next; list->next = temp->next; free (temp); } return s; } } int socket_connect(sockrec *s, char *name, int port) { struct hostent *host; struct sockaddr_in sin; unsigned char IPadr[4], lp, flag; char *p; #ifdef FUNCTIONS puts ("**socket_connect"); #endif if (isdigit(*(name))) { lp = flag = IPadr[0] = IPadr[1] = IPadr[2] = IPadr[3] = 0; p = name; while (*p) { if (*p == '.') if ((!flag) || (lp == 3)) return(ERR_SOCKBADADDR); else lp++; else if (isdigit(*p)) { IPadr[lp] = IPadr[lp] * 10 + (*p) - '0'; flag = 1; } else return(ERR_SOCKBADADDR); p++; } if (lp < 3) return(ERR_SOCKBADADDR); } else { host = gethostbyname(name); if (host == (struct hostent *)0) return(ERR_SOCKBADADDR); (void)bcopy(host->h_addr, IPadr, 4); } if ((s->sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return(ERR_SOCKCANTCREATE); sin.sin_family = AF_INET; sin.sin_port = htons(port); (void)bcopy(IPadr, (char *)&sin.sin_addr, 4); if (connect(s->sd, &sin, sizeof(struct sockaddr_in)) < 0) return(ERR_SOCKCANTCONNECT); return(0); } void socket_disconnect(sockrec *s) { #ifdef FUNCTIONS puts ("**socket_disconnect"); #endif close(*s); } int socket_read(sockrec *s, char **str) { char buf[65536]; /* longer than will be needed [hopefully] */ char *p, ch; int ret; #ifdef FUNCTIONS puts ("**socket_read"); #endif p = buf; while(1) { if ((ret=recv(s->sd, &ch, 1, 0)) < 0) return(ERR_SOCKERRREAD); else if (!ret) return(ERR_SOCKCLOSED); if (ch == '\n') break; if (ch != '\r') *(p++) = ch; } *p = '\0'; copystring (*str, buf); return(0); } int socket_write(sockrec *s, char *str) { char nl = '\n'; #ifdef FUNCTIONS puts ("**socket_write"); #endif if ((write(s->sd, str, strlen(str)) < 0) || (write(s->sd, &nl, 1))) return(ERR_SOCKERRWRITE); return(0); } int socket_write_noret(sockrec *s, char *str) { #ifdef FUNCTIONS puts ("**socket_write_noret"); #endif if ((write(s->sd, str, strlen(str)) < 0)) return(ERR_SOCKERRWRITE); return(0); } int socket_ready(sockrec *s) { #ifdef FUNCTIONS puts ("**socket_ready"); #endif return(socket_wait(s, 0L, 50L)); } int socket_wait(sockrec *s, long timeout, long utimeout) { struct timeval wait; fd_set readfds; #ifdef FUNCTIONS puts ("**socket_wait"); #endif wait.tv_sec = timeout; wait.tv_usec = utimeout; FD_ZERO(&readfds); FD_SET(s->sd, &readfds); if (timeout < 0) { if (select(FD_SETSIZE, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) return(ERR_SOCKSELECT); } else if (select(FD_SETSIZE, &readfds, (fd_set *)0, (fd_set *)0, &wait) < 0) return(ERR_SOCKSELECT); if (FD_ISSET(s->sd, &readfds)) return(1); return(0); } int socket_wait_kbd(sockrec *s, long timeout, long utimeout) { struct timeval wait; fd_set readfds; #ifdef FUNCTIONS puts ("**socket_wait_kbd"); #endif wait.tv_sec = timeout; wait.tv_usec = utimeout; FD_ZERO(&readfds); FD_SET(s->sd, &readfds); FD_SET(0, &readfds); if (timeout < 0) { if (select(FD_SETSIZE, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) return(ERR_SOCKSELECT); } else if (select(FD_SETSIZE, &readfds, (fd_set *)0, (fd_set *)0, &wait) < 0) return(ERR_SOCKSELECT); if (FD_ISSET(s->sd, &readfds)) return(1); if (FD_ISSET(0, &readfds)) return(2); return(0); }