00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
00045
00046 #include "curlx.h"
00047 #include "getpart.h"
00048 #include "util.h"
00049 #include "timeval.h"
00050
00051 #ifdef USE_WINSOCK
00052 #undef EINTR
00053 #define EINTR 4
00054 #undef EINVAL
00055 #define EINVAL 22
00056 #endif
00057
00058 #if defined(ENABLE_IPV6) && defined(__MINGW32__)
00059 const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
00060 #endif
00061
00062
00063
00064
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;
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);
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
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
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
00182
00183
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
00195
00196
00197
00198
00199
00200
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
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
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;
00260 }
00261 fprintf(pidfile, "%ld\n", pid);
00262 fclose(pidfile);
00263 logmsg("Wrote pid %ld to %s", pid, filename);
00264 return 1;
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
00297
00298
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
00311
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;
00389
00390 return raw_toupper(*first) == raw_toupper(*second);
00391 }