]> jfr.im git - irc/evilnet/x3.git/blob - src/compat.c
Added missing Nefarious 2 IRCop privs
[irc/evilnet/x3.git] / src / compat.c
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 #ifdef HAVE_ARPA_INET_H
15 # include <arpa/inet.h>
16 #endif
17
18 #if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
19 extern 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
39 return 0;
40 }
41 #endif
42
43 #ifndef HAVE_MEMCPY
44 extern void * memcpy(void * dest, void const * src, unsigned long n)
45 {
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;
57 }
58 #endif
59
60 #ifndef HAVE_MEMSET
61 /* very slow, deal with it */
62 extern 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
77 extern 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
91 extern 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
354
355 #ifndef HAVE_GETADDRINFO
356
357 int 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) {
369 #if HAVE_INET_ATON
370 if (!inet_aton(node, &sin.sin_addr))
371 return 2;
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
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
409 void 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