summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2016-08-06 10:49:58 +0100
committerColin Watson <cjwatson@debian.org>2016-08-06 10:49:58 +0100
commita8ed8d256b2e2c05b0c15565a7938028c5192277 (patch)
tree87abbdc914a38b43e4e5bb9581ad1f46eabbf88e /misc.c
parentf0329aac23c61e1a5197d6d57349a63f459bccb0 (diff)
parent99522ba7ec6963a05c04a156bf20e3ba3605987c (diff)
Import openssh_7.3p1.orig.tar.gz
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c150
1 files changed, 137 insertions, 13 deletions
diff --git a/misc.c b/misc.c
index de7e1facd..9421b4d39 100644
--- a/misc.c
+++ b/misc.c
@@ -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 */
462int
463parse_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 */
455void 516void
456addargs(arglist *args, char *fmt, ...) 517addargs(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
973double
974monotime_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
912void 998void
913bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 999bandwidth_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 */
1213static int
1214strcmp_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 */
1227int
1228forward_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