diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 59 |
1 files changed, 39 insertions, 20 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.86 2011/09/05 05:59:08 djm Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.91 2013/07/12 00:43:50 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -127,7 +127,7 @@ unset_nonblock(int fd) | |||
127 | const char * | 127 | const char * |
128 | ssh_gai_strerror(int gaierr) | 128 | ssh_gai_strerror(int gaierr) |
129 | { | 129 | { |
130 | if (gaierr == EAI_SYSTEM) | 130 | if (gaierr == EAI_SYSTEM && errno != 0) |
131 | return strerror(errno); | 131 | return strerror(errno); |
132 | return gai_strerror(gaierr); | 132 | return gai_strerror(gaierr); |
133 | } | 133 | } |
@@ -206,16 +206,18 @@ pwcopy(struct passwd *pw) | |||
206 | 206 | ||
207 | copy->pw_name = xstrdup(pw->pw_name); | 207 | copy->pw_name = xstrdup(pw->pw_name); |
208 | copy->pw_passwd = xstrdup(pw->pw_passwd); | 208 | copy->pw_passwd = xstrdup(pw->pw_passwd); |
209 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS | ||
209 | copy->pw_gecos = xstrdup(pw->pw_gecos); | 210 | copy->pw_gecos = xstrdup(pw->pw_gecos); |
211 | #endif | ||
210 | copy->pw_uid = pw->pw_uid; | 212 | copy->pw_uid = pw->pw_uid; |
211 | copy->pw_gid = pw->pw_gid; | 213 | copy->pw_gid = pw->pw_gid; |
212 | #ifdef HAVE_PW_EXPIRE_IN_PASSWD | 214 | #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE |
213 | copy->pw_expire = pw->pw_expire; | 215 | copy->pw_expire = pw->pw_expire; |
214 | #endif | 216 | #endif |
215 | #ifdef HAVE_PW_CHANGE_IN_PASSWD | 217 | #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE |
216 | copy->pw_change = pw->pw_change; | 218 | copy->pw_change = pw->pw_change; |
217 | #endif | 219 | #endif |
218 | #ifdef HAVE_PW_CLASS_IN_PASSWD | 220 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS |
219 | copy->pw_class = xstrdup(pw->pw_class); | 221 | copy->pw_class = xstrdup(pw->pw_class); |
220 | #endif | 222 | #endif |
221 | copy->pw_dir = xstrdup(pw->pw_dir); | 223 | copy->pw_dir = xstrdup(pw->pw_dir); |
@@ -251,13 +253,13 @@ a2tun(const char *s, int *remote) | |||
251 | *remote = SSH_TUNID_ANY; | 253 | *remote = SSH_TUNID_ANY; |
252 | sp = xstrdup(s); | 254 | sp = xstrdup(s); |
253 | if ((ep = strchr(sp, ':')) == NULL) { | 255 | if ((ep = strchr(sp, ':')) == NULL) { |
254 | xfree(sp); | 256 | free(sp); |
255 | return (a2tun(s, NULL)); | 257 | return (a2tun(s, NULL)); |
256 | } | 258 | } |
257 | ep[0] = '\0'; ep++; | 259 | ep[0] = '\0'; ep++; |
258 | *remote = a2tun(ep, NULL); | 260 | *remote = a2tun(ep, NULL); |
259 | tun = a2tun(sp, NULL); | 261 | tun = a2tun(sp, NULL); |
260 | xfree(sp); | 262 | free(sp); |
261 | return (*remote == SSH_TUNID_ERR ? *remote : tun); | 263 | return (*remote == SSH_TUNID_ERR ? *remote : tun); |
262 | } | 264 | } |
263 | 265 | ||
@@ -490,7 +492,7 @@ replacearg(arglist *args, u_int which, char *fmt, ...) | |||
490 | if (which >= args->num) | 492 | if (which >= args->num) |
491 | fatal("replacearg: tried to replace invalid arg %d >= %d", | 493 | fatal("replacearg: tried to replace invalid arg %d >= %d", |
492 | which, args->num); | 494 | which, args->num); |
493 | xfree(args->list[which]); | 495 | free(args->list[which]); |
494 | args->list[which] = cp; | 496 | args->list[which] = cp; |
495 | } | 497 | } |
496 | 498 | ||
@@ -501,8 +503,8 @@ freeargs(arglist *args) | |||
501 | 503 | ||
502 | if (args->list != NULL) { | 504 | if (args->list != NULL) { |
503 | for (i = 0; i < args->num; i++) | 505 | for (i = 0; i < args->num; i++) |
504 | xfree(args->list[i]); | 506 | free(args->list[i]); |
505 | xfree(args->list); | 507 | free(args->list); |
506 | args->nalloc = args->num = 0; | 508 | args->nalloc = args->num = 0; |
507 | args->list = NULL; | 509 | args->list = NULL; |
508 | } | 510 | } |
@@ -515,8 +517,8 @@ freeargs(arglist *args) | |||
515 | char * | 517 | char * |
516 | tilde_expand_filename(const char *filename, uid_t uid) | 518 | tilde_expand_filename(const char *filename, uid_t uid) |
517 | { | 519 | { |
518 | const char *path; | 520 | const char *path, *sep; |
519 | char user[128], ret[MAXPATHLEN]; | 521 | char user[128], *ret; |
520 | struct passwd *pw; | 522 | struct passwd *pw; |
521 | u_int len, slash; | 523 | u_int len, slash; |
522 | 524 | ||
@@ -536,22 +538,21 @@ tilde_expand_filename(const char *filename, uid_t uid) | |||
536 | } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ | 538 | } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ |
537 | fatal("tilde_expand_filename: No such uid %ld", (long)uid); | 539 | fatal("tilde_expand_filename: No such uid %ld", (long)uid); |
538 | 540 | ||
539 | if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret)) | ||
540 | fatal("tilde_expand_filename: Path too long"); | ||
541 | |||
542 | /* Make sure directory has a trailing '/' */ | 541 | /* Make sure directory has a trailing '/' */ |
543 | len = strlen(pw->pw_dir); | 542 | len = strlen(pw->pw_dir); |
544 | if ((len == 0 || pw->pw_dir[len - 1] != '/') && | 543 | if (len == 0 || pw->pw_dir[len - 1] != '/') |
545 | strlcat(ret, "/", sizeof(ret)) >= sizeof(ret)) | 544 | sep = "/"; |
546 | fatal("tilde_expand_filename: Path too long"); | 545 | else |
546 | sep = ""; | ||
547 | 547 | ||
548 | /* Skip leading '/' from specified path */ | 548 | /* Skip leading '/' from specified path */ |
549 | if (path != NULL) | 549 | if (path != NULL) |
550 | filename = path + 1; | 550 | filename = path + 1; |
551 | if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret)) | 551 | |
552 | if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= MAXPATHLEN) | ||
552 | fatal("tilde_expand_filename: Path too long"); | 553 | fatal("tilde_expand_filename: Path too long"); |
553 | 554 | ||
554 | return (xstrdup(ret)); | 555 | return (ret); |
555 | } | 556 | } |
556 | 557 | ||
557 | /* | 558 | /* |
@@ -853,6 +854,24 @@ ms_to_timeval(struct timeval *tv, int ms) | |||
853 | tv->tv_usec = (ms % 1000) * 1000; | 854 | tv->tv_usec = (ms % 1000) * 1000; |
854 | } | 855 | } |
855 | 856 | ||
857 | time_t | ||
858 | monotime(void) | ||
859 | { | ||
860 | #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) | ||
861 | struct timespec ts; | ||
862 | static int gettime_failed = 0; | ||
863 | |||
864 | if (!gettime_failed) { | ||
865 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) | ||
866 | return (ts.tv_sec); | ||
867 | debug3("clock_gettime: %s", strerror(errno)); | ||
868 | gettime_failed = 1; | ||
869 | } | ||
870 | #endif | ||
871 | |||
872 | return time(NULL); | ||
873 | } | ||
874 | |||
856 | void | 875 | void |
857 | bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) | 876 | bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) |
858 | { | 877 | { |