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 168*6888a9beSDag-Erling Smørgrav #if !defined(HAVE_USLEEP) 169*6888a9beSDag-Erling Smørgrav int usleep(unsigned int useconds) 170*6888a9beSDag-Erling Smørgrav { 171*6888a9beSDag-Erling Smørgrav struct timespec ts; 172*6888a9beSDag-Erling Smørgrav 173*6888a9beSDag-Erling Smørgrav ts.tv_sec = useconds / 1000000; 174*6888a9beSDag-Erling Smørgrav ts.tv_nsec = (useconds % 1000000) * 1000; 175*6888a9beSDag-Erling Smørgrav return nanosleep(&ts, NULL); 176*6888a9beSDag-Erling Smørgrav } 177*6888a9beSDag-Erling Smørgrav #endif 178*6888a9beSDag-Erling Smørgrav 179d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCGETPGRP 180d95e11bfSDag-Erling Smørgrav pid_t 181d95e11bfSDag-Erling Smørgrav tcgetpgrp(int fd) 182d95e11bfSDag-Erling Smørgrav { 183d95e11bfSDag-Erling Smørgrav int ctty_pgrp; 184d95e11bfSDag-Erling Smørgrav 185d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) 186d95e11bfSDag-Erling Smørgrav return(-1); 187d95e11bfSDag-Erling Smørgrav else 188d95e11bfSDag-Erling Smørgrav return(ctty_pgrp); 189d95e11bfSDag-Erling Smørgrav } 190d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCGETPGRP */ 191d95e11bfSDag-Erling Smørgrav 192d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCSENDBREAK 193d95e11bfSDag-Erling Smørgrav int 194d95e11bfSDag-Erling Smørgrav tcsendbreak(int fd, int duration) 195d95e11bfSDag-Erling Smørgrav { 196d95e11bfSDag-Erling Smørgrav # if defined(TIOCSBRK) && defined(TIOCCBRK) 197d95e11bfSDag-Erling Smørgrav struct timeval sleepytime; 198d95e11bfSDag-Erling Smørgrav 199d95e11bfSDag-Erling Smørgrav sleepytime.tv_sec = 0; 200d95e11bfSDag-Erling Smørgrav sleepytime.tv_usec = 400000; 201d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCSBRK, 0) == -1) 202d95e11bfSDag-Erling Smørgrav return (-1); 203d95e11bfSDag-Erling Smørgrav (void)select(0, 0, 0, 0, &sleepytime); 204d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCCBRK, 0) == -1) 205d95e11bfSDag-Erling Smørgrav return (-1); 206d95e11bfSDag-Erling Smørgrav return (0); 207d95e11bfSDag-Erling Smørgrav # else 208d95e11bfSDag-Erling Smørgrav return -1; 209d95e11bfSDag-Erling Smørgrav # endif 210d95e11bfSDag-Erling Smørgrav } 211d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCSENDBREAK */ 212d95e11bfSDag-Erling Smørgrav 213d95e11bfSDag-Erling Smørgrav mysig_t 214d95e11bfSDag-Erling Smørgrav mysignal(int sig, mysig_t act) 215d95e11bfSDag-Erling Smørgrav { 216d95e11bfSDag-Erling Smørgrav #ifdef HAVE_SIGACTION 217d95e11bfSDag-Erling Smørgrav struct sigaction sa, osa; 218d95e11bfSDag-Erling Smørgrav 219d95e11bfSDag-Erling Smørgrav if (sigaction(sig, NULL, &osa) == -1) 220d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 221d95e11bfSDag-Erling Smørgrav if (osa.sa_handler != act) { 222d95e11bfSDag-Erling Smørgrav memset(&sa, 0, sizeof(sa)); 223d95e11bfSDag-Erling Smørgrav sigemptyset(&sa.sa_mask); 224d95e11bfSDag-Erling Smørgrav sa.sa_flags = 0; 225d95e11bfSDag-Erling Smørgrav #ifdef SA_INTERRUPT 226d95e11bfSDag-Erling Smørgrav if (sig == SIGALRM) 227d95e11bfSDag-Erling Smørgrav sa.sa_flags |= SA_INTERRUPT; 228d95e11bfSDag-Erling Smørgrav #endif 229d95e11bfSDag-Erling Smørgrav sa.sa_handler = act; 230d95e11bfSDag-Erling Smørgrav if (sigaction(sig, &sa, NULL) == -1) 231d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 232d95e11bfSDag-Erling Smørgrav } 233d95e11bfSDag-Erling Smørgrav return (osa.sa_handler); 234d95e11bfSDag-Erling Smørgrav #else 235efcad6b7SDag-Erling Smørgrav #undef signal 236d95e11bfSDag-Erling Smørgrav return (signal(sig, act)); 237d95e11bfSDag-Erling Smørgrav #endif 238d95e11bfSDag-Erling Smørgrav } 239043840dfSDag-Erling Smørgrav 240043840dfSDag-Erling Smørgrav #ifndef HAVE_STRDUP 241043840dfSDag-Erling Smørgrav char * 242043840dfSDag-Erling Smørgrav strdup(const char *str) 243043840dfSDag-Erling Smørgrav { 244043840dfSDag-Erling Smørgrav size_t len; 245043840dfSDag-Erling Smørgrav char *cp; 246043840dfSDag-Erling Smørgrav 247043840dfSDag-Erling Smørgrav len = strlen(str) + 1; 248043840dfSDag-Erling Smørgrav cp = malloc(len); 249043840dfSDag-Erling Smørgrav if (cp != NULL) 250021d409fSDag-Erling Smørgrav return(memcpy(cp, str, len)); 251043840dfSDag-Erling Smørgrav return NULL; 252043840dfSDag-Erling Smørgrav } 253043840dfSDag-Erling Smørgrav #endif 2544a421b63SDag-Erling Smørgrav 2554a421b63SDag-Erling Smørgrav #ifndef HAVE_ISBLANK 256*6888a9beSDag-Erling Smørgrav int 257*6888a9beSDag-Erling Smørgrav isblank(int c) 2584a421b63SDag-Erling Smørgrav { 2594a421b63SDag-Erling Smørgrav return (c == ' ' || c == '\t'); 2604a421b63SDag-Erling Smørgrav } 2614a421b63SDag-Erling Smørgrav #endif 262*6888a9beSDag-Erling Smørgrav 263*6888a9beSDag-Erling Smørgrav #ifndef HAVE_GETPGID 264*6888a9beSDag-Erling Smørgrav pid_t 265*6888a9beSDag-Erling Smørgrav getpgid(pid_t pid) 266*6888a9beSDag-Erling Smørgrav { 267*6888a9beSDag-Erling Smørgrav #if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) 268*6888a9beSDag-Erling Smørgrav return getpgrp(pid); 269*6888a9beSDag-Erling Smørgrav #elif defined(HAVE_GETPGRP) 270*6888a9beSDag-Erling Smørgrav if (pid == 0) 271*6888a9beSDag-Erling Smørgrav return getpgrp(); 272*6888a9beSDag-Erling Smørgrav #endif 273*6888a9beSDag-Erling Smørgrav 274*6888a9beSDag-Erling Smørgrav errno = ESRCH; 275*6888a9beSDag-Erling Smørgrav return -1; 276*6888a9beSDag-Erling Smørgrav } 277*6888a9beSDag-Erling Smørgrav #endif 278