3 * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/types.h>
21 #ifdef HAVE_SYS_SELECT_H
22 # include <sys/select.h>
24 #ifdef HAVE_SYS_TIME_H
25 # include <sys/time.h>
36 #ifndef HAVE___PROGNAME
41 * NB. duplicate __progname in case it is an alias for argv[0]
42 * Otherwise it may get clobbered by setproctitle()
44 char *ssh_get_progname(char *argv0)
47 #ifdef HAVE___PROGNAME
48 extern char *__progname;
53 return ("unknown"); /* XXX */
54 p = strrchr(argv0, '/');
60 if ((q = strdup(p)) == NULL) {
68 int setlogin(const char *name)
72 #endif /* !HAVE_SETLOGIN */
75 int innetgr(const char *netgroup, const char *host,
76 const char *user, const char *domain)
80 #endif /* HAVE_INNETGR */
82 #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
83 int seteuid(uid_t euid)
85 return (setreuid(-1, euid));
87 #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */
89 #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID)
90 int setegid(uid_t egid)
92 return(setresgid(-1, egid, -1));
94 #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */
96 #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR)
97 const char *strerror(int e)
100 extern char *sys_errlist[];
102 if ((e >= 0) && (e < sys_nerr))
103 return (sys_errlist[e]);
105 return ("unlisted error");
110 int utimes(const char *filename, struct timeval *tvp)
114 ub.actime = tvp[0].tv_sec;
115 ub.modtime = tvp[1].tv_sec;
117 return (utime(filename, &ub));
121 #ifndef HAVE_UTIMENSAT
123 * A limited implementation of utimensat() that only implements the
124 * functionality used by OpenSSH, currently only AT_FDCWD and
125 * AT_SYMLINK_NOFOLLOW.
128 utimensat(int fd, const char *path, const struct timespec times[2],
131 struct timeval tv[2];
133 int ret, oflags = O_WRONLY;
136 tv[0].tv_sec = times[0].tv_sec;
137 tv[0].tv_usec = times[0].tv_nsec / 1000;
138 tv[1].tv_sec = times[1].tv_sec;
139 tv[1].tv_usec = times[1].tv_nsec / 1000;
141 if (fd != AT_FDCWD) {
145 # ifndef HAVE_FUTIMES
146 return utimes(path, tv);
149 if (flag & AT_SYMLINK_NOFOLLOW)
150 oflags |= O_NOFOLLOW;
151 # endif /* O_NOFOLLOW */
152 if ((fd = open(path, oflags)) == -1)
154 ret = futimes(fd, tv);
161 #ifndef HAVE_FCHOWNAT
163 * A limited implementation of fchownat() that only implements the
164 * functionality used by OpenSSH, currently only AT_FDCWD and
165 * AT_SYMLINK_NOFOLLOW.
168 fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
170 int ret, oflags = O_WRONLY;
172 if (fd != AT_FDCWD) {
177 return chown(path, owner, group);
180 if (flag & AT_SYMLINK_NOFOLLOW)
181 oflags |= O_NOFOLLOW;
182 # endif /* O_NOFOLLOW */
183 if ((fd = open(path, oflags)) == -1)
185 ret = fchown(fd, owner, group);
192 #ifndef HAVE_FCHMODAT
194 * A limited implementation of fchmodat() that only implements the
195 * functionality used by OpenSSH, currently only AT_FDCWD and
196 * AT_SYMLINK_NOFOLLOW.
199 fchmodat(int fd, const char *path, mode_t mode, int flag)
201 int ret, oflags = O_WRONLY;
203 if (fd != AT_FDCWD) {
208 return chmod(path, mode);
211 if (flag & AT_SYMLINK_NOFOLLOW)
212 oflags |= O_NOFOLLOW;
213 # endif /* O_NOFOLLOW */
214 if ((fd = open(path, oflags)) == -1)
216 ret = fchmod(fd, mode);
223 #ifndef HAVE_TRUNCATE
224 int truncate(const char *path, off_t length)
226 int fd, ret, saverrno;
228 fd = open(path, O_WRONLY);
232 ret = ftruncate(fd, length);
240 #endif /* HAVE_TRUNCATE */
242 #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP)
243 int nanosleep(const struct timespec *req, struct timespec *rem)
247 struct timeval tstart, tstop, tremain, time2wait;
249 TIMESPEC_TO_TIMEVAL(&time2wait, req)
250 (void) gettimeofday(&tstart, NULL);
251 rc = select(0, NULL, NULL, NULL, &time2wait);
254 (void) gettimeofday (&tstop, NULL);
256 tremain.tv_sec = time2wait.tv_sec -
257 (tstop.tv_sec - tstart.tv_sec);
258 tremain.tv_usec = time2wait.tv_usec -
259 (tstop.tv_usec - tstart.tv_usec);
260 tremain.tv_sec += tremain.tv_usec / 1000000L;
261 tremain.tv_usec %= 1000000L;
267 TIMEVAL_TO_TIMESPEC(&tremain, rem)
273 #if !defined(HAVE_USLEEP)
274 int usleep(unsigned int useconds)
278 ts.tv_sec = useconds / 1000000;
279 ts.tv_nsec = (useconds % 1000000) * 1000;
280 return nanosleep(&ts, NULL);
284 #ifndef HAVE_TCGETPGRP
290 if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1)
295 #endif /* HAVE_TCGETPGRP */
297 #ifndef HAVE_TCSENDBREAK
299 tcsendbreak(int fd, int duration)
301 # if defined(TIOCSBRK) && defined(TIOCCBRK)
302 struct timeval sleepytime;
304 sleepytime.tv_sec = 0;
305 sleepytime.tv_usec = 400000;
306 if (ioctl(fd, TIOCSBRK, 0) == -1)
308 (void)select(0, 0, 0, 0, &sleepytime);
309 if (ioctl(fd, TIOCCBRK, 0) == -1)
316 #endif /* HAVE_TCSENDBREAK */
320 strdup(const char *str)
325 len = strlen(str) + 1;
328 return(memcpy(cp, str, len));
337 return (c == ' ' || c == '\t');
345 #if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) && GETPGRP_VOID == 0
347 #elif defined(HAVE_GETPGRP)
359 pledge(const char *promises, const char *paths[])
366 /* a mbtowc that only supports ASCII */
368 mbtowc(wchar_t *pwc, const char *s, size_t n)
370 if (s == NULL || *s == '\0')
371 return 0; /* ASCII is not state-dependent */
372 if (*s < 0 || *s > 0x7f || n < 1) {
386 return (j < 0 ? -j : j);
392 bzero(void *b, size_t n)
394 (void)memset(b, 0, n);
417 killpg(pid_t pgrp, int sig)
419 return kill(pgrp, sig);
423 #ifdef FFLUSH_NULL_BUG
425 int _ssh_compat_fflush(FILE *f)
432 if (r1 == -1 || r2 == -1)
440 #ifndef HAVE_LOCALTIME_R
442 localtime_r(const time_t *timep, struct tm *result)
444 struct tm *tm = localtime(timep);
451 const char *__asan_default_options(void) {
457 const char *__msan_default_options(void) {