-/* $OpenBSD: misc.c,v 1.56 2006/07/10 12:46:51 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.75 2010/01/09 23:04:13 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
#include "includes.h"
-#include <sys/ioctl.h>
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <sys/param.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#include <errno.h>
#include <fcntl.h>
+#include <netdb.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#include <pwd.h>
#include <net/if.h>
#endif
+#include "xmalloc.h"
#include "misc.h"
#include "log.h"
-#include "xmalloc.h"
#include "ssh.h"
/* remove newline at end of string */
return (0);
}
+const char *
+ssh_gai_strerror(int gaierr)
+{
+ if (gaierr == EAI_SYSTEM)
+ return strerror(errno);
+ return gai_strerror(gaierr);
+}
+
/* disable nagle on socket */
void
set_nodelay(int fd)
/*
* Convert ASCII string to TCP/IP port number.
- * Port must be >0 and <=65535.
- * Return 0 if invalid.
+ * Port must be >=0 and <=65535.
+ * Return -1 if invalid.
*/
int
a2port(const char *s)
{
- long port;
- char *endp;
+ long long port;
+ const char *errstr;
- errno = 0;
- port = strtol(s, &endp, 0);
- if (s == endp || *endp != '\0' ||
- (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) ||
- port <= 0 || port > 65535)
- return 0;
-
- return port;
+ port = strtonum(s, 0, 65535, &errstr);
+ if (errstr != NULL)
+ return -1;
+ return (int)port;
}
int
if ((pw = getpwnam(user)) == NULL)
fatal("tilde_expand_filename: No such user %s", user);
} else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
- fatal("tilde_expand_filename: No such uid %d", uid);
+ fatal("tilde_expand_filename: No such uid %ld", (long)uid);
if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
fatal("tilde_expand_filename: Path too long");
percent_expand(const char *string, ...)
{
#define EXPAND_MAX_KEYS 16
+ u_int num_keys, i, j;
struct {
const char *key;
const char *repl;
} keys[EXPAND_MAX_KEYS];
- u_int num_keys, i, j;
char buf[4096];
va_list ap;
break;
keys[num_keys].repl = va_arg(ap, char *);
if (keys[num_keys].repl == NULL)
- fatal("percent_expand: NULL replacement");
+ fatal("%s: NULL replacement", __func__);
}
+ if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
+ fatal("%s: too many keys", __func__);
va_end(ap);
- if (num_keys >= EXPAND_MAX_KEYS)
- fatal("percent_expand: too many keys");
-
/* Expand string */
*buf = '\0';
for (i = 0; *string != '\0'; string++) {
append:
buf[i++] = *string;
if (i >= sizeof(buf))
- fatal("percent_expand: string too long");
+ fatal("%s: string too long", __func__);
buf[i] = '\0';
continue;
}
string++;
+ /* %% case */
if (*string == '%')
goto append;
for (j = 0; j < num_keys; j++) {
if (strchr(keys[j].key, *string) != NULL) {
i = strlcat(buf, keys[j].repl, sizeof(buf));
if (i >= sizeof(buf))
- fatal("percent_expand: string too long");
+ fatal("%s: string too long", __func__);
break;
}
}
if (j >= num_keys)
- fatal("percent_expand: unknown key %%%c", *string);
+ fatal("%s: unknown key %%%c", __func__, *string);
}
return (xstrdup(buf));
#undef EXPAND_MAX_KEYS
u_long *lineno)
{
while (fgets(buf, bufsz, f) != NULL) {
+ if (buf[0] == '\0')
+ continue;
(*lineno)++;
if (buf[strlen(buf) - 1] == '\n' || feof(f)) {
return 0;
int nullfd, dupfd;
if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
- fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
+ fprintf(stderr, "Couldn't open /dev/null: %s\n",
+ strerror(errno));
exit(1);
}
while (++dupfd <= 2) {
if (fcntl(dupfd, F_GETFL, 0) >= 0)
continue;
if (dup2(nullfd, dupfd) == -1) {
- fprintf(stderr, "dup2: %s", strerror(errno));
+ fprintf(stderr, "dup2: %s\n", strerror(errno));
exit(1);
}
}
p[0] = (u_char)(v >> 8) & 0xff;
p[1] = (u_char)v & 0xff;
}
+
+void
+ms_subtract_diff(struct timeval *start, int *ms)
+{
+ struct timeval diff, finish;
+
+ gettimeofday(&finish, NULL);
+ timersub(&finish, start, &diff);
+ *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
+}
+
+void
+ms_to_timeval(struct timeval *tv, int ms)
+{
+ if (ms < 0)
+ ms = 0;
+ tv->tv_sec = ms / 1000;
+ tv->tv_usec = (ms % 1000) * 1000;
+}
+
+void
+sock_set_v6only(int s)
+{
+#ifdef IPV6_V6ONLY
+ int on = 1;
+
+ debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)
+ error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
+#endif
+}