Commit | Line | Data |
---|---|---|
059ec3d9 PH |
1 | /************************************************* |
2 | * Exim - an Internet mail transport agent * | |
3 | *************************************************/ | |
4 | ||
f9ba5e22 | 5 | /* Copyright (c) University of Cambridge 1995 - 2018 */ |
059ec3d9 PH |
6 | /* See the file NOTICE for conditions of use and distribution. */ |
7 | ||
8 | #ifdef STAND_ALONE | |
cb683277 JH |
9 | # include <signal.h> |
10 | # include <stdio.h> | |
11 | # include <time.h> | |
12 | #endif | |
13 | ||
14 | #ifndef CS | |
15 | # define CS (char *) | |
16 | # define US (unsigned char *) | |
059ec3d9 PH |
17 | #endif |
18 | ||
19 | /* This source file contains "default" system-dependent functions which | |
20 | provide functionality (or lack of it) in cases where the OS-specific os.c | |
21 | file has not. Some of them are tailored by macros defined in os.h files. */ | |
22 | ||
23 | ||
24 | #ifndef OS_RESTARTING_SIGNAL | |
25 | /************************************************* | |
26 | * Set up restarting signal * | |
27 | *************************************************/ | |
28 | ||
29 | /* This function has the same functionality as the ANSI C signal() function, | |
30 | except that it arranges that, if the signal happens during a system call, the | |
31 | system call gets restarted. (Also, it doesn't return a result.) Different | |
32 | versions of Unix have different defaults, and different ways of setting up a | |
33 | restarting signal handler. If the functionality is not available, the signal | |
34 | should be set to be ignored. This function is used only for catching SIGUSR1. | |
35 | */ | |
36 | ||
37 | void | |
38 | os_restarting_signal(int sig, void (*handler)(int)) | |
39 | { | |
40 | /* Many systems have the SA_RESTART sigaction for specifying that a signal | |
41 | should restart system calls. These include SunOS5, AIX, BSDI, IRIX, FreeBSD, | |
42 | OSF1, Linux and HP-UX 10 (but *not* HP-UX 9). */ | |
43 | ||
44 | #ifdef SA_RESTART | |
45 | struct sigaction act; | |
46 | act.sa_handler = handler; | |
47 | sigemptyset(&(act.sa_mask)); | |
48 | act.sa_flags = SA_RESTART; | |
49 | sigaction(sig, &act, NULL); | |
50 | ||
51 | #ifdef STAND_ALONE | |
52 | printf("Used SA_RESTART\n"); | |
53 | #endif | |
54 | ||
55 | /* SunOS4 and Ultrix default to non-interruptable signals, with SV_INTERRUPT | |
56 | for making them interruptable. This seems to be a dying fashion. */ | |
57 | ||
58 | #elif defined SV_INTERRUPT | |
59 | signal(sig, handler); | |
60 | ||
61 | #ifdef STAND_ALONE | |
62 | printf("Used default signal()\n"); | |
63 | #endif | |
64 | ||
65 | ||
66 | /* If neither SA_RESTART nor SV_INTERRUPT is available we don't know how to | |
67 | set up a restarting signal, so simply suppress the facility. */ | |
68 | ||
69 | #else | |
70 | signal(sig, SIG_IGN); | |
71 | ||
72 | #ifdef STAND_ALONE | |
73 | printf("Used SIG_IGN\n"); | |
74 | #endif | |
75 | ||
76 | #endif | |
77 | } | |
78 | ||
79 | #endif /* OS_RESTARTING_SIGNAL */ | |
80 | ||
81 | ||
82 | #ifndef OS_NON_RESTARTING_SIGNAL | |
83 | /************************************************* | |
84 | * Set up non-restarting signal * | |
85 | *************************************************/ | |
86 | ||
87 | /* This function has the same functionality as the ANSI C signal() function, | |
88 | except that it arranges that, if the signal happens during a system call, the | |
89 | system call gets interrupted. (Also, it doesn't return a result.) Different | |
90 | versions of Unix have different defaults, and different ways of setting up a | |
91 | non-restarting signal handler. For systems for which we don't know what to do, | |
92 | just use the normal signal() function and hope for the best. */ | |
93 | ||
94 | void | |
95 | os_non_restarting_signal(int sig, void (*handler)(int)) | |
96 | { | |
97 | /* Many systems have the SA_RESTART sigaction for specifying that a signal | |
98 | should restart system calls. These include SunOS5, AIX, BSDI, IRIX, FreeBSD, | |
99 | OSF1, Linux and HP-UX 10 (but *not* HP-UX 9). */ | |
100 | ||
101 | #ifdef SA_RESTART | |
102 | struct sigaction act; | |
103 | act.sa_handler = handler; | |
104 | sigemptyset(&(act.sa_mask)); | |
105 | act.sa_flags = 0; | |
106 | sigaction(sig, &act, NULL); | |
107 | ||
108 | #ifdef STAND_ALONE | |
109 | printf("Used sigaction() with flags = 0\n"); | |
110 | #endif | |
111 | ||
112 | /* SunOS4 and Ultrix default to non-interruptable signals, with SV_INTERRUPT | |
113 | for making them interruptable. This seems to be a dying fashion. */ | |
114 | ||
115 | #elif defined SV_INTERRUPT | |
116 | struct sigvec sv; | |
117 | sv.sv_handler = handler; | |
118 | sv.sv_flags = SV_INTERRUPT; | |
119 | sv.sv_mask = -1; | |
120 | sigvec(sig, &sv, NULL); | |
121 | ||
122 | #ifdef STAND_ALONE | |
123 | printf("Used sigvec() with flags = SV_INTERRUPT\n"); | |
124 | #endif | |
125 | ||
126 | /* If neither SA_RESTART nor SV_INTERRUPT is available we don't know how to | |
127 | set up a restarting signal, so just use the standard signal() function. */ | |
128 | ||
129 | #else | |
130 | signal(sig, handler); | |
131 | ||
132 | #ifdef STAND_ALONE | |
133 | printf("Used default signal()\n"); | |
134 | #endif | |
135 | ||
136 | #endif | |
137 | } | |
138 | ||
139 | #endif /* OS_NON_RESTARTING_SIGNAL */ | |
140 | ||
141 | ||
142 | ||
143 | #ifdef STRERROR_FROM_ERRLIST | |
144 | /************************************************* | |
145 | * Provide strerror() for non-ANSI libraries * | |
146 | *************************************************/ | |
147 | ||
148 | /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() | |
149 | in their libraries, but can provide the same facility by this simple | |
150 | alternative function. */ | |
151 | ||
152 | char * | |
153 | strerror(int n) | |
154 | { | |
155 | if (n < 0 || n >= sys_nerr) return "unknown error number"; | |
156 | return sys_errlist[n]; | |
157 | } | |
158 | #endif /* STRERROR_FROM_ERRLIST */ | |
159 | ||
160 | ||
161 | ||
162 | #ifndef OS_STRSIGNAL | |
163 | /************************************************* | |
164 | * Provide strsignal() for systems without * | |
165 | *************************************************/ | |
166 | ||
167 | /* Some systems have strsignal() to turn signal numbers into names; others | |
168 | may have other means of doing this. This function is used for those systems | |
169 | that have nothing. It provides a basic translation for the common standard | |
170 | signal numbers. I've been extra cautious with the ifdef's here. Probably more | |
171 | than is necessary... */ | |
172 | ||
1ba28e2b PP |
173 | const char * |
174 | os_strsignal(const int n) | |
059ec3d9 PH |
175 | { |
176 | switch (n) | |
177 | { | |
178 | #ifdef SIGHUP | |
179 | case SIGHUP: return "hangup"; | |
180 | #endif | |
181 | ||
182 | #ifdef SIGINT | |
183 | case SIGINT: return "interrupt"; | |
184 | #endif | |
185 | ||
186 | #ifdef SIGQUIT | |
187 | case SIGQUIT: return "quit"; | |
188 | #endif | |
189 | ||
190 | #ifdef SIGILL | |
191 | case SIGILL: return "illegal instruction"; | |
192 | #endif | |
193 | ||
194 | #ifdef SIGTRAP | |
195 | case SIGTRAP: return "trace trap"; | |
196 | #endif | |
197 | ||
198 | #ifdef SIGABRT | |
199 | case SIGABRT: return "abort"; | |
200 | #endif | |
201 | ||
202 | #ifdef SIGEMT | |
203 | case SIGEMT: return "EMT instruction"; | |
204 | #endif | |
205 | ||
206 | #ifdef SIGFPE | |
207 | case SIGFPE: return "arithmetic exception"; | |
208 | #endif | |
209 | ||
210 | #ifdef SIGKILL | |
211 | case SIGKILL: return "killed"; | |
212 | #endif | |
213 | ||
214 | #ifdef SIGBUS | |
215 | case SIGBUS: return "bus error"; | |
216 | #endif | |
217 | ||
218 | #ifdef SIGSEGV | |
219 | case SIGSEGV: return "segmentation fault"; | |
220 | #endif | |
221 | ||
222 | #ifdef SIGSYS | |
223 | case SIGSYS: return "bad system call"; | |
224 | #endif | |
225 | ||
226 | #ifdef SIGPIPE | |
227 | case SIGPIPE: return "broken pipe"; | |
228 | #endif | |
229 | ||
230 | #ifdef SIGALRM | |
231 | case SIGALRM: return "alarm"; | |
232 | #endif | |
233 | ||
234 | #ifdef SIGTERM | |
235 | case SIGTERM: return "terminated"; | |
236 | #endif | |
237 | ||
238 | #ifdef SIGUSR1 | |
239 | case SIGUSR1: return "user signal 1"; | |
240 | #endif | |
241 | ||
242 | #ifdef SIGUSR2 | |
243 | case SIGUSR2: return "user signal 2"; | |
244 | #endif | |
245 | ||
246 | #ifdef SIGCHLD | |
247 | case SIGCHLD: return "child stop or exit"; | |
248 | #endif | |
249 | ||
250 | #ifdef SIGPWR | |
251 | case SIGPWR: return "power fail/restart"; | |
252 | #endif | |
253 | ||
254 | #ifdef SIGURG | |
255 | case SIGURG: return "urgent condition on I/O channel"; | |
256 | #endif | |
257 | ||
258 | #ifdef SIGSTOP | |
259 | case SIGSTOP: return "stop"; | |
260 | #endif | |
261 | ||
262 | #ifdef SIGTSTP | |
263 | case SIGTSTP: return "stop from tty"; | |
264 | #endif | |
265 | ||
266 | #ifdef SIGXCPU | |
267 | case SIGXCPU: return "exceeded CPU limit"; | |
268 | #endif | |
269 | ||
270 | #ifdef SIGXFSZ | |
271 | case SIGXFSZ: return "exceeded file size limit"; | |
272 | #endif | |
273 | ||
274 | default: return "unrecognized signal number"; | |
275 | } | |
276 | } | |
277 | #endif /* OS_STRSIGNAL */ | |
278 | ||
279 | ||
280 | ||
281 | #ifndef OS_STREXIT | |
282 | /************************************************* | |
283 | * Provide strexit() for systems without * | |
284 | *************************************************/ | |
285 | ||
286 | /* Actually, I don't know of any system that has a strexit() function to turn | |
287 | exit codes into text, but this function is implemented this way so that if any | |
288 | OS does have such a thing, it could be used instead of this build-in one. */ | |
289 | ||
1ba28e2b PP |
290 | const char * |
291 | os_strexit(const int n) | |
059ec3d9 PH |
292 | { |
293 | switch (n) | |
294 | { | |
295 | /* On systems without sysexits.h we can assume only those exit codes | |
296 | that are given a default value in exim.h. */ | |
297 | ||
298 | #ifndef NO_SYSEXITS | |
299 | case EX_USAGE: return "(could mean usage or syntax error)"; | |
300 | case EX_DATAERR: return "(could mean error in input data)"; | |
301 | case EX_NOINPUT: return "(could mean input data missing)"; | |
302 | case EX_NOUSER: return "(could mean user nonexistent)"; | |
303 | case EX_NOHOST: return "(could mean host nonexistent)"; | |
304 | case EX_SOFTWARE: return "(could mean internal software error)"; | |
305 | case EX_OSERR: return "(could mean internal operating system error)"; | |
306 | case EX_OSFILE: return "(could mean system file missing)"; | |
307 | case EX_IOERR: return "(could mean input/output error)"; | |
308 | case EX_PROTOCOL: return "(could mean protocol error)"; | |
309 | case EX_NOPERM: return "(could mean permission denied)"; | |
310 | #endif | |
311 | ||
312 | case EX_EXECFAILED: return "(could mean unable to exec or command does not exist)"; | |
313 | case EX_UNAVAILABLE: return "(could mean service or program unavailable)"; | |
314 | case EX_CANTCREAT: return "(could mean can't create output file)"; | |
315 | case EX_TEMPFAIL: return "(could mean temporary error)"; | |
316 | case EX_CONFIG: return "(could mean configuration error)"; | |
317 | default: return ""; | |
318 | } | |
319 | } | |
320 | #endif /* OS_STREXIT */ | |
321 | ||
322 | ||
323 | ||
324 | ||
325 | /*********************************************************** | |
326 | * Load average function * | |
327 | ***********************************************************/ | |
328 | ||
329 | /* Although every Unix seems to have a different way of getting the load | |
330 | average, a number of them have things in common. Some common variants are | |
331 | provided below, but if an OS has unique requirements it can be handled in | |
332 | a specific os.c file. What is required is a function called os_getloadavg | |
333 | which takes no arguments and passes back the load average * 1000 as an int, | |
334 | or -1 if no data is available. */ | |
335 | ||
336 | ||
337 | /* ----------------------------------------------------------------------- */ | |
338 | /* If the OS has got a BSD getloadavg() function, life is very easy. */ | |
339 | ||
340 | #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_BSD_GETLOADAVG) | |
341 | #define OS_LOAD_AVERAGE | |
342 | ||
343 | int | |
344 | os_getloadavg(void) | |
345 | { | |
346 | double avg; | |
347 | int loads = getloadavg (&avg, 1); | |
348 | if (loads != 1) return -1; | |
349 | return (int)(avg * 1000.0); | |
350 | } | |
351 | #endif | |
352 | /* ----------------------------------------------------------------------- */ | |
353 | ||
354 | ||
355 | ||
356 | /* ----------------------------------------------------------------------- */ | |
357 | /* Only SunOS5 has the kstat functions as far as I know, but put the code | |
358 | here as there is the -hal variant, and other systems might follow this road one | |
359 | day. */ | |
360 | ||
361 | #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_KSTAT) | |
362 | #define OS_LOAD_AVERAGE | |
363 | ||
364 | #include <kstat.h> | |
365 | ||
366 | int | |
367 | os_getloadavg(void) | |
368 | { | |
369 | int avg; | |
370 | kstat_ctl_t *kc; | |
371 | kstat_t *ksp; | |
372 | kstat_named_t *kn; | |
373 | ||
374 | if ((kc = kstat_open()) == NULL || | |
375 | (ksp = kstat_lookup(kc, LOAD_AVG_KSTAT_MODULE, 0, LOAD_AVG_KSTAT)) | |
376 | == NULL || | |
377 | kstat_read(kc, ksp, NULL) < 0 || | |
378 | (kn = kstat_data_lookup(ksp, LOAD_AVG_SYMBOL)) == NULL) | |
379 | return -1; | |
380 | ||
381 | avg = (int)(((double)(kn->LOAD_AVG_FIELD)/FSCALE) * 1000.0); | |
382 | ||
383 | kstat_close(kc); | |
384 | return avg; | |
385 | } | |
386 | ||
387 | #endif | |
388 | /* ----------------------------------------------------------------------- */ | |
389 | ||
390 | ||
391 | ||
392 | /* ----------------------------------------------------------------------- */ | |
393 | /* Handle OS where a kernel symbol has to be read from /dev/kmem */ | |
394 | ||
395 | #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_DEV_KMEM) | |
396 | #define OS_LOAD_AVERAGE | |
397 | ||
398 | #include <nlist.h> | |
399 | ||
400 | static int avg_kd = -1; | |
401 | static long avg_offset; | |
402 | ||
403 | int | |
404 | os_getloadavg(void) | |
405 | { | |
406 | LOAD_AVG_TYPE avg; | |
407 | ||
408 | if (avg_kd < 0) | |
409 | { | |
410 | struct nlist nl[2]; | |
411 | nl[0].n_name = LOAD_AVG_SYMBOL; | |
412 | nl[1].n_name = ""; | |
413 | nlist (KERNEL_PATH, nl); | |
414 | avg_offset = (long)nl[0].n_value; | |
415 | avg_kd = open ("/dev/kmem", 0); | |
416 | if (avg_kd < 0) return -1; | |
417 | (void) fcntl(avg_kd, F_SETFD, FD_CLOEXEC); | |
418 | } | |
419 | ||
420 | if (lseek (avg_kd, avg_offset, 0) == -1L | |
5903c6ff | 421 | || read (avg_kd, CS (&avg), sizeof (avg)) != sizeof(avg)) |
059ec3d9 PH |
422 | return -1; |
423 | ||
424 | return (int)(((double)avg/FSCALE)*1000.0); | |
425 | } | |
426 | ||
427 | #endif | |
428 | /* ----------------------------------------------------------------------- */ | |
429 | ||
430 | ||
431 | ||
432 | /* ----------------------------------------------------------------------- */ | |
433 | /* If nothing is known about this OS, then the load average facility is | |
434 | not available. */ | |
435 | ||
436 | #ifndef OS_LOAD_AVERAGE | |
437 | ||
438 | int | |
439 | os_getloadavg(void) | |
440 | { | |
441 | return -1; | |
442 | } | |
443 | ||
444 | #endif | |
445 | ||
446 | /* ----------------------------------------------------------------------- */ | |
447 | ||
448 | ||
449 | ||
450 | #if !defined FIND_RUNNING_INTERFACES | |
451 | /************************************************* | |
452 | * Find all the running network interfaces * | |
453 | *************************************************/ | |
454 | ||
455 | /* Finding all the running interfaces is something that has os-dependent | |
456 | tweaks, even in the IPv4 case, and it gets worse for IPv6, which is why this | |
457 | code is now in the os-dependent source file. There is a common function which | |
458 | works on most OS (except IRIX) for IPv4 interfaces, and, with some variations | |
459 | controlled by macros, on at least one OS for IPv6 and IPv4 interfaces. On Linux | |
460 | with IPv6, the common function is used for the IPv4 interfaces and additional | |
461 | code used for IPv6. Consequently, the real function is called | |
462 | os_common_find_running_interfaces() so that it can be called from the Linux | |
463 | function. On non-Linux systems, the macro for os_find_running_interfaces just | |
464 | calls the common function; on Linux it calls the Linux function. | |
465 | ||
466 | This function finds the addresses of all the running interfaces on the machine. | |
467 | A chain of blocks containing the textual form of the addresses is returned. | |
468 | ||
92f9ced0 NM |
469 | getifaddrs() provides a sane consistent way to query this on modern OSs, |
470 | otherwise fall back to a maze of twisty ioctl() calls | |
471 | ||
472 | Arguments: none | |
473 | Returns: a chain of ip_address_items, each pointing to a textual | |
474 | version of an IP address, with the port field set to zero | |
475 | */ | |
476 | ||
477 | ||
478 | #ifndef NO_FIND_INTERFACES | |
479 | ||
480 | #ifdef HAVE_GETIFADDRS | |
481 | ||
482 | #include <ifaddrs.h> | |
483 | ||
484 | ip_address_item * | |
485 | os_common_find_running_interfaces(void) | |
486 | { | |
487 | struct ifaddrs *ifalist = NULL; | |
488 | ip_address_item *yield = NULL; | |
489 | ip_address_item *last = NULL; | |
490 | ip_address_item *next; | |
491 | ||
492 | if (getifaddrs(&ifalist) != 0) | |
493 | log_write(0, LOG_PANIC_DIE, "Unable to call getifaddrs: %d %s", | |
494 | errno, strerror(errno)); | |
495 | ||
d7978c0f | 496 | for (struct ifaddrs * ifa = ifalist; ifa; ifa = ifa->ifa_next) |
92f9ced0 NM |
497 | { |
498 | if (ifa->ifa_addr->sa_family != AF_INET | |
499 | #if HAVE_IPV6 | |
500 | && ifa->ifa_addr->sa_family != AF_INET6 | |
501 | #endif /* HAVE_IPV6 */ | |
502 | ) | |
503 | continue; | |
504 | ||
505 | if ( !(ifa->ifa_flags & IFF_UP) ) /* Only want 'UP' interfaces */ | |
506 | continue; | |
507 | ||
508 | /* Create a data block for the address, fill in the data, and put it on the | |
509 | chain. */ | |
510 | ||
511 | next = store_get(sizeof(ip_address_item)); | |
512 | next->next = NULL; | |
513 | next->port = 0; | |
514 | (void)host_ntoa(-1, ifa->ifa_addr, next->address, NULL); | |
515 | ||
516 | if (yield == NULL) | |
517 | yield = last = next; | |
518 | else | |
519 | { | |
520 | last->next = next; | |
521 | last = next; | |
522 | } | |
523 | ||
524 | DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n", | |
525 | last->address, ifa->ifa_name); | |
526 | } | |
527 | ||
528 | /* free the list of addresses, and return the chain of data blocks. */ | |
529 | ||
530 | freeifaddrs (ifalist); | |
531 | return yield; | |
532 | } | |
533 | ||
534 | #else /* HAVE_GETIFADDRS */ | |
535 | ||
536 | /* | |
059ec3d9 PH |
537 | Problems: |
538 | ||
539 | (1) Solaris 2 has the SIOGIFNUM call to get the number of interfaces, but | |
540 | other OS (including Solaris 1) appear not to. So just screw in a largeish | |
541 | fixed number, defined by MAX_INTERFACES. This is in the config.h file and | |
542 | can be changed in Local/Makefile. Unfortunately, the www addressing scheme | |
543 | means that some hosts have a very large number of virtual interfaces. Such | |
544 | hosts are recommended to set local_interfaces to avoid problems with this. | |
545 | ||
546 | (2) If the standard code is run on IRIX, it does not return any alias | |
547 | interfaces. There is special purpose code for that operating system, which | |
548 | uses the sysctl() function. The code is in OS/os.c-IRIX, and this code isn't | |
549 | used on that OS. | |
550 | ||
551 | (3) Some experimental/developing OS (e.g. GNU/Hurd) do not have any means | |
552 | of finding the interfaces. If NO_FIND_INTERFACES is set, a fudge-up is used | |
553 | instead. | |
554 | ||
555 | (4) Some operating systems set the IP address in what SIOCGIFCONF returns; | |
556 | others do not, and require SIOCGIFADDR to be called to get it. For most of | |
557 | the former, calling the latter does no harm, but it causes grief on Linux and | |
558 | BSD systems in the case of IP aliasing, so a means of cutting it out is | |
559 | provided. | |
059ec3d9 PH |
560 | */ |
561 | ||
059ec3d9 PH |
562 | /* If there is IPv6 support, and SIOCGLIFCONF is defined, define macros to |
563 | use these new, longer versions of the old IPv4 interfaces. Otherwise, define | |
564 | the macros to use the historical versions. */ | |
565 | ||
566 | #if HAVE_IPV6 && defined SIOCGLIFCONF | |
567 | #define V_ifconf lifconf | |
568 | #define V_ifreq lifreq | |
569 | #define V_GIFADDR SIOCGLIFADDR | |
570 | #define V_GIFCONF SIOCGLIFCONF | |
571 | #define V_GIFFLAGS SIOCGLIFFLAGS | |
572 | #define V_ifc_buf lifc_buf | |
573 | #define V_ifc_family lifc_family | |
574 | #define V_ifc_flags lifc_flags | |
575 | #define V_ifc_len lifc_len | |
576 | #define V_ifr_addr lifr_addr | |
577 | #define V_ifr_flags lifr_flags | |
578 | #define V_ifr_name lifr_name | |
579 | #define V_FAMILY_QUERY AF_UNSPEC | |
580 | #define V_family ss_family | |
581 | #else | |
582 | #define V_ifconf ifconf | |
583 | #define V_ifreq ifreq | |
584 | #define V_GIFADDR SIOCGIFADDR | |
585 | #define V_GIFCONF SIOCGIFCONF | |
586 | #define V_GIFFLAGS SIOCGIFFLAGS | |
587 | #define V_ifc_buf ifc_buf | |
588 | #define V_ifc_family ifc_family | |
589 | #define V_ifc_flags ifc_flags | |
590 | #define V_ifc_len ifc_len | |
591 | #define V_ifr_addr ifr_addr | |
592 | #define V_ifr_flags ifr_flags | |
593 | #define V_ifr_name ifr_name | |
594 | #define V_family sa_family | |
595 | #endif | |
596 | ||
597 | /* In all cases of IPv6 support, use an IPv6 socket. Otherwise (at least on | |
598 | Solaris 8) the call to read the flags doesn't work for IPv6 interfaces. If | |
599 | we find we can't actually make an IPv6 socket, the code will revert to trying | |
600 | an IPv4 socket. */ | |
601 | ||
602 | #if HAVE_IPV6 | |
603 | #define FAMILY AF_INET6 | |
604 | #else | |
605 | #define FAMILY AF_INET | |
606 | #endif | |
607 | ||
608 | /* OK, after all that preliminary stuff, here's the code. */ | |
609 | ||
610 | ip_address_item * | |
611 | os_common_find_running_interfaces(void) | |
612 | { | |
613 | struct V_ifconf ifc; | |
614 | struct V_ifreq ifreq; | |
615 | int vs; | |
616 | ip_address_item *yield = NULL; | |
617 | ip_address_item *last = NULL; | |
618 | ip_address_item *next; | |
059ec3d9 PH |
619 | char buf[MAX_INTERFACES*sizeof(struct V_ifreq)]; |
620 | struct sockaddr *addrp; | |
621 | size_t len = 0; | |
92f9ced0 | 622 | char addrbuf[512]; |
059ec3d9 PH |
623 | |
624 | /* We have to create a socket in order to do ioctls on it to find out | |
625 | what we want to know. */ | |
626 | ||
627 | if ((vs = socket(FAMILY, SOCK_DGRAM, 0)) < 0) | |
628 | { | |
629 | #if HAVE_IPV6 | |
630 | DEBUG(D_interface) | |
631 | debug_printf("Unable to create IPv6 socket to find interface addresses:\n " | |
632 | "error %d %s\nTrying for an IPv4 socket\n", errno, strerror(errno)); | |
633 | vs = socket(AF_INET, SOCK_DGRAM, 0); | |
634 | if (vs < 0) | |
635 | #endif | |
636 | log_write(0, LOG_PANIC_DIE, "Unable to create IPv4 socket to find interface " | |
637 | "addresses: %d %s", errno, strerror(errno)); | |
638 | } | |
639 | ||
640 | /* Get the interface configuration. Some additional data is required when the | |
641 | new structures are in use. */ | |
642 | ||
643 | ifc.V_ifc_len = sizeof(buf); | |
644 | ifc.V_ifc_buf = buf; | |
645 | ||
646 | #ifdef V_FAMILY_QUERY | |
647 | ifc.V_ifc_family = V_FAMILY_QUERY; | |
648 | ifc.V_ifc_flags = 0; | |
649 | #endif | |
650 | ||
5903c6ff | 651 | if (ioctl(vs, V_GIFCONF, CS &ifc) < 0) |
059ec3d9 PH |
652 | log_write(0, LOG_PANIC_DIE, "Unable to get interface configuration: %d %s", |
653 | errno, strerror(errno)); | |
654 | ||
655 | /* If the buffer is big enough, the ioctl sets the value of ifc.V_ifc_len to | |
656 | the amount actually used. If the buffer isn't big enough, at least on some | |
657 | operating systems, ifc.V_ifc_len still gets set to correspond to the total | |
658 | number of interfaces, even though they don't all fit in the buffer. */ | |
659 | ||
660 | if (ifc.V_ifc_len > sizeof(buf)) | |
661 | { | |
662 | ifc.V_ifc_len = sizeof(buf); | |
663 | DEBUG(D_interface) | |
664 | debug_printf("more than %d interfaces found: remainder not used\n" | |
665 | "(set MAX_INTERFACES in Local/Makefile and rebuild if you want more)\n", | |
666 | MAX_INTERFACES); | |
667 | } | |
668 | ||
669 | /* For each interface, check it is an IP interface, get its flags, and see if | |
670 | it is up; if not, skip. | |
671 | ||
672 | BSD systems differ from others in what SIOCGIFCONF returns. Other systems | |
673 | return a vector of ifreq structures whose size is as defined by the structure. | |
674 | BSD systems allow sockaddrs to be longer than their sizeof, which in turn makes | |
675 | the ifreq structures longer than their sizeof. The code below has its origins | |
676 | in amd and ifconfig; it uses the sa_len field of each sockaddr to determine | |
677 | each item's length. | |
678 | ||
679 | This is complicated by the fact that, at least on BSD systems, the data in the | |
680 | buffer is not guaranteed to be aligned. Thus, we must first copy the basic | |
681 | struct to some aligned memory before looking at the field in the fixed part to | |
682 | find its length, and then recopy the correct length. */ | |
683 | ||
d7978c0f | 684 | for (char * cp = buf; cp < buf + ifc.V_ifc_len; cp += len) |
059ec3d9 | 685 | { |
5903c6ff | 686 | memcpy(CS &ifreq, cp, sizeof(ifreq)); |
059ec3d9 PH |
687 | |
688 | #ifndef HAVE_SA_LEN | |
689 | len = sizeof(struct V_ifreq); | |
690 | ||
691 | #else | |
692 | len = ((ifreq.ifr_addr.sa_len > sizeof(ifreq.ifr_addr))? | |
693 | ifreq.ifr_addr.sa_len : sizeof(ifreq.ifr_addr)) + | |
694 | sizeof(ifreq.V_ifr_name); | |
695 | if (len > sizeof(addrbuf)) | |
696 | log_write(0, LOG_PANIC_DIE, "Address for %s interface is absurdly long", | |
697 | ifreq.V_ifr_name); | |
698 | ||
699 | #endif | |
700 | ||
701 | /* If not an IP interface, skip */ | |
702 | ||
703 | if (ifreq.V_ifr_addr.V_family != AF_INET | |
704 | #if HAVE_IPV6 | |
705 | && ifreq.V_ifr_addr.V_family != AF_INET6 | |
706 | #endif | |
707 | ) continue; | |
708 | ||
709 | /* Get the interface flags, and if the interface is down, continue. Formerly, | |
710 | we treated the inability to get the flags as a panic-die error. However, it | |
711 | seems that on some OS (Solaris 9 being the case noted), it is possible to | |
712 | have an interface in this list for which this call fails because the | |
713 | interface hasn't been "plumbed" to any protocol (IPv4 or IPv6). Therefore, | |
714 | we now just treat this case as "down" as well. */ | |
715 | ||
5903c6ff | 716 | if (ioctl(vs, V_GIFFLAGS, CS &ifreq) < 0) |
059ec3d9 PH |
717 | { |
718 | continue; | |
719 | /************* | |
720 | log_write(0, LOG_PANIC_DIE, "Unable to get flags for %s interface: %d %s", | |
721 | ifreq.V_ifr_name, errno, strerror(errno)); | |
722 | *************/ | |
723 | } | |
724 | if ((ifreq.V_ifr_flags & IFF_UP) == 0) continue; | |
725 | ||
726 | /* On some operating systems we have to get the IP address of the interface | |
214e2000 PH |
727 | by another call. On others, it's already there, but we must copy the full |
728 | length because we only copied the basic length above, and anyway, | |
729 | GIFFLAGS may have wrecked the data. */ | |
059ec3d9 PH |
730 | |
731 | #ifndef SIOCGIFCONF_GIVES_ADDR | |
5903c6ff | 732 | if (ioctl(vs, V_GIFADDR, CS &ifreq) < 0) |
059ec3d9 PH |
733 | log_write(0, LOG_PANIC_DIE, "Unable to get IP address for %s interface: " |
734 | "%d %s", ifreq.V_ifr_name, errno, strerror(errno)); | |
735 | addrp = &ifreq.V_ifr_addr; | |
736 | ||
737 | #else | |
214e2000 PH |
738 | memcpy(addrbuf, cp + offsetof(struct V_ifreq, V_ifr_addr), |
739 | len - sizeof(ifreq.V_ifr_name)); | |
059ec3d9 PH |
740 | addrp = (struct sockaddr *)addrbuf; |
741 | #endif | |
742 | ||
743 | /* Create a data block for the address, fill in the data, and put it on the | |
744 | chain. */ | |
745 | ||
746 | next = store_get(sizeof(ip_address_item)); | |
747 | next->next = NULL; | |
748 | next->port = 0; | |
749 | (void)host_ntoa(-1, addrp, next->address, NULL); | |
750 | ||
751 | if (yield == NULL) yield = last = next; else | |
752 | { | |
753 | last->next = next; | |
754 | last = next; | |
755 | } | |
756 | ||
757 | DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n", | |
758 | last->address, ifreq.V_ifr_name); | |
759 | } | |
760 | ||
761 | /* Close the socket, and return the chain of data blocks. */ | |
762 | ||
f1e894f3 | 763 | (void)close(vs); |
059ec3d9 PH |
764 | return yield; |
765 | } | |
766 | ||
92f9ced0 NM |
767 | #endif /* HAVE_GETIFADDRS */ |
768 | ||
059ec3d9 PH |
769 | #else /* NO_FIND_INTERFACES */ |
770 | ||
771 | /* Some experimental or developing OS (e.g. GNU/Hurd) do not have the ioctls, | |
772 | and there is no other way to get a list of the (IP addresses of) local | |
773 | interfaces. We just return the loopback address(es). */ | |
774 | ||
775 | ip_address_item * | |
776 | os_common_find_running_interfaces(void) | |
777 | { | |
778 | ip_address_item *yield = store_get(sizeof(address_item)); | |
779 | yield->address = US"127.0.0.1"; | |
780 | yield->port = 0; | |
781 | yield->next = NULL; | |
782 | ||
783 | #if HAVE_IPV6 | |
784 | yield->next = store_get(sizeof(address_item)); | |
785 | yield->next->address = US"::1"; | |
786 | yield->next->port = 0; | |
787 | yield->next->next = NULL; | |
788 | #endif | |
789 | ||
790 | DEBUG(D_interface) debug_printf("Unable to find local interface addresses " | |
791 | "on this OS: returning loopback address(es)\n"); | |
792 | return yield; | |
793 | } | |
794 | ||
795 | #endif /* NO_FIND_INTERFACES */ | |
796 | #endif /* FIND_RUNNING_INTERFACES */ | |
797 | ||
798 | ||
799 | ||
800 | ||
5bfb4cdf PP |
801 | /* ----------------------------------------------------------------------- */ |
802 | ||
803 | /*********************************************************** | |
804 | * DNS Resolver Base Finder * | |
805 | ***********************************************************/ | |
806 | ||
807 | /* We need to be able to set options for the system resolver(5), historically | |
808 | made available as _res. At least one OS (NetBSD) now no longer provides this | |
809 | directly, instead making you call a function per thread to get a handle. | |
810 | Other OSs handle thread-safe resolver differently, in ways which fail if the | |
811 | programmer creates their own structs. */ | |
812 | ||
0a3df1d6 | 813 | #if !defined(OS_GET_DNS_RESOLVER_RES) && !defined(COMPILE_UTILITY) |
5bfb4cdf PP |
814 | |
815 | #include <resolv.h> | |
816 | ||
817 | /* confirmed that res_state is typedef'd as a struct* on BSD and Linux, will | |
818 | find out how unportable it is on other OSes, but most resolver implementations | |
819 | should be descended from ISC's bind. | |
820 | ||
821 | Linux and BSD do: | |
822 | define _res (*__res_state()) | |
823 | identically. We just can't rely on __foo functions. It's surprising that use | |
824 | of _res has been as portable as it has, for so long. | |
825 | ||
826 | So, since _res works everywhere, and everything can decode the struct, I'm | |
827 | going to gamble that res_state is a typedef everywhere and use that as the | |
828 | return type. | |
829 | */ | |
830 | ||
831 | res_state | |
832 | os_get_dns_resolver_res(void) | |
833 | { | |
834 | return &_res; | |
835 | } | |
836 | ||
837 | #endif /* OS_GET_DNS_RESOLVER_RES */ | |
838 | ||
5bfb4cdf PP |
839 | /* ----------------------------------------------------------------------- */ |
840 | ||
271019bd HSHR |
841 | /*********************************************************** |
842 | * unsetenv() * | |
843 | ***********************************************************/ | |
844 | ||
845 | /* Most modern systems define int unsetenv(const char*), | |
846 | * some don't. */ | |
847 | ||
848 | #if !defined(OS_UNSETENV) | |
849 | int | |
f8c0a35c | 850 | os_unsetenv(const unsigned char * name) |
271019bd | 851 | { |
5903c6ff | 852 | return unsetenv(CS name); |
271019bd HSHR |
853 | } |
854 | #endif | |
855 | ||
3ae121c9 HSHR |
856 | /* ----------------------------------------------------------------------- */ |
857 | ||
858 | /*********************************************************** | |
859 | * getcwd() * | |
860 | ***********************************************************/ | |
861 | ||
862 | /* Glibc allows getcwd(NULL, 0) to do auto-allocation. Some systems | |
863 | do auto-allocation, but need the size of the buffer, and others | |
864 | may not even do this. If the OS supports getcwd(NULL, 0) we'll use | |
865 | this, for all other systems we provide our own getcwd() */ | |
866 | ||
867 | #if !defined(OS_GETCWD) | |
f8c0a35c JH |
868 | unsigned char * |
869 | os_getcwd(unsigned char * buffer, size_t size) | |
3ae121c9 | 870 | { |
5903c6ff | 871 | return US getcwd(CS buffer, size); |
3ae121c9 HSHR |
872 | } |
873 | #else | |
874 | #ifndef PATH_MAX | |
875 | # define PATH_MAX 4096 | |
876 | #endif | |
f8c0a35c JH |
877 | unsigned char * |
878 | os_getcwd(unsigned char * buffer, size_t size) | |
3ae121c9 | 879 | { |
5903c6ff | 880 | char * b = CS buffer; |
3ae121c9 HSHR |
881 | |
882 | if (!size) size = PATH_MAX; | |
490f424e JH |
883 | if (!b && !(b = malloc(size))) return NULL; |
884 | if (!(b = getcwd(b, size))) return NULL; | |
4a5ee04f | 885 | return buffer ? buffer : realloc(b, strlen(b) + 1); |
3ae121c9 HSHR |
886 | } |
887 | #endif | |
271019bd HSHR |
888 | |
889 | /* ----------------------------------------------------------------------- */ | |
5bfb4cdf PP |
890 | |
891 | ||
892 | ||
059ec3d9 PH |
893 | |
894 | /************************************************* | |
895 | ************************************************** | |
896 | * Stand-alone test program * | |
897 | ************************************************** | |
898 | *************************************************/ | |
899 | ||
900 | ||
901 | #ifdef STAND_ALONE | |
902 | ||
903 | #ifdef CLOCKS_PER_SEC | |
904 | #define REAL_CLOCK_TICK CLOCKS_PER_SEC | |
905 | #else | |
906 | #ifdef CLK_TCK | |
907 | #define REAL_CLOCK_TICK CLK_TCK | |
908 | #else | |
909 | #define REAL_CLOCK_TICK 1000000 /* SunOS4 */ | |
910 | #endif | |
911 | #endif | |
912 | ||
913 | ||
914 | int main(int argc, char **argv) | |
915 | { | |
916 | char buffer[128]; | |
917 | int fd = fileno(stdin); | |
918 | int rc; | |
919 | ||
920 | printf("Testing restarting signal; wait for handler message, then type a line\n"); | |
921 | strcpy(buffer, "*** default ***\n"); | |
922 | os_restarting_signal(SIGALRM, sigalrm_handler); | |
c2a1bba0 | 923 | ALARM(2); |
059ec3d9 PH |
924 | if ((rc = read(fd, buffer, sizeof(buffer))) < 0) |
925 | printf("No data read\n"); | |
926 | else | |
927 | { | |
928 | buffer[rc] = 0; | |
929 | printf("Read: %s", buffer); | |
930 | } | |
c2a1bba0 | 931 | ALARM_CLR(0); |
059ec3d9 PH |
932 | |
933 | printf("Testing non-restarting signal; should read no data after handler message\n"); | |
934 | strcpy(buffer, "*** default ***\n"); | |
935 | os_non_restarting_signal(SIGALRM, sigalrm_handler); | |
c2a1bba0 | 936 | ALARM(2); |
059ec3d9 PH |
937 | if ((rc = read(fd, buffer, sizeof(buffer))) < 0) |
938 | printf("No data read\n"); | |
939 | else | |
940 | { | |
941 | buffer[rc] = 0; | |
942 | printf("Read: %s", buffer); | |
943 | } | |
c2a1bba0 | 944 | ALARM_CLR(0); |
059ec3d9 PH |
945 | |
946 | printf("Testing load averages (last test - ^C to kill)\n"); | |
947 | for (;;) | |
948 | { | |
949 | int avg; | |
950 | clock_t used; | |
951 | clock_t before = clock(); | |
952 | avg = os_getloadavg(); | |
953 | used = clock() - before; | |
954 | printf("cpu time = %.2f ", (double)used/REAL_CLOCK_TICK); | |
955 | if (avg < 0) | |
956 | { | |
957 | printf("load average not available\n"); | |
958 | break; | |
959 | } | |
960 | printf("load average = %.2f\n", (double)avg/1000.0); | |
961 | sleep(2); | |
962 | } | |
963 | return 0; | |
964 | } | |
965 | ||
966 | #endif | |
967 | ||
968 | /* End of os.c */ |