]> jfr.im git - irc/evilnet/x3.git/blame - src/compat.c
remove some debug chatter
[irc/evilnet/x3.git] / src / compat.c
CommitLineData
d76ed9a9 1#undef gettimeofday
2#undef memcpy
3#undef memset
4#undef strerror
5
6#include "common.h"
7
8#ifdef HAVE_SYS_TIMEB_H
9# include <sys/timeb.h>
10#endif
11#ifdef HAVE_MEMORY_H
12# include <memory.h>
13#endif
1136f709 14#ifdef HAVE_ARPA_INET_H
15# include <arpa/inet.h>
16#endif
d76ed9a9 17
18#if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
19extern gettimeofday(struct timeval * tv, struct timezone * tz);
20{
21 if (!tv)
22 {
23 errno = EFAULT;
24 return -1;
25 }
26
27 struct timeb tb;
28
29 ftime(&tb); /* FIXME: some versions are void return others int */
30
31 tv->tv_sec = tb.time;
32 tv->tv_usec = ((long)tb.millitm)*1000;
33 if (tz)
34 {
35 tz->tz_minuteswest = 0;
36 tz->tz_dsttime = 0;
37 }
38
0f6fe38c 39 return 0;
d76ed9a9 40}
41#endif
42
43#ifndef HAVE_MEMCPY
44extern void * memcpy(void * dest, void const * src, unsigned long n)
45{
d76ed9a9 46/* very slow, your fault for not having memcpy()*/
47 unsigned char * td=dest;
48 unsigned char * ts=src;
49 unsigned long i;
50
51 if (!td || !ts)
52 return NULL;
53
54 for (i=0; i<n; i++)
55 td[i] = ts[i];
56 return dest;
d76ed9a9 57}
58#endif
59
60#ifndef HAVE_MEMSET
61/* very slow, deal with it */
62extern void * memset(void * dest, int c, unsigned long n)
63{
64 unsigned char * temp=dest;
65 unsigned long i;
66
67 if (!temp)
68 return NULL;
69
70 for (i=0; i<n; i++)
71 temp[i] = (unsigned char)c;
72 return dest;
73}
74#endif
75
76#ifndef HAVE_STRDUP
77extern char * strdup(char const * str)
78{
79 char * out;
80
81 if (!str)
82 return NULL;
83 if (!(out = malloc(strlen(str)+1)))
84 return NULL;
85 strcpy(out,str);
86 return out;
87}
88#endif
89
90#ifndef HAVE_STRERROR
91extern char const * strerror(int errornum)
92{
93 if (errornum==0)
94 return "No error";
95#ifdef EPERM
96 if (errornum==EPERM)
97 return "Operation not permitted";
98#endif
99#ifdef ENOENT
100 if (errornum==ENOENT)
101 return "No such file or directory";
102#endif
103#ifdef ESRCH
104 if (errornum==ESRCH)
105 return "No such process";
106#endif
107#ifdef EINTR
108 if (errornum==EINTR)
109 return "Interrupted system call";
110#endif
111#ifdef EIO
112 if (errornum==EIO)
113 return "I/O error";
114#endif
115#ifdef ENXIO
116 if (errornum==EIO)
117 return "No such device or address";
118#endif
119#ifdef EBADF
120 if (errornum==EBADF)
121 return "Bad file number";
122#endif
123#ifdef EAGAIN
124 if (errornum==EAGAIN)
125 return "Try again";
126#endif
127#ifdef ENOMEM
128 if (errornum==ENOMEM)
129 return "Out of memory";
130#endif
131#ifdef EACCES
132 if (errornum==EACCES)
133 return "Permission denied";
134#endif
135#ifdef EFAULT
136 if (errornum==EFAULT)
137 return "Bad address";
138#endif
139#ifdef EBUSY
140 if (errornum==EBUSY)
141 return "Device or resource busy";
142#endif
143#ifdef EEXIST
144 if (errornum==EEXIST)
145 return "File exists";
146#endif
147#ifdef EXDEV
148 if (errornum==EXDEV)
149 return "Cross-device link";
150#endif
151#ifdef EDEADLK
152 if (errornum==EXDEV)
153 return "Resource deadlock would occur";
154#endif
155#ifdef EDEADLOCK
156 if (errornum==EDEADLOCK)
157 return "Resource deadlock would occur";
158#endif
159#ifdef ENODEV
160 if (errornum==ENODEV)
161 return "No such device";
162#endif
163#ifdef ENOTDIR
164 if (errornum==ENOTDIR)
165 return "Not a directory";
166#endif
167#ifdef EISDIR
168 if (errornum==EISDIR)
169 return "Is a directory";
170#endif
171#ifdef EINVAL
172 if (errornum==EINVAL)
173 return "Invalid argument";
174#endif
175#ifdef ENFILE
176 if (errornum==ENFILE)
177 return "Too many open files in system";
178#endif
179#ifdef EMFILE
180 if (errornum==EMFILE)
181 return "Too many open files";
182#endif
183#ifdef ENOTTY
184 if (errornum==ENOTTY)
185 return "Not a typewriter";
186#endif
187#ifdef ETXTBSY
188 if (errornum==ETXTBSY)
189 return "Text file busy";
190#endif
191#ifdef EFBIG
192 if (errornum==EFBIG)
193 return "File too large";
194#endif
195#ifdef ENOSPC
196 if (errornum==ENOSPC)
197 return "No space left on device";
198#endif
199#ifdef ESPIPE
200 if (errornum==ESPIPE)
201 return "Illegal seek";
202#endif
203#ifdef EROFS
204 if (errornum==EROFS)
205 return "Read-only file system";
206#endif
207#ifdef EMLINK
208 if (errornum==EMLINK)
209 return "Too many links";
210#endif
211#ifdef EPIPE
212 if (errornum==EPIPE)
213 return "Broken pipe";
214#endif
215#ifdef EDOM
216 if (errornum==EDOM)
217 return "Math argument out of domain of func";
218#endif
219#ifdef ERANGE
220 if (errornum==ERANGE)
221 return "Math result not representable";
222#endif
223#ifdef ENAMETOOLONG
224 if (errornum==ENAMETOOLONG)
225 return "File name too long";
226#endif
227#ifdef ENOLCK
228 if (errornum==ENOLCK)
229 return "No record locks avaliable";
230#endif
231#ifdef ENOSYS
232 if (errornum==ENOSYS)
233 return "Function not implemented";
234#endif
235#ifdef ENOTEMPTY
236 if (errornum==ENOTEMPTY)
237 return "Directory not empty";
238#endif
239#ifdef ELOOP
240 if (errornum==ELOOP)
241 return "Too many symbolic links encountered";
242#endif
243#ifdef EHOSTDOWN
244 if (errornum==EHOSTDOWN)
245 return "Host is down";
246#endif
247#ifdef EHOSTUNREACH
248 if (errornum==EHOSTUNREACH)
249 return "No route to host";
250#endif
251#ifdef EALREADY
252 if (errornum==EALREADY)
253 return "Operation already in progress";
254#endif
255#ifdef EINPROGRESS
256 if (errornum==EINPROGRESS)
257 return "Operation now in progress";
258#endif
259#ifdef ESTALE
260 if (errornum==ESTALE)
261 return "Stale NFS filehandle";
262#endif
263#ifdef EDQUOT
264 if (errornum==EDQUOT)
265 return "Quota exceeded";
266#endif
267#ifdef EWOULDBLOCK
268 if (errornum==EWOULDBLOCK)
269 return "Operation would block";
270#endif
271#ifdef ECOMM
272 if (errornum==ECOMM)
273 return "Communication error on send";
274#endif
275#ifdef EPROTO
276 if (errornum==EPROTO)
277 return "Protocol error";
278#endif
279#ifdef EPROTONOSUPPORT
280 if (errornum==EPROTONOSUPPORT)
281 return "Protocol not supported";
282#endif
283#ifdef ESOCKTNOSUPPORT
284 if (errornum==ESOCKTNOSUPPORT)
285 return "Socket type not supported";
286#endif
287#ifdef ESOCKTNOSUPPORT
288 if (errornum==EOPNOTSUPP)
289 return "Operation not supported";
290#endif
291#ifdef EPFNOSUPPORT
292 if (errornum==EPFNOSUPPORT)
293 return "Protocol family not supported";
294#endif
295#ifdef EAFNOSUPPORT
296 if (errornum==EAFNOSUPPORT)
297 return "Address family not supported by protocol family";
298#endif
299#ifdef EADDRINUSE
300 if (errornum==EADDRINUSE)
301 return "Address already in use";
302#endif
303#ifdef EADDRNOTAVAIL
304 if (errornum==EADDRNOTAVAIL)
305 return "Cannot assign requested address";
306#endif
307#ifdef ENETDOWN
308 if (errornum==ENETDOWN)
309 return "Network is down";
310#endif
311#ifdef ENETUNREACH
312 if (errornum==ENETUNREACH)
313 return "Network is unreachable";
314#endif
315#ifdef ENETRESET
316 if (errornum==ENETRESET)
317 return "Network dropped connection on reset";
318#endif
319#ifdef ECONNABORTED
320 if (errornum==ECONNABORTED)
321 return "Software caused connection abort";
322#endif
323#ifdef ECONNRESET
324 if (errornum==ECONNRESET)
325 return " Connection reset by peer";
326#endif
327#ifdef ENOBUFS
328 if (errornum==ENOBUFS)
329 return "No buffer space available";
330#endif
331#ifdef EISCONN
332 if (errornum==EISCONN)
333 return "Socket is already connected";
334#endif
335#ifdef ENOTCONN
336 if (errornum==ENOTCONN)
337 return "Socket is not connected";
338#endif
339#ifdef ESHUTDOWN
340 if (errornum==ESHUTDOWN)
341 return " Cannot send after socket shutdown";
342#endif
343#ifdef ETIMEDOUT
344 if (errornum==ETIMEDOUT)
345 return "Connection timed out";
346#endif
347#ifdef ECONNREFUSED
348 if (errornum==ECONNREFUSED)
349 return "Connection refused";
350#endif
351 return "Unknown error";
352}
353#endif
2f61d1d7 354
355#ifndef HAVE_GETADDRINFO
356
357int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
358{
359 /* Only support IPv4 if OS doesn't provide this function. */
360 struct sockaddr_in sin;
361
362 if (hints && hints->ai_family != AF_INET)
363 return 1;
364 memset(&sin, 0, sizeof(sin));
365 sin.sin_family = AF_INET;
366
367 if (node) {
368 if (hints && hints->ai_flags & AI_NUMERICHOST) {
1136f709 369#if HAVE_INET_ATON
2f61d1d7 370 if (!inet_aton(node, &sin.sin_addr))
371 return 2;
1136f709 372#else
373 sin.sin_addr.s_addr = inet_addr(node);
374 if (sin.sin_addr.s_addr == INADDR_NONE)
375 return 2;
376#endif
2f61d1d7 377 } else {
378 struct hostent *he;
379 he = gethostbyname(node);
380 if (!he)
381 return 3;
382 memcpy(&sin.sin_addr, he->h_addr, he->h_length);
383 }
384 } else if (hints && hints->ai_flags & AI_PASSIVE) {
385 /* leave it unspecifed */
386 } else {
387 inet_aton("127.0.0.1", &sin.sin_addr);
388 }
389
390 if (!service)
391 sin.sin_port = ntohs(0);
392 else if (!(sin.sin_port = ntohs(atoi(service))))
393 return 4;
394
395 *res = calloc(1, sizeof(**res) + sizeof(sin));
396 (*res)->ai_family = sin.sin_family;
397 (*res)->ai_socktype = hints && hints->ai_socktype ? hints->ai_socktype : SOCK_STREAM;
398 (*res)->ai_protocol = hints && hints->ai_socktype ? hints->ai_socktype : 0;
399 (*res)->ai_addrlen = sizeof(sin);
400 (*res)->ai_addr = (struct sockaddr*)(*res + 1);
401 memcpy((*res)->ai_addr, &sin, (*res)->ai_addrlen);
402 (*res)->ai_canonname = 0;
403 (*res)->ai_next = 0;
404 return 0;
405}
406
407/* TODO: implement fallback getnameinfo() */
408
409void freeaddrinfo(struct addrinfo *res)
410{
411 struct addrinfo *next;
412 for (; res; res = next) {
413 next = res->ai_next;
414 free(res);
415 }
416}
417
418#endif
419