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