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> 31d4af9e69SDag-Erling Smørgrav #include <unistd.h> 32761efaa7SDag-Erling Smørgrav 33761efaa7SDag-Erling Smørgrav #include "xmalloc.h" 34d74d50a8SDag-Erling Smørgrav 35d74d50a8SDag-Erling Smørgrav #ifndef HAVE___PROGNAME 36d74d50a8SDag-Erling Smørgrav char *__progname; 37d74d50a8SDag-Erling Smørgrav #endif 3883d2307dSDag-Erling Smørgrav 39d0c8c0bcSDag-Erling Smørgrav /* 40d0c8c0bcSDag-Erling Smørgrav * NB. duplicate __progname in case it is an alias for argv[0] 41d0c8c0bcSDag-Erling Smørgrav * Otherwise it may get clobbered by setproctitle() 42d0c8c0bcSDag-Erling Smørgrav */ 43d95e11bfSDag-Erling Smørgrav char *ssh_get_progname(char *argv0) 4483d2307dSDag-Erling Smørgrav { 4583d2307dSDag-Erling Smørgrav #ifdef HAVE___PROGNAME 4683d2307dSDag-Erling Smørgrav extern char *__progname; 4783d2307dSDag-Erling Smørgrav 48d0c8c0bcSDag-Erling Smørgrav return xstrdup(__progname); 4983d2307dSDag-Erling Smørgrav #else 5083d2307dSDag-Erling Smørgrav char *p; 5183d2307dSDag-Erling Smørgrav 5283d2307dSDag-Erling Smørgrav if (argv0 == NULL) 53d95e11bfSDag-Erling Smørgrav return ("unknown"); /* XXX */ 5483d2307dSDag-Erling Smørgrav p = strrchr(argv0, '/'); 5583d2307dSDag-Erling Smørgrav if (p == NULL) 5683d2307dSDag-Erling Smørgrav p = argv0; 5783d2307dSDag-Erling Smørgrav else 5883d2307dSDag-Erling Smørgrav p++; 59d0c8c0bcSDag-Erling Smørgrav 60d95e11bfSDag-Erling Smørgrav return (xstrdup(p)); 6183d2307dSDag-Erling Smørgrav #endif 6283d2307dSDag-Erling Smørgrav } 6383d2307dSDag-Erling Smørgrav 6483d2307dSDag-Erling Smørgrav #ifndef HAVE_SETLOGIN 6583d2307dSDag-Erling Smørgrav int setlogin(const char *name) 6683d2307dSDag-Erling Smørgrav { 6783d2307dSDag-Erling Smørgrav return (0); 6883d2307dSDag-Erling Smørgrav } 6983d2307dSDag-Erling Smørgrav #endif /* !HAVE_SETLOGIN */ 7083d2307dSDag-Erling Smørgrav 7183d2307dSDag-Erling Smørgrav #ifndef HAVE_INNETGR 7283d2307dSDag-Erling Smørgrav int innetgr(const char *netgroup, const char *host, 7383d2307dSDag-Erling Smørgrav const char *user, const char *domain) 7483d2307dSDag-Erling Smørgrav { 7583d2307dSDag-Erling Smørgrav return (0); 7683d2307dSDag-Erling Smørgrav } 7783d2307dSDag-Erling Smørgrav #endif /* HAVE_INNETGR */ 7883d2307dSDag-Erling Smørgrav 7983d2307dSDag-Erling Smørgrav #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) 8083d2307dSDag-Erling Smørgrav int seteuid(uid_t euid) 8183d2307dSDag-Erling Smørgrav { 8283d2307dSDag-Erling Smørgrav return (setreuid(-1, euid)); 8383d2307dSDag-Erling Smørgrav } 8483d2307dSDag-Erling Smørgrav #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ 8583d2307dSDag-Erling Smørgrav 8683d2307dSDag-Erling Smørgrav #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) 8783d2307dSDag-Erling Smørgrav int setegid(uid_t egid) 8883d2307dSDag-Erling Smørgrav { 8983d2307dSDag-Erling Smørgrav return(setresgid(-1, egid, -1)); 9083d2307dSDag-Erling Smørgrav } 9183d2307dSDag-Erling Smørgrav #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ 9283d2307dSDag-Erling Smørgrav 9383d2307dSDag-Erling Smørgrav #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) 9483d2307dSDag-Erling Smørgrav const char *strerror(int e) 9583d2307dSDag-Erling Smørgrav { 9683d2307dSDag-Erling Smørgrav extern int sys_nerr; 9783d2307dSDag-Erling Smørgrav extern char *sys_errlist[]; 9883d2307dSDag-Erling Smørgrav 9983d2307dSDag-Erling Smørgrav if ((e >= 0) && (e < sys_nerr)) 10083d2307dSDag-Erling Smørgrav return (sys_errlist[e]); 101d95e11bfSDag-Erling Smørgrav 10283d2307dSDag-Erling Smørgrav return ("unlisted error"); 10383d2307dSDag-Erling Smørgrav } 10483d2307dSDag-Erling Smørgrav #endif 10583d2307dSDag-Erling Smørgrav 10683d2307dSDag-Erling Smørgrav #ifndef HAVE_UTIMES 10783d2307dSDag-Erling Smørgrav int utimes(char *filename, struct timeval *tvp) 10883d2307dSDag-Erling Smørgrav { 10983d2307dSDag-Erling Smørgrav struct utimbuf ub; 11083d2307dSDag-Erling Smørgrav 1114b17dab0SDag-Erling Smørgrav ub.actime = tvp[0].tv_sec; 1124b17dab0SDag-Erling Smørgrav ub.modtime = tvp[1].tv_sec; 11383d2307dSDag-Erling Smørgrav 11483d2307dSDag-Erling Smørgrav return (utime(filename, &ub)); 11583d2307dSDag-Erling Smørgrav } 11683d2307dSDag-Erling Smørgrav #endif 11783d2307dSDag-Erling Smørgrav 11883d2307dSDag-Erling Smørgrav #ifndef HAVE_TRUNCATE 11983d2307dSDag-Erling Smørgrav int truncate(const char *path, off_t length) 12083d2307dSDag-Erling Smørgrav { 12183d2307dSDag-Erling Smørgrav int fd, ret, saverrno; 12283d2307dSDag-Erling Smørgrav 12383d2307dSDag-Erling Smørgrav fd = open(path, O_WRONLY); 12483d2307dSDag-Erling Smørgrav if (fd < 0) 125d95e11bfSDag-Erling Smørgrav return (-1); 12683d2307dSDag-Erling Smørgrav 12783d2307dSDag-Erling Smørgrav ret = ftruncate(fd, length); 12883d2307dSDag-Erling Smørgrav saverrno = errno; 129d95e11bfSDag-Erling Smørgrav close(fd); 13083d2307dSDag-Erling Smørgrav if (ret == -1) 13183d2307dSDag-Erling Smørgrav errno = saverrno; 132d95e11bfSDag-Erling Smørgrav 13383d2307dSDag-Erling Smørgrav return(ret); 13483d2307dSDag-Erling Smørgrav } 13583d2307dSDag-Erling Smørgrav #endif /* HAVE_TRUNCATE */ 13683d2307dSDag-Erling Smørgrav 137d0c8c0bcSDag-Erling Smørgrav #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) 138d0c8c0bcSDag-Erling Smørgrav int nanosleep(const struct timespec *req, struct timespec *rem) 139d0c8c0bcSDag-Erling Smørgrav { 140d0c8c0bcSDag-Erling Smørgrav int rc, saverrno; 141d0c8c0bcSDag-Erling Smørgrav extern int errno; 142d0c8c0bcSDag-Erling Smørgrav struct timeval tstart, tstop, tremain, time2wait; 143d0c8c0bcSDag-Erling Smørgrav 144d0c8c0bcSDag-Erling Smørgrav TIMESPEC_TO_TIMEVAL(&time2wait, req) 145d0c8c0bcSDag-Erling Smørgrav (void) gettimeofday(&tstart, NULL); 146d0c8c0bcSDag-Erling Smørgrav rc = select(0, NULL, NULL, NULL, &time2wait); 147d0c8c0bcSDag-Erling Smørgrav if (rc == -1) { 148d0c8c0bcSDag-Erling Smørgrav saverrno = errno; 149d0c8c0bcSDag-Erling Smørgrav (void) gettimeofday (&tstop, NULL); 150d0c8c0bcSDag-Erling Smørgrav errno = saverrno; 151d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec = time2wait.tv_sec - 152d0c8c0bcSDag-Erling Smørgrav (tstop.tv_sec - tstart.tv_sec); 153d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec = time2wait.tv_usec - 154d0c8c0bcSDag-Erling Smørgrav (tstop.tv_usec - tstart.tv_usec); 155d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec += tremain.tv_usec / 1000000L; 156d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec %= 1000000L; 157d0c8c0bcSDag-Erling Smørgrav } else { 158d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec = 0; 159d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec = 0; 160d0c8c0bcSDag-Erling Smørgrav } 161d4af9e69SDag-Erling Smørgrav if (rem != NULL) 162d0c8c0bcSDag-Erling Smørgrav TIMEVAL_TO_TIMESPEC(&tremain, rem) 163d0c8c0bcSDag-Erling Smørgrav 164d0c8c0bcSDag-Erling Smørgrav return(rc); 165d0c8c0bcSDag-Erling Smørgrav } 166d0c8c0bcSDag-Erling Smørgrav #endif 167d0c8c0bcSDag-Erling Smørgrav 168d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCGETPGRP 169d95e11bfSDag-Erling Smørgrav pid_t 170d95e11bfSDag-Erling Smørgrav tcgetpgrp(int fd) 171d95e11bfSDag-Erling Smørgrav { 172d95e11bfSDag-Erling Smørgrav int ctty_pgrp; 173d95e11bfSDag-Erling Smørgrav 174d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) 175d95e11bfSDag-Erling Smørgrav return(-1); 176d95e11bfSDag-Erling Smørgrav else 177d95e11bfSDag-Erling Smørgrav return(ctty_pgrp); 178d95e11bfSDag-Erling Smørgrav } 179d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCGETPGRP */ 180d95e11bfSDag-Erling Smørgrav 181d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCSENDBREAK 182d95e11bfSDag-Erling Smørgrav int 183d95e11bfSDag-Erling Smørgrav tcsendbreak(int fd, int duration) 184d95e11bfSDag-Erling Smørgrav { 185d95e11bfSDag-Erling Smørgrav # if defined(TIOCSBRK) && defined(TIOCCBRK) 186d95e11bfSDag-Erling Smørgrav struct timeval sleepytime; 187d95e11bfSDag-Erling Smørgrav 188d95e11bfSDag-Erling Smørgrav sleepytime.tv_sec = 0; 189d95e11bfSDag-Erling Smørgrav sleepytime.tv_usec = 400000; 190d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCSBRK, 0) == -1) 191d95e11bfSDag-Erling Smørgrav return (-1); 192d95e11bfSDag-Erling Smørgrav (void)select(0, 0, 0, 0, &sleepytime); 193d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCCBRK, 0) == -1) 194d95e11bfSDag-Erling Smørgrav return (-1); 195d95e11bfSDag-Erling Smørgrav return (0); 196d95e11bfSDag-Erling Smørgrav # else 197d95e11bfSDag-Erling Smørgrav return -1; 198d95e11bfSDag-Erling Smørgrav # endif 199d95e11bfSDag-Erling Smørgrav } 200d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCSENDBREAK */ 201d95e11bfSDag-Erling Smørgrav 202d95e11bfSDag-Erling Smørgrav mysig_t 203d95e11bfSDag-Erling Smørgrav mysignal(int sig, mysig_t act) 204d95e11bfSDag-Erling Smørgrav { 205d95e11bfSDag-Erling Smørgrav #ifdef HAVE_SIGACTION 206d95e11bfSDag-Erling Smørgrav struct sigaction sa, osa; 207d95e11bfSDag-Erling Smørgrav 208d95e11bfSDag-Erling Smørgrav if (sigaction(sig, NULL, &osa) == -1) 209d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 210d95e11bfSDag-Erling Smørgrav if (osa.sa_handler != act) { 211d95e11bfSDag-Erling Smørgrav memset(&sa, 0, sizeof(sa)); 212d95e11bfSDag-Erling Smørgrav sigemptyset(&sa.sa_mask); 213d95e11bfSDag-Erling Smørgrav sa.sa_flags = 0; 214d95e11bfSDag-Erling Smørgrav #ifdef SA_INTERRUPT 215d95e11bfSDag-Erling Smørgrav if (sig == SIGALRM) 216d95e11bfSDag-Erling Smørgrav sa.sa_flags |= SA_INTERRUPT; 217d95e11bfSDag-Erling Smørgrav #endif 218d95e11bfSDag-Erling Smørgrav sa.sa_handler = act; 219d95e11bfSDag-Erling Smørgrav if (sigaction(sig, &sa, NULL) == -1) 220d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 221d95e11bfSDag-Erling Smørgrav } 222d95e11bfSDag-Erling Smørgrav return (osa.sa_handler); 223d95e11bfSDag-Erling Smørgrav #else 224efcad6b7SDag-Erling Smørgrav #undef signal 225d95e11bfSDag-Erling Smørgrav return (signal(sig, act)); 226d95e11bfSDag-Erling Smørgrav #endif 227d95e11bfSDag-Erling Smørgrav } 228043840dfSDag-Erling Smørgrav 229043840dfSDag-Erling Smørgrav #ifndef HAVE_STRDUP 230043840dfSDag-Erling Smørgrav char * 231043840dfSDag-Erling Smørgrav strdup(const char *str) 232043840dfSDag-Erling Smørgrav { 233043840dfSDag-Erling Smørgrav size_t len; 234043840dfSDag-Erling Smørgrav char *cp; 235043840dfSDag-Erling Smørgrav 236043840dfSDag-Erling Smørgrav len = strlen(str) + 1; 237043840dfSDag-Erling Smørgrav cp = malloc(len); 238043840dfSDag-Erling Smørgrav if (cp != NULL) 239021d409fSDag-Erling Smørgrav return(memcpy(cp, str, len)); 240043840dfSDag-Erling Smørgrav return NULL; 241043840dfSDag-Erling Smørgrav } 242043840dfSDag-Erling Smørgrav #endif 243*4a421b63SDag-Erling Smørgrav 244*4a421b63SDag-Erling Smørgrav #ifndef HAVE_ISBLANK 245*4a421b63SDag-Erling Smørgrav int isblank(int c) 246*4a421b63SDag-Erling Smørgrav { 247*4a421b63SDag-Erling Smørgrav return (c == ' ' || c == '\t'); 248*4a421b63SDag-Erling Smørgrav } 249*4a421b63SDag-Erling Smørgrav #endif 250