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