Postfix3.3.1
sys_compat.c
[詳解]
1 /*++
2 /* NAME
3 /* sys_compat 3
4 /* SUMMARY
5 /* compatibility routines
6 /* SYNOPSIS
7 /* #include <sys_defs.h>
8 /*
9 /* void closefrom(int lowfd)
10 /* int lowfd;
11 /*
12 /* const char *strerror(err)
13 /* int err;
14 /*
15 /* int setenv(name, value, clobber)
16 /* const char *name;
17 /* const char *value;
18 /* int clobber;
19 /*
20 /* int unsetenv(name)
21 /* const char *name;
22 /*
23 /* int seteuid(euid)
24 /* uid_t euid;
25 /*
26 /* int setegid(egid)
27 /* gid_t euid;
28 /*
29 /* int mkfifo(path, mode)
30 /* char *path;
31 /* int mode;
32 /*
33 /* int waitpid(pid, statusp, options)
34 /* int pid;
35 /* WAIT_STATUS_T *statusp;
36 /* int options;
37 /*
38 /* int setsid()
39 /*
40 /* void dup2_pass_on_exec(int oldd, int newd)
41 /*
42 /* char *inet_ntop(af, src, dst, size)
43 /* int af;
44 /* const void *src;
45 /* char *dst;
46 /* SOCKADDR_SIZE size;
47 /*
48 /* int inet_pton(af, src, dst)
49 /* int af;
50 /* const char *src;
51 /* void *dst;
52 /* DESCRIPTION
53 /* These routines are compiled for platforms that lack the functionality
54 /* or that have broken versions that we prefer to stay away from.
55 /* LICENSE
56 /* .ad
57 /* .fi
58 /* The Secure Mailer license must be distributed with this software.
59 /* AUTHOR(S)
60 /* Wietse Venema
61 /* IBM T.J. Watson Research
62 /* P.O. Box 704
63 /* Yorktown Heights, NY 10598, USA
64 /*
65 /* Wietse Venema
66 /* Google, Inc.
67 /* 111 8th Avenue
68 /* New York, NY 10011, USA
69 /*--*/
70 
71 /* System library. */
72 
73 #include "sys_defs.h"
74 
75  /*
76  * ANSI strerror() emulation
77  */
78 #ifdef MISSING_STRERROR
79 
80 extern int errno;
81 extern char *sys_errlist[];
82 extern int sys_nerr;
83 
84 #include <vstring.h>
85 
86 /* strerror - print text corresponding to error */
87 
88 const char *strerror(int err)
89 {
90  static VSTRING *buf;
91 
92  if (err < 0 || err >= sys_nerr) {
93  if (buf == 0)
94  buf = vstring_alloc(10);
95  vstring_sprintf(buf, "Unknown error %d", err);
96  return (vstring_str(buf));
97  } else {
98  return (sys_errlist[errno]);
99  }
100 }
101 
102 #endif
103 
104  /*
105  * setenv() emulation on top of putenv().
106  */
107 #ifdef MISSING_SETENV
108 
109 #include <stdio.h>
110 #include <string.h>
111 #include <stdlib.h>
112 
113 /* setenv - update or insert environment (name,value) pair */
114 
115 int setenv(const char *name, const char *value, int clobber)
116 {
117  char *cp;
118 
119  if (clobber == 0 && getenv(name) != 0)
120  return (0);
121  if ((cp = malloc(strlen(name) + strlen(value) + 2)) == 0)
122  return (1);
123  sprintf(cp, "%s=%s", name, value);
124  return (putenv(cp));
125 }
126 
127 /* unsetenv - remove all instances of the name */
128 
129 int unsetenv(const char *name)
130 {
131  extern char **environ;
132  ssize_t name_len = strlen(name);
133  char **src_pp;
134  char **dst_pp;
135 
136  for (dst_pp = src_pp = environ; *src_pp; src_pp++, dst_pp++) {
137  if (strncmp(*src_pp, name, name_len) == 0
138  && *(*src_pp + name_len) == '=') {
139  dst_pp--;
140  } else if (dst_pp != src_pp) {
141  *dst_pp = *src_pp;
142  }
143  }
144  *dst_pp = 0;
145  return (0);
146 }
147 
148 #endif
149 
150  /*
151  * seteuid() and setegid() emulation, the HP-UX way
152  */
153 #ifdef MISSING_SETEUID
154 #ifdef HAVE_SETRESUID
155 #include <unistd.h>
156 
157 int seteuid(uid_t euid)
158 {
159  return setresuid(-1, euid, -1);
160 }
161 
162 #else
163 #error MISSING_SETEUID
164 #endif
165 
166 #endif
167 
168 #ifdef MISSING_SETEGID
169 #ifdef HAVE_SETRESGID
170 #include <unistd.h>
171 
172 int setegid(gid_t egid)
173 {
174  return setresgid(-1, egid, -1);
175 }
176 
177 #else
178 #error MISSING_SETEGID
179 #endif
180 
181 #endif
182 
183  /*
184  * mkfifo() emulation - requires superuser privileges
185  */
186 #ifdef MISSING_MKFIFO
187 
188 #include <sys/stat.h>
189 
190 int mkfifo(char *path, int mode)
191 {
192  return mknod(path, (mode & ~_S_IFMT) | _S_IFIFO, 0);
193 }
194 
195 #endif
196 
197  /*
198  * waitpid() emulation on top of Berkeley UNIX wait4()
199  */
200 #ifdef MISSING_WAITPID
201 #ifdef HAS_WAIT4
202 
203 #include <sys/wait.h>
204 #include <errno.h>
205 
206 int waitpid(int pid, WAIT_STATUS_T *status, int options)
207 {
208  if (pid == -1)
209  pid = 0;
210  return wait4(pid, status, options, (struct rusage *) 0);
211 }
212 
213 #else
214 #error MISSING_WAITPID
215 #endif
216 
217 #endif
218 
219  /*
220  * setsid() emulation, the Berkeley UNIX way
221  */
222 #ifdef MISSING_SETSID
223 
224 #include <sys/ioctl.h>
225 #include <unistd.h>
226 #include <fcntl.h>
227 #include <errno.h>
228 
229 #ifdef TIOCNOTTY
230 
231 #include <msg.h>
232 
233 int setsid(void)
234 {
235  int p = getpid();
236  int fd;
237 
238  if (setpgrp(p, p))
239  return -1;
240 
241  fd = open("/dev/tty", O_RDONLY, 0);
242  if (fd >= 0 || errno != ENXIO) {
243  if (fd < 0) {
244  msg_warn("open /dev/tty: %m");
245  return -1;
246  }
247  if (ioctl(fd, TIOCNOTTY, 0)) {
248  msg_warn("ioctl TIOCNOTTY: %m");
249  return -1;
250  }
251  close(fd);
252  }
253  return 0;
254 }
255 
256 #else
257 #error MISSING_SETSID
258 #endif
259 
260 #endif
261 
262  /*
263  * dup2_pass_on_exec() - dup2() and clear close-on-exec flag on the result
264  */
265 #ifdef DUP2_DUPS_CLOSE_ON_EXEC
266 
267 #include "iostuff.h"
268 
269 int dup2_pass_on_exec(int oldd, int newd)
270 {
271  int res;
272 
273  if ((res = dup2(oldd, newd)) >= 0)
275 
276  return res;
277 }
278 
279 #endif
280 
281 #ifndef HAS_CLOSEFROM
282 
283 #include <unistd.h>
284 #include <errno.h>
285 #include <iostuff.h>
286 
287 /* closefrom() - closes all file descriptors from the given one up */
288 
289 int closefrom(int lowfd)
290 {
291  int fd_limit = open_limit(0);
292  int fd;
293 
294  /*
295  * lowfrom does not have an easy to determine upper limit. A process may
296  * have files open that were inherited from a parent process with a less
297  * restrictive resource limit.
298  */
299  if (lowfd < 0) {
300  errno = EBADF;
301  return (-1);
302  }
303  if (fd_limit > 500)
304  fd_limit = 500;
305  for (fd = lowfd; fd < fd_limit; fd++)
306  (void) close(fd);
307 
308  return (0);
309 }
310 
311 #endif
312 
313 #ifdef MISSING_INET_NTOP
314 
315 #include <sys/types.h>
316 #include <sys/socket.h>
317 #include <netinet/in.h>
318 #include <arpa/inet.h>
319 #include <stdio.h>
320 #include <string.h>
321 #include <errno.h>
322 
323 /* inet_ntop - convert binary address to printable address */
324 
325 const char *inet_ntop(int af, const void *src, char *dst, SOCKADDR_SIZE size)
326 {
327  const unsigned char *addr;
328  char buffer[sizeof("255.255.255.255")];
329  int len;
330 
331  if (af != AF_INET) {
332  errno = EAFNOSUPPORT;
333  return (0);
334  }
335  addr = (const unsigned char *) src;
336 #if (CHAR_BIT > 8)
337  sprintf(buffer, "%d.%d.%d.%d", addr[0] & 0xff,
338  addr[1] & 0xff, addr[2] & 0xff, addr[3] & 0xff);
339 #else
340  sprintf(buffer, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
341 #endif
342  if ((len = strlen(buffer)) >= size) {
343  errno = ENOSPC;
344  return (0);
345  } else {
346  memcpy(dst, buffer, len + 1);
347  return (dst);
348  }
349 }
350 
351 #endif
352 
353 #ifdef MISSING_INET_PTON
354 
355 #include <sys/types.h>
356 #include <sys/socket.h>
357 #include <netinet/in.h>
358 #include <arpa/inet.h>
359 #include <string.h>
360 #include <errno.h>
361 
362 #ifndef INADDR_NONE
363 #define INADDR_NONE 0xffffffff
364 #endif
365 
366 /* inet_pton - convert printable address to binary address */
367 
368 int inet_pton(int af, const char *src, void *dst)
369 {
370  struct in_addr addr;
371 
372  /*
373  * inet_addr() accepts a wider range of input formats than inet_pton();
374  * the former accepts 1-, 2-, or 3-part dotted addresses, while the
375  * latter requires dotted quad form.
376  */
377  if (af != AF_INET) {
378  errno = EAFNOSUPPORT;
379  return (-1);
380  } else if ((addr.s_addr = inet_addr(src)) == INADDR_NONE
381  && strcmp(src, "255.255.255.255") != 0) {
382  return (0);
383  } else {
384  memcpy(dst, (void *) &addr, sizeof(addr));
385  return (1);
386  }
387 }
388 
389 #endif
#define vstring_str(vp)
Definition: vstring.h:71
int open_limit(int)
Definition: open_limit.c:57
#define SOCKADDR_SIZE
Definition: sys_defs.h:1411
int closefrom(int lowfd)
Definition: sys_compat.c:289
const char * inet_ntop(int af, const void *src, char *dst, SOCKADDR_SIZE size)
Definition: sys_compat.c:325
#define PASS_ON_EXEC
Definition: iostuff.h:52
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
int inet_pton(int af, const char *src, void *dst)
Definition: sys_compat.c:368
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
Definition: vstring.c:602
#define INADDR_NONE
Definition: sys_compat.c:363
int WAIT_STATUS_T
Definition: sys_defs.h:1436
int close_on_exec(int fd, int on)
Definition: close_on_exec.c:49