1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
22 #include "server_setup.h"
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
30 #ifdef _XOPEN_SOURCE_EXTENDED
31 /* This define is "almost" required to build on HPUX 11 */
32 #include <arpa/inet.h>
39 #elif defined(HAVE_SYS_POLL_H)
46 #define ENABLE_CURLX_PRINTF
47 /* make the curlx header define all printf() functions to use the curlx_*
49 #include "curlx.h" /* from the private lib dir */
56 #define EINTR 4 /* errno.h value */
58 #define EINVAL 22 /* errno.h value */
61 /* MinGW with w32api version < 3.6 declared in6addr_any as extern,
62 but lacked the definition */
63 #if defined(ENABLE_IPV6) && defined(__MINGW32__)
64 #if (__W32API_MAJOR_VERSION < 3) || \
65 ((__W32API_MAJOR_VERSION == 3) && (__W32API_MINOR_VERSION < 6))
66 const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
67 #endif /* w32api < 3.6 */
68 #endif /* ENABLE_IPV6 && __MINGW32__*/
70 static struct timeval tvnow(void);
72 /* This function returns a pointer to STATIC memory. It converts the given
73 * binary lump to a hex formatted string usable for output in logs or
76 char *data_to_hex(char *data, size_t len)
78 static char buf[256*3];
86 for(i = 0; i < len; i++) {
87 if((data[i] >= 0x20) && (data[i] < 0x7f))
90 snprintf(optr, 4, "%%%02x", *iptr++);
94 *optr = 0; /* in case no sprintf was used */
99 void logmsg(const char *msg, ...)
102 char buffer[2048 + 1];
109 static time_t epoch_offset;
110 static int known_offset;
113 fprintf(stderr, "Error: serverlogfile not set\n");
119 epoch_offset = time(NULL) - tv.tv_sec;
122 sec = epoch_offset + tv.tv_sec;
123 now = localtime(&sec); /* not thread safe but we don't care */
125 snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
126 (int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec, (long)tv.tv_usec);
129 vsnprintf(buffer, sizeof(buffer), msg, ap);
132 logfp = fopen(serverlogfile, "ab");
134 fprintf(logfp, "%s %s\n", timebuf, buffer);
139 fprintf(stderr, "fopen() failed with error: %d %s\n",
140 error, strerror(error));
141 fprintf(stderr, "Error opening file: %s\n", serverlogfile);
142 fprintf(stderr, "Msg not logged: %s %s\n", timebuf, buffer);
147 /* use instead of perror() on generic windows */
148 void win32_perror(const char *msg)
151 DWORD err = SOCKERRNO;
153 if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
154 LANG_NEUTRAL, buf, sizeof(buf), NULL))
155 snprintf(buf, sizeof(buf), "Unknown error %lu (%#lx)", err, err);
157 fprintf(stderr, "%s: ", msg);
158 fprintf(stderr, "%s\n", buf);
163 void win32_init(void)
165 WORD wVersionRequested;
168 wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
170 err = WSAStartup(wVersionRequested, &wsaData);
173 perror("Winsock init failed");
174 logmsg("Error initialising winsock -- aborting");
178 if(LOBYTE(wsaData.wVersion) != USE_WINSOCK ||
179 HIBYTE(wsaData.wVersion) != USE_WINSOCK) {
181 perror("Winsock init failed");
182 logmsg("No suitable winsock.dll found -- aborting");
187 void win32_cleanup(void)
191 #endif /* USE_WINSOCK */
193 /* set by the main code to point to where the test dir is */
194 const char *path = ".";
196 char *test2file(long testno)
198 static char filename[256];
199 snprintf(filename, sizeof(filename), TEST_DATA_PATH, path, testno);
204 * Portable function used for waiting a specific amount of ms.
205 * Waiting indefinitely with this function is not allowed, a
206 * zero or negative timeout value will return immediately.
209 * -1 = system call error, or invalid timeout value
210 * 0 = specified timeout has elapsed
212 int wait_ms(int timeout_ms)
214 #if !defined(MSDOS) && !defined(USE_WINSOCK)
215 #ifndef HAVE_POLL_FINE
216 struct timeval pending_tv;
218 struct timeval initial_tv;
232 #elif defined(USE_WINSOCK)
235 pending_ms = timeout_ms;
236 initial_tv = tvnow();
238 #if defined(HAVE_POLL_FINE)
239 r = poll(NULL, 0, pending_ms);
241 pending_tv.tv_sec = pending_ms / 1000;
242 pending_tv.tv_usec = (pending_ms % 1000) * 1000;
243 r = select(0, NULL, NULL, NULL, &pending_tv);
244 #endif /* HAVE_POLL_FINE */
248 if(error && (error != EINTR))
250 pending_ms = timeout_ms - (int)timediff(tvnow(), initial_tv);
254 #endif /* USE_WINSOCK */
260 int write_pidfile(const char *filename)
265 pid = (long)getpid();
266 pidfile = fopen(filename, "wb");
268 logmsg("Couldn't write pid file: %s %s", filename, strerror(errno));
271 fprintf(pidfile, "%ld\n", pid);
273 logmsg("Wrote pid %ld to %s", pid, filename);
274 return 1; /* success */
277 void set_advisor_read_lock(const char *filename)
284 lockfile = fopen(filename, "wb");
285 } while((lockfile == NULL) && ((error = errno) == EINTR));
286 if(lockfile == NULL) {
287 logmsg("Error creating lock file %s error: %d %s",
288 filename, error, strerror(error));
293 res = fclose(lockfile);
294 } while(res && ((error = errno) == EINTR));
296 logmsg("Error closing lock file %s error: %d %s",
297 filename, error, strerror(error));
300 void clear_advisor_read_lock(const char *filename)
306 ** Log all removal failures. Even those due to file not existing.
307 ** This allows to detect if unexpectedly the file has already been
308 ** removed by a process different than the one that should do this.
312 res = unlink(filename);
313 } while(res && ((error = errno) == EINTR));
315 logmsg("Error removing lock file %s error: %d %s",
316 filename, error, strerror(error));
320 /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
321 its behavior is altered by the current locale. */
322 static char raw_toupper(char in)
324 #if !defined(CURL_DOES_CONVERSIONS)
325 if(in >= 'a' && in <= 'z')
326 return (char)('A' + in - 'a');
387 int strncasecompare(const char *first, const char *second, size_t max)
389 while(*first && *second && max) {
390 if(raw_toupper(*first) != raw_toupper(*second)) {
398 return 1; /* they are equal this far */
400 return raw_toupper(*first) == raw_toupper(*second);
403 #if defined(WIN32) && !defined(MSDOS)
405 static struct timeval tvnow(void)
408 ** GetTickCount() is available on _all_ Windows versions from W95 up
409 ** to nowadays. Returns milliseconds elapsed since last system boot,
410 ** increases monotonically and wraps once 49.7 days have elapsed.
412 ** GetTickCount64() is available on Windows version from Windows Vista
413 ** and Windows Server 2008 up to nowadays. The resolution of the
414 ** function is limited to the resolution of the system timer, which
415 ** is typically in the range of 10 milliseconds to 16 milliseconds.
418 #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
419 ULONGLONG milliseconds = GetTickCount64();
421 DWORD milliseconds = GetTickCount();
423 now.tv_sec = (long)(milliseconds / 1000);
424 now.tv_usec = (milliseconds % 1000) * 1000;
428 #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
430 static struct timeval tvnow(void)
433 ** clock_gettime() is granted to be increased monotonically when the
434 ** monotonic clock is queried. Time starting point is unspecified, it
435 ** could be the system start-up time, the Epoch, or something else,
436 ** in any case the time starting point does not change once that the
437 ** system has started up.
440 struct timespec tsnow;
441 if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
442 now.tv_sec = tsnow.tv_sec;
443 now.tv_usec = tsnow.tv_nsec / 1000;
446 ** Even when the configure process has truly detected monotonic clock
447 ** availability, it might happen that it is not actually available at
448 ** run-time. When this occurs simply fallback to other time source.
450 #ifdef HAVE_GETTIMEOFDAY
452 (void)gettimeofday(&now, NULL);
455 now.tv_sec = (long)time(NULL);
462 #elif defined(HAVE_GETTIMEOFDAY)
464 static struct timeval tvnow(void)
467 ** gettimeofday() is not granted to be increased monotonically, due to
468 ** clock drifting and external source time synchronization it can jump
469 ** forward or backward in time.
472 (void)gettimeofday(&now, NULL);
478 static struct timeval tvnow(void)
481 ** time() returns the value of time in seconds since the Epoch.
484 now.tv_sec = (long)time(NULL);
491 long timediff(struct timeval newer, struct timeval older)
493 timediff_t diff = newer.tv_sec-older.tv_sec;
494 if(diff >= (LONG_MAX/1000))
496 else if(diff <= (LONG_MIN/1000))
498 return (long)(newer.tv_sec-older.tv_sec)*1000+
499 (long)(newer.tv_usec-older.tv_usec)/1000;