diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 85 |
1 files changed, 82 insertions, 3 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.92 2013/10/14 23:28:23 djm Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.94 2014/07/15 15:54:14 millert 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. |
@@ -29,6 +29,7 @@ | |||
29 | #include <sys/types.h> | 29 | #include <sys/types.h> |
30 | #include <sys/ioctl.h> | 30 | #include <sys/ioctl.h> |
31 | #include <sys/socket.h> | 31 | #include <sys/socket.h> |
32 | #include <sys/un.h> | ||
32 | #include <sys/param.h> | 33 | #include <sys/param.h> |
33 | 34 | ||
34 | #include <stdarg.h> | 35 | #include <stdarg.h> |
@@ -855,6 +856,20 @@ get_u32(const void *vp) | |||
855 | return (v); | 856 | return (v); |
856 | } | 857 | } |
857 | 858 | ||
859 | u_int32_t | ||
860 | get_u32_le(const void *vp) | ||
861 | { | ||
862 | const u_char *p = (const u_char *)vp; | ||
863 | u_int32_t v; | ||
864 | |||
865 | v = (u_int32_t)p[0]; | ||
866 | v |= (u_int32_t)p[1] << 8; | ||
867 | v |= (u_int32_t)p[2] << 16; | ||
868 | v |= (u_int32_t)p[3] << 24; | ||
869 | |||
870 | return (v); | ||
871 | } | ||
872 | |||
858 | u_int16_t | 873 | u_int16_t |
859 | get_u16(const void *vp) | 874 | get_u16(const void *vp) |
860 | { | 875 | { |
@@ -893,6 +908,16 @@ put_u32(void *vp, u_int32_t v) | |||
893 | p[3] = (u_char)v & 0xff; | 908 | p[3] = (u_char)v & 0xff; |
894 | } | 909 | } |
895 | 910 | ||
911 | void | ||
912 | put_u32_le(void *vp, u_int32_t v) | ||
913 | { | ||
914 | u_char *p = (u_char *)vp; | ||
915 | |||
916 | p[0] = (u_char)v & 0xff; | ||
917 | p[1] = (u_char)(v >> 8) & 0xff; | ||
918 | p[2] = (u_char)(v >> 16) & 0xff; | ||
919 | p[3] = (u_char)(v >> 24) & 0xff; | ||
920 | } | ||
896 | 921 | ||
897 | void | 922 | void |
898 | put_u16(void *vp, u_int16_t v) | 923 | put_u16(void *vp, u_int16_t v) |
@@ -925,17 +950,24 @@ ms_to_timeval(struct timeval *tv, int ms) | |||
925 | time_t | 950 | time_t |
926 | monotime(void) | 951 | monotime(void) |
927 | { | 952 | { |
928 | #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) | 953 | #if defined(HAVE_CLOCK_GETTIME) && \ |
954 | (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) | ||
929 | struct timespec ts; | 955 | struct timespec ts; |
930 | static int gettime_failed = 0; | 956 | static int gettime_failed = 0; |
931 | 957 | ||
932 | if (!gettime_failed) { | 958 | if (!gettime_failed) { |
959 | #if defined(CLOCK_BOOTTIME) | ||
960 | if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) | ||
961 | return (ts.tv_sec); | ||
962 | #endif | ||
963 | #if defined(CLOCK_MONOTONIC) | ||
933 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) | 964 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) |
934 | return (ts.tv_sec); | 965 | return (ts.tv_sec); |
966 | #endif | ||
935 | debug3("clock_gettime: %s", strerror(errno)); | 967 | debug3("clock_gettime: %s", strerror(errno)); |
936 | gettime_failed = 1; | 968 | gettime_failed = 1; |
937 | } | 969 | } |
938 | #endif | 970 | #endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ |
939 | 971 | ||
940 | return time(NULL); | 972 | return time(NULL); |
941 | } | 973 | } |
@@ -1092,6 +1124,53 @@ lowercase(char *s) | |||
1092 | for (; *s; s++) | 1124 | for (; *s; s++) |
1093 | *s = tolower((u_char)*s); | 1125 | *s = tolower((u_char)*s); |
1094 | } | 1126 | } |
1127 | |||
1128 | int | ||
1129 | unix_listener(const char *path, int backlog, int unlink_first) | ||
1130 | { | ||
1131 | struct sockaddr_un sunaddr; | ||
1132 | int saved_errno, sock; | ||
1133 | |||
1134 | memset(&sunaddr, 0, sizeof(sunaddr)); | ||
1135 | sunaddr.sun_family = AF_UNIX; | ||
1136 | if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { | ||
1137 | error("%s: \"%s\" too long for Unix domain socket", __func__, | ||
1138 | path); | ||
1139 | errno = ENAMETOOLONG; | ||
1140 | return -1; | ||
1141 | } | ||
1142 | |||
1143 | sock = socket(PF_UNIX, SOCK_STREAM, 0); | ||
1144 | if (sock < 0) { | ||
1145 | saved_errno = errno; | ||
1146 | error("socket: %.100s", strerror(errno)); | ||
1147 | errno = saved_errno; | ||
1148 | return -1; | ||
1149 | } | ||
1150 | if (unlink_first == 1) { | ||
1151 | if (unlink(path) != 0 && errno != ENOENT) | ||
1152 | error("unlink(%s): %.100s", path, strerror(errno)); | ||
1153 | } | ||
1154 | if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { | ||
1155 | saved_errno = errno; | ||
1156 | error("bind: %.100s", strerror(errno)); | ||
1157 | close(sock); | ||
1158 | error("%s: cannot bind to path: %s", __func__, path); | ||
1159 | errno = saved_errno; | ||
1160 | return -1; | ||
1161 | } | ||
1162 | if (listen(sock, backlog) < 0) { | ||
1163 | saved_errno = errno; | ||
1164 | error("listen: %.100s", strerror(errno)); | ||
1165 | close(sock); | ||
1166 | unlink(path); | ||
1167 | error("%s: cannot listen on path: %s", __func__, path); | ||
1168 | errno = saved_errno; | ||
1169 | return -1; | ||
1170 | } | ||
1171 | return sock; | ||
1172 | } | ||
1173 | |||
1095 | void | 1174 | void |
1096 | sock_set_v6only(int s) | 1175 | sock_set_v6only(int s) |
1097 | { | 1176 | { |