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#if !defined(HAVE_USLEEP) 169int usleep(unsigned int useconds) 170{ 171 struct timespec ts; 172 173 ts.tv_sec = useconds / 1000000; 174 ts.tv_nsec = (useconds % 1000000) * 1000; 175 return nanosleep(&ts, NULL); 176} 177#endif 178 179#ifndef HAVE_TCGETPGRP 180pid_t 181tcgetpgrp(int fd) 182{ 183 int ctty_pgrp; 184 185 if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) 186 return(-1); 187 else 188 return(ctty_pgrp); 189} 190#endif /* HAVE_TCGETPGRP */ 191 192#ifndef HAVE_TCSENDBREAK 193int 194tcsendbreak(int fd, int duration) 195{ 196# if defined(TIOCSBRK) && defined(TIOCCBRK) 197 struct timeval sleepytime; 198 199 sleepytime.tv_sec = 0; 200 sleepytime.tv_usec = 400000; 201 if (ioctl(fd, TIOCSBRK, 0) == -1) 202 return (-1); 203 (void)select(0, 0, 0, 0, &sleepytime); 204 if (ioctl(fd, TIOCCBRK, 0) == -1) 205 return (-1); 206 return (0); 207# else 208 return -1; 209# endif 210} 211#endif /* HAVE_TCSENDBREAK */ 212 213mysig_t 214mysignal(int sig, mysig_t act) 215{ 216#ifdef HAVE_SIGACTION 217 struct sigaction sa, osa; 218 219 if (sigaction(sig, NULL, &osa) == -1) 220 return (mysig_t) -1; 221 if (osa.sa_handler != act) { 222 memset(&sa, 0, sizeof(sa)); 223 sigemptyset(&sa.sa_mask); 224 sa.sa_flags = 0; 225#ifdef SA_INTERRUPT 226 if (sig == SIGALRM) 227 sa.sa_flags |= SA_INTERRUPT; 228#endif 229 sa.sa_handler = act; 230 if (sigaction(sig, &sa, NULL) == -1) 231 return (mysig_t) -1; 232 } 233 return (osa.sa_handler); 234#else 235 #undef signal 236 return (signal(sig, act)); 237#endif 238} 239 240#ifndef HAVE_STRDUP 241char * 242strdup(const char *str) 243{ 244 size_t len; 245 char *cp; 246 247 len = strlen(str) + 1; 248 cp = malloc(len); 249 if (cp != NULL) 250 return(memcpy(cp, str, len)); 251 return NULL; 252} 253#endif 254 255#ifndef HAVE_ISBLANK 256int 257isblank(int c) 258{ 259 return (c == ' ' || c == '\t'); 260} 261#endif 262 263#ifndef HAVE_GETPGID 264pid_t 265getpgid(pid_t pid) 266{ 267#if defined(HAVE_GETPGRP) && !defined(GETPGRP_VOID) 268 return getpgrp(pid); 269#elif defined(HAVE_GETPGRP) 270 if (pid == 0) 271 return getpgrp(); 272#endif 273 274 errno = ESRCH; 275 return -1; 276} 277#endif 278