2
* Copyright (c) 2007-2009, Paul Mattes.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
7
* * Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* * Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
* * Neither the names of Paul Mattes nor the names of his contributors
13
* may be used to endorse or promote products derived from this software
14
* without specific prior written permission.
16
* THIS SOFTWARE IS PROVIDED BY PAUL MATTES "AS IS" AND ANY EXPRESS OR IMPLIED
17
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
* EVENT SHALL PAUL MATTES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
* Miscellaneous Win32 functions.
35
#if !defined(_WIN32) /*[*/
36
#error This module is only for Win32.
46
/* Initialize Winsock. */
50
static int initted = 0;
51
WORD wVersionRequested;
59
wVersionRequested = MAKEWORD(2, 2);
61
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
62
fprintf(stderr, "WSAStartup failed: %s\n",
63
win32_strerror(GetLastError()));
67
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
68
fprintf(stderr, "Bad winsock version: %d.%d\n",
69
LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
76
/* Convert a network address to a string. */
78
inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
82
struct sockaddr_in sin;
83
struct sockaddr_in6 sin6;
88
memset(&sa, '\0', sizeof(sa));
92
sa.sin = *(struct sockaddr_in *)src; /* struct copy */
93
ssz = sizeof(struct sockaddr_in);
96
sa.sin6 = *(struct sockaddr_in6 *)src; /* struct copy */
97
ssz = sizeof(struct sockaddr_in6);
105
sa.sa.sa_family = af;
107
if (WSAAddressToString(&sa.sa, ssz, NULL, dst, &sz) != 0) {
116
/* Decode a Win32 error number. */
118
win32_strerror(int e)
120
static char buffer[4096];
122
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
125
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
130
sprintf(buffer, "Windows error %d", e);
136
#if defined(_MSC_VER) /*[*/
138
/* MinGW has gettimofday(), but MSVC does not. */
141
#define SECS_BETWEEN_EPOCHS 11644473600ULL
142
#define SECS_TO_100NS 10000000ULL /* 10^7 */
145
gettimeofday(struct timeval *tv, void *ignored)
150
GetSystemTimeAsFileTime(&t);
151
memcpy(&u, &t, sizeof(ULARGE_INTEGER));
153
/* Isolate seconds and move epochs. */
154
tv->tv_sec = (DWORD)((u.QuadPart / SECS_TO_100NS) -
155
SECS_BETWEEN_EPOCHS);
156
tv->tv_usec = (u.QuadPart % SECS_TO_100NS) / 10ULL;
160
/* MinGW has getopt(), but MSVC does not. */
163
int optind = 1, opterr = 1, optopt;
164
static const char *nextchar = NULL;
167
getopt(int argc, char * const argv[], const char *optstring)
173
nextchar = argv[optind++];
176
if (nextchar == argv[optind - 1]) {
178
--optind; /* went too far */
181
if (nextchar == NULL) {
182
--optind; /* went too far */
185
if (!strcmp(nextchar, "--"))
187
if (*nextchar++ != '-') {
193
if ((c = *nextchar++) == '\0')
194
nextchar = argv[optind++];
195
} while (nextchar == argv[optind - 1]);
197
s = strchr(optstring, c);
200
fprintf(stderr, "Unknown option '%c'\n", c);
203
if (*(s + 1) == ':') {
205
optarg = (char *)nextchar;
206
nextchar = argv[optind++];
208
} else if (optind < argc && argv[optind] != NULL) {
209
optarg = (char *)argv[optind++];
210
nextchar = argv[optind++];
214
fprintf(stderr, "Missing value after '%c'\n",