util.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
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.
13  *
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.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 #include "server_setup.h"
23 
24 #ifdef HAVE_SIGNAL_H
25 #include <signal.h>
26 #endif
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
29 #endif
30 #ifdef _XOPEN_SOURCE_EXTENDED
31 /* This define is "almost" required to build on HPUX 11 */
32 #include <arpa/inet.h>
33 #endif
34 #ifdef HAVE_NETDB_H
35 #include <netdb.h>
36 #endif
37 #ifdef HAVE_POLL_H
38 #include <poll.h>
39 #elif defined(HAVE_SYS_POLL_H)
40 #include <sys/poll.h>
41 #endif
42 #ifdef __MINGW32__
43 #include <w32api.h>
44 #endif
45 
46 #define ENABLE_CURLX_PRINTF
47 /* make the curlx header define all printf() functions to use the curlx_*
48  versions instead */
49 #include "curlx.h" /* from the private lib dir */
50 #include "getpart.h"
51 #include "util.h"
52 #include "timeval.h"
53 
54 #ifdef USE_WINSOCK
55 #undef EINTR
56 #define EINTR 4 /* errno.h value */
57 #undef EINVAL
58 #define EINVAL 22 /* errno.h value */
59 #endif
60 
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__*/
69 
70 /* This function returns a pointer to STATIC memory. It converts the given
71  * binary lump to a hex formatted string usable for output in logs or
72  * whatever.
73  */
74 char *data_to_hex(char *data, size_t len)
75 {
76  static char buf[256*3];
77  size_t i;
78  char *optr = buf;
79  char *iptr = data;
80 
81  if(len > 255)
82  len = 255;
83 
84  for(i = 0; i < len; i++) {
85  if((data[i] >= 0x20) && (data[i] < 0x7f))
86  *optr++ = *iptr++;
87  else {
88  snprintf(optr, 4, "%%%02x", *iptr++);
89  optr += 3;
90  }
91  }
92  *optr = 0; /* in case no sprintf was used */
93 
94  return buf;
95 }
96 
97 void logmsg(const char *msg, ...)
98 {
99  va_list ap;
100  char buffer[2048 + 1];
101  FILE *logfp;
102  int error;
103  struct curltime tv;
104  time_t sec;
105  struct tm *now;
106  char timebuf[20];
107  static time_t epoch_offset;
108  static int known_offset;
109 
110  if(!serverlogfile) {
111  fprintf(stderr, "Error: serverlogfile not set\n");
112  return;
113  }
114 
115  tv = curlx_tvnow();
116  if(!known_offset) {
117  epoch_offset = time(NULL) - tv.tv_sec;
118  known_offset = 1;
119  }
120  sec = epoch_offset + tv.tv_sec;
121  now = localtime(&sec); /* not thread safe but we don't care */
122 
123  snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
124  (int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec, (long)tv.tv_usec);
125 
126  va_start(ap, msg);
127  vsnprintf(buffer, sizeof(buffer), msg, ap);
128  va_end(ap);
129 
130  logfp = fopen(serverlogfile, "ab");
131  if(logfp) {
132  fprintf(logfp, "%s %s\n", timebuf, buffer);
133  fclose(logfp);
134  }
135  else {
136  error = errno;
137  fprintf(stderr, "fopen() failed with error: %d %s\n",
138  error, strerror(error));
139  fprintf(stderr, "Error opening file: %s\n", serverlogfile);
140  fprintf(stderr, "Msg not logged: %s %s\n", timebuf, buffer);
141  }
142 }
143 
144 #ifdef WIN32
145 /* use instead of perror() on generic windows */
146 void win32_perror(const char *msg)
147 {
148  char buf[512];
149  DWORD err = SOCKERRNO;
150 
151  if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
152  LANG_NEUTRAL, buf, sizeof(buf), NULL))
153  snprintf(buf, sizeof(buf), "Unknown error %lu (%#lx)", err, err);
154  if(msg)
155  fprintf(stderr, "%s: ", msg);
156  fprintf(stderr, "%s\n", buf);
157 }
158 #endif /* WIN32 */
159 
160 #ifdef USE_WINSOCK
161 void win32_init(void)
162 {
163  WORD wVersionRequested;
164  WSADATA wsaData;
165  int err;
166  wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
167 
168  err = WSAStartup(wVersionRequested, &wsaData);
169 
170  if(err != 0) {
171  perror("Winsock init failed");
172  logmsg("Error initialising winsock -- aborting");
173  exit(1);
174  }
175 
176  if(LOBYTE(wsaData.wVersion) != USE_WINSOCK ||
177  HIBYTE(wsaData.wVersion) != USE_WINSOCK) {
178  WSACleanup();
179  perror("Winsock init failed");
180  logmsg("No suitable winsock.dll found -- aborting");
181  exit(1);
182  }
183 }
184 
185 void win32_cleanup(void)
186 {
187  WSACleanup();
188 }
189 #endif /* USE_WINSOCK */
190 
191 /* set by the main code to point to where the test dir is */
192 const char *path = ".";
193 
194 char *test2file(long testno)
195 {
196  static char filename[256];
197  snprintf(filename, sizeof(filename), TEST_DATA_PATH, path, testno);
198  return filename;
199 }
200 
201 /*
202  * Portable function used for waiting a specific amount of ms.
203  * Waiting indefinitely with this function is not allowed, a
204  * zero or negative timeout value will return immediately.
205  *
206  * Return values:
207  * -1 = system call error, or invalid timeout value
208  * 0 = specified timeout has elapsed
209  */
210 int wait_ms(int timeout_ms)
211 {
212 #if !defined(MSDOS) && !defined(USE_WINSOCK)
213 #ifndef HAVE_POLL_FINE
214  struct timeval pending_tv;
215 #endif
216  struct curltime initial_tv;
217  int pending_ms;
218  int error;
219 #endif
220  int r = 0;
221 
222  if(!timeout_ms)
223  return 0;
224  if(timeout_ms < 0) {
225  errno = EINVAL;
226  return -1;
227  }
228 #if defined(MSDOS)
229  delay(timeout_ms);
230 #elif defined(USE_WINSOCK)
231  Sleep(timeout_ms);
232 #else
233  pending_ms = timeout_ms;
234  initial_tv = curlx_tvnow();
235  do {
236 #if defined(HAVE_POLL_FINE)
237  r = poll(NULL, 0, pending_ms);
238 #else
239  pending_tv.tv_sec = pending_ms / 1000;
240  pending_tv.tv_usec = (pending_ms % 1000) * 1000;
241  r = select(0, NULL, NULL, NULL, &pending_tv);
242 #endif /* HAVE_POLL_FINE */
243  if(r != -1)
244  break;
245  error = errno;
246  if(error && (error != EINTR))
247  break;
248  pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv);
249  if(pending_ms <= 0)
250  break;
251  } while(r == -1);
252 #endif /* USE_WINSOCK */
253  if(r)
254  r = -1;
255  return r;
256 }
257 
258 int write_pidfile(const char *filename)
259 {
260  FILE *pidfile;
261  long pid;
262 
263  pid = (long)getpid();
264  pidfile = fopen(filename, "wb");
265  if(!pidfile) {
266  logmsg("Couldn't write pid file: %s %s", filename, strerror(errno));
267  return 0; /* fail */
268  }
269  fprintf(pidfile, "%ld\n", pid);
270  fclose(pidfile);
271  logmsg("Wrote pid %ld to %s", pid, filename);
272  return 1; /* success */
273 }
274 
275 void set_advisor_read_lock(const char *filename)
276 {
277  FILE *lockfile;
278  int error = 0;
279  int res;
280 
281  do {
282  lockfile = fopen(filename, "wb");
283  } while((lockfile == NULL) && ((error = errno) == EINTR));
284  if(lockfile == NULL) {
285  logmsg("Error creating lock file %s error: %d %s",
286  filename, error, strerror(error));
287  return;
288  }
289 
290  do {
291  res = fclose(lockfile);
292  } while(res && ((error = errno) == EINTR));
293  if(res)
294  logmsg("Error closing lock file %s error: %d %s",
295  filename, error, strerror(error));
296 }
297 
298 void clear_advisor_read_lock(const char *filename)
299 {
300  int error = 0;
301  int res;
302 
303  /*
304  ** Log all removal failures. Even those due to file not existing.
305  ** This allows to detect if unexpectedly the file has already been
306  ** removed by a process different than the one that should do this.
307  */
308 
309  do {
310  res = unlink(filename);
311  } while(res && ((error = errno) == EINTR));
312  if(res)
313  logmsg("Error removing lock file %s error: %d %s",
314  filename, error, strerror(error));
315 }
316 
317 
318 /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
319  its behavior is altered by the current locale. */
320 static char raw_toupper(char in)
321 {
322 #if !defined(CURL_DOES_CONVERSIONS)
323  if(in >= 'a' && in <= 'z')
324  return (char)('A' + in - 'a');
325 #else
326  switch(in) {
327  case 'a':
328  return 'A';
329  case 'b':
330  return 'B';
331  case 'c':
332  return 'C';
333  case 'd':
334  return 'D';
335  case 'e':
336  return 'E';
337  case 'f':
338  return 'F';
339  case 'g':
340  return 'G';
341  case 'h':
342  return 'H';
343  case 'i':
344  return 'I';
345  case 'j':
346  return 'J';
347  case 'k':
348  return 'K';
349  case 'l':
350  return 'L';
351  case 'm':
352  return 'M';
353  case 'n':
354  return 'N';
355  case 'o':
356  return 'O';
357  case 'p':
358  return 'P';
359  case 'q':
360  return 'Q';
361  case 'r':
362  return 'R';
363  case 's':
364  return 'S';
365  case 't':
366  return 'T';
367  case 'u':
368  return 'U';
369  case 'v':
370  return 'V';
371  case 'w':
372  return 'W';
373  case 'x':
374  return 'X';
375  case 'y':
376  return 'Y';
377  case 'z':
378  return 'Z';
379  }
380 #endif
381 
382  return in;
383 }
384 
385 int strncasecompare(const char *first, const char *second, size_t max)
386 {
387  while(*first && *second && max) {
388  if(raw_toupper(*first) != raw_toupper(*second)) {
389  break;
390  }
391  max--;
392  first++;
393  second++;
394  }
395  if(0 == max)
396  return 1; /* they are equal this far */
397 
398  return raw_toupper(*first) == raw_toupper(*second);
399 }
filename
const char * serverlogfile
Definition: fake_ntlm.c:42
char * data_to_hex(char *data, size_t len)
Definition: util.c:74
time_t tv_sec
Definition: timeval.h:33
struct curltime curlx_tvnow(void)
Definition: timeval.c:106
#define SOCKERRNO
struct curltime now
Definition: unit1399.c:83
int write_pidfile(const char *filename)
Definition: util.c:258
static int res
static void win32_cleanup(void)
Definition: easy.c:84
void clear_advisor_read_lock(const char *filename)
Definition: util.c:298
#define vsnprintf
Definition: curl_printf.h:45
char buffer[]
Definition: unit1308.c:48
unsigned int i
Definition: unit1303.c:79
size_t len
Definition: curl_sasl.c:55
#define TEST_DATA_PATH
static time_t epoch_offset
Definition: testtrace.c:30
static char raw_toupper(char in)
Definition: util.c:320
void logmsg(const char *msg,...)
Definition: util.c:97
UNITTEST_START struct Curl_easy data
Definition: unit1399.c:82
int strncasecompare(const char *first, const char *second, size_t max)
Definition: util.c:385
static int known_offset
Definition: testtrace.c:31
time_t curlx_tvdiff(struct curltime newer, struct curltime older)
Definition: timeval.c:128
static CURLcode win32_init(void)
Definition: easy.c:96
char buf[3]
Definition: unit1398.c:32
char * test2file(long testno)
Definition: util.c:194
#define fprintf
Definition: curl_printf.h:41
#define snprintf
Definition: curl_printf.h:42
void set_advisor_read_lock(const char *filename)
Definition: util.c:275
Definition: debug.c:29
unsigned int tv_usec
Definition: timeval.h:34
const char * path
Definition: util.c:192
int wait_ms(int timeout_ms)
Definition: util.c:210


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:17