diff options
author | Colin Watson <cjwatson@debian.org> | 2016-08-06 10:49:58 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2016-08-06 10:49:58 +0100 |
commit | a8ed8d256b2e2c05b0c15565a7938028c5192277 (patch) | |
tree | 87abbdc914a38b43e4e5bb9581ad1f46eabbf88e /misc.c | |
parent | f0329aac23c61e1a5197d6d57349a63f459bccb0 (diff) | |
parent | 99522ba7ec6963a05c04a156bf20e3ba3605987c (diff) |
Import openssh_7.3p1.orig.tar.gz
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 150 |
1 files changed, 137 insertions, 13 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.101 2016/01/20 09:22:39 dtucker Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.105 2016/07/15 00:24:30 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. |
@@ -84,9 +84,9 @@ set_nonblock(int fd) | |||
84 | { | 84 | { |
85 | int val; | 85 | int val; |
86 | 86 | ||
87 | val = fcntl(fd, F_GETFL, 0); | 87 | val = fcntl(fd, F_GETFL); |
88 | if (val < 0) { | 88 | if (val < 0) { |
89 | error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); | 89 | error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); |
90 | return (-1); | 90 | return (-1); |
91 | } | 91 | } |
92 | if (val & O_NONBLOCK) { | 92 | if (val & O_NONBLOCK) { |
@@ -108,9 +108,9 @@ unset_nonblock(int fd) | |||
108 | { | 108 | { |
109 | int val; | 109 | int val; |
110 | 110 | ||
111 | val = fcntl(fd, F_GETFL, 0); | 111 | val = fcntl(fd, F_GETFL); |
112 | if (val < 0) { | 112 | if (val < 0) { |
113 | error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); | 113 | error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); |
114 | return (-1); | 114 | return (-1); |
115 | } | 115 | } |
116 | if (!(val & O_NONBLOCK)) { | 116 | if (!(val & O_NONBLOCK)) { |
@@ -451,6 +451,67 @@ colon(char *cp) | |||
451 | return NULL; | 451 | return NULL; |
452 | } | 452 | } |
453 | 453 | ||
454 | /* | ||
455 | * Parse a [user@]host[:port] string. | ||
456 | * Caller must free returned user and host. | ||
457 | * Any of the pointer return arguments may be NULL (useful for syntax checking). | ||
458 | * If user was not specified then *userp will be set to NULL. | ||
459 | * If port was not specified then *portp will be -1. | ||
460 | * Returns 0 on success, -1 on failure. | ||
461 | */ | ||
462 | int | ||
463 | parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) | ||
464 | { | ||
465 | char *sdup, *cp, *tmp; | ||
466 | char *user = NULL, *host = NULL; | ||
467 | int port = -1, ret = -1; | ||
468 | |||
469 | if (userp != NULL) | ||
470 | *userp = NULL; | ||
471 | if (hostp != NULL) | ||
472 | *hostp = NULL; | ||
473 | if (portp != NULL) | ||
474 | *portp = -1; | ||
475 | |||
476 | if ((sdup = tmp = strdup(s)) == NULL) | ||
477 | return -1; | ||
478 | /* Extract optional username */ | ||
479 | if ((cp = strchr(tmp, '@')) != NULL) { | ||
480 | *cp = '\0'; | ||
481 | if (*tmp == '\0') | ||
482 | goto out; | ||
483 | if ((user = strdup(tmp)) == NULL) | ||
484 | goto out; | ||
485 | tmp = cp + 1; | ||
486 | } | ||
487 | /* Extract mandatory hostname */ | ||
488 | if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0') | ||
489 | goto out; | ||
490 | host = xstrdup(cleanhostname(cp)); | ||
491 | /* Convert and verify optional port */ | ||
492 | if (tmp != NULL && *tmp != '\0') { | ||
493 | if ((port = a2port(tmp)) <= 0) | ||
494 | goto out; | ||
495 | } | ||
496 | /* Success */ | ||
497 | if (userp != NULL) { | ||
498 | *userp = user; | ||
499 | user = NULL; | ||
500 | } | ||
501 | if (hostp != NULL) { | ||
502 | *hostp = host; | ||
503 | host = NULL; | ||
504 | } | ||
505 | if (portp != NULL) | ||
506 | *portp = port; | ||
507 | ret = 0; | ||
508 | out: | ||
509 | free(sdup); | ||
510 | free(user); | ||
511 | free(host); | ||
512 | return ret; | ||
513 | } | ||
514 | |||
454 | /* function to assist building execv() arguments */ | 515 | /* function to assist building execv() arguments */ |
455 | void | 516 | void |
456 | addargs(arglist *args, char *fmt, ...) | 517 | addargs(arglist *args, char *fmt, ...) |
@@ -729,16 +790,16 @@ sanitise_stdfd(void) | |||
729 | strerror(errno)); | 790 | strerror(errno)); |
730 | exit(1); | 791 | exit(1); |
731 | } | 792 | } |
732 | while (++dupfd <= 2) { | 793 | while (++dupfd <= STDERR_FILENO) { |
733 | /* Only clobber closed fds */ | 794 | /* Only populate closed fds. */ |
734 | if (fcntl(dupfd, F_GETFL, 0) >= 0) | 795 | if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { |
735 | continue; | 796 | if (dup2(nullfd, dupfd) == -1) { |
736 | if (dup2(nullfd, dupfd) == -1) { | 797 | fprintf(stderr, "dup2: %s\n", strerror(errno)); |
737 | fprintf(stderr, "dup2: %s\n", strerror(errno)); | 798 | exit(1); |
738 | exit(1); | 799 | } |
739 | } | 800 | } |
740 | } | 801 | } |
741 | if (nullfd > 2) | 802 | if (nullfd > STDERR_FILENO) |
742 | close(nullfd); | 803 | close(nullfd); |
743 | } | 804 | } |
744 | 805 | ||
@@ -909,6 +970,31 @@ monotime(void) | |||
909 | return time(NULL); | 970 | return time(NULL); |
910 | } | 971 | } |
911 | 972 | ||
973 | double | ||
974 | monotime_double(void) | ||
975 | { | ||
976 | #if defined(HAVE_CLOCK_GETTIME) && \ | ||
977 | (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) | ||
978 | struct timespec ts; | ||
979 | static int gettime_failed = 0; | ||
980 | |||
981 | if (!gettime_failed) { | ||
982 | #if defined(CLOCK_BOOTTIME) | ||
983 | if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) | ||
984 | return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); | ||
985 | #endif | ||
986 | #if defined(CLOCK_MONOTONIC) | ||
987 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) | ||
988 | return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); | ||
989 | #endif | ||
990 | debug3("clock_gettime: %s", strerror(errno)); | ||
991 | gettime_failed = 1; | ||
992 | } | ||
993 | #endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ | ||
994 | |||
995 | return (double)time(NULL); | ||
996 | } | ||
997 | |||
912 | void | 998 | void |
913 | bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) | 999 | bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) |
914 | { | 1000 | { |
@@ -1119,3 +1205,41 @@ sock_set_v6only(int s) | |||
1119 | error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); | 1205 | error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); |
1120 | #endif | 1206 | #endif |
1121 | } | 1207 | } |
1208 | |||
1209 | /* | ||
1210 | * Compares two strings that maybe be NULL. Returns non-zero if strings | ||
1211 | * are both NULL or are identical, returns zero otherwise. | ||
1212 | */ | ||
1213 | static int | ||
1214 | strcmp_maybe_null(const char *a, const char *b) | ||
1215 | { | ||
1216 | if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) | ||
1217 | return 0; | ||
1218 | if (a != NULL && strcmp(a, b) != 0) | ||
1219 | return 0; | ||
1220 | return 1; | ||
1221 | } | ||
1222 | |||
1223 | /* | ||
1224 | * Compare two forwards, returning non-zero if they are identical or | ||
1225 | * zero otherwise. | ||
1226 | */ | ||
1227 | int | ||
1228 | forward_equals(const struct Forward *a, const struct Forward *b) | ||
1229 | { | ||
1230 | if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) | ||
1231 | return 0; | ||
1232 | if (a->listen_port != b->listen_port) | ||
1233 | return 0; | ||
1234 | if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) | ||
1235 | return 0; | ||
1236 | if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) | ||
1237 | return 0; | ||
1238 | if (a->connect_port != b->connect_port) | ||
1239 | return 0; | ||
1240 | if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) | ||
1241 | return 0; | ||
1242 | /* allocated_port and handle are not checked */ | ||
1243 | return 1; | ||
1244 | } | ||
1245 | |||