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 36 char *__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 */ 43 char *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 65 int setlogin(const char *name) 66 { 67 return (0); 68 } 69 #endif /* !HAVE_SETLOGIN */ 70 71 #ifndef HAVE_INNETGR 72 int 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) 80 int 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) 87 int 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) 94 const 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 107 int 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 119 int 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) 138 int 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 169 pid_t 170 tcgetpgrp(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 182 int 183 tcsendbreak(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 202 mysig_t 203 mysignal(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 230 char * 231 strdup(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 245 int isblank(int c) 246 { 247 return (c == ' ' || c == '\t'); 248 } 249 #endif 250