1 2/* 3 * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org> 4 * 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. 8 * 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. 16 */ 17 18#include "includes.h" 19 20#include <sys/types.h> 21#ifdef HAVE_SYS_SELECT_H 22# include <sys/select.h> 23#endif 24#ifdef HAVE_SYS_TIME_H 25# include <sys/time.h> 26#endif 27 28#include <string.h> 29#include <signal.h> 30#include <stdlib.h> 31#include <unistd.h> 32 33#include "xmalloc.h" 34 35#ifndef HAVE___PROGNAME 36char *__progname; 37#endif 38 39/* 40 * NB. duplicate __progname in case it is an alias for argv[0] 41 * Otherwise it may get clobbered by setproctitle() 42 */ 43char *ssh_get_progname(char *argv0) 44{ 45#ifdef HAVE___PROGNAME 46 extern char *__progname; 47 48 return xstrdup(__progname); 49#else 50 char *p; 51 52 if (argv0 == NULL) 53 return ("unknown"); /* XXX */ 54 p = strrchr(argv0, '/'); 55 if (p == NULL) 56 p = argv0; 57 else 58 p++; 59 60 return (xstrdup(p)); 61#endif 62} 63 64#ifndef HAVE_SETLOGIN 65int setlogin(const char *name) 66{ 67 return (0); 68} 69#endif /* !HAVE_SETLOGIN */ 70 71#ifndef HAVE_INNETGR 72int innetgr(const char *netgroup, const char *host, 73 const char *user, const char *domain) 74{ 75 return (0); 76} 77#endif /* HAVE_INNETGR */ 78 79#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) 80int seteuid(uid_t euid) 81{ 82 return (setreuid(-1, euid)); 83} 84#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ 85 86#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) 87int setegid(uid_t egid) 88{ 89 return(setresgid(-1, egid, -1)); 90} 91#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ 92 93#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) 94const char *strerror(int e) 95{ 96 extern int sys_nerr; 97 extern char *sys_errlist[]; 98 99 if ((e >= 0) && (e < sys_nerr)) 100 return (sys_errlist[e]); 101 102 return ("unlisted error"); 103} 104#endif 105 106#ifndef HAVE_UTIMES 107int utimes(char *filename, struct timeval *tvp) 108{ 109 struct utimbuf ub; 110 111 ub.actime = tvp[0].tv_sec; 112 ub.modtime = tvp[1].tv_sec; 113 114 return (utime(filename, &ub)); 115} 116#endif 117 118#ifndef HAVE_TRUNCATE 119int truncate(const char *path, off_t length) 120{ 121 int fd, ret, saverrno; 122 123 fd = open(path, O_WRONLY); 124 if (fd < 0) 125 return (-1); 126 127 ret = ftruncate(fd, length); 128 saverrno = errno; 129 close(fd); 130 if (ret == -1) 131 errno = saverrno; 132 133 return(ret); 134} 135#endif /* HAVE_TRUNCATE */ 136 137#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) 138int nanosleep(const struct timespec *req, struct timespec *rem) 139{ 140 int rc, saverrno; 141 extern int errno; 142 struct timeval tstart, tstop, tremain, time2wait; 143 144 TIMESPEC_TO_TIMEVAL(&time2wait, req) 145 (void) gettimeofday(&tstart, NULL); 146 rc = select(0, NULL, NULL, NULL, &time2wait); 147 if (rc == -1) { 148 saverrno = errno; 149 (void) gettimeofday (&tstop, NULL); 150 errno = saverrno; 151 tremain.tv_sec = time2wait.tv_sec - 152 (tstop.tv_sec - tstart.tv_sec); 153 tremain.tv_usec = time2wait.tv_usec - 154 (tstop.tv_usec - tstart.tv_usec); 155 tremain.tv_sec += tremain.tv_usec / 1000000L; 156 tremain.tv_usec %= 1000000L; 157 } else { 158 tremain.tv_sec = 0; 159 tremain.tv_usec = 0; 160 } 161 if (rem != NULL) 162 TIMEVAL_TO_TIMESPEC(&tremain, rem) 163 164 return(rc); 165} 166#endif 167 168#ifndef HAVE_TCGETPGRP 169pid_t 170tcgetpgrp(int fd) 171{ 172 int ctty_pgrp; 173 174 if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) 175 return(-1); 176 else 177 return(ctty_pgrp); 178} 179#endif /* HAVE_TCGETPGRP */ 180 181#ifndef HAVE_TCSENDBREAK 182int 183tcsendbreak(int fd, int duration) 184{ 185# if defined(TIOCSBRK) && defined(TIOCCBRK) 186 struct timeval sleepytime; 187 188 sleepytime.tv_sec = 0; 189 sleepytime.tv_usec = 400000; 190 if (ioctl(fd, TIOCSBRK, 0) == -1) 191 return (-1); 192 (void)select(0, 0, 0, 0, &sleepytime); 193 if (ioctl(fd, TIOCCBRK, 0) == -1) 194 return (-1); 195 return (0); 196# else 197 return -1; 198# endif 199} 200#endif /* HAVE_TCSENDBREAK */ 201 202mysig_t 203mysignal(int sig, mysig_t act) 204{ 205#ifdef HAVE_SIGACTION 206 struct sigaction sa, osa; 207 208 if (sigaction(sig, NULL, &osa) == -1) 209 return (mysig_t) -1; 210 if (osa.sa_handler != act) { 211 memset(&sa, 0, sizeof(sa)); 212 sigemptyset(&sa.sa_mask); 213 sa.sa_flags = 0; 214#ifdef SA_INTERRUPT 215 if (sig == SIGALRM) 216 sa.sa_flags |= SA_INTERRUPT; 217#endif 218 sa.sa_handler = act; 219 if (sigaction(sig, &sa, NULL) == -1) 220 return (mysig_t) -1; 221 } 222 return (osa.sa_handler); 223#else 224 #undef signal 225 return (signal(sig, act)); 226#endif 227} 228 229#ifndef HAVE_STRDUP 230char * 231strdup(const char *str) 232{ 233 size_t len; 234 char *cp; 235 236 len = strlen(str) + 1; 237 cp = malloc(len); 238 if (cp != NULL) 239 return(memcpy(cp, str, len)); 240 return NULL; 241} 242#endif 243 244#ifndef HAVE_ISBLANK 245int isblank(int c) 246{ 247 return (c == ' ' || c == '\t'); 248} 249#endif 250