Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / sys_compat.c
blobf14bc521b0b1d16ad59b219e6f3b26fdcb9dc969
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* sys_compat 3
6 /* SUMMARY
7 /* compatibility routines
8 /* SYNOPSIS
9 /* #include <sys_defs.h>
11 /* void closefrom(int lowfd)
12 /* int lowfd;
14 /* const char *strerror(err)
15 /* int err;
17 /* int setenv(name, value, clobber)
18 /* const char *name;
19 /* const char *value;
20 /* int clobber;
22 /* int seteuid(euid)
23 /* uid_t euid;
25 /* int setegid(egid)
26 /* gid_t euid;
28 /* int mkfifo(path, mode)
29 /* char *path;
30 /* int mode;
32 /* int waitpid(pid, statusp, options)
33 /* int pid;
34 /* WAIT_STATUS_T *statusp;
35 /* int options;
37 /* int setsid()
39 /* void dup2_pass_on_exec(int oldd, int newd)
41 /* char *inet_ntop(af, src, dst, size)
42 /* int af;
43 /* const void *src;
44 /* char *dst;
45 /* size_t size;
47 /* int inet_pton(af, src, dst)
48 /* int af;
49 /* const char *src;
50 /* void *dst;
51 /* DESCRIPTION
52 /* These routines are compiled for platforms that lack the functionality
53 /* or that have broken versions that we prefer to stay away from.
54 /* LICENSE
55 /* .ad
56 /* .fi
57 /* The Secure Mailer license must be distributed with this software.
58 /* AUTHOR(S)
59 /* Wietse Venema
60 /* IBM T.J. Watson Research
61 /* P.O. Box 704
62 /* Yorktown Heights, NY 10598, USA
63 /*--*/
65 /* System library. */
67 #include "sys_defs.h"
70 * ANSI strerror() emulation
72 #ifdef MISSING_STRERROR
74 extern int errno;
75 extern char *sys_errlist[];
76 extern int sys_nerr;
78 #include <vstring.h>
80 /* strerror - print text corresponding to error */
82 const char *strerror(int err)
84 static VSTRING *buf;
86 if (err < 0 || err >= sys_nerr) {
87 if (buf == 0)
88 buf = vstring_alloc(10);
89 vstring_sprintf(buf, "Unknown error %d", err);
90 return (vstring_str(buf));
91 } else {
92 return (sys_errlist[errno]);
96 #endif
99 * setenv() emulation on top of putenv().
101 #ifdef MISSING_SETENV
103 #include <stdio.h>
104 #include <string.h>
105 #include <stdlib.h>
107 /* setenv - update or insert environment (name,value) pair */
109 int setenv(const char *name, const char *value, int clobber)
111 char *cp;
113 if (clobber == 0 && getenv(name) != 0)
114 return (0);
115 if ((cp = malloc(strlen(name) + strlen(value) + 2)) == 0)
116 return (1);
117 sprintf(cp, "%s=%s", name, value);
118 return (putenv(cp));
121 #endif
124 * seteuid() and setegid() emulation, the HP-UX way
126 #ifdef MISSING_SETEUID
127 #ifdef HAVE_SETRESUID
128 #include <unistd.h>
130 int seteuid(uid_t euid)
132 return setresuid(-1, euid, -1);
135 #else
136 #error MISSING_SETEUID
137 #endif
139 #endif
141 #ifdef MISSING_SETEGID
142 #ifdef HAVE_SETRESGID
143 #include <unistd.h>
145 int setegid(gid_t egid)
147 return setresgid(-1, egid, -1);
150 #else
151 #error MISSING_SETEGID
152 #endif
154 #endif
157 * mkfifo() emulation - requires superuser privileges
159 #ifdef MISSING_MKFIFO
161 #include <sys/stat.h>
163 int mkfifo(char *path, int mode)
165 return mknod(path, (mode & ~_S_IFMT) | _S_IFIFO, 0);
168 #endif
171 * waitpid() emulation on top of Berkeley UNIX wait4()
173 #ifdef MISSING_WAITPID
174 #ifdef HAS_WAIT4
176 #include <sys/wait.h>
177 #include <errno.h>
179 int waitpid(int pid, WAIT_STATUS_T *status, int options)
181 if (pid == -1)
182 pid = 0;
183 return wait4(pid, status, options, (struct rusage *) 0);
186 #else
187 #error MISSING_WAITPID
188 #endif
190 #endif
193 * setsid() emulation, the Berkeley UNIX way
195 #ifdef MISSING_SETSID
197 #include <sys/ioctl.h>
198 #include <unistd.h>
199 #include <fcntl.h>
200 #include <errno.h>
202 #ifdef TIOCNOTTY
204 #include <msg.h>
206 int setsid(void)
208 int p = getpid();
209 int fd;
211 if (setpgrp(p, p))
212 return -1;
214 fd = open("/dev/tty", O_RDONLY, 0);
215 if (fd >= 0 || errno != ENXIO) {
216 if (fd < 0) {
217 msg_warn("open /dev/tty: %m");
218 return -1;
220 if (ioctl(fd, TIOCNOTTY, 0)) {
221 msg_warn("ioctl TIOCNOTTY: %m");
222 return -1;
224 close(fd);
226 return 0;
229 #else
230 #error MISSING_SETSID
231 #endif
233 #endif
236 * dup2_pass_on_exec() - dup2() and clear close-on-exec flag on the result
238 #ifdef DUP2_DUPS_CLOSE_ON_EXEC
240 #include "iostuff.h"
242 int dup2_pass_on_exec(int oldd, int newd)
244 int res;
246 if ((res = dup2(oldd, newd)) >= 0)
247 close_on_exec(newd, PASS_ON_EXEC);
249 return res;
252 #endif
254 #ifndef HAS_CLOSEFROM
256 #include <unistd.h>
257 #include <errno.h>
258 #include <iostuff.h>
260 /* closefrom() - closes all file descriptors from the given one up */
262 int closefrom(int lowfd)
264 int fd_limit = open_limit(0);
265 int fd;
268 * lowfrom does not have an easy to determine upper limit. A process may
269 * have files open that were inherited from a parent process with a less
270 * restrictive resource limit.
272 if (lowfd < 0) {
273 errno = EBADF;
274 return (-1);
276 if (fd_limit > 500)
277 fd_limit = 500;
278 for (fd = lowfd; fd < fd_limit; fd++)
279 (void) close(fd);
281 return (0);
284 #endif
286 #ifdef MISSING_INET_NTOP
288 #include <sys/types.h>
289 #include <sys/socket.h>
290 #include <netinet/in.h>
291 #include <arpa/inet.h>
292 #include <stdio.h>
293 #include <string.h>
294 #include <errno.h>
296 /* inet_ntop - convert binary address to printable address */
298 const char *inet_ntop(int af, const void *src, char *dst, size_t size)
300 const unsigned char *addr;
301 char buffer[sizeof("255.255.255.255")];
302 int len;
304 if (af != AF_INET) {
305 errno = EAFNOSUPPORT;
306 return (0);
308 addr = (const unsigned char *) src;
309 #if (CHAR_BIT > 8)
310 sprintf(buffer, "%d.%d.%d.%d", addr[0] & 0xff,
311 addr[1] & 0xff, addr[2] & 0xff, addr[3] & 0xff);
312 #else
313 sprintf(buffer, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
314 #endif
315 if ((len = strlen(buffer)) >= size) {
316 errno = ENOSPC;
317 return (0);
318 } else {
319 memcpy(dst, buffer, len + 1);
320 return (dst);
324 #endif
326 #ifdef MISSING_INET_PTON
328 #include <sys/types.h>
329 #include <sys/socket.h>
330 #include <netinet/in.h>
331 #include <arpa/inet.h>
332 #include <string.h>
333 #include <errno.h>
335 #ifndef INADDR_NONE
336 #define INADDR_NONE 0xffffffff
337 #endif
339 /* inet_pton - convert printable address to binary address */
341 int inet_pton(int af, const char *src, void *dst)
343 struct in_addr addr;
346 * inet_addr() accepts a wider range of input formats than inet_pton();
347 * the former accepts 1-, 2-, or 3-part dotted addresses, while the
348 * latter requires dotted quad form.
350 if (af != AF_INET) {
351 errno = EAFNOSUPPORT;
352 return (-1);
353 } else if ((addr.s_addr = inet_addr(src)) == INADDR_NONE
354 && strcmp(src, "255.255.255.255") != 0) {
355 return (0);
356 } else {
357 memcpy(dst, (char *) &addr, sizeof(addr));
358 return (1);
362 #endif