Damien Miller | d4a8b7e | 1999-10-27 13:42:43 +1000 | [diff] [blame] | 1 | /* |
Damien Miller | 98225c2 | 2004-02-17 16:49:41 +1100 | [diff] [blame] | 2 | * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org> |
Damien Miller | 040f383 | 2000-04-03 14:50:43 +1000 | [diff] [blame] | 3 | * |
Damien Miller | 98225c2 | 2004-02-17 16:49:41 +1100 | [diff] [blame] | 4 | * Permission to use, copy, modify, and distribute this software for any |
| 5 | * purpose with or without fee is hereby granted, provided that the above |
| 6 | * copyright notice and this permission notice appear in all copies. |
Damien Miller | 040f383 | 2000-04-03 14:50:43 +1000 | [diff] [blame] | 7 | * |
Damien Miller | 98225c2 | 2004-02-17 16:49:41 +1100 | [diff] [blame] | 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
Damien Miller | 040f383 | 2000-04-03 14:50:43 +1000 | [diff] [blame] | 15 | */ |
Damien Miller | d4a8b7e | 1999-10-27 13:42:43 +1000 | [diff] [blame] | 16 | |
Damien Miller | 11fa2cc | 2000-08-16 10:35:58 +1000 | [diff] [blame] | 17 | #include "includes.h" |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 18 | #include "xmalloc.h" |
Damien Miller | d4a8b7e | 1999-10-27 13:42:43 +1000 | [diff] [blame] | 19 | |
Darren Tucker | 03669a3 | 2004-08-13 18:37:21 +1000 | [diff] [blame^] | 20 | RCSID("$Id: bsd-misc.c,v 1.24 2004/08/13 08:37:21 dtucker Exp $"); |
Darren Tucker | ba6de95 | 2004-07-17 14:07:42 +1000 | [diff] [blame] | 21 | |
Darren Tucker | 03669a3 | 2004-08-13 18:37:21 +1000 | [diff] [blame^] | 22 | #ifndef HAVE___PROGNAME |
Darren Tucker | ba6de95 | 2004-07-17 14:07:42 +1000 | [diff] [blame] | 23 | char *__progname; |
| 24 | #endif |
Damien Miller | e9cf357 | 2001-02-09 12:55:35 +1100 | [diff] [blame] | 25 | |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 26 | /* |
| 27 | * NB. duplicate __progname in case it is an alias for argv[0] |
| 28 | * Otherwise it may get clobbered by setproctitle() |
| 29 | */ |
Damien Miller | 59d3d5b | 2003-08-22 09:34:41 +1000 | [diff] [blame] | 30 | char *ssh_get_progname(char *argv0) |
Ben Lindstrom | 49a79c0 | 2000-11-17 03:47:20 +0000 | [diff] [blame] | 31 | { |
| 32 | #ifdef HAVE___PROGNAME |
| 33 | extern char *__progname; |
| 34 | |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 35 | return xstrdup(__progname); |
Ben Lindstrom | 49a79c0 | 2000-11-17 03:47:20 +0000 | [diff] [blame] | 36 | #else |
| 37 | char *p; |
| 38 | |
| 39 | if (argv0 == NULL) |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 40 | return ("unknown"); /* XXX */ |
Ben Lindstrom | 49a79c0 | 2000-11-17 03:47:20 +0000 | [diff] [blame] | 41 | p = strrchr(argv0, '/'); |
| 42 | if (p == NULL) |
| 43 | p = argv0; |
| 44 | else |
| 45 | p++; |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 46 | |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 47 | return (xstrdup(p)); |
Ben Lindstrom | 49a79c0 | 2000-11-17 03:47:20 +0000 | [diff] [blame] | 48 | #endif |
| 49 | } |
| 50 | |
Damien Miller | e72b7af | 1999-12-30 15:08:44 +1100 | [diff] [blame] | 51 | #ifndef HAVE_SETLOGIN |
| 52 | int setlogin(const char *name) |
| 53 | { |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 54 | return (0); |
Damien Miller | e72b7af | 1999-12-30 15:08:44 +1100 | [diff] [blame] | 55 | } |
| 56 | #endif /* !HAVE_SETLOGIN */ |
| 57 | |
| 58 | #ifndef HAVE_INNETGR |
| 59 | int innetgr(const char *netgroup, const char *host, |
| 60 | const char *user, const char *domain) |
| 61 | { |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 62 | return (0); |
Damien Miller | e72b7af | 1999-12-30 15:08:44 +1100 | [diff] [blame] | 63 | } |
| 64 | #endif /* HAVE_INNETGR */ |
| 65 | |
| 66 | #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) |
| 67 | int seteuid(uid_t euid) |
| 68 | { |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 69 | return (setreuid(-1, euid)); |
Damien Miller | e72b7af | 1999-12-30 15:08:44 +1100 | [diff] [blame] | 70 | } |
| 71 | #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ |
Damien Miller | ecbb26d | 2000-07-15 14:59:14 +1000 | [diff] [blame] | 72 | |
Kevin Steves | cb17e99 | 2001-04-09 14:50:52 +0000 | [diff] [blame] | 73 | #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) |
| 74 | int setegid(uid_t egid) |
| 75 | { |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 76 | return(setresgid(-1, egid, -1)); |
Kevin Steves | cb17e99 | 2001-04-09 14:50:52 +0000 | [diff] [blame] | 77 | } |
| 78 | #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ |
| 79 | |
Damien Miller | 11fa2cc | 2000-08-16 10:35:58 +1000 | [diff] [blame] | 80 | #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) |
| 81 | const char *strerror(int e) |
Damien Miller | ecbb26d | 2000-07-15 14:59:14 +1000 | [diff] [blame] | 82 | { |
Damien Miller | 11fa2cc | 2000-08-16 10:35:58 +1000 | [diff] [blame] | 83 | extern int sys_nerr; |
| 84 | extern char *sys_errlist[]; |
| 85 | |
Ben Lindstrom | 46e55aa | 2001-03-13 23:38:20 +0000 | [diff] [blame] | 86 | if ((e >= 0) && (e < sys_nerr)) |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 87 | return (sys_errlist[e]); |
| 88 | |
| 89 | return ("unlisted error"); |
Damien Miller | ecbb26d | 2000-07-15 14:59:14 +1000 | [diff] [blame] | 90 | } |
Damien Miller | 11fa2cc | 2000-08-16 10:35:58 +1000 | [diff] [blame] | 91 | #endif |
Ben Lindstrom | 42202bc | 2001-01-15 02:34:37 +0000 | [diff] [blame] | 92 | |
| 93 | #ifndef HAVE_UTIMES |
| 94 | int utimes(char *filename, struct timeval *tvp) |
| 95 | { |
| 96 | struct utimbuf ub; |
| 97 | |
Ben Lindstrom | 100d586 | 2002-07-08 21:09:41 +0000 | [diff] [blame] | 98 | ub.actime = tvp[0].tv_sec; |
| 99 | ub.modtime = tvp[1].tv_sec; |
Ben Lindstrom | 42202bc | 2001-01-15 02:34:37 +0000 | [diff] [blame] | 100 | |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 101 | return (utime(filename, &ub)); |
Ben Lindstrom | 42202bc | 2001-01-15 02:34:37 +0000 | [diff] [blame] | 102 | } |
| 103 | #endif |
Tim Rice | 4bd2a19 | 2002-05-07 19:51:31 -0700 | [diff] [blame] | 104 | |
| 105 | #ifndef HAVE_TRUNCATE |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 106 | int truncate(const char *path, off_t length) |
Tim Rice | 4bd2a19 | 2002-05-07 19:51:31 -0700 | [diff] [blame] | 107 | { |
| 108 | int fd, ret, saverrno; |
| 109 | |
| 110 | fd = open(path, O_WRONLY); |
| 111 | if (fd < 0) |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 112 | return (-1); |
Tim Rice | 4bd2a19 | 2002-05-07 19:51:31 -0700 | [diff] [blame] | 113 | |
| 114 | ret = ftruncate(fd, length); |
| 115 | saverrno = errno; |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 116 | close(fd); |
Tim Rice | 4bd2a19 | 2002-05-07 19:51:31 -0700 | [diff] [blame] | 117 | if (ret == -1) |
| 118 | errno = saverrno; |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 119 | |
Tim Rice | 4bd2a19 | 2002-05-07 19:51:31 -0700 | [diff] [blame] | 120 | return(ret); |
| 121 | } |
| 122 | #endif /* HAVE_TRUNCATE */ |
| 123 | |
Ben Lindstrom | 837461b | 2002-06-12 16:57:14 +0000 | [diff] [blame] | 124 | #if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) |
| 125 | /* |
| 126 | * Cygwin setgroups should be a noop. |
| 127 | */ |
| 128 | int |
Ben Lindstrom | 0e23ebc | 2002-06-13 21:34:57 +0000 | [diff] [blame] | 129 | setgroups(size_t size, const gid_t *list) |
Ben Lindstrom | 837461b | 2002-06-12 16:57:14 +0000 | [diff] [blame] | 130 | { |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 131 | return (0); |
Ben Lindstrom | 837461b | 2002-06-12 16:57:14 +0000 | [diff] [blame] | 132 | } |
| 133 | #endif |
| 134 | |
Tim Rice | 4e4dc56 | 2003-03-18 10:21:40 -0800 | [diff] [blame] | 135 | #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) |
| 136 | int nanosleep(const struct timespec *req, struct timespec *rem) |
| 137 | { |
| 138 | int rc, saverrno; |
| 139 | extern int errno; |
| 140 | struct timeval tstart, tstop, tremain, time2wait; |
| 141 | |
| 142 | TIMESPEC_TO_TIMEVAL(&time2wait, req) |
| 143 | (void) gettimeofday(&tstart, NULL); |
| 144 | rc = select(0, NULL, NULL, NULL, &time2wait); |
| 145 | if (rc == -1) { |
| 146 | saverrno = errno; |
| 147 | (void) gettimeofday (&tstop, NULL); |
| 148 | errno = saverrno; |
| 149 | tremain.tv_sec = time2wait.tv_sec - |
| 150 | (tstop.tv_sec - tstart.tv_sec); |
| 151 | tremain.tv_usec = time2wait.tv_usec - |
| 152 | (tstop.tv_usec - tstart.tv_usec); |
| 153 | tremain.tv_sec += tremain.tv_usec / 1000000L; |
| 154 | tremain.tv_usec %= 1000000L; |
| 155 | } else { |
| 156 | tremain.tv_sec = 0; |
| 157 | tremain.tv_usec = 0; |
| 158 | } |
| 159 | TIMEVAL_TO_TIMESPEC(&tremain, rem) |
| 160 | |
| 161 | return(rc); |
| 162 | } |
Tim Rice | 4e4dc56 | 2003-03-18 10:21:40 -0800 | [diff] [blame] | 163 | #endif |
| 164 | |
Darren Tucker | 2e9c9cf | 2003-08-02 23:31:42 +1000 | [diff] [blame] | 165 | #ifndef HAVE_TCGETPGRP |
| 166 | pid_t |
| 167 | tcgetpgrp(int fd) |
| 168 | { |
Darren Tucker | 048737c | 2003-08-02 23:33:48 +1000 | [diff] [blame] | 169 | int ctty_pgrp; |
Darren Tucker | 2e9c9cf | 2003-08-02 23:31:42 +1000 | [diff] [blame] | 170 | |
Darren Tucker | bdf571b | 2003-08-03 00:36:16 +1000 | [diff] [blame] | 171 | if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) |
Darren Tucker | 2e9c9cf | 2003-08-02 23:31:42 +1000 | [diff] [blame] | 172 | return(-1); |
| 173 | else |
| 174 | return(ctty_pgrp); |
| 175 | } |
| 176 | #endif /* HAVE_TCGETPGRP */ |
| 177 | |
Darren Tucker | f38ea77 | 2003-08-13 20:48:07 +1000 | [diff] [blame] | 178 | #ifndef HAVE_TCSENDBREAK |
| 179 | int |
| 180 | tcsendbreak(int fd, int duration) |
| 181 | { |
| 182 | # if defined(TIOCSBRK) && defined(TIOCCBRK) |
| 183 | struct timeval sleepytime; |
| 184 | |
| 185 | sleepytime.tv_sec = 0; |
| 186 | sleepytime.tv_usec = 400000; |
| 187 | if (ioctl(fd, TIOCSBRK, 0) == -1) |
| 188 | return (-1); |
| 189 | (void)select(0, 0, 0, 0, &sleepytime); |
| 190 | if (ioctl(fd, TIOCCBRK, 0) == -1) |
| 191 | return (-1); |
| 192 | return (0); |
| 193 | # else |
| 194 | return -1; |
| 195 | # endif |
| 196 | } |
| 197 | #endif /* HAVE_TCSENDBREAK */ |
Ben Lindstrom | 5ade9ab | 2003-08-25 01:16:21 +0000 | [diff] [blame] | 198 | |
Darren Tucker | 60bd409 | 2004-06-25 14:03:34 +1000 | [diff] [blame] | 199 | #ifndef HAVE_CLOSEFROM |
| 200 | int |
| 201 | closefrom(int fd) |
| 202 | { |
| 203 | int i, result = 0, err = 0; |
| 204 | |
| 205 | for (i = fd; i < 128; i++) |
| 206 | if (close(i) != 0) { |
| 207 | err = errno; |
| 208 | result = -1; |
| 209 | } |
| 210 | errno = err; |
| 211 | return result; |
| 212 | } |
| 213 | #endif /* HAVE_CLOSEFROM */ |
| 214 | |
Ben Lindstrom | 5ade9ab | 2003-08-25 01:16:21 +0000 | [diff] [blame] | 215 | mysig_t |
| 216 | mysignal(int sig, mysig_t act) |
| 217 | { |
| 218 | #ifdef HAVE_SIGACTION |
| 219 | struct sigaction sa, osa; |
| 220 | |
| 221 | if (sigaction(sig, NULL, &osa) == -1) |
| 222 | return (mysig_t) -1; |
| 223 | if (osa.sa_handler != act) { |
| 224 | memset(&sa, 0, sizeof(sa)); |
| 225 | sigemptyset(&sa.sa_mask); |
| 226 | sa.sa_flags = 0; |
| 227 | #ifdef SA_INTERRUPT |
| 228 | if (sig == SIGALRM) |
| 229 | sa.sa_flags |= SA_INTERRUPT; |
| 230 | #endif |
| 231 | sa.sa_handler = act; |
| 232 | if (sigaction(sig, &sa, NULL) == -1) |
| 233 | return (mysig_t) -1; |
| 234 | } |
| 235 | return (osa.sa_handler); |
| 236 | #else |
Ben Lindstrom | 563eb99 | 2003-12-18 00:34:06 +0000 | [diff] [blame] | 237 | #undef signal |
Ben Lindstrom | 5ade9ab | 2003-08-25 01:16:21 +0000 | [diff] [blame] | 238 | return (signal(sig, act)); |
| 239 | #endif |
| 240 | } |