util.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 #include "server_setup.h"
00023 
00024 #ifdef HAVE_SIGNAL_H
00025 #include <signal.h>
00026 #endif
00027 #ifdef HAVE_NETINET_IN_H
00028 #include <netinet/in.h>
00029 #endif
00030 #ifdef _XOPEN_SOURCE_EXTENDED
00031 /* This define is "almost" required to build on HPUX 11 */
00032 #include <arpa/inet.h>
00033 #endif
00034 #ifdef HAVE_NETDB_H
00035 #include <netdb.h>
00036 #endif
00037 #ifdef HAVE_SYS_POLL_H
00038 #include <sys/poll.h>
00039 #elif defined(HAVE_POLL_H)
00040 #include <poll.h>
00041 #endif
00042 
00043 #define ENABLE_CURLX_PRINTF
00044 /* make the curlx header define all printf() functions to use the curlx_*
00045    versions instead */
00046 #include "curlx.h" /* from the private lib dir */
00047 #include "getpart.h"
00048 #include "util.h"
00049 #include "timeval.h"
00050 
00051 #ifdef USE_WINSOCK
00052 #undef  EINTR
00053 #define EINTR    4 /* errno.h value */
00054 #undef  EINVAL
00055 #define EINVAL  22 /* errno.h value */
00056 #endif
00057 
00058 #if defined(ENABLE_IPV6) && defined(__MINGW32__)
00059 const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
00060 #endif
00061 
00062 /* This function returns a pointer to STATIC memory. It converts the given
00063  * binary lump to a hex formatted string usable for output in logs or
00064  * whatever.
00065  */
00066 char *data_to_hex(char *data, size_t len)
00067 {
00068   static char buf[256*3];
00069   size_t i;
00070   char *optr = buf;
00071   char *iptr = data;
00072 
00073   if(len > 255)
00074     len = 255;
00075 
00076   for(i=0; i < len; i++) {
00077     if((data[i] >= 0x20) && (data[i] < 0x7f))
00078       *optr++ = *iptr++;
00079     else {
00080       snprintf(optr, 4, "%%%02x", *iptr++);
00081       optr+=3;
00082     }
00083   }
00084   *optr=0; /* in case no sprintf was used */
00085 
00086   return buf;
00087 }
00088 
00089 void logmsg(const char *msg, ...)
00090 {
00091   va_list ap;
00092   char buffer[2048 + 1];
00093   FILE *logfp;
00094   int error;
00095   struct timeval tv;
00096   time_t sec;
00097   struct tm *now;
00098   char timebuf[20];
00099   static time_t epoch_offset;
00100   static int    known_offset;
00101 
00102   if(!serverlogfile) {
00103     fprintf(stderr, "Error: serverlogfile not set\n");
00104     return;
00105   }
00106 
00107   tv = curlx_tvnow();
00108   if(!known_offset) {
00109     epoch_offset = time(NULL) - tv.tv_sec;
00110     known_offset = 1;
00111   }
00112   sec = epoch_offset + tv.tv_sec;
00113   now = localtime(&sec); /* not thread safe but we don't care */
00114 
00115   snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
00116     (int)now->tm_hour, (int)now->tm_min, (int)now->tm_sec, (long)tv.tv_usec);
00117 
00118   va_start(ap, msg);
00119   vsnprintf(buffer, sizeof(buffer), msg, ap);
00120   va_end(ap);
00121 
00122   logfp = fopen(serverlogfile, "ab");
00123   if(logfp) {
00124     fprintf(logfp, "%s %s\n", timebuf, buffer);
00125     fclose(logfp);
00126   }
00127   else {
00128     error = errno;
00129     fprintf(stderr, "fopen() failed with error: %d %s\n",
00130             error, strerror(error));
00131     fprintf(stderr, "Error opening file: %s\n", serverlogfile);
00132     fprintf(stderr, "Msg not logged: %s %s\n", timebuf, buffer);
00133   }
00134 }
00135 
00136 #ifdef WIN32
00137 /* use instead of perror() on generic windows */
00138 void win32_perror(const char *msg)
00139 {
00140   char buf[512];
00141   DWORD err = SOCKERRNO;
00142 
00143   if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
00144                     LANG_NEUTRAL, buf, sizeof(buf), NULL))
00145      snprintf(buf, sizeof(buf), "Unknown error %lu (%#lx)", err, err);
00146   if(msg)
00147     fprintf(stderr, "%s: ", msg);
00148   fprintf(stderr, "%s\n", buf);
00149 }
00150 #endif  /* WIN32 */
00151 
00152 #ifdef USE_WINSOCK
00153 void win32_init(void)
00154 {
00155   WORD wVersionRequested;
00156   WSADATA wsaData;
00157   int err;
00158   wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
00159 
00160   err = WSAStartup(wVersionRequested, &wsaData);
00161 
00162   if(err != 0) {
00163     perror("Winsock init failed");
00164     logmsg("Error initialising winsock -- aborting");
00165     exit(1);
00166   }
00167 
00168   if(LOBYTE(wsaData.wVersion) != USE_WINSOCK ||
00169      HIBYTE(wsaData.wVersion) != USE_WINSOCK) {
00170     WSACleanup();
00171     perror("Winsock init failed");
00172     logmsg("No suitable winsock.dll found -- aborting");
00173     exit(1);
00174   }
00175 }
00176 
00177 void win32_cleanup(void)
00178 {
00179   WSACleanup();
00180 }
00181 #endif  /* USE_WINSOCK */
00182 
00183 /* set by the main code to point to where the test dir is */
00184 const char *path=".";
00185 
00186 char *test2file(long testno)
00187 {
00188   static char filename[256];
00189   snprintf(filename, sizeof(filename), TEST_DATA_PATH, path, testno);
00190   return filename;
00191 }
00192 
00193 /*
00194  * Portable function used for waiting a specific amount of ms.
00195  * Waiting indefinitely with this function is not allowed, a
00196  * zero or negative timeout value will return immediately.
00197  *
00198  * Return values:
00199  *   -1 = system call error, or invalid timeout value
00200  *    0 = specified timeout has elapsed
00201  */
00202 int wait_ms(int timeout_ms)
00203 {
00204 #if !defined(MSDOS) && !defined(USE_WINSOCK)
00205 #ifndef HAVE_POLL_FINE
00206   struct timeval pending_tv;
00207 #endif
00208   struct timeval initial_tv;
00209   int pending_ms;
00210   int error;
00211 #endif
00212   int r = 0;
00213 
00214   if(!timeout_ms)
00215     return 0;
00216   if(timeout_ms < 0) {
00217     errno = EINVAL;
00218     return -1;
00219   }
00220 #if defined(MSDOS)
00221   delay(timeout_ms);
00222 #elif defined(USE_WINSOCK)
00223   Sleep(timeout_ms);
00224 #else
00225   pending_ms = timeout_ms;
00226   initial_tv = curlx_tvnow();
00227   do {
00228 #if defined(HAVE_POLL_FINE)
00229     r = poll(NULL, 0, pending_ms);
00230 #else
00231     pending_tv.tv_sec = pending_ms / 1000;
00232     pending_tv.tv_usec = (pending_ms % 1000) * 1000;
00233     r = select(0, NULL, NULL, NULL, &pending_tv);
00234 #endif /* HAVE_POLL_FINE */
00235     if(r != -1)
00236       break;
00237     error = errno;
00238     if(error && (error != EINTR))
00239       break;
00240     pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv);
00241     if(pending_ms <= 0)
00242       break;
00243   } while(r == -1);
00244 #endif /* USE_WINSOCK */
00245   if(r)
00246     r = -1;
00247   return r;
00248 }
00249 
00250 int write_pidfile(const char *filename)
00251 {
00252   FILE *pidfile;
00253   long pid;
00254 
00255   pid = (long)getpid();
00256   pidfile = fopen(filename, "wb");
00257   if(!pidfile) {
00258     logmsg("Couldn't write pid file: %s %s", filename, strerror(errno));
00259     return 0; /* fail */
00260   }
00261   fprintf(pidfile, "%ld\n", pid);
00262   fclose(pidfile);
00263   logmsg("Wrote pid %ld to %s", pid, filename);
00264   return 1; /* success */
00265 }
00266 
00267 void set_advisor_read_lock(const char *filename)
00268 {
00269   FILE *lockfile;
00270   int error = 0;
00271   int res;
00272 
00273   do {
00274     lockfile = fopen(filename, "wb");
00275   } while((lockfile == NULL) && ((error = errno) == EINTR));
00276   if(lockfile == NULL) {
00277     logmsg("Error creating lock file %s error: %d %s",
00278            filename, error, strerror(error));
00279     return;
00280   }
00281 
00282   do {
00283     res = fclose(lockfile);
00284   } while(res && ((error = errno) == EINTR));
00285   if(res)
00286     logmsg("Error closing lock file %s error: %d %s",
00287            filename, error, strerror(error));
00288 }
00289 
00290 void clear_advisor_read_lock(const char *filename)
00291 {
00292   int error = 0;
00293   int res;
00294 
00295   /*
00296   ** Log all removal failures. Even those due to file not existing.
00297   ** This allows to detect if unexpectedly the file has already been
00298   ** removed by a process different than the one that should do this.
00299   */
00300 
00301   do {
00302     res = unlink(filename);
00303   } while(res && ((error = errno) == EINTR));
00304   if(res)
00305     logmsg("Error removing lock file %s error: %d %s",
00306            filename, error, strerror(error));
00307 }
00308 
00309 
00310 /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
00311    its behavior is altered by the current locale. */
00312 static char raw_toupper(char in)
00313 {
00314 #if !defined(CURL_DOES_CONVERSIONS)
00315   if(in >= 'a' && in <= 'z')
00316     return (char)('A' + in - 'a');
00317 #else
00318   switch(in) {
00319   case 'a':
00320     return 'A';
00321   case 'b':
00322     return 'B';
00323   case 'c':
00324     return 'C';
00325   case 'd':
00326     return 'D';
00327   case 'e':
00328     return 'E';
00329   case 'f':
00330     return 'F';
00331   case 'g':
00332     return 'G';
00333   case 'h':
00334     return 'H';
00335   case 'i':
00336     return 'I';
00337   case 'j':
00338     return 'J';
00339   case 'k':
00340     return 'K';
00341   case 'l':
00342     return 'L';
00343   case 'm':
00344     return 'M';
00345   case 'n':
00346     return 'N';
00347   case 'o':
00348     return 'O';
00349   case 'p':
00350     return 'P';
00351   case 'q':
00352     return 'Q';
00353   case 'r':
00354     return 'R';
00355   case 's':
00356     return 'S';
00357   case 't':
00358     return 'T';
00359   case 'u':
00360     return 'U';
00361   case 'v':
00362     return 'V';
00363   case 'w':
00364     return 'W';
00365   case 'x':
00366     return 'X';
00367   case 'y':
00368     return 'Y';
00369   case 'z':
00370     return 'Z';
00371   }
00372 #endif
00373 
00374   return in;
00375 }
00376 
00377 int strncasecompare(const char *first, const char *second, size_t max)
00378 {
00379   while(*first && *second && max) {
00380     if(raw_toupper(*first) != raw_toupper(*second)) {
00381       break;
00382     }
00383     max--;
00384     first++;
00385     second++;
00386   }
00387   if(0 == max)
00388     return 1; /* they are equal this far */
00389 
00390   return raw_toupper(*first) == raw_toupper(*second);
00391 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:07