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 | ||
496 | struct ifaddrs *ifa; | |
497 | for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) | |
498 | { | |
499 | if (ifa->ifa_addr->sa_family != AF_INET | |
500 | #if HAVE_IPV6 | |
501 | && ifa->ifa_addr->sa_family != AF_INET6 | |
502 | #endif /* HAVE_IPV6 */ | |
503 | ) | |
504 | continue; | |
505 | ||
506 | if ( !(ifa->ifa_flags & IFF_UP) ) /* Only want 'UP' interfaces */ | |
507 | continue; | |
508 | ||
509 | /* Create a data block for the address, fill in the data, and put it on the | |
510 | chain. */ | |
511 | ||
512 | next = store_get(sizeof(ip_address_item)); | |
513 | next->next = NULL; | |
514 | next->port = 0; | |
515 | (void)host_ntoa(-1, ifa->ifa_addr, next->address, NULL); | |
516 | ||
517 | if (yield == NULL) | |
518 | yield = last = next; | |
519 | else | |
520 | { | |
521 | last->next = next; | |
522 | last = next; | |
523 | } | |
524 | ||
525 | DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n", | |
526 | last->address, ifa->ifa_name); | |
527 | } | |
528 | ||
529 | /* free the list of addresses, and return the chain of data blocks. */ | |
530 | ||
531 | freeifaddrs (ifalist); | |
532 | return yield; | |
533 | } | |
534 | ||
535 | #else /* HAVE_GETIFADDRS */ | |
536 | ||
537 | /* | |
059ec3d9 PH |
538 | Problems: |
539 | ||
540 | (1) Solaris 2 has the SIOGIFNUM call to get the number of interfaces, but | |
541 | other OS (including Solaris 1) appear not to. So just screw in a largeish | |
542 | fixed number, defined by MAX_INTERFACES. This is in the config.h file and | |
543 | can be changed in Local/Makefile. Unfortunately, the www addressing scheme | |
544 | means that some hosts have a very large number of virtual interfaces. Such | |
545 | hosts are recommended to set local_interfaces to avoid problems with this. | |
546 | ||
547 | (2) If the standard code is run on IRIX, it does not return any alias | |
548 | interfaces. There is special purpose code for that operating system, which | |
549 | uses the sysctl() function. The code is in OS/os.c-IRIX, and this code isn't | |
550 | used on that OS. | |
551 | ||
552 | (3) Some experimental/developing OS (e.g. GNU/Hurd) do not have any means | |
553 | of finding the interfaces. If NO_FIND_INTERFACES is set, a fudge-up is used | |
554 | instead. | |
555 | ||
556 | (4) Some operating systems set the IP address in what SIOCGIFCONF returns; | |
557 | others do not, and require SIOCGIFADDR to be called to get it. For most of | |
558 | the former, calling the latter does no harm, but it causes grief on Linux and | |
559 | BSD systems in the case of IP aliasing, so a means of cutting it out is | |
560 | provided. | |
059ec3d9 PH |
561 | */ |
562 | ||
059ec3d9 PH |
563 | /* If there is IPv6 support, and SIOCGLIFCONF is defined, define macros to |
564 | use these new, longer versions of the old IPv4 interfaces. Otherwise, define | |
565 | the macros to use the historical versions. */ | |
566 | ||
567 | #if HAVE_IPV6 && defined SIOCGLIFCONF | |
568 | #define V_ifconf lifconf | |
569 | #define V_ifreq lifreq | |
570 | #define V_GIFADDR SIOCGLIFADDR | |
571 | #define V_GIFCONF SIOCGLIFCONF | |
572 | #define V_GIFFLAGS SIOCGLIFFLAGS | |
573 | #define V_ifc_buf lifc_buf | |
574 | #define V_ifc_family lifc_family | |
575 | #define V_ifc_flags lifc_flags | |
576 | #define V_ifc_len lifc_len | |
577 | #define V_ifr_addr lifr_addr | |
578 | #define V_ifr_flags lifr_flags | |
579 | #define V_ifr_name lifr_name | |
580 | #define V_FAMILY_QUERY AF_UNSPEC | |
581 | #define V_family ss_family | |
582 | #else | |
583 | #define V_ifconf ifconf | |
584 | #define V_ifreq ifreq | |
585 | #define V_GIFADDR SIOCGIFADDR | |
586 | #define V_GIFCONF SIOCGIFCONF | |
587 | #define V_GIFFLAGS SIOCGIFFLAGS | |
588 | #define V_ifc_buf ifc_buf | |
589 | #define V_ifc_family ifc_family | |
590 | #define V_ifc_flags ifc_flags | |
591 | #define V_ifc_len ifc_len | |
592 | #define V_ifr_addr ifr_addr | |
593 | #define V_ifr_flags ifr_flags | |
594 | #define V_ifr_name ifr_name | |
595 | #define V_family sa_family | |
596 | #endif | |
597 | ||
598 | /* In all cases of IPv6 support, use an IPv6 socket. Otherwise (at least on | |
599 | Solaris 8) the call to read the flags doesn't work for IPv6 interfaces. If | |
600 | we find we can't actually make an IPv6 socket, the code will revert to trying | |
601 | an IPv4 socket. */ | |
602 | ||
603 | #if HAVE_IPV6 | |
604 | #define FAMILY AF_INET6 | |
605 | #else | |
606 | #define FAMILY AF_INET | |
607 | #endif | |
608 | ||
609 | /* OK, after all that preliminary stuff, here's the code. */ | |
610 | ||
611 | ip_address_item * | |
612 | os_common_find_running_interfaces(void) | |
613 | { | |
614 | struct V_ifconf ifc; | |
615 | struct V_ifreq ifreq; | |
616 | int vs; | |
617 | ip_address_item *yield = NULL; | |
618 | ip_address_item *last = NULL; | |
619 | ip_address_item *next; | |
620 | char *cp; | |
621 | char buf[MAX_INTERFACES*sizeof(struct V_ifreq)]; | |
622 | struct sockaddr *addrp; | |
623 | size_t len = 0; | |
92f9ced0 | 624 | char addrbuf[512]; |
059ec3d9 PH |
625 | |
626 | /* We have to create a socket in order to do ioctls on it to find out | |
627 | what we want to know. */ | |
628 | ||
629 | if ((vs = socket(FAMILY, SOCK_DGRAM, 0)) < 0) | |
630 | { | |
631 | #if HAVE_IPV6 | |
632 | DEBUG(D_interface) | |
633 | debug_printf("Unable to create IPv6 socket to find interface addresses:\n " | |
634 | "error %d %s\nTrying for an IPv4 socket\n", errno, strerror(errno)); | |
635 | vs = socket(AF_INET, SOCK_DGRAM, 0); | |
636 | if (vs < 0) | |
637 | #endif | |
638 | log_write(0, LOG_PANIC_DIE, "Unable to create IPv4 socket to find interface " | |
639 | "addresses: %d %s", errno, strerror(errno)); | |
640 | } | |
641 | ||
642 | /* Get the interface configuration. Some additional data is required when the | |
643 | new structures are in use. */ | |
644 | ||
645 | ifc.V_ifc_len = sizeof(buf); | |
646 | ifc.V_ifc_buf = buf; | |
647 | ||
648 | #ifdef V_FAMILY_QUERY | |
649 | ifc.V_ifc_family = V_FAMILY_QUERY; | |
650 | ifc.V_ifc_flags = 0; | |
651 | #endif | |
652 | ||
5903c6ff | 653 | if (ioctl(vs, V_GIFCONF, CS &ifc) < 0) |
059ec3d9 PH |
654 | log_write(0, LOG_PANIC_DIE, "Unable to get interface configuration: %d %s", |
655 | errno, strerror(errno)); | |
656 | ||
657 | /* If the buffer is big enough, the ioctl sets the value of ifc.V_ifc_len to | |
658 | the amount actually used. If the buffer isn't big enough, at least on some | |
659 | operating systems, ifc.V_ifc_len still gets set to correspond to the total | |
660 | number of interfaces, even though they don't all fit in the buffer. */ | |
661 | ||
662 | if (ifc.V_ifc_len > sizeof(buf)) | |
663 | { | |
664 | ifc.V_ifc_len = sizeof(buf); | |
665 | DEBUG(D_interface) | |
666 | debug_printf("more than %d interfaces found: remainder not used\n" | |
667 | "(set MAX_INTERFACES in Local/Makefile and rebuild if you want more)\n", | |
668 | MAX_INTERFACES); | |
669 | } | |
670 | ||
671 | /* For each interface, check it is an IP interface, get its flags, and see if | |
672 | it is up; if not, skip. | |
673 | ||
674 | BSD systems differ from others in what SIOCGIFCONF returns. Other systems | |
675 | return a vector of ifreq structures whose size is as defined by the structure. | |
676 | BSD systems allow sockaddrs to be longer than their sizeof, which in turn makes | |
677 | the ifreq structures longer than their sizeof. The code below has its origins | |
678 | in amd and ifconfig; it uses the sa_len field of each sockaddr to determine | |
679 | each item's length. | |
680 | ||
681 | This is complicated by the fact that, at least on BSD systems, the data in the | |
682 | buffer is not guaranteed to be aligned. Thus, we must first copy the basic | |
683 | struct to some aligned memory before looking at the field in the fixed part to | |
684 | find its length, and then recopy the correct length. */ | |
685 | ||
686 | for (cp = buf; cp < buf + ifc.V_ifc_len; cp += len) | |
687 | { | |
5903c6ff | 688 | memcpy(CS &ifreq, cp, sizeof(ifreq)); |
059ec3d9 PH |
689 | |
690 | #ifndef HAVE_SA_LEN | |
691 | len = sizeof(struct V_ifreq); | |
692 | ||
693 | #else | |
694 | len = ((ifreq.ifr_addr.sa_len > sizeof(ifreq.ifr_addr))? | |
695 | ifreq.ifr_addr.sa_len : sizeof(ifreq.ifr_addr)) + | |
696 | sizeof(ifreq.V_ifr_name); | |
697 | if (len > sizeof(addrbuf)) | |
698 | log_write(0, LOG_PANIC_DIE, "Address for %s interface is absurdly long", | |
699 | ifreq.V_ifr_name); | |
700 | ||
701 | #endif | |
702 | ||
703 | /* If not an IP interface, skip */ | |
704 | ||
705 | if (ifreq.V_ifr_addr.V_family != AF_INET | |
706 | #if HAVE_IPV6 | |
707 | && ifreq.V_ifr_addr.V_family != AF_INET6 | |
708 | #endif | |
709 | ) continue; | |
710 | ||
711 | /* Get the interface flags, and if the interface is down, continue. Formerly, | |
712 | we treated the inability to get the flags as a panic-die error. However, it | |
713 | seems that on some OS (Solaris 9 being the case noted), it is possible to | |
714 | have an interface in this list for which this call fails because the | |
715 | interface hasn't been "plumbed" to any protocol (IPv4 or IPv6). Therefore, | |
716 | we now just treat this case as "down" as well. */ | |
717 | ||
5903c6ff | 718 | if (ioctl(vs, V_GIFFLAGS, CS &ifreq) < 0) |
059ec3d9 PH |
719 | { |
720 | continue; | |
721 | /************* | |
722 | log_write(0, LOG_PANIC_DIE, "Unable to get flags for %s interface: %d %s", | |
723 | ifreq.V_ifr_name, errno, strerror(errno)); | |
724 | *************/ | |
725 | } | |
726 | if ((ifreq.V_ifr_flags & IFF_UP) == 0) continue; | |
727 | ||
728 | /* On some operating systems we have to get the IP address of the interface | |
214e2000 PH |
729 | by another call. On others, it's already there, but we must copy the full |
730 | length because we only copied the basic length above, and anyway, | |
731 | GIFFLAGS may have wrecked the data. */ | |
059ec3d9 PH |
732 | |
733 | #ifndef SIOCGIFCONF_GIVES_ADDR | |
5903c6ff | 734 | if (ioctl(vs, V_GIFADDR, CS &ifreq) < 0) |
059ec3d9 PH |
735 | log_write(0, LOG_PANIC_DIE, "Unable to get IP address for %s interface: " |
736 | "%d %s", ifreq.V_ifr_name, errno, strerror(errno)); | |
737 | addrp = &ifreq.V_ifr_addr; | |
738 | ||
739 | #else | |
214e2000 PH |
740 | memcpy(addrbuf, cp + offsetof(struct V_ifreq, V_ifr_addr), |
741 | len - sizeof(ifreq.V_ifr_name)); | |
059ec3d9 PH |
742 | addrp = (struct sockaddr *)addrbuf; |
743 | #endif | |
744 | ||
745 | /* Create a data block for the address, fill in the data, and put it on the | |
746 | chain. */ | |
747 | ||
748 | next = store_get(sizeof(ip_address_item)); | |
749 | next->next = NULL; | |
750 | next->port = 0; | |
751 | (void)host_ntoa(-1, addrp, next->address, NULL); | |
752 | ||
753 | if (yield == NULL) yield = last = next; else | |
754 | { | |
755 | last->next = next; | |
756 | last = next; | |
757 | } | |
758 | ||
759 | DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n", | |
760 | last->address, ifreq.V_ifr_name); | |
761 | } | |
762 | ||
763 | /* Close the socket, and return the chain of data blocks. */ | |
764 | ||
f1e894f3 | 765 | (void)close(vs); |
059ec3d9 PH |
766 | return yield; |
767 | } | |
768 | ||
92f9ced0 NM |
769 | #endif /* HAVE_GETIFADDRS */ |
770 | ||
059ec3d9 PH |
771 | #else /* NO_FIND_INTERFACES */ |
772 | ||
773 | /* Some experimental or developing OS (e.g. GNU/Hurd) do not have the ioctls, | |
774 | and there is no other way to get a list of the (IP addresses of) local | |
775 | interfaces. We just return the loopback address(es). */ | |
776 | ||
777 | ip_address_item * | |
778 | os_common_find_running_interfaces(void) | |
779 | { | |
780 | ip_address_item *yield = store_get(sizeof(address_item)); | |
781 | yield->address = US"127.0.0.1"; | |
782 | yield->port = 0; | |
783 | yield->next = NULL; | |
784 | ||
785 | #if HAVE_IPV6 | |
786 | yield->next = store_get(sizeof(address_item)); | |
787 | yield->next->address = US"::1"; | |
788 | yield->next->port = 0; | |
789 | yield->next->next = NULL; | |
790 | #endif | |
791 | ||
792 | DEBUG(D_interface) debug_printf("Unable to find local interface addresses " | |
793 | "on this OS: returning loopback address(es)\n"); | |
794 | return yield; | |
795 | } | |
796 | ||
797 | #endif /* NO_FIND_INTERFACES */ | |
798 | #endif /* FIND_RUNNING_INTERFACES */ | |
799 | ||
800 | ||
801 | ||
802 | ||
5bfb4cdf PP |
803 | /* ----------------------------------------------------------------------- */ |
804 | ||
805 | /*********************************************************** | |
806 | * DNS Resolver Base Finder * | |
807 | ***********************************************************/ | |
808 | ||
809 | /* We need to be able to set options for the system resolver(5), historically | |
810 | made available as _res. At least one OS (NetBSD) now no longer provides this | |
811 | directly, instead making you call a function per thread to get a handle. | |
812 | Other OSs handle thread-safe resolver differently, in ways which fail if the | |
813 | programmer creates their own structs. */ | |
814 | ||
0a3df1d6 | 815 | #if !defined(OS_GET_DNS_RESOLVER_RES) && !defined(COMPILE_UTILITY) |
5bfb4cdf PP |
816 | |
817 | #include <resolv.h> | |
818 | ||
819 | /* confirmed that res_state is typedef'd as a struct* on BSD and Linux, will | |
820 | find out how unportable it is on other OSes, but most resolver implementations | |
821 | should be descended from ISC's bind. | |
822 | ||
823 | Linux and BSD do: | |
824 | define _res (*__res_state()) | |
825 | identically. We just can't rely on __foo functions. It's surprising that use | |
826 | of _res has been as portable as it has, for so long. | |
827 | ||
828 | So, since _res works everywhere, and everything can decode the struct, I'm | |
829 | going to gamble that res_state is a typedef everywhere and use that as the | |
830 | return type. | |
831 | */ | |
832 | ||
833 | res_state | |
834 | os_get_dns_resolver_res(void) | |
835 | { | |
836 | return &_res; | |
837 | } | |
838 | ||
839 | #endif /* OS_GET_DNS_RESOLVER_RES */ | |
840 | ||
5bfb4cdf PP |
841 | /* ----------------------------------------------------------------------- */ |
842 | ||
271019bd HSHR |
843 | /*********************************************************** |
844 | * unsetenv() * | |
845 | ***********************************************************/ | |
846 | ||
847 | /* Most modern systems define int unsetenv(const char*), | |
848 | * some don't. */ | |
849 | ||
850 | #if !defined(OS_UNSETENV) | |
851 | int | |
f8c0a35c | 852 | os_unsetenv(const unsigned char * name) |
271019bd | 853 | { |
5903c6ff | 854 | return unsetenv(CS name); |
271019bd HSHR |
855 | } |
856 | #endif | |
857 | ||
3ae121c9 HSHR |
858 | /* ----------------------------------------------------------------------- */ |
859 | ||
860 | /*********************************************************** | |
861 | * getcwd() * | |
862 | ***********************************************************/ | |
863 | ||
864 | /* Glibc allows getcwd(NULL, 0) to do auto-allocation. Some systems | |
865 | do auto-allocation, but need the size of the buffer, and others | |
866 | may not even do this. If the OS supports getcwd(NULL, 0) we'll use | |
867 | this, for all other systems we provide our own getcwd() */ | |
868 | ||
869 | #if !defined(OS_GETCWD) | |
f8c0a35c JH |
870 | unsigned char * |
871 | os_getcwd(unsigned char * buffer, size_t size) | |
3ae121c9 | 872 | { |
5903c6ff | 873 | return US getcwd(CS buffer, size); |
3ae121c9 HSHR |
874 | } |
875 | #else | |
876 | #ifndef PATH_MAX | |
877 | # define PATH_MAX 4096 | |
878 | #endif | |
f8c0a35c JH |
879 | unsigned char * |
880 | os_getcwd(unsigned char * buffer, size_t size) | |
3ae121c9 | 881 | { |
5903c6ff | 882 | char * b = CS buffer; |
3ae121c9 HSHR |
883 | |
884 | if (!size) size = PATH_MAX; | |
490f424e JH |
885 | if (!b && !(b = malloc(size))) return NULL; |
886 | if (!(b = getcwd(b, size))) return NULL; | |
4a5ee04f | 887 | return buffer ? buffer : realloc(b, strlen(b) + 1); |
3ae121c9 HSHR |
888 | } |
889 | #endif | |
271019bd HSHR |
890 | |
891 | /* ----------------------------------------------------------------------- */ | |
5bfb4cdf PP |
892 | |
893 | ||
894 | ||
059ec3d9 PH |
895 | |
896 | /************************************************* | |
897 | ************************************************** | |
898 | * Stand-alone test program * | |
899 | ************************************************** | |
900 | *************************************************/ | |
901 | ||
902 | ||
903 | #ifdef STAND_ALONE | |
904 | ||
905 | #ifdef CLOCKS_PER_SEC | |
906 | #define REAL_CLOCK_TICK CLOCKS_PER_SEC | |
907 | #else | |
908 | #ifdef CLK_TCK | |
909 | #define REAL_CLOCK_TICK CLK_TCK | |
910 | #else | |
911 | #define REAL_CLOCK_TICK 1000000 /* SunOS4 */ | |
912 | #endif | |
913 | #endif | |
914 | ||
915 | ||
916 | int main(int argc, char **argv) | |
917 | { | |
918 | char buffer[128]; | |
919 | int fd = fileno(stdin); | |
920 | int rc; | |
921 | ||
922 | printf("Testing restarting signal; wait for handler message, then type a line\n"); | |
923 | strcpy(buffer, "*** default ***\n"); | |
924 | os_restarting_signal(SIGALRM, sigalrm_handler); | |
c2a1bba0 | 925 | ALARM(2); |
059ec3d9 PH |
926 | if ((rc = read(fd, buffer, sizeof(buffer))) < 0) |
927 | printf("No data read\n"); | |
928 | else | |
929 | { | |
930 | buffer[rc] = 0; | |
931 | printf("Read: %s", buffer); | |
932 | } | |
c2a1bba0 | 933 | ALARM_CLR(0); |
059ec3d9 PH |
934 | |
935 | printf("Testing non-restarting signal; should read no data after handler message\n"); | |
936 | strcpy(buffer, "*** default ***\n"); | |
937 | os_non_restarting_signal(SIGALRM, sigalrm_handler); | |
c2a1bba0 | 938 | ALARM(2); |
059ec3d9 PH |
939 | if ((rc = read(fd, buffer, sizeof(buffer))) < 0) |
940 | printf("No data read\n"); | |
941 | else | |
942 | { | |
943 | buffer[rc] = 0; | |
944 | printf("Read: %s", buffer); | |
945 | } | |
c2a1bba0 | 946 | ALARM_CLR(0); |
059ec3d9 PH |
947 | |
948 | printf("Testing load averages (last test - ^C to kill)\n"); | |
949 | for (;;) | |
950 | { | |
951 | int avg; | |
952 | clock_t used; | |
953 | clock_t before = clock(); | |
954 | avg = os_getloadavg(); | |
955 | used = clock() - before; | |
956 | printf("cpu time = %.2f ", (double)used/REAL_CLOCK_TICK); | |
957 | if (avg < 0) | |
958 | { | |
959 | printf("load average not available\n"); | |
960 | break; | |
961 | } | |
962 | printf("load average = %.2f\n", (double)avg/1000.0); | |
963 | sleep(2); | |
964 | } | |
965 | return 0; | |
966 | } | |
967 | ||
968 | #endif | |
969 | ||
970 | /* End of os.c */ |