1d74d50a8SDag-Erling Smørgrav 283d2307dSDag-Erling Smørgrav /* 3efcad6b7SDag-Erling Smørgrav * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org> 483d2307dSDag-Erling Smørgrav * 5efcad6b7SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 6efcad6b7SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 7efcad6b7SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 883d2307dSDag-Erling Smørgrav * 9efcad6b7SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10efcad6b7SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11efcad6b7SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12efcad6b7SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13efcad6b7SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14efcad6b7SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15efcad6b7SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1683d2307dSDag-Erling Smørgrav */ 1783d2307dSDag-Erling Smørgrav 1883d2307dSDag-Erling Smørgrav #include "includes.h" 1983d2307dSDag-Erling Smørgrav 20d4af9e69SDag-Erling Smørgrav #include <sys/types.h> 21761efaa7SDag-Erling Smørgrav #ifdef HAVE_SYS_SELECT_H 22761efaa7SDag-Erling Smørgrav # include <sys/select.h> 23761efaa7SDag-Erling Smørgrav #endif 24761efaa7SDag-Erling Smørgrav #ifdef HAVE_SYS_TIME_H 25761efaa7SDag-Erling Smørgrav # include <sys/time.h> 26761efaa7SDag-Erling Smørgrav #endif 27761efaa7SDag-Erling Smørgrav 28761efaa7SDag-Erling Smørgrav #include <string.h> 29761efaa7SDag-Erling Smørgrav #include <signal.h> 30761efaa7SDag-Erling Smørgrav #include <stdlib.h> 31f7167e0eSDag-Erling Smørgrav #include <time.h> 32d4af9e69SDag-Erling Smørgrav #include <unistd.h> 33761efaa7SDag-Erling Smørgrav 34d74d50a8SDag-Erling Smørgrav #ifndef HAVE___PROGNAME 35d74d50a8SDag-Erling Smørgrav char *__progname; 36d74d50a8SDag-Erling Smørgrav #endif 3783d2307dSDag-Erling Smørgrav 38d0c8c0bcSDag-Erling Smørgrav /* 39d0c8c0bcSDag-Erling Smørgrav * NB. duplicate __progname in case it is an alias for argv[0] 40d0c8c0bcSDag-Erling Smørgrav * Otherwise it may get clobbered by setproctitle() 41d0c8c0bcSDag-Erling Smørgrav */ 42d95e11bfSDag-Erling Smørgrav char *ssh_get_progname(char *argv0) 4383d2307dSDag-Erling Smørgrav { 44bc5531deSDag-Erling Smørgrav char *p, *q; 4583d2307dSDag-Erling Smørgrav #ifdef HAVE___PROGNAME 4683d2307dSDag-Erling Smørgrav extern char *__progname; 4783d2307dSDag-Erling Smørgrav 48bc5531deSDag-Erling Smørgrav p = __progname; 4983d2307dSDag-Erling Smørgrav #else 5083d2307dSDag-Erling Smørgrav if (argv0 == NULL) 51d95e11bfSDag-Erling Smørgrav return ("unknown"); /* XXX */ 5283d2307dSDag-Erling Smørgrav p = strrchr(argv0, '/'); 5383d2307dSDag-Erling Smørgrav if (p == NULL) 5483d2307dSDag-Erling Smørgrav p = argv0; 5583d2307dSDag-Erling Smørgrav else 5683d2307dSDag-Erling Smørgrav p++; 5783d2307dSDag-Erling Smørgrav #endif 58bc5531deSDag-Erling Smørgrav if ((q = strdup(p)) == NULL) { 59bc5531deSDag-Erling Smørgrav perror("strdup"); 60bc5531deSDag-Erling Smørgrav exit(1); 61bc5531deSDag-Erling Smørgrav } 62bc5531deSDag-Erling Smørgrav return q; 6383d2307dSDag-Erling Smørgrav } 6483d2307dSDag-Erling Smørgrav 6583d2307dSDag-Erling Smørgrav #ifndef HAVE_SETLOGIN 6683d2307dSDag-Erling Smørgrav int setlogin(const char *name) 6783d2307dSDag-Erling Smørgrav { 6883d2307dSDag-Erling Smørgrav return (0); 6983d2307dSDag-Erling Smørgrav } 7083d2307dSDag-Erling Smørgrav #endif /* !HAVE_SETLOGIN */ 7183d2307dSDag-Erling Smørgrav 7283d2307dSDag-Erling Smørgrav #ifndef HAVE_INNETGR 7383d2307dSDag-Erling Smørgrav int innetgr(const char *netgroup, const char *host, 7483d2307dSDag-Erling Smørgrav const char *user, const char *domain) 7583d2307dSDag-Erling Smørgrav { 7683d2307dSDag-Erling Smørgrav return (0); 7783d2307dSDag-Erling Smørgrav } 7883d2307dSDag-Erling Smørgrav #endif /* HAVE_INNETGR */ 7983d2307dSDag-Erling Smørgrav 8083d2307dSDag-Erling Smørgrav #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) 8183d2307dSDag-Erling Smørgrav int seteuid(uid_t euid) 8283d2307dSDag-Erling Smørgrav { 8383d2307dSDag-Erling Smørgrav return (setreuid(-1, euid)); 8483d2307dSDag-Erling Smørgrav } 8583d2307dSDag-Erling Smørgrav #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ 8683d2307dSDag-Erling Smørgrav 8783d2307dSDag-Erling Smørgrav #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) 8883d2307dSDag-Erling Smørgrav int setegid(uid_t egid) 8983d2307dSDag-Erling Smørgrav { 9083d2307dSDag-Erling Smørgrav return(setresgid(-1, egid, -1)); 9183d2307dSDag-Erling Smørgrav } 9283d2307dSDag-Erling Smørgrav #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ 9383d2307dSDag-Erling Smørgrav 9483d2307dSDag-Erling Smørgrav #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) 9583d2307dSDag-Erling Smørgrav const char *strerror(int e) 9683d2307dSDag-Erling Smørgrav { 9783d2307dSDag-Erling Smørgrav extern int sys_nerr; 9883d2307dSDag-Erling Smørgrav extern char *sys_errlist[]; 9983d2307dSDag-Erling Smørgrav 10083d2307dSDag-Erling Smørgrav if ((e >= 0) && (e < sys_nerr)) 10183d2307dSDag-Erling Smørgrav return (sys_errlist[e]); 102d95e11bfSDag-Erling Smørgrav 10383d2307dSDag-Erling Smørgrav return ("unlisted error"); 10483d2307dSDag-Erling Smørgrav } 10583d2307dSDag-Erling Smørgrav #endif 10683d2307dSDag-Erling Smørgrav 10783d2307dSDag-Erling Smørgrav #ifndef HAVE_UTIMES 10883d2307dSDag-Erling Smørgrav int utimes(char *filename, struct timeval *tvp) 10983d2307dSDag-Erling Smørgrav { 11083d2307dSDag-Erling Smørgrav struct utimbuf ub; 11183d2307dSDag-Erling Smørgrav 1124b17dab0SDag-Erling Smørgrav ub.actime = tvp[0].tv_sec; 1134b17dab0SDag-Erling Smørgrav ub.modtime = tvp[1].tv_sec; 11483d2307dSDag-Erling Smørgrav 11583d2307dSDag-Erling Smørgrav return (utime(filename, &ub)); 11683d2307dSDag-Erling Smørgrav } 11783d2307dSDag-Erling Smørgrav #endif 11883d2307dSDag-Erling Smørgrav 11983d2307dSDag-Erling Smørgrav #ifndef HAVE_TRUNCATE 12083d2307dSDag-Erling Smørgrav int truncate(const char *path, off_t length) 12183d2307dSDag-Erling Smørgrav { 12283d2307dSDag-Erling Smørgrav int fd, ret, saverrno; 12383d2307dSDag-Erling Smørgrav 12483d2307dSDag-Erling Smørgrav fd = open(path, O_WRONLY); 12583d2307dSDag-Erling Smørgrav if (fd < 0) 126d95e11bfSDag-Erling Smørgrav return (-1); 12783d2307dSDag-Erling Smørgrav 12883d2307dSDag-Erling Smørgrav ret = ftruncate(fd, length); 12983d2307dSDag-Erling Smørgrav saverrno = errno; 130d95e11bfSDag-Erling Smørgrav close(fd); 13183d2307dSDag-Erling Smørgrav if (ret == -1) 13283d2307dSDag-Erling Smørgrav errno = saverrno; 133d95e11bfSDag-Erling Smørgrav 13483d2307dSDag-Erling Smørgrav return(ret); 13583d2307dSDag-Erling Smørgrav } 13683d2307dSDag-Erling Smørgrav #endif /* HAVE_TRUNCATE */ 13783d2307dSDag-Erling Smørgrav 138d0c8c0bcSDag-Erling Smørgrav #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) 139d0c8c0bcSDag-Erling Smørgrav int nanosleep(const struct timespec *req, struct timespec *rem) 140d0c8c0bcSDag-Erling Smørgrav { 141d0c8c0bcSDag-Erling Smørgrav int rc, saverrno; 142d0c8c0bcSDag-Erling Smørgrav extern int errno; 143d0c8c0bcSDag-Erling Smørgrav struct timeval tstart, tstop, tremain, time2wait; 144d0c8c0bcSDag-Erling Smørgrav 145d0c8c0bcSDag-Erling Smørgrav TIMESPEC_TO_TIMEVAL(&time2wait, req) 146d0c8c0bcSDag-Erling Smørgrav (void) gettimeofday(&tstart, NULL); 147d0c8c0bcSDag-Erling Smørgrav rc = select(0, NULL, NULL, NULL, &time2wait); 148d0c8c0bcSDag-Erling Smørgrav if (rc == -1) { 149d0c8c0bcSDag-Erling Smørgrav saverrno = errno; 150d0c8c0bcSDag-Erling Smørgrav (void) gettimeofday (&tstop, NULL); 151d0c8c0bcSDag-Erling Smørgrav errno = saverrno; 152d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec = time2wait.tv_sec - 153d0c8c0bcSDag-Erling Smørgrav (tstop.tv_sec - tstart.tv_sec); 154d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec = time2wait.tv_usec - 155d0c8c0bcSDag-Erling Smørgrav (tstop.tv_usec - tstart.tv_usec); 156d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec += tremain.tv_usec / 1000000L; 157d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec %= 1000000L; 158d0c8c0bcSDag-Erling Smørgrav } else { 159d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec = 0; 160d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec = 0; 161d0c8c0bcSDag-Erling Smørgrav } 162d4af9e69SDag-Erling Smørgrav if (rem != NULL) 163d0c8c0bcSDag-Erling Smørgrav TIMEVAL_TO_TIMESPEC(&tremain, rem) 164d0c8c0bcSDag-Erling Smørgrav 165d0c8c0bcSDag-Erling Smørgrav return(rc); 166d0c8c0bcSDag-Erling Smørgrav } 167d0c8c0bcSDag-Erling Smørgrav #endif 168d0c8c0bcSDag-Erling Smørgrav 1696888a9beSDag-Erling Smørgrav #if !defined(HAVE_USLEEP) 1706888a9beSDag-Erling Smørgrav int usleep(unsigned int useconds) 1716888a9beSDag-Erling Smørgrav { 1726888a9beSDag-Erling Smørgrav struct timespec ts; 1736888a9beSDag-Erling Smørgrav 1746888a9beSDag-Erling Smørgrav ts.tv_sec = useconds / 1000000; 1756888a9beSDag-Erling Smørgrav ts.tv_nsec = (useconds % 1000000) * 1000; 1766888a9beSDag-Erling Smørgrav return nanosleep(&ts, NULL); 1776888a9beSDag-Erling Smørgrav } 1786888a9beSDag-Erling Smørgrav #endif 1796888a9beSDag-Erling Smørgrav 180d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCGETPGRP 181d95e11bfSDag-Erling Smørgrav pid_t 182d95e11bfSDag-Erling Smørgrav tcgetpgrp(int fd) 183d95e11bfSDag-Erling Smørgrav { 184d95e11bfSDag-Erling Smørgrav int ctty_pgrp; 185d95e11bfSDag-Erling Smørgrav 186d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) 187d95e11bfSDag-Erling Smørgrav return(-1); 188d95e11bfSDag-Erling Smørgrav else 189d95e11bfSDag-Erling Smørgrav return(ctty_pgrp); 190d95e11bfSDag-Erling Smørgrav } 191d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCGETPGRP */ 192d95e11bfSDag-Erling Smørgrav 193d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCSENDBREAK 194d95e11bfSDag-Erling Smørgrav int 195d95e11bfSDag-Erling Smørgrav tcsendbreak(int fd, int duration) 196d95e11bfSDag-Erling Smørgrav { 197d95e11bfSDag-Erling Smørgrav # if defined(TIOCSBRK) && defined(TIOCCBRK) 198d95e11bfSDag-Erling Smørgrav struct timeval sleepytime; 199d95e11bfSDag-Erling Smørgrav 200d95e11bfSDag-Erling Smørgrav sleepytime.tv_sec = 0; 201d95e11bfSDag-Erling Smørgrav sleepytime.tv_usec = 400000; 202d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCSBRK, 0) == -1) 203d95e11bfSDag-Erling Smørgrav return (-1); 204d95e11bfSDag-Erling Smørgrav (void)select(0, 0, 0, 0, &sleepytime); 205d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCCBRK, 0) == -1) 206d95e11bfSDag-Erling Smørgrav return (-1); 207d95e11bfSDag-Erling Smørgrav return (0); 208d95e11bfSDag-Erling Smørgrav # else 209d95e11bfSDag-Erling Smørgrav return -1; 210d95e11bfSDag-Erling Smørgrav # endif 211d95e11bfSDag-Erling Smørgrav } 212d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCSENDBREAK */ 213d95e11bfSDag-Erling Smørgrav 214d95e11bfSDag-Erling Smørgrav mysig_t 215d95e11bfSDag-Erling Smørgrav mysignal(int sig, mysig_t act) 216d95e11bfSDag-Erling Smørgrav { 217d95e11bfSDag-Erling Smørgrav #ifdef HAVE_SIGACTION 218d95e11bfSDag-Erling Smørgrav struct sigaction sa, osa; 219d95e11bfSDag-Erling Smørgrav 220d95e11bfSDag-Erling Smørgrav if (sigaction(sig, NULL, &osa) == -1) 221d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 222d95e11bfSDag-Erling Smørgrav if (osa.sa_handler != act) { 223d95e11bfSDag-Erling Smørgrav memset(&sa, 0, sizeof(sa)); 224d95e11bfSDag-Erling Smørgrav sigemptyset(&sa.sa_mask); 225d95e11bfSDag-Erling Smørgrav sa.sa_flags = 0; 226d95e11bfSDag-Erling Smørgrav #ifdef SA_INTERRUPT 227d95e11bfSDag-Erling Smørgrav if (sig == SIGALRM) 228d95e11bfSDag-Erling Smørgrav sa.sa_flags |= SA_INTERRUPT; 229d95e11bfSDag-Erling Smørgrav #endif 230d95e11bfSDag-Erling Smørgrav sa.sa_handler = act; 231d95e11bfSDag-Erling Smørgrav if (sigaction(sig, &sa, NULL) == -1) 232d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 233d95e11bfSDag-Erling Smørgrav } 234d95e11bfSDag-Erling Smørgrav return (osa.sa_handler); 235d95e11bfSDag-Erling Smørgrav #else 236efcad6b7SDag-Erling Smørgrav #undef signal 237d95e11bfSDag-Erling Smørgrav return (signal(sig, act)); 238d95e11bfSDag-Erling Smørgrav #endif 239d95e11bfSDag-Erling Smørgrav } 240043840dfSDag-Erling Smørgrav 241043840dfSDag-Erling Smørgrav #ifndef HAVE_STRDUP 242043840dfSDag-Erling Smørgrav char * 243043840dfSDag-Erling Smørgrav strdup(const char *str) 244043840dfSDag-Erling Smørgrav { 245043840dfSDag-Erling Smørgrav size_t len; 246043840dfSDag-Erling Smørgrav char *cp; 247043840dfSDag-Erling Smørgrav 248043840dfSDag-Erling Smørgrav len = strlen(str) + 1; 249043840dfSDag-Erling Smørgrav cp = malloc(len); 250043840dfSDag-Erling Smørgrav if (cp != NULL) 251021d409fSDag-Erling Smørgrav return(memcpy(cp, str, len)); 252043840dfSDag-Erling Smørgrav return NULL; 253043840dfSDag-Erling Smørgrav } 254043840dfSDag-Erling Smørgrav #endif 2554a421b63SDag-Erling Smørgrav 2564a421b63SDag-Erling Smørgrav #ifndef HAVE_ISBLANK 2576888a9beSDag-Erling Smørgrav int 2586888a9beSDag-Erling Smørgrav isblank(int c) 2594a421b63SDag-Erling Smørgrav { 2604a421b63SDag-Erling Smørgrav return (c == ' ' || c == '\t'); 2614a421b63SDag-Erling Smørgrav } 2624a421b63SDag-Erling Smørgrav #endif 2636888a9beSDag-Erling Smørgrav 2646888a9beSDag-Erling Smørgrav #ifndef HAVE_GETPGID 2656888a9beSDag-Erling Smørgrav pid_t 2666888a9beSDag-Erling Smørgrav getpgid(pid_t pid) 2676888a9beSDag-Erling Smørgrav { 2686888a9beSDag-Erling Smørgrav #if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) 2696888a9beSDag-Erling Smørgrav return getpgrp(pid); 2706888a9beSDag-Erling Smørgrav #elif defined(HAVE_GETPGRP) 2716888a9beSDag-Erling Smørgrav if (pid == 0) 2726888a9beSDag-Erling Smørgrav return getpgrp(); 2736888a9beSDag-Erling Smørgrav #endif 2746888a9beSDag-Erling Smørgrav 2756888a9beSDag-Erling Smørgrav errno = ESRCH; 2766888a9beSDag-Erling Smørgrav return -1; 2776888a9beSDag-Erling Smørgrav } 2786888a9beSDag-Erling Smørgrav #endif 279acc1a9efSDag-Erling Smørgrav 280acc1a9efSDag-Erling Smørgrav #ifndef HAVE_PLEDGE 281acc1a9efSDag-Erling Smørgrav int 282acc1a9efSDag-Erling Smørgrav pledge(const char *promises, const char *paths[]) 283acc1a9efSDag-Erling Smørgrav { 284acc1a9efSDag-Erling Smørgrav return 0; 285acc1a9efSDag-Erling Smørgrav } 286acc1a9efSDag-Erling Smørgrav #endif 287076ad2f8SDag-Erling Smørgrav 288076ad2f8SDag-Erling Smørgrav #ifndef HAVE_MBTOWC 289076ad2f8SDag-Erling Smørgrav /* a mbtowc that only supports ASCII */ 290076ad2f8SDag-Erling Smørgrav int 291076ad2f8SDag-Erling Smørgrav mbtowc(wchar_t *pwc, const char *s, size_t n) 292076ad2f8SDag-Erling Smørgrav { 293076ad2f8SDag-Erling Smørgrav if (s == NULL || *s == '\0') 294076ad2f8SDag-Erling Smørgrav return 0; /* ASCII is not state-dependent */ 295076ad2f8SDag-Erling Smørgrav if (*s < 0 || *s > 0x7f || n < 1) { 296076ad2f8SDag-Erling Smørgrav errno = EOPNOTSUPP; 297076ad2f8SDag-Erling Smørgrav return -1; 298076ad2f8SDag-Erling Smørgrav } 299076ad2f8SDag-Erling Smørgrav if (pwc != NULL) 300076ad2f8SDag-Erling Smørgrav *pwc = *s; 301076ad2f8SDag-Erling Smørgrav return 1; 302076ad2f8SDag-Erling Smørgrav } 303076ad2f8SDag-Erling Smørgrav #endif 304*d93a896eSDag-Erling Smørgrav 305*d93a896eSDag-Erling Smørgrav #ifndef HAVE_LLABS 306*d93a896eSDag-Erling Smørgrav long long 307*d93a896eSDag-Erling Smørgrav llabs(long long j) 308*d93a896eSDag-Erling Smørgrav { 309*d93a896eSDag-Erling Smørgrav return (j < 0 ? -j : j); 310*d93a896eSDag-Erling Smørgrav } 311*d93a896eSDag-Erling Smørgrav #endif 312