1 /* 2 * Copyright (c) 1999-2003 Damien Miller. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #include "includes.h" 26 #include "xmalloc.h" 27 28 RCSID("$Id: bsd-misc.c,v 1.19 2003/08/25 01:16:21 mouring Exp $"); 29 30 /* 31 * NB. duplicate __progname in case it is an alias for argv[0] 32 * Otherwise it may get clobbered by setproctitle() 33 */ 34 char *ssh_get_progname(char *argv0) 35 { 36 #ifdef HAVE___PROGNAME 37 extern char *__progname; 38 39 return xstrdup(__progname); 40 #else 41 char *p; 42 43 if (argv0 == NULL) 44 return ("unknown"); /* XXX */ 45 p = strrchr(argv0, '/'); 46 if (p == NULL) 47 p = argv0; 48 else 49 p++; 50 51 return (xstrdup(p)); 52 #endif 53 } 54 55 #ifndef HAVE_SETLOGIN 56 int setlogin(const char *name) 57 { 58 return (0); 59 } 60 #endif /* !HAVE_SETLOGIN */ 61 62 #ifndef HAVE_INNETGR 63 int innetgr(const char *netgroup, const char *host, 64 const char *user, const char *domain) 65 { 66 return (0); 67 } 68 #endif /* HAVE_INNETGR */ 69 70 #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) 71 int seteuid(uid_t euid) 72 { 73 return (setreuid(-1, euid)); 74 } 75 #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ 76 77 #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) 78 int setegid(uid_t egid) 79 { 80 return(setresgid(-1, egid, -1)); 81 } 82 #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ 83 84 #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) 85 const char *strerror(int e) 86 { 87 extern int sys_nerr; 88 extern char *sys_errlist[]; 89 90 if ((e >= 0) && (e < sys_nerr)) 91 return (sys_errlist[e]); 92 93 return ("unlisted error"); 94 } 95 #endif 96 97 #ifndef HAVE_UTIMES 98 int utimes(char *filename, struct timeval *tvp) 99 { 100 struct utimbuf ub; 101 102 ub.actime = tvp[0].tv_sec; 103 ub.modtime = tvp[1].tv_sec; 104 105 return (utime(filename, &ub)); 106 } 107 #endif 108 109 #ifndef HAVE_TRUNCATE 110 int truncate(const char *path, off_t length) 111 { 112 int fd, ret, saverrno; 113 114 fd = open(path, O_WRONLY); 115 if (fd < 0) 116 return (-1); 117 118 ret = ftruncate(fd, length); 119 saverrno = errno; 120 close(fd); 121 if (ret == -1) 122 errno = saverrno; 123 124 return(ret); 125 } 126 #endif /* HAVE_TRUNCATE */ 127 128 #if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) 129 /* 130 * Cygwin setgroups should be a noop. 131 */ 132 int 133 setgroups(size_t size, const gid_t *list) 134 { 135 return (0); 136 } 137 #endif 138 139 #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) 140 int nanosleep(const struct timespec *req, struct timespec *rem) 141 { 142 int rc, saverrno; 143 extern int errno; 144 struct timeval tstart, tstop, tremain, time2wait; 145 146 TIMESPEC_TO_TIMEVAL(&time2wait, req) 147 (void) gettimeofday(&tstart, NULL); 148 rc = select(0, NULL, NULL, NULL, &time2wait); 149 if (rc == -1) { 150 saverrno = errno; 151 (void) gettimeofday (&tstop, NULL); 152 errno = saverrno; 153 tremain.tv_sec = time2wait.tv_sec - 154 (tstop.tv_sec - tstart.tv_sec); 155 tremain.tv_usec = time2wait.tv_usec - 156 (tstop.tv_usec - tstart.tv_usec); 157 tremain.tv_sec += tremain.tv_usec / 1000000L; 158 tremain.tv_usec %= 1000000L; 159 } else { 160 tremain.tv_sec = 0; 161 tremain.tv_usec = 0; 162 } 163 TIMEVAL_TO_TIMESPEC(&tremain, rem) 164 165 return(rc); 166 } 167 168 #endif 169 170 #ifndef HAVE_TCGETPGRP 171 pid_t 172 tcgetpgrp(int fd) 173 { 174 int ctty_pgrp; 175 176 if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) 177 return(-1); 178 else 179 return(ctty_pgrp); 180 } 181 #endif /* HAVE_TCGETPGRP */ 182 183 #ifndef HAVE_TCSENDBREAK 184 int 185 tcsendbreak(int fd, int duration) 186 { 187 # if defined(TIOCSBRK) && defined(TIOCCBRK) 188 struct timeval sleepytime; 189 190 sleepytime.tv_sec = 0; 191 sleepytime.tv_usec = 400000; 192 if (ioctl(fd, TIOCSBRK, 0) == -1) 193 return (-1); 194 (void)select(0, 0, 0, 0, &sleepytime); 195 if (ioctl(fd, TIOCCBRK, 0) == -1) 196 return (-1); 197 return (0); 198 # else 199 return -1; 200 # endif 201 } 202 #endif /* HAVE_TCSENDBREAK */ 203 204 mysig_t 205 mysignal(int sig, mysig_t act) 206 { 207 #ifdef HAVE_SIGACTION 208 struct sigaction sa, osa; 209 210 if (sigaction(sig, NULL, &osa) == -1) 211 return (mysig_t) -1; 212 if (osa.sa_handler != act) { 213 memset(&sa, 0, sizeof(sa)); 214 sigemptyset(&sa.sa_mask); 215 sa.sa_flags = 0; 216 #ifdef SA_INTERRUPT 217 if (sig == SIGALRM) 218 sa.sa_flags |= SA_INTERRUPT; 219 #endif 220 sa.sa_handler = act; 221 if (sigaction(sig, &sa, NULL) == -1) 222 return (mysig_t) -1; 223 } 224 return (osa.sa_handler); 225 #else 226 return (signal(sig, act)); 227 #endif 228 } 229