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