summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
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 5704fa6c4..68efb2b38 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.
@@ -86,9 +86,9 @@ set_nonblock(int fd)
86{ 86{
87 int val; 87 int val;
88 88
89 val = fcntl(fd, F_GETFL, 0); 89 val = fcntl(fd, F_GETFL);
90 if (val < 0) { 90 if (val < 0) {
91 error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); 91 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
92 return (-1); 92 return (-1);
93 } 93 }
94 if (val & O_NONBLOCK) { 94 if (val & O_NONBLOCK) {
@@ -110,9 +110,9 @@ unset_nonblock(int fd)
110{ 110{
111 int val; 111 int val;
112 112
113 val = fcntl(fd, F_GETFL, 0); 113 val = fcntl(fd, F_GETFL);
114 if (val < 0) { 114 if (val < 0) {
115 error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); 115 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
116 return (-1); 116 return (-1);
117 } 117 }
118 if (!(val & O_NONBLOCK)) { 118 if (!(val & O_NONBLOCK)) {
@@ -453,6 +453,67 @@ colon(char *cp)
453 return NULL; 453 return NULL;
454} 454}
455 455
456/*
457 * Parse a [user@]host[:port] string.
458 * Caller must free returned user and host.
459 * Any of the pointer return arguments may be NULL (useful for syntax checking).
460 * If user was not specified then *userp will be set to NULL.
461 * If port was not specified then *portp will be -1.
462 * Returns 0 on success, -1 on failure.
463 */
464int
465parse_user_host_port(const char *s, char **userp, char **hostp, int *portp)
466{
467 char *sdup, *cp, *tmp;
468 char *user = NULL, *host = NULL;
469 int port = -1, ret = -1;
470
471 if (userp != NULL)
472 *userp = NULL;
473 if (hostp != NULL)
474 *hostp = NULL;
475 if (portp != NULL)
476 *portp = -1;
477
478 if ((sdup = tmp = strdup(s)) == NULL)
479 return -1;
480 /* Extract optional username */
481 if ((cp = strchr(tmp, '@')) != NULL) {
482 *cp = '\0';
483 if (*tmp == '\0')
484 goto out;
485 if ((user = strdup(tmp)) == NULL)
486 goto out;
487 tmp = cp + 1;
488 }
489 /* Extract mandatory hostname */
490 if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0')
491 goto out;
492 host = xstrdup(cleanhostname(cp));
493 /* Convert and verify optional port */
494 if (tmp != NULL && *tmp != '\0') {
495 if ((port = a2port(tmp)) <= 0)
496 goto out;
497 }
498 /* Success */
499 if (userp != NULL) {
500 *userp = user;
501 user = NULL;
502 }
503 if (hostp != NULL) {
504 *hostp = host;
505 host = NULL;
506 }
507 if (portp != NULL)
508 *portp = port;
509 ret = 0;
510 out:
511 free(sdup);
512 free(user);
513 free(host);
514 return ret;
515}
516
456/* function to assist building execv() arguments */ 517/* function to assist building execv() arguments */
457void 518void
458addargs(arglist *args, char *fmt, ...) 519addargs(arglist *args, char *fmt, ...)
@@ -796,16 +857,16 @@ sanitise_stdfd(void)
796 strerror(errno)); 857 strerror(errno));
797 exit(1); 858 exit(1);
798 } 859 }
799 while (++dupfd <= 2) { 860 while (++dupfd <= STDERR_FILENO) {
800 /* Only clobber closed fds */ 861 /* Only populate closed fds. */
801 if (fcntl(dupfd, F_GETFL, 0) >= 0) 862 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {
802 continue; 863 if (dup2(nullfd, dupfd) == -1) {
803 if (dup2(nullfd, dupfd) == -1) { 864 fprintf(stderr, "dup2: %s\n", strerror(errno));
804 fprintf(stderr, "dup2: %s\n", strerror(errno)); 865 exit(1);
805 exit(1); 866 }
806 } 867 }
807 } 868 }
808 if (nullfd > 2) 869 if (nullfd > STDERR_FILENO)
809 close(nullfd); 870 close(nullfd);
810} 871}
811 872
@@ -976,6 +1037,31 @@ monotime(void)
976 return time(NULL); 1037 return time(NULL);
977} 1038}
978 1039
1040double
1041monotime_double(void)
1042{
1043#if defined(HAVE_CLOCK_GETTIME) && \
1044 (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME))
1045 struct timespec ts;
1046 static int gettime_failed = 0;
1047
1048 if (!gettime_failed) {
1049#if defined(CLOCK_BOOTTIME)
1050 if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0)
1051 return (ts.tv_sec + (double)ts.tv_nsec / 1000000000);
1052#endif
1053#if defined(CLOCK_MONOTONIC)
1054 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
1055 return (ts.tv_sec + (double)ts.tv_nsec / 1000000000);
1056#endif
1057 debug3("clock_gettime: %s", strerror(errno));
1058 gettime_failed = 1;
1059 }
1060#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */
1061
1062 return (double)time(NULL);
1063}
1064
979void 1065void
980bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 1066bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
981{ 1067{
@@ -1186,3 +1272,41 @@ sock_set_v6only(int s)
1186 error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); 1272 error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
1187#endif 1273#endif
1188} 1274}
1275
1276/*
1277 * Compares two strings that maybe be NULL. Returns non-zero if strings
1278 * are both NULL or are identical, returns zero otherwise.
1279 */
1280static int
1281strcmp_maybe_null(const char *a, const char *b)
1282{
1283 if ((a == NULL && b != NULL) || (a != NULL && b == NULL))
1284 return 0;
1285 if (a != NULL && strcmp(a, b) != 0)
1286 return 0;
1287 return 1;
1288}
1289
1290/*
1291 * Compare two forwards, returning non-zero if they are identical or
1292 * zero otherwise.
1293 */
1294int
1295forward_equals(const struct Forward *a, const struct Forward *b)
1296{
1297 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)
1298 return 0;
1299 if (a->listen_port != b->listen_port)
1300 return 0;
1301 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)
1302 return 0;
1303 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)
1304 return 0;
1305 if (a->connect_port != b->connect_port)
1306 return 0;
1307 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)
1308 return 0;
1309 /* allocated_port and handle are not checked */
1310 return 1;
1311}
1312