bsd-misc.c revision 149749
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 21RCSID("$Id: bsd-misc.c,v 1.27 2005/05/27 11:13:41 dtucker Exp $"); 22 23#ifndef HAVE___PROGNAME 24char *__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 */ 31char *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 53int setlogin(const char *name) 54{ 55 return (0); 56} 57#endif /* !HAVE_SETLOGIN */ 58 59#ifndef HAVE_INNETGR 60int 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) 68int 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) 75int 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) 82const 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 95int 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 107int 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) 126int 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 156pid_t 157tcgetpgrp(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 169int 170tcsendbreak(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 189mysig_t 190mysignal(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 217char * 218strdup(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 if (strlcpy(cp, str, len) != len) { 227 free(cp); 228 return NULL; 229 } 230 return cp; 231} 232#endif 233