7 /* compatibility routines
9 /* #include <sys_defs.h>
11 /* void closefrom(int lowfd)
14 /* const char *strerror(err)
17 /* int setenv(name, value, clobber)
28 /* int mkfifo(path, mode)
32 /* int waitpid(pid, statusp, options)
34 /* WAIT_STATUS_T *statusp;
39 /* void dup2_pass_on_exec(int oldd, int newd)
41 /* char *inet_ntop(af, src, dst, size)
47 /* int inet_pton(af, src, dst)
52 /* These routines are compiled for platforms that lack the functionality
53 /* or that have broken versions that we prefer to stay away from.
57 /* The Secure Mailer license must be distributed with this software.
60 /* IBM T.J. Watson Research
62 /* Yorktown Heights, NY 10598, USA
70 * ANSI strerror() emulation
72 #ifdef MISSING_STRERROR
75 extern char *sys_errlist
[];
80 /* strerror - print text corresponding to error */
82 const char *strerror(int err
)
86 if (err
< 0 || err
>= sys_nerr
) {
88 buf
= vstring_alloc(10);
89 vstring_sprintf(buf
, "Unknown error %d", err
);
90 return (vstring_str(buf
));
92 return (sys_errlist
[errno
]);
99 * setenv() emulation on top of putenv().
101 #ifdef MISSING_SETENV
107 /* setenv - update or insert environment (name,value) pair */
109 int setenv(const char *name
, const char *value
, int clobber
)
113 if (clobber
== 0 && getenv(name
) != 0)
115 if ((cp
= malloc(strlen(name
) + strlen(value
) + 2)) == 0)
117 sprintf(cp
, "%s=%s", name
, value
);
124 * seteuid() and setegid() emulation, the HP-UX way
126 #ifdef MISSING_SETEUID
127 #ifdef HAVE_SETRESUID
130 int seteuid(uid_t euid
)
132 return setresuid(-1, euid
, -1);
136 #error MISSING_SETEUID
141 #ifdef MISSING_SETEGID
142 #ifdef HAVE_SETRESGID
145 int setegid(gid_t egid
)
147 return setresgid(-1, egid
, -1);
151 #error MISSING_SETEGID
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);
171 * waitpid() emulation on top of Berkeley UNIX wait4()
173 #ifdef MISSING_WAITPID
176 #include <sys/wait.h>
179 int waitpid(int pid
, WAIT_STATUS_T
*status
, int options
)
183 return wait4(pid
, status
, options
, (struct rusage
*) 0);
187 #error MISSING_WAITPID
193 * setsid() emulation, the Berkeley UNIX way
195 #ifdef MISSING_SETSID
197 #include <sys/ioctl.h>
214 fd
= open("/dev/tty", O_RDONLY
, 0);
215 if (fd
>= 0 || errno
!= ENXIO
) {
217 msg_warn("open /dev/tty: %m");
220 if (ioctl(fd
, TIOCNOTTY
, 0)) {
221 msg_warn("ioctl TIOCNOTTY: %m");
230 #error MISSING_SETSID
236 * dup2_pass_on_exec() - dup2() and clear close-on-exec flag on the result
238 #ifdef DUP2_DUPS_CLOSE_ON_EXEC
242 int dup2_pass_on_exec(int oldd
, int newd
)
246 if ((res
= dup2(oldd
, newd
)) >= 0)
247 close_on_exec(newd
, PASS_ON_EXEC
);
254 #ifndef HAS_CLOSEFROM
260 /* closefrom() - closes all file descriptors from the given one up */
262 int closefrom(int lowfd
)
264 int fd_limit
= open_limit(0);
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.
278 for (fd
= lowfd
; fd
< fd_limit
; fd
++)
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>
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")];
305 errno
= EAFNOSUPPORT
;
308 addr
= (const unsigned char *) src
;
310 sprintf(buffer
, "%d.%d.%d.%d", addr
[0] & 0xff,
311 addr
[1] & 0xff, addr
[2] & 0xff, addr
[3] & 0xff);
313 sprintf(buffer
, "%d.%d.%d.%d", addr
[0], addr
[1], addr
[2], addr
[3]);
315 if ((len
= strlen(buffer
)) >= size
) {
319 memcpy(dst
, buffer
, len
+ 1);
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>
336 #define INADDR_NONE 0xffffffff
339 /* inet_pton - convert printable address to binary address */
341 int inet_pton(int af
, const char *src
, void *dst
)
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.
351 errno
= EAFNOSUPPORT
;
353 } else if ((addr
.s_addr
= inet_addr(src
)) == INADDR_NONE
354 && strcmp(src
, "255.255.255.255") != 0) {
357 memcpy(dst
, (char *) &addr
, sizeof(addr
));