]>
Commit | Line | Data |
---|---|---|
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 |