tidying
[exim.git] / src / src / os.c
CommitLineData
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
20provide functionality (or lack of it) in cases where the OS-specific os.c
21file 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,
30except that it arranges that, if the signal happens during a system call, the
31system call gets restarted. (Also, it doesn't return a result.) Different
32versions of Unix have different defaults, and different ways of setting up a
33restarting signal handler. If the functionality is not available, the signal
34should be set to be ignored. This function is used only for catching SIGUSR1.
35*/
36
37void
38os_restarting_signal(int sig, void (*handler)(int))
39{
40/* Many systems have the SA_RESTART sigaction for specifying that a signal
41should restart system calls. These include SunOS5, AIX, BSDI, IRIX, FreeBSD,
42OSF1, Linux and HP-UX 10 (but *not* HP-UX 9). */
43
44#ifdef SA_RESTART
45struct sigaction act;
46act.sa_handler = handler;
47sigemptyset(&(act.sa_mask));
48act.sa_flags = SA_RESTART;
49sigaction(sig, &act, NULL);
50
51#ifdef STAND_ALONE
52printf("Used SA_RESTART\n");
53#endif
54
55/* SunOS4 and Ultrix default to non-interruptable signals, with SV_INTERRUPT
56for making them interruptable. This seems to be a dying fashion. */
57
58#elif defined SV_INTERRUPT
59signal(sig, handler);
60
61#ifdef STAND_ALONE
62printf("Used default signal()\n");
63#endif
64
65
66/* If neither SA_RESTART nor SV_INTERRUPT is available we don't know how to
67set up a restarting signal, so simply suppress the facility. */
68
69#else
70signal(sig, SIG_IGN);
71
72#ifdef STAND_ALONE
73printf("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,
88except that it arranges that, if the signal happens during a system call, the
89system call gets interrupted. (Also, it doesn't return a result.) Different
90versions of Unix have different defaults, and different ways of setting up a
91non-restarting signal handler. For systems for which we don't know what to do,
92just use the normal signal() function and hope for the best. */
93
94void
95os_non_restarting_signal(int sig, void (*handler)(int))
96{
97/* Many systems have the SA_RESTART sigaction for specifying that a signal
98should restart system calls. These include SunOS5, AIX, BSDI, IRIX, FreeBSD,
99OSF1, Linux and HP-UX 10 (but *not* HP-UX 9). */
100
101#ifdef SA_RESTART
102struct sigaction act;
103act.sa_handler = handler;
104sigemptyset(&(act.sa_mask));
105act.sa_flags = 0;
106sigaction(sig, &act, NULL);
107
108#ifdef STAND_ALONE
109printf("Used sigaction() with flags = 0\n");
110#endif
111
112/* SunOS4 and Ultrix default to non-interruptable signals, with SV_INTERRUPT
113for making them interruptable. This seems to be a dying fashion. */
114
115#elif defined SV_INTERRUPT
116struct sigvec sv;
117sv.sv_handler = handler;
118sv.sv_flags = SV_INTERRUPT;
119sv.sv_mask = -1;
120sigvec(sig, &sv, NULL);
121
122#ifdef STAND_ALONE
123printf("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
127set up a restarting signal, so just use the standard signal() function. */
128
129#else
130signal(sig, handler);
131
132#ifdef STAND_ALONE
133printf("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()
149in their libraries, but can provide the same facility by this simple
150alternative function. */
151
152char *
153strerror(int n)
154{
155if (n < 0 || n >= sys_nerr) return "unknown error number";
156return 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
168may have other means of doing this. This function is used for those systems
169that have nothing. It provides a basic translation for the common standard
170signal numbers. I've been extra cautious with the ifdef's here. Probably more
171than is necessary... */
172
1ba28e2b
PP
173const char *
174os_strsignal(const int n)
059ec3d9
PH
175{
176switch (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
287exit codes into text, but this function is implemented this way so that if any
288OS does have such a thing, it could be used instead of this build-in one. */
289
1ba28e2b
PP
290const char *
291os_strexit(const int n)
059ec3d9
PH
292{
293switch (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
330average, a number of them have things in common. Some common variants are
331provided below, but if an OS has unique requirements it can be handled in
332a specific os.c file. What is required is a function called os_getloadavg
333which takes no arguments and passes back the load average * 1000 as an int,
334or -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
343int
344os_getloadavg(void)
345{
346double avg;
347int loads = getloadavg (&avg, 1);
348if (loads != 1) return -1;
349return (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
358here as there is the -hal variant, and other systems might follow this road one
359day. */
360
361#if !defined(OS_LOAD_AVERAGE) && defined(HAVE_KSTAT)
362#define OS_LOAD_AVERAGE
363
364#include <kstat.h>
365
366int
367os_getloadavg(void)
368{
369int avg;
370kstat_ctl_t *kc;
371kstat_t *ksp;
372kstat_named_t *kn;
373
374if ((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
381avg = (int)(((double)(kn->LOAD_AVG_FIELD)/FSCALE) * 1000.0);
382
383kstat_close(kc);
384return 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
400static int avg_kd = -1;
401static long avg_offset;
402
403int
404os_getloadavg(void)
405{
406LOAD_AVG_TYPE avg;
407
408if (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
420if (lseek (avg_kd, avg_offset, 0) == -1L
5903c6ff 421 || read (avg_kd, CS (&avg), sizeof (avg)) != sizeof(avg))
059ec3d9
PH
422 return -1;
423
424return (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
434not available. */
435
436#ifndef OS_LOAD_AVERAGE
437
438int
439os_getloadavg(void)
440{
441return -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
456tweaks, even in the IPv4 case, and it gets worse for IPv6, which is why this
457code is now in the os-dependent source file. There is a common function which
458works on most OS (except IRIX) for IPv4 interfaces, and, with some variations
459controlled by macros, on at least one OS for IPv6 and IPv4 interfaces. On Linux
460with IPv6, the common function is used for the IPv4 interfaces and additional
461code used for IPv6. Consequently, the real function is called
462os_common_find_running_interfaces() so that it can be called from the Linux
463function. On non-Linux systems, the macro for os_find_running_interfaces just
464calls the common function; on Linux it calls the Linux function.
465
466This function finds the addresses of all the running interfaces on the machine.
467A chain of blocks containing the textual form of the addresses is returned.
468
92f9ced0
NM
469getifaddrs() provides a sane consistent way to query this on modern OSs,
470otherwise fall back to a maze of twisty ioctl() calls
471
472Arguments: none
473Returns: 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
484ip_address_item *
485os_common_find_running_interfaces(void)
486{
487struct ifaddrs *ifalist = NULL;
488ip_address_item *yield = NULL;
489ip_address_item *last = NULL;
490ip_address_item *next;
491
492if (getifaddrs(&ifalist) != 0)
493 log_write(0, LOG_PANIC_DIE, "Unable to call getifaddrs: %d %s",
494 errno, strerror(errno));
495
d7978c0f 496for (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
f3ebb786 511 next = store_get(sizeof(ip_address_item), FALSE);
92f9ced0
NM
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
530freeifaddrs (ifalist);
531return yield;
532}
533
534#else /* HAVE_GETIFADDRS */
535
536/*
059ec3d9
PH
537Problems:
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
563use these new, longer versions of the old IPv4 interfaces. Otherwise, define
564the 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
598Solaris 8) the call to read the flags doesn't work for IPv6 interfaces. If
599we find we can't actually make an IPv6 socket, the code will revert to trying
600an 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
610ip_address_item *
611os_common_find_running_interfaces(void)
612{
613struct V_ifconf ifc;
614struct V_ifreq ifreq;
615int vs;
616ip_address_item *yield = NULL;
617ip_address_item *last = NULL;
618ip_address_item *next;
059ec3d9
PH
619char buf[MAX_INTERFACES*sizeof(struct V_ifreq)];
620struct sockaddr *addrp;
621size_t len = 0;
92f9ced0 622char addrbuf[512];
059ec3d9
PH
623
624/* We have to create a socket in order to do ioctls on it to find out
625what we want to know. */
626
627if ((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
641new structures are in use. */
642
643ifc.V_ifc_len = sizeof(buf);
644ifc.V_ifc_buf = buf;
645
646#ifdef V_FAMILY_QUERY
647ifc.V_ifc_family = V_FAMILY_QUERY;
648ifc.V_ifc_flags = 0;
649#endif
650
5903c6ff 651if (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
656the amount actually used. If the buffer isn't big enough, at least on some
657operating systems, ifc.V_ifc_len still gets set to correspond to the total
658number of interfaces, even though they don't all fit in the buffer. */
659
660if (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
670it is up; if not, skip.
671
672BSD systems differ from others in what SIOCGIFCONF returns. Other systems
673return a vector of ifreq structures whose size is as defined by the structure.
674BSD systems allow sockaddrs to be longer than their sizeof, which in turn makes
675the ifreq structures longer than their sizeof. The code below has its origins
676in amd and ifconfig; it uses the sa_len field of each sockaddr to determine
677each item's length.
678
679This is complicated by the fact that, at least on BSD systems, the data in the
680buffer is not guaranteed to be aligned. Thus, we must first copy the basic
681struct to some aligned memory before looking at the field in the fixed part to
682find its length, and then recopy the correct length. */
683
d7978c0f 684for (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
f3ebb786 746 next = store_get(sizeof(ip_address_item), FALSE);
059ec3d9
PH
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
764return 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,
772and there is no other way to get a list of the (IP addresses of) local
773interfaces. We just return the loopback address(es). */
774
775ip_address_item *
776os_common_find_running_interfaces(void)
777{
f3ebb786 778ip_address_item *yield = store_get(sizeof(address_item), FALSE);
059ec3d9
PH
779yield->address = US"127.0.0.1";
780yield->port = 0;
781yield->next = NULL;
782
783#if HAVE_IPV6
f3ebb786 784yield->next = store_get(sizeof(address_item), FALSE);
059ec3d9
PH
785yield->next->address = US"::1";
786yield->next->port = 0;
787yield->next->next = NULL;
788#endif
789
790DEBUG(D_interface) debug_printf("Unable to find local interface addresses "
791 "on this OS: returning loopback address(es)\n");
792return 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
808made available as _res. At least one OS (NetBSD) now no longer provides this
809directly, instead making you call a function per thread to get a handle.
810Other OSs handle thread-safe resolver differently, in ways which fail if the
811programmer 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
818find out how unportable it is on other OSes, but most resolver implementations
819should be descended from ISC's bind.
820
821Linux and BSD do:
822 define _res (*__res_state())
823identically. We just can't rely on __foo functions. It's surprising that use
824of _res has been as portable as it has, for so long.
825
826So, since _res works everywhere, and everything can decode the struct, I'm
827going to gamble that res_state is a typedef everywhere and use that as the
828return type.
829*/
830
831res_state
832os_get_dns_resolver_res(void)
833{
7d8d08c4 834return &_res;
5bfb4cdf
PP
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)
849int
f8c0a35c 850os_unsetenv(const unsigned char * name)
271019bd 851{
5903c6ff 852return 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
863do auto-allocation, but need the size of the buffer, and others
864may not even do this. If the OS supports getcwd(NULL, 0) we'll use
865this, for all other systems we provide our own getcwd() */
866
867#if !defined(OS_GETCWD)
f8c0a35c
JH
868unsigned char *
869os_getcwd(unsigned char * buffer, size_t size)
3ae121c9 870{
5903c6ff 871return US getcwd(CS buffer, size);
3ae121c9
HSHR
872}
873#else
874#ifndef PATH_MAX
875# define PATH_MAX 4096
876#endif
f8c0a35c
JH
877unsigned char *
878os_getcwd(unsigned char * buffer, size_t size)
3ae121c9 879{
5903c6ff 880char * b = CS buffer;
3ae121c9
HSHR
881
882if (!size) size = PATH_MAX;
490f424e
JH
883if (!b && !(b = malloc(size))) return NULL;
884if (!(b = getcwd(b, size))) return NULL;
4a5ee04f 885return 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
914int main(int argc, char **argv)
915{
916char buffer[128];
917int fd = fileno(stdin);
918int rc;
919
920printf("Testing restarting signal; wait for handler message, then type a line\n");
921strcpy(buffer, "*** default ***\n");
922os_restarting_signal(SIGALRM, sigalrm_handler);
c2a1bba0 923ALARM(2);
059ec3d9
PH
924if ((rc = read(fd, buffer, sizeof(buffer))) < 0)
925 printf("No data read\n");
926else
927 {
928 buffer[rc] = 0;
929 printf("Read: %s", buffer);
930 }
c2a1bba0 931ALARM_CLR(0);
059ec3d9
PH
932
933printf("Testing non-restarting signal; should read no data after handler message\n");
934strcpy(buffer, "*** default ***\n");
935os_non_restarting_signal(SIGALRM, sigalrm_handler);
c2a1bba0 936ALARM(2);
059ec3d9
PH
937if ((rc = read(fd, buffer, sizeof(buffer))) < 0)
938 printf("No data read\n");
939else
940 {
941 buffer[rc] = 0;
942 printf("Read: %s", buffer);
943 }
c2a1bba0 944ALARM_CLR(0);
059ec3d9
PH
945
946printf("Testing load averages (last test - ^C to kill)\n");
947for (;;)
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 }
963return 0;
964}
965
966#endif
967
968/* End of os.c */