1 /* This is mostly emulation of socklib.c from xpilot used by koules before.
2 * It was removed because of copyright problems. Current implementation is
3 * completly rewrote just partially compatible with socklib API. It implements
4 * just few calls used by koules and in a bit different way. It is not drop-in
5 * replacement for socklib.
6 */
7 #if defined(__sparc)
8 #define __EXTENSIONS__
9 #endif
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <sys/param.h>
13 #include <sys/ioctl.h>
14 #if (SVR4)
15 #include <sys/filio.h>
16 #endif
17 #ifdef __hpux
18 #include <time.h>
19 #else
20 #include <sys/time.h>
21 #endif
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <netinet/tcp.h>
25 #include <arpa/inet.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <netdb.h>
30 #include <signal.h>
31 #include <setjmp.h>
32 #include <errno.h>
33 #if defined(__sparc)
34 #include <sys/fcntl.h>
35 #endif
36 #if defined(__sun__)
37 #include <arpa/nameser.h>
38 #include <resolv.h>
39 #endif
40
41 #include "sock.h"
42 static struct timeval timeout;
43 static struct sockaddr_in lastaddr;
44
45
SetTimeout(int s,int us)46 void SetTimeout(int s,int us)
47 {
48 timeout.tv_sec=s;
49 timeout.tv_usec=us;
50 }
51
GetPortNum(int fd)52 int GetPortNum(int fd)
53 {
54 struct sockaddr_in a;
55 int s=sizeof(a);
56 if(getsockname(fd,(struct sockaddr *)&a,&s)<0) return -1;
57 return(ntohs(a.sin_port));
58 }
GetSockAddr(int fd)59 char *GetSockAddr(int fd)
60 {
61 struct sockaddr_in a;
62 int s=sizeof(a);
63 if(getsockname(fd,(struct sockaddr *)&a,&s)<0) return NULL;
64 return(inet_ntoa(a.sin_addr));
65 }
SetSocketReceiveBufferSize(int fd,int size)66 int SetSocketReceiveBufferSize(int fd,int size)
67 {
68 return(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&size, sizeof(size)));
69 }
SetSocketSendBufferSize(int fd,int size)70 int SetSocketSendBufferSize(int fd,int size)
71 {
72 return(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(size)));
73 }
74
75
SetSocketNonBlocking(int fd,int flag)76 int SetSocketNonBlocking (int fd, int flag)
77 {
78 /*
79 * This code is copied from original socklib library. I hope it is not
80 * problem... I want to avoid compilation problems on some systems...
81 *
82 * There are some problems on some particular systems (suns) with
83 * getting sockets to be non-blocking. Just try all possible ways
84 * until one of them succeeds. Please keep us informed by e-mail
85 * to xpilot@cs.uit.no.
86 */
87
88 #ifndef USE_FCNTL_O_NONBLOCK
89 #ifndef USE_FCNTL_O_NDELAY
90 #ifndef USE_FCNTL_FNDELAY
91 #ifndef USE_IOCTL_FIONBIO
92
93 #if defined(_SEQUENT_) || defined(__svr4__) || defined(SVR4)
94 #define USE_FCNTL_O_NDELAY
95 #elif defined(__sun__) && defined(FNDELAY)
96 #define USE_FCNTL_FNDELAY
97 #elif defined(FIONBIO)
98 #define USE_IOCTL_FIONBIO
99 #elif defined(FNDELAY)
100 #define USE_FCNTL_FNDELAY
101 #elif defined(O_NONBLOCK)
102 #define USE_FCNTL_O_NONBLOCK
103 #else
104 #define USE_FCNTL_O_NDELAY
105 #endif
106
107 #endif
108 #endif
109 #endif
110 #endif
111
112 #ifdef USE_FCNTL_FNDELAY
113 if (fcntl (fd, F_SETFL, (flag != 0) ? FNDELAY : 0) != -1)
114 return 0;
115 fprintf (stderr, "fcntl FNDELAY failed in file \"%s\", line %d: %s\n",
116 __FILE__, __LINE__, strerror (errno));
117 #endif
118
119 #ifdef USE_IOCTL_FIONBIO
120 if (ioctl (fd, FIONBIO, &flag) != -1)
121 return 0;
122 fprintf (stderr, "ioctl FIONBIO failed in file \"%s\", line %d: %s\n",
123 __FILE__, __LINE__, strerror (errno));
124 #endif
125
126 #ifdef USE_FCNTL_O_NONBLOCK
127 if (fcntl (fd, F_SETFL, (flag != 0) ? O_NONBLOCK : 0) != -1)
128 return 0;
129 fprintf (stderr, "fcntl O_NONBLOCK failed in file \"%s\", line %d: %s\n",
130 __FILE__, __LINE__, strerror (errno));
131 #endif
132
133 #ifdef USE_FCNTL_O_NDELAY
134 if (fcntl (fd, F_SETFL, (flag != 0) ? O_NDELAY : 0) != -1)
135 return 0;
136 fprintf (stderr, "fcntl O_NDELAY failed in file \"%s\", line %d: %s\n",
137 __FILE__, __LINE__, strerror (errno));
138 #endif
139
140 return (-1);
141 }
142
GetSocketError(int fd)143 int GetSocketError(int fd)
144 {
145 int size=sizeof(errno);
146 return (getsockopt(fd,SOL_SOCKET,SO_ERROR,(char *)&errno,&size));
147 }
148
SocketReadable(int fd)149 int SocketReadable(int fd)
150 {
151 fd_set fds;
152 FD_ZERO(&fds);
153 FD_SET(fd,&fds);
154 if (select (fd + 1, &fds, NULL, NULL, &timeout) == -1) return ((errno == EINTR) ? 0 : -1);
155 return(FD_ISSET(fd,&fds));
156 }
157
CreateDgramSocket(int port)158 int CreateDgramSocket(int port)
159 {
160 struct sockaddr_in addr;
161 int fd;
162
163 fd=socket(AF_INET, SOCK_DGRAM, 0);
164 if (fd<0) return -1;
165 memset(&addr,0,sizeof(addr));
166 addr.sin_addr.s_addr=INADDR_ANY;
167 addr.sin_port=htons(port);
168 addr.sin_family=AF_INET;
169 if(bind(fd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0) {
170 fd=errno;
171 close(fd);
172 errno=fd;
173 return -1;
174 }
175 return fd;
176
177 }
DgramConnect(int fd,char * host,int port)178 int DgramConnect(int fd, char *host, int port)
179 {
180 struct sockaddr_in addr;
181 memset(&addr,0,sizeof(addr));
182 addr.sin_addr.s_addr = inet_addr (host);
183 if(addr.sin_addr.s_addr==-1) return -1;
184 addr.sin_family = AF_INET;
185 addr.sin_port = htons (port);
186 return(connect (fd, (struct sockaddr *) &addr, sizeof (addr)));
187 }
DgramSend(int fd,char * host,int port,char * sbuf,int size)188 int DgramSend(int fd, char *host, int port, char *sbuf, int size)
189 {
190 struct sockaddr_in addr;
191 struct hostent *hp;
192 #if 0
193 if (!rand()%10) return 0;/*Internet emulation :))))))) */
194 if (rand()%2) {size=rand()%size;}
195 #endif
196 memset(&addr,0,sizeof(addr));
197 addr.sin_addr.s_addr = inet_addr (host);
198 if(addr.sin_addr.s_addr==-1) {
199 if (addr.sin_addr.s_addr == (int) -1)
200 {
201 hp = gethostbyname (host);
202 if (hp == NULL)
203 {
204 fprintf(stderr,"Host '%s' unknown\n",host);
205 return -1;
206 }
207 else
208 addr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
209 }
210
211 }
212 addr.sin_family = AF_INET;
213 addr.sin_port = htons (port);
214 return(sendto (fd, sbuf, size, 0, (struct sockaddr *) &addr,
215 sizeof (struct sockaddr_in)));
216
217 }
DgramReceiveAny(int fd,char * buf,int size)218 int DgramReceiveAny(int fd,char *buf, int size)
219 {
220 int len=sizeof (struct sockaddr_in);
221 return(recvfrom (fd, buf, size, 0, (struct sockaddr *) &lastaddr, &len));
222 }
DgramReceiveConnected(int fd,char * buf,int size)223 int DgramReceiveConnected(int fd,char *buf, int size)
224 {
225 return(recv (fd, buf, size, 0));
226 }
SocketClose(int fd)227 int SocketClose (int fd)
228 {
229 shutdown (fd, 2);
230 if (close (fd) == -1)
231 {
232 return (-1);
233 }
234 return (1);
235 }
DgramLastaddr(void)236 char *DgramLastaddr (void)
237 {
238 return (inet_ntoa (lastaddr.sin_addr));
239 }
DgramLastport(void)240 int DgramLastport (void)
241 {
242 return (ntohs ((int) lastaddr.sin_port));
243 }
244
245
246