| 1 | Configuring Exim for different Operating Systems |
| 2 | ------------------------------------------------ |
| 3 | |
| 4 | These notes describe the way in which Exim is configured at the C program level |
| 5 | for different operating systems. The normal configuration options that apply |
| 6 | independently of the operating system are specified by creating files in the |
| 7 | Local directory, as described in chapter 4 of the manual. |
| 8 | |
| 9 | These notes cover the os.* files in the OS directory, and contain information |
| 10 | for people who want to port the program to some new OS, or to modify the |
| 11 | configuration for an existing port. If you are just wanting to compile Exim on |
| 12 | a system that it already knows about, you do not need to read further unless |
| 13 | there are problems. |
| 14 | |
| 15 | The os.c-<ostype> files |
| 16 | ----------------------- |
| 17 | |
| 18 | There may be an os.c-<ostype> file for each operating system, but for many of |
| 19 | them it is not necessary. No error occurs is there isn't one. There is a |
| 20 | generic file called os.c which contains code that is common to two or more OS |
| 21 | for setting a restarting or a non-restarting signal, for computing the load |
| 22 | average, and for finding all the network interface addresses. A few OS have |
| 23 | their own individual code for one or more of these. When they do, the code is |
| 24 | put into an os.c-<ostype> file, which also defines a macro such as |
| 25 | OS_RESTARTING_SIGNAL (for example) to cut out the common code in the generic |
| 26 | os.c. |
| 27 | |
| 28 | The os.h-<ostype> files |
| 29 | ----------------------- |
| 30 | |
| 31 | For each OS that Exim knows about, there is an os.h-<ostype> file, where |
| 32 | <ostype> is the OS name. The relevant file is included as a C header file for |
| 33 | all Exim compilation by pointing a symbolic link called os.h at it from the |
| 34 | build directory. The settings are as follows: |
| 35 | |
| 36 | The select() function |
| 37 | --------------------- |
| 38 | |
| 39 | There is a difference in the data type for the second argument to the select() |
| 40 | function in some OS. The macro SELECT_ARG2_TYPE can be used to define the type. |
| 41 | If it is not defined in os.h, then it is defaulted to fs_set in exim.h. |
| 42 | |
| 43 | The dn_expand() function |
| 44 | ------------------------ |
| 45 | |
| 46 | There is a difference in the data type for the fourth argument to the |
| 47 | dn_expand() function in some OS. The macro DN_EXPAND_ARG4_TYPE can be used to |
| 48 | define the type. If it is not defined in os.h, then it is defaulted to char * |
| 49 | in exim.h. |
| 50 | |
| 51 | The h_errno variable |
| 52 | -------------------- |
| 53 | |
| 54 | If NEED_H_ERRNO is defined, then a definition of the form |
| 55 | |
| 56 | extern int h_errno |
| 57 | |
| 58 | is included in the compiled code of Exim. |
| 59 | |
| 60 | The strerror() function |
| 61 | ----------------------- |
| 62 | |
| 63 | Most systems provide the ANSI standard strerror() function; older systems may |
| 64 | instead have an errlist[] variable in which to look up error texts. Defining |
| 65 | STRERROR_FROM_ERRLIST causes Exim to build its own strerror() function that |
| 66 | mimics the ANSI function by lookup up the error code in errlist. |
| 67 | |
| 68 | Truncating files |
| 69 | ---------------- |
| 70 | |
| 71 | The fcntl() option for truncating the length of a file is called F_FREESP in |
| 72 | most systems; in some, however, it is called O_TRUNC. Some os.h files define |
| 73 | F_FREESP to be O_TRUNC for this reason. |
| 74 | |
| 75 | Finding local interfaces |
| 76 | ------------------------ |
| 77 | |
| 78 | The SIOCGIFCONF ioctl for finding local interfaces behaves differently on BSD |
| 79 | systems. It returns a vector of ifreq blocks containing sockaddr structures |
| 80 | that can be longer than their sizeof definition, making the returned ifreq |
| 81 | blocks longer than their sizeof definitions. BSD sockaddrs structures contain |
| 82 | an sa_len field giving the actual size. To cope with difference, there is a |
| 83 | macro called HAVE_SA_LEN. If it is defined, code that works on BSD systems is |
| 84 | used. Otherwise, the objects returned by SIOCGIFCONF are assumed to be of |
| 85 | length sizeof(struct ifreq). |
| 86 | |
| 87 | On some operating systems, the SIOCGIFCONF ioctl returns the IP addresses |
| 88 | with the list of interfaces, and there is no need to call SIOCGIFADDR for each |
| 89 | individual address. Mostly, making the second call does no harm, but on Linux |
| 90 | when there are IP aliases, it causes things to go wrong. This also happens on |
| 91 | BSDI and GNU Hurd. Therefore, there is now a macro to cut it out, called |
| 92 | SIOCGIFCONF_GIVES_ADDR. |
| 93 | |
| 94 | Note that, if IPv6 support is configured, Exim cannot find the IPv6 addresses |
| 95 | on local interfaces by itself. You need to set the local_interfaces option in |
| 96 | this situation. |
| 97 | |
| 98 | Computing load averages |
| 99 | ----------------------- |
| 100 | |
| 101 | There are several different ways that load averages are computed. One-off code |
| 102 | is put in the os.c-<ostype>, but several OS use similar methods, and these |
| 103 | are coded in the generic os.c, using a number of parameters to make variations |
| 104 | between OS. |
| 105 | |
| 106 | Sometimes the load average is not available to unprivileged callers. If |
| 107 | LOAD_AVG_NEEDS_ROOT is set, Exim ensures that it is root before trying to |
| 108 | obtain a load average value. |
| 109 | |
| 110 | (1) If HAVE_BSD_GETLOADAVG is defined, Exim uses a simple call to the |
| 111 | getloadavg() function. |
| 112 | |
| 113 | (2) If HAVE_KSTAT is defined, Exim uses the kstat package as found in Solaris 2 |
| 114 | (but nowhere else as yet). It uses some supplementary definitions: |
| 115 | |
| 116 | LOAD_AVG_KSTAT the kstat to use |
| 117 | LOAD_AVG_KSTAT_MODULE the module to access |
| 118 | LOAD_AVG_KSTAT_SYMBOL the symbol containing the value we want |
| 119 | LOAD_AVG_KSTAT_FIELD the field identity |
| 120 | |
| 121 | (3) If HAVE_DEV_KMEM is defined, Exim reads load average values from the |
| 122 | /dev/kmem device. It uses some supplementary definitions: |
| 123 | |
| 124 | LOAD_AVG_TYPE the data type |
| 125 | LOAD_AVG_SYMBOL the symbol to look up |
| 126 | KERNEL_PATH the name of the kernel |
| 127 | FSCALE a scaling factor |
| 128 | |
| 129 | Sometimes FSCALE is defined in system headers so need not be defined in the |
| 130 | os.h-<ostype> file. |
| 131 | |
| 132 | Glibc systems and IP options |
| 133 | ---------------------------- |
| 134 | |
| 135 | The code for inspecting IP options is the same in all OS except for systems |
| 136 | using glibc (e.g. Linux), which uses a different structure to return data from |
| 137 | getsockopt(). To handle this, there is a macro called |
| 138 | |
| 139 | GLIBC_IP_OPTIONS |
| 140 | |
| 141 | which should be set for Linux (in os.h-Linux) and any other operating system |
| 142 | that uses glibc. |
| 143 | |
| 144 | Options for statvfs() |
| 145 | --------------------- |
| 146 | |
| 147 | The following settings apply to the compilation of the Exim monitor as well as |
| 148 | to the main Exim binary. |
| 149 | |
| 150 | #undefine HAVE_STATFS |
| 151 | |
| 152 | Exim has options for checking the amount of space in the spool partition |
| 153 | before accepting a message, and the monitor has the ability to display a |
| 154 | stripchart of the percentage fullness of a particular disc partition, usually |
| 155 | /var/spool/mail. The standard way of finding out the data is to call the |
| 156 | statvfs() function, but some operating systems use statfs() and some may not |
| 157 | have the ability at all. The Exim code uses STATVFS() for this function and |
| 158 | this gets defined appropriately. HAVE_STATFS is defined before including the |
| 159 | os.h file; undefining it suppresses the code for checking a partition in the |
| 160 | main binary, and for monitoring disc partition in the monitor. |
| 161 | |
| 162 | When HAVE_STATFS is defined, the distinction between statvfs() and statfs() is |
| 163 | made by checking HAVE_SYS_STATVFS_H. If it is defined, then sys/statvfs.h is |
| 164 | included. Otherwise, STATVFS() is defined as a macro for statfs(), and some |
| 165 | further includes are done, according to the following definitions: |
| 166 | |
| 167 | #define HAVE_SYS_MOUNT_H |
| 168 | #define HAVE_VFS_H |
| 169 | |
| 170 | Each of those definitions causes the inclusion of the corresponding system |
| 171 | header file in the Exim monitor compilation. For example, the first one causes |
| 172 | |
| 173 | #include <sys/mount.h> |
| 174 | |
| 175 | to be obeyed. Different systems may require different combinations of these |
| 176 | headers. |
| 177 | |
| 178 | The sys/resource.h header |
| 179 | ------------------------- |
| 180 | |
| 181 | One OS does not have the sys/resource.h header. If NO_SYS_RESOURCE_H is defined |
| 182 | in an os.h-<ostype> file, then the #include for this header is skipped in |
| 183 | exim.h. |
| 184 | |
| 185 | Support for login_cap functions |
| 186 | ------------------------------- |
| 187 | |
| 188 | Some of the BSD systems support functions for controlling the resources that |
| 189 | user processes can use (e.g. login_getpwclass). If HAVE_SETCLASSRESOURCES is |
| 190 | defined, Exim supports this feature for running pipe deliveries, using the |
| 191 | setclassresources() function. |
| 192 | |
| 193 | The crypt_h header |
| 194 | ------------------ |
| 195 | |
| 196 | Some OS require crypt.h to be included to get a prototype for the crypt() |
| 197 | function. This is needed only when compiling with AUTH support. If CRYPT_H is |
| 198 | defined, then this header is included. |
| 199 | |
| 200 | mmap() support |
| 201 | -------------- |
| 202 | |
| 203 | The CDB support includes the option of handling file operations by using |
| 204 | mmap()/munmap(). This gives a reasonable performance increase which will |
| 205 | probably scale over multiple processes (since the files are mapped read-only |
| 206 | shared). The vast majority of modern operating systems will support mmap |
| 207 | (certainly in the simplified way that it is being used here). For example any |
| 208 | BSD 4.x derived or POSIX compliant system will support it, as will pretty much |
| 209 | any system using dynamically shared link libraries. |
| 210 | |
| 211 | If the OS is believed to support mmap() then the symbol HAVE_MMAP is defined. |
| 212 | Not all systems that support mmap will have had their config files updated to |
| 213 | reflect this. Currently Linux, Sun, BSD and SGI/mips systems have been updated. |
| 214 | |
| 215 | *** End *** |