/* This is mostly emulation of socklib.c from xpilot used by koules before. * It was removed because of copyright problems. Current implementation is * completly rewrote just partially compatible with socklib API. It implements * just few calls used by koules and in a bit different way. It is not drop-in * replacement for socklib. */ #if defined(__sparc) #define __EXTENSIONS__ #endif #include #include #include #include #if (SVR4) #include #endif #ifdef __hpux #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #if defined(__sparc) #include #endif #if defined(__sun__) #include #include #endif #include "sock.h" static struct timeval timeout; static struct sockaddr_in lastaddr; void SetTimeout(int s,int us) { timeout.tv_sec=s; timeout.tv_usec=us; } int GetPortNum(int fd) { struct sockaddr_in a; int s=sizeof(a); if(getsockname(fd,(struct sockaddr *)&a,&s)<0) return -1; return(ntohs(a.sin_port)); } char *GetSockAddr(int fd) { struct sockaddr_in a; int s=sizeof(a); if(getsockname(fd,(struct sockaddr *)&a,&s)<0) return NULL; return(inet_ntoa(a.sin_addr)); } int SetSocketReceiveBufferSize(int fd,int size) { return(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&size, sizeof(size))); } int SetSocketSendBufferSize(int fd,int size) { return(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size))); } int SetSocketNonBlocking (int fd, int flag) { /* * This code is copied from original socklib library. I hope it is not * problem... I want to avoid compilation problems on some systems... * * There are some problems on some particular systems (suns) with * getting sockets to be non-blocking. Just try all possible ways * until one of them succeeds. Please keep us informed by e-mail * to xpilot@cs.uit.no. */ #ifndef USE_FCNTL_O_NONBLOCK #ifndef USE_FCNTL_O_NDELAY #ifndef USE_FCNTL_FNDELAY #ifndef USE_IOCTL_FIONBIO #if defined(_SEQUENT_) || defined(__svr4__) || defined(SVR4) #define USE_FCNTL_O_NDELAY #elif defined(__sun__) && defined(FNDELAY) #define USE_FCNTL_FNDELAY #elif defined(FIONBIO) #define USE_IOCTL_FIONBIO #elif defined(FNDELAY) #define USE_FCNTL_FNDELAY #elif defined(O_NONBLOCK) #define USE_FCNTL_O_NONBLOCK #else #define USE_FCNTL_O_NDELAY #endif #endif #endif #endif #endif #ifdef USE_FCNTL_FNDELAY if (fcntl (fd, F_SETFL, (flag != 0) ? FNDELAY : 0) != -1) return 0; fprintf (stderr, "fcntl FNDELAY failed in file \"%s\", line %d: %s\n", __FILE__, __LINE__, strerror (errno)); #endif #ifdef USE_IOCTL_FIONBIO if (ioctl (fd, FIONBIO, &flag) != -1) return 0; fprintf (stderr, "ioctl FIONBIO failed in file \"%s\", line %d: %s\n", __FILE__, __LINE__, strerror (errno)); #endif #ifdef USE_FCNTL_O_NONBLOCK if (fcntl (fd, F_SETFL, (flag != 0) ? O_NONBLOCK : 0) != -1) return 0; fprintf (stderr, "fcntl O_NONBLOCK failed in file \"%s\", line %d: %s\n", __FILE__, __LINE__, strerror (errno)); #endif #ifdef USE_FCNTL_O_NDELAY if (fcntl (fd, F_SETFL, (flag != 0) ? O_NDELAY : 0) != -1) return 0; fprintf (stderr, "fcntl O_NDELAY failed in file \"%s\", line %d: %s\n", __FILE__, __LINE__, strerror (errno)); #endif return (-1); } int GetSocketError(int fd) { int size=sizeof(errno); return (getsockopt(fd,SOL_SOCKET,SO_ERROR,(char *)&errno,&size)); } int SocketReadable(int fd) { fd_set fds; FD_ZERO(&fds); FD_SET(fd,&fds); if (select (fd + 1, &fds, NULL, NULL, &timeout) == -1) return ((errno == EINTR) ? 0 : -1); return(FD_ISSET(fd,&fds)); } int CreateDgramSocket(int port) { struct sockaddr_in addr; int fd; fd=socket(AF_INET, SOCK_DGRAM, 0); if (fd<0) return -1; memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr=INADDR_ANY; addr.sin_port=htons(port); addr.sin_family=AF_INET; if(bind(fd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0) { fd=errno; close(fd); errno=fd; return -1; } return fd; } int DgramConnect(int fd, char *host, int port) { struct sockaddr_in addr; memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr = inet_addr (host); if(addr.sin_addr.s_addr==-1) return -1; addr.sin_family = AF_INET; addr.sin_port = htons (port); return(connect (fd, (struct sockaddr *) &addr, sizeof (addr))); } int DgramSend(int fd, char *host, int port, char *sbuf, int size) { struct sockaddr_in addr; struct hostent *hp; #if 0 if (!rand()%10) return 0;/*Internet emulation :))))))) */ if (rand()%2) {size=rand()%size;} #endif memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr = inet_addr (host); if(addr.sin_addr.s_addr==-1) { if (addr.sin_addr.s_addr == (int) -1) { hp = gethostbyname (host); if (hp == NULL) { fprintf(stderr,"Host '%s' unknown\n",host); return -1; } else addr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr; } } addr.sin_family = AF_INET; addr.sin_port = htons (port); return(sendto (fd, sbuf, size, 0, (struct sockaddr *) &addr, sizeof (struct sockaddr_in))); } int DgramReceiveAny(int fd,char *buf, int size) { int len=sizeof (struct sockaddr_in); return(recvfrom (fd, buf, size, 0, (struct sockaddr *) &lastaddr, &len)); } int DgramReceiveConnected(int fd,char *buf, int size) { return(recv (fd, buf, size, 0)); } int SocketClose (int fd) { shutdown (fd, 2); if (close (fd) == -1) { return (-1); } return (1); } char *DgramLastaddr (void) { return (inet_ntoa (lastaddr.sin_addr)); } int DgramLastport (void) { return (ntohs ((int) lastaddr.sin_port)); }