]>
Commit | Line | Data |
---|---|---|
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 | |
1136f709 | 14 | #ifdef HAVE_ARPA_INET_H |
15 | # include <arpa/inet.h> | |
16 | #endif | |
d76ed9a9 AS |
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 | ||
0f6fe38c | 39 | return 0; |
d76ed9a9 AS |
40 | } |
41 | #endif | |
42 | ||
43 | #ifndef HAVE_MEMCPY | |
44 | extern void * memcpy(void * dest, void const * src, unsigned long n) | |
45 | { | |
d76ed9a9 AS |
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 AS |
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 | |
2f61d1d7 | 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) { | |
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 | ||
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 |