]> jfr.im git - irc/evilnet/x3.git/blob - src/compat.c
Added 3 new hooks available for python scripts: new_user, nick_change, and server_link
[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
15 #if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
16 extern 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
41 extern void * memcpy(void * dest, void const * src, unsigned long n)
42 {
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;
54 }
55 #endif
56
57 #ifndef HAVE_MEMSET
58 /* very slow, deal with it */
59 extern 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
74 extern 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
88 extern 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
351
352 #ifndef HAVE_GETADDRINFO
353
354 int 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
400 void 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