183d2307dSDag-Erling Smørgrav /* 2efcad6b7SDag-Erling Smørgrav * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org> 383d2307dSDag-Erling Smørgrav * 4efcad6b7SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 5efcad6b7SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 6efcad6b7SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 783d2307dSDag-Erling Smørgrav * 8efcad6b7SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9efcad6b7SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10efcad6b7SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11efcad6b7SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12efcad6b7SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13efcad6b7SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14efcad6b7SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1583d2307dSDag-Erling Smørgrav */ 1683d2307dSDag-Erling Smørgrav 1783d2307dSDag-Erling Smørgrav #include "includes.h" 18d0c8c0bcSDag-Erling Smørgrav #include "xmalloc.h" 1983d2307dSDag-Erling Smørgrav 20efcad6b7SDag-Erling Smørgrav RCSID("$Id: bsd-misc.c,v 1.21 2004/02/17 05:49:55 djm Exp $"); 2183d2307dSDag-Erling Smørgrav 22d0c8c0bcSDag-Erling Smørgrav /* 23d0c8c0bcSDag-Erling Smørgrav * NB. duplicate __progname in case it is an alias for argv[0] 24d0c8c0bcSDag-Erling Smørgrav * Otherwise it may get clobbered by setproctitle() 25d0c8c0bcSDag-Erling Smørgrav */ 26d95e11bfSDag-Erling Smørgrav char *ssh_get_progname(char *argv0) 2783d2307dSDag-Erling Smørgrav { 2883d2307dSDag-Erling Smørgrav #ifdef HAVE___PROGNAME 2983d2307dSDag-Erling Smørgrav extern char *__progname; 3083d2307dSDag-Erling Smørgrav 31d0c8c0bcSDag-Erling Smørgrav return xstrdup(__progname); 3283d2307dSDag-Erling Smørgrav #else 3383d2307dSDag-Erling Smørgrav char *p; 3483d2307dSDag-Erling Smørgrav 3583d2307dSDag-Erling Smørgrav if (argv0 == NULL) 36d95e11bfSDag-Erling Smørgrav return ("unknown"); /* XXX */ 3783d2307dSDag-Erling Smørgrav p = strrchr(argv0, '/'); 3883d2307dSDag-Erling Smørgrav if (p == NULL) 3983d2307dSDag-Erling Smørgrav p = argv0; 4083d2307dSDag-Erling Smørgrav else 4183d2307dSDag-Erling Smørgrav p++; 42d0c8c0bcSDag-Erling Smørgrav 43d95e11bfSDag-Erling Smørgrav return (xstrdup(p)); 4483d2307dSDag-Erling Smørgrav #endif 4583d2307dSDag-Erling Smørgrav } 4683d2307dSDag-Erling Smørgrav 4783d2307dSDag-Erling Smørgrav #ifndef HAVE_SETLOGIN 4883d2307dSDag-Erling Smørgrav int setlogin(const char *name) 4983d2307dSDag-Erling Smørgrav { 5083d2307dSDag-Erling Smørgrav return (0); 5183d2307dSDag-Erling Smørgrav } 5283d2307dSDag-Erling Smørgrav #endif /* !HAVE_SETLOGIN */ 5383d2307dSDag-Erling Smørgrav 5483d2307dSDag-Erling Smørgrav #ifndef HAVE_INNETGR 5583d2307dSDag-Erling Smørgrav int innetgr(const char *netgroup, const char *host, 5683d2307dSDag-Erling Smørgrav const char *user, const char *domain) 5783d2307dSDag-Erling Smørgrav { 5883d2307dSDag-Erling Smørgrav return (0); 5983d2307dSDag-Erling Smørgrav } 6083d2307dSDag-Erling Smørgrav #endif /* HAVE_INNETGR */ 6183d2307dSDag-Erling Smørgrav 6283d2307dSDag-Erling Smørgrav #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) 6383d2307dSDag-Erling Smørgrav int seteuid(uid_t euid) 6483d2307dSDag-Erling Smørgrav { 6583d2307dSDag-Erling Smørgrav return (setreuid(-1, euid)); 6683d2307dSDag-Erling Smørgrav } 6783d2307dSDag-Erling Smørgrav #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ 6883d2307dSDag-Erling Smørgrav 6983d2307dSDag-Erling Smørgrav #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) 7083d2307dSDag-Erling Smørgrav int setegid(uid_t egid) 7183d2307dSDag-Erling Smørgrav { 7283d2307dSDag-Erling Smørgrav return(setresgid(-1, egid, -1)); 7383d2307dSDag-Erling Smørgrav } 7483d2307dSDag-Erling Smørgrav #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ 7583d2307dSDag-Erling Smørgrav 7683d2307dSDag-Erling Smørgrav #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) 7783d2307dSDag-Erling Smørgrav const char *strerror(int e) 7883d2307dSDag-Erling Smørgrav { 7983d2307dSDag-Erling Smørgrav extern int sys_nerr; 8083d2307dSDag-Erling Smørgrav extern char *sys_errlist[]; 8183d2307dSDag-Erling Smørgrav 8283d2307dSDag-Erling Smørgrav if ((e >= 0) && (e < sys_nerr)) 8383d2307dSDag-Erling Smørgrav return (sys_errlist[e]); 84d95e11bfSDag-Erling Smørgrav 8583d2307dSDag-Erling Smørgrav return ("unlisted error"); 8683d2307dSDag-Erling Smørgrav } 8783d2307dSDag-Erling Smørgrav #endif 8883d2307dSDag-Erling Smørgrav 8983d2307dSDag-Erling Smørgrav #ifndef HAVE_UTIMES 9083d2307dSDag-Erling Smørgrav int utimes(char *filename, struct timeval *tvp) 9183d2307dSDag-Erling Smørgrav { 9283d2307dSDag-Erling Smørgrav struct utimbuf ub; 9383d2307dSDag-Erling Smørgrav 944b17dab0SDag-Erling Smørgrav ub.actime = tvp[0].tv_sec; 954b17dab0SDag-Erling Smørgrav ub.modtime = tvp[1].tv_sec; 9683d2307dSDag-Erling Smørgrav 9783d2307dSDag-Erling Smørgrav return (utime(filename, &ub)); 9883d2307dSDag-Erling Smørgrav } 9983d2307dSDag-Erling Smørgrav #endif 10083d2307dSDag-Erling Smørgrav 10183d2307dSDag-Erling Smørgrav #ifndef HAVE_TRUNCATE 10283d2307dSDag-Erling Smørgrav int truncate(const char *path, off_t length) 10383d2307dSDag-Erling Smørgrav { 10483d2307dSDag-Erling Smørgrav int fd, ret, saverrno; 10583d2307dSDag-Erling Smørgrav 10683d2307dSDag-Erling Smørgrav fd = open(path, O_WRONLY); 10783d2307dSDag-Erling Smørgrav if (fd < 0) 108d95e11bfSDag-Erling Smørgrav return (-1); 10983d2307dSDag-Erling Smørgrav 11083d2307dSDag-Erling Smørgrav ret = ftruncate(fd, length); 11183d2307dSDag-Erling Smørgrav saverrno = errno; 112d95e11bfSDag-Erling Smørgrav close(fd); 11383d2307dSDag-Erling Smørgrav if (ret == -1) 11483d2307dSDag-Erling Smørgrav errno = saverrno; 115d95e11bfSDag-Erling Smørgrav 11683d2307dSDag-Erling Smørgrav return(ret); 11783d2307dSDag-Erling Smørgrav } 11883d2307dSDag-Erling Smørgrav #endif /* HAVE_TRUNCATE */ 11983d2307dSDag-Erling Smørgrav 12083d2307dSDag-Erling Smørgrav #if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) 12183d2307dSDag-Erling Smørgrav /* 12283d2307dSDag-Erling Smørgrav * Cygwin setgroups should be a noop. 12383d2307dSDag-Erling Smørgrav */ 12483d2307dSDag-Erling Smørgrav int 12583d2307dSDag-Erling Smørgrav setgroups(size_t size, const gid_t *list) 12683d2307dSDag-Erling Smørgrav { 127d95e11bfSDag-Erling Smørgrav return (0); 12883d2307dSDag-Erling Smørgrav } 12983d2307dSDag-Erling Smørgrav #endif 13083d2307dSDag-Erling Smørgrav 131d0c8c0bcSDag-Erling Smørgrav #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) 132d0c8c0bcSDag-Erling Smørgrav int nanosleep(const struct timespec *req, struct timespec *rem) 133d0c8c0bcSDag-Erling Smørgrav { 134d0c8c0bcSDag-Erling Smørgrav int rc, saverrno; 135d0c8c0bcSDag-Erling Smørgrav extern int errno; 136d0c8c0bcSDag-Erling Smørgrav struct timeval tstart, tstop, tremain, time2wait; 137d0c8c0bcSDag-Erling Smørgrav 138d0c8c0bcSDag-Erling Smørgrav TIMESPEC_TO_TIMEVAL(&time2wait, req) 139d0c8c0bcSDag-Erling Smørgrav (void) gettimeofday(&tstart, NULL); 140d0c8c0bcSDag-Erling Smørgrav rc = select(0, NULL, NULL, NULL, &time2wait); 141d0c8c0bcSDag-Erling Smørgrav if (rc == -1) { 142d0c8c0bcSDag-Erling Smørgrav saverrno = errno; 143d0c8c0bcSDag-Erling Smørgrav (void) gettimeofday (&tstop, NULL); 144d0c8c0bcSDag-Erling Smørgrav errno = saverrno; 145d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec = time2wait.tv_sec - 146d0c8c0bcSDag-Erling Smørgrav (tstop.tv_sec - tstart.tv_sec); 147d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec = time2wait.tv_usec - 148d0c8c0bcSDag-Erling Smørgrav (tstop.tv_usec - tstart.tv_usec); 149d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec += tremain.tv_usec / 1000000L; 150d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec %= 1000000L; 151d0c8c0bcSDag-Erling Smørgrav } else { 152d0c8c0bcSDag-Erling Smørgrav tremain.tv_sec = 0; 153d0c8c0bcSDag-Erling Smørgrav tremain.tv_usec = 0; 154d0c8c0bcSDag-Erling Smørgrav } 155d0c8c0bcSDag-Erling Smørgrav TIMEVAL_TO_TIMESPEC(&tremain, rem) 156d0c8c0bcSDag-Erling Smørgrav 157d0c8c0bcSDag-Erling Smørgrav return(rc); 158d0c8c0bcSDag-Erling Smørgrav } 159d0c8c0bcSDag-Erling Smørgrav #endif 160d0c8c0bcSDag-Erling Smørgrav 161d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCGETPGRP 162d95e11bfSDag-Erling Smørgrav pid_t 163d95e11bfSDag-Erling Smørgrav tcgetpgrp(int fd) 164d95e11bfSDag-Erling Smørgrav { 165d95e11bfSDag-Erling Smørgrav int ctty_pgrp; 166d95e11bfSDag-Erling Smørgrav 167d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) 168d95e11bfSDag-Erling Smørgrav return(-1); 169d95e11bfSDag-Erling Smørgrav else 170d95e11bfSDag-Erling Smørgrav return(ctty_pgrp); 171d95e11bfSDag-Erling Smørgrav } 172d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCGETPGRP */ 173d95e11bfSDag-Erling Smørgrav 174d95e11bfSDag-Erling Smørgrav #ifndef HAVE_TCSENDBREAK 175d95e11bfSDag-Erling Smørgrav int 176d95e11bfSDag-Erling Smørgrav tcsendbreak(int fd, int duration) 177d95e11bfSDag-Erling Smørgrav { 178d95e11bfSDag-Erling Smørgrav # if defined(TIOCSBRK) && defined(TIOCCBRK) 179d95e11bfSDag-Erling Smørgrav struct timeval sleepytime; 180d95e11bfSDag-Erling Smørgrav 181d95e11bfSDag-Erling Smørgrav sleepytime.tv_sec = 0; 182d95e11bfSDag-Erling Smørgrav sleepytime.tv_usec = 400000; 183d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCSBRK, 0) == -1) 184d95e11bfSDag-Erling Smørgrav return (-1); 185d95e11bfSDag-Erling Smørgrav (void)select(0, 0, 0, 0, &sleepytime); 186d95e11bfSDag-Erling Smørgrav if (ioctl(fd, TIOCCBRK, 0) == -1) 187d95e11bfSDag-Erling Smørgrav return (-1); 188d95e11bfSDag-Erling Smørgrav return (0); 189d95e11bfSDag-Erling Smørgrav # else 190d95e11bfSDag-Erling Smørgrav return -1; 191d95e11bfSDag-Erling Smørgrav # endif 192d95e11bfSDag-Erling Smørgrav } 193d95e11bfSDag-Erling Smørgrav #endif /* HAVE_TCSENDBREAK */ 194d95e11bfSDag-Erling Smørgrav 195d95e11bfSDag-Erling Smørgrav mysig_t 196d95e11bfSDag-Erling Smørgrav mysignal(int sig, mysig_t act) 197d95e11bfSDag-Erling Smørgrav { 198d95e11bfSDag-Erling Smørgrav #ifdef HAVE_SIGACTION 199d95e11bfSDag-Erling Smørgrav struct sigaction sa, osa; 200d95e11bfSDag-Erling Smørgrav 201d95e11bfSDag-Erling Smørgrav if (sigaction(sig, NULL, &osa) == -1) 202d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 203d95e11bfSDag-Erling Smørgrav if (osa.sa_handler != act) { 204d95e11bfSDag-Erling Smørgrav memset(&sa, 0, sizeof(sa)); 205d95e11bfSDag-Erling Smørgrav sigemptyset(&sa.sa_mask); 206d95e11bfSDag-Erling Smørgrav sa.sa_flags = 0; 207d95e11bfSDag-Erling Smørgrav #ifdef SA_INTERRUPT 208d95e11bfSDag-Erling Smørgrav if (sig == SIGALRM) 209d95e11bfSDag-Erling Smørgrav sa.sa_flags |= SA_INTERRUPT; 210d95e11bfSDag-Erling Smørgrav #endif 211d95e11bfSDag-Erling Smørgrav sa.sa_handler = act; 212d95e11bfSDag-Erling Smørgrav if (sigaction(sig, &sa, NULL) == -1) 213d95e11bfSDag-Erling Smørgrav return (mysig_t) -1; 214d95e11bfSDag-Erling Smørgrav } 215d95e11bfSDag-Erling Smørgrav return (osa.sa_handler); 216d95e11bfSDag-Erling Smørgrav #else 217efcad6b7SDag-Erling Smørgrav #undef signal 218d95e11bfSDag-Erling Smørgrav return (signal(sig, act)); 219d95e11bfSDag-Erling Smørgrav #endif 220d95e11bfSDag-Erling Smørgrav } 221