00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "utils.h"
00039 #include "ApMon.h"
00040
00041
00042 bool apmon_utils::urlModified(char *url, char *lastModified) throw(runtime_error) {
00043 char temp_filename[300];
00044 FILE *tmp_file;
00045 bool lineFound;
00046 char line[MAX_STRING_LEN1];
00047
00048 #ifndef WIN32
00049 long mypid = getpid();
00050 #else
00051 long mypid = _getpid();
00052 #endif
00053
00054 char str1[100], str2[100];
00055 #ifndef WIN32
00056 sprintf(temp_filename, "/tmp/apmon_http%ld", mypid);
00057 #else
00058 char *tmp = getenv("TEMP");
00059 if(tmp == NULL)
00060 tmp = getenv("TMP");
00061 if(tmp == NULL)
00062 tmp = "c:";
00063 sprintf(temp_filename, "%s\\apmon_http%ld", tmp, mypid);
00064 #endif
00065
00066 httpRequest(url, (char*)"HEAD", temp_filename);
00067
00068
00069 tmp_file = fopen(temp_filename, "rt");
00070 if (tmp_file == NULL)
00071 throw runtime_error("[ urlModified() ] Error getting the configuration web page");
00072
00073
00074
00075
00076 fgets(line, MAX_STRING_LEN, tmp_file);
00077 sscanf(line, "%s %s", str1, str2);
00078 if (atoi(str2) != 200) {
00079 fclose(tmp_file);
00080 unlink(temp_filename);
00081 free(line);
00082 throw runtime_error("[ urlModified() ] Error getting the configuration web page");
00083 }
00084
00085
00086 lineFound = false;
00087 while (fgets(line, MAX_STRING_LEN, tmp_file) != NULL) {
00088 if (strstr(line, "Last-Modified") == line) {
00089 lineFound = true;
00090 break;
00091 }
00092 }
00093
00094 fclose(tmp_file);
00095 unlink(temp_filename);
00096 if (lineFound) {
00097 if (strcmp(line, lastModified) != 0) {
00098 return true;
00099 }
00100 else
00101 return false;
00102 } else
00103
00104 return true;
00105
00106 }
00107
00108 int apmon_utils::httpRequest(char *url, char *reqType, char *temp_filename)
00109 throw(runtime_error) {
00110
00111 char hostname[MAX_STRING_LEN];
00112
00113 char filename[MAX_STRING_LEN];
00114
00115 int port;
00116 char msg[MAX_STRING_LEN];
00117
00118 int sd, rc;
00119 struct sockaddr_in localAddr, servAddr;
00120 struct hostent *h;
00121 struct timeval optval;
00122
00123 char *request;
00124
00125 char buffer[MAX_STRING_LEN];
00126 int totalSize;
00127 FILE *tmp_file;
00128
00129 parse_URL(url, hostname, &port, filename);
00130
00131 sprintf(msg, "Sending HTTP %s request to: \n Hostname: %s , Port: %d , Filename: %s",
00132 reqType, hostname, port, filename);
00133 logger(INFO, msg);
00134
00135 request = (char *)malloc(MAX_STRING_LEN * sizeof(char));
00136 strcpy(request, reqType);
00137 strcat(request, " ");
00138
00139 request = (char *)strcat( request, filename);
00140 request = (char *)strcat( request, " HTTP/1.0\r\nHOST: ");
00141 request = (char *)strcat( request, hostname);
00142 request = (char *)strcat( request, "\r\n\r\n");
00143
00144 h = gethostbyname(hostname);
00145 if(h==NULL) {
00146 free(request);
00147 sprintf(msg,"[ httpRequest() ] Unknown host: %s ", hostname);
00148 throw runtime_error(msg);
00149 }
00150
00151 servAddr.sin_family = h->h_addrtype;
00152 memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
00153 servAddr.sin_port = htons(port);
00154
00155 sd = socket(AF_INET, SOCK_STREAM, 0);
00156 if(sd<0) {
00157 free(request);
00158 throw runtime_error(" [ httpRequest() ] Cannot open socket ");
00159 }
00160
00161
00162
00163 optval.tv_sec = 10;
00164 optval.tv_usec = 0;
00165
00166
00167 setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char *) &optval,
00168 sizeof(optval));
00169
00170 localAddr.sin_family = AF_INET;
00171 localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00172 localAddr.sin_port = htons(0);
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
00186 if(rc<0) {
00187 free(request);
00188 #ifndef WIN32
00189 close(sd);
00190 #else
00191 closesocket(sd);
00192 #endif
00193 throw runtime_error("[ httpRequest() ] Cannot connect to http server");
00194 }
00195
00196
00197 rc = send(sd, request, strlen(request), 0);
00198 if(rc<0) {
00199 #ifndef WIN32
00200 close(sd);
00201 #else
00202 closesocket(sd);
00203 #endif
00204 free(request);
00205 throw runtime_error("[ httpRequest() ] Cannot send the request to the http server");
00206 }
00207
00208 free(request);
00209
00210
00211 tmp_file = fopen(temp_filename, "wb");
00212 if (tmp_file == NULL) {
00213 #ifndef WIN32
00214 close(sd);
00215 #else
00216 closesocket(sd);
00217 #endif
00218 throw runtime_error("[ httpRequest() ] Unable to open for writing temporary file");
00219 }
00220
00221 rc = 0, totalSize = 0;
00222 do {
00223 memset(buffer,0x0,MAX_STRING_LEN);
00224 rc = recv(sd, buffer, MAX_STRING_LEN, 0);
00225 if( rc > 0) {
00226 fwrite(buffer, rc, 1, tmp_file);
00227 totalSize +=rc;
00228 }
00229 }while(rc>0);
00230
00231 sprintf(msg, "Received response from %s, response size is %d bytes",
00232 hostname, totalSize);
00233 logger(INFO, msg);
00234
00235 #ifndef WIN32
00236 close(sd);
00237 #else
00238 closesocket(sd);
00239 #endif
00240 fclose(tmp_file);
00241 return totalSize;
00242 }
00243
00244 char *apmon_utils::findIP(char *address) throw(runtime_error) {
00245 int isIP = 1;
00246 char *destIP, *s;
00247 struct in_addr addr;
00248 unsigned int j;
00249 bool ipFound;
00250
00251 for (j = 0; j < strlen(address); j++)
00252 if (isalpha(address[j])) {
00253
00254 isIP = 0;
00255 break;
00256 }
00257
00258 if (!isIP) {
00259 struct hostent *he = gethostbyname(address);
00260 if (he == NULL) {
00261 char tmp_msg[40];
00262 sprintf(tmp_msg, "[ findIP() ] Invalid destination address %s", address);
00263 throw runtime_error(tmp_msg);
00264 }
00265 j = 0;
00266
00267
00268 ipFound = false;
00269 while ((he -> h_addr_list)[j] != NULL) {
00270 memcpy(&(addr.s_addr), (he -> h_addr_list)[j], 4);
00271 s = inet_ntoa(addr);
00272 if (strcmp(s, "127.0.0.1") != 0) {
00273 destIP = strdup(s);
00274 ipFound = true;
00275 break;
00276 }
00277 j++;
00278 }
00279 if (!ipFound) {
00280 destIP = strdup("127.0.0.1");
00281 fprintf(stderr, "The destination for datagrams is localhost\n");
00282 }
00283
00284 } else
00285 destIP = strdup(address);
00286
00287 return destIP;
00288 }
00289
00290
00291 void apmon_utils::parse_URL(char *url, char *hostname, int *port, char *identifier)
00292 throw(runtime_error) {
00293 char protocol[MAX_STRING_LEN], scratch[MAX_STRING_LEN], *ptr=0, *nptr=0;
00294 char msg[MAX_STRING_LEN];
00295
00296 strcpy(scratch, url);
00297 ptr = (char *)strchr(scratch, ':');
00298 if (!ptr)
00299 throw runtime_error("[ parse_URL() ] Wrong url: no protocol specified");
00300
00301 strcpy(ptr, "\0");
00302 strcpy(protocol, scratch);
00303 if (strcmp(protocol, "http")) {
00304 sprintf(msg, "[ parse_URL() ] Wrong protocol in URL: %s", protocol);
00305 throw runtime_error(msg);
00306 }
00307
00308 strcpy(scratch, url);
00309 ptr = (char *)strstr(scratch, "//");
00310 if (!ptr) {
00311 throw runtime_error("[ parse_URL() ] Wrong url: no server specified");
00312 }
00313 ptr += 2;
00314
00315 strcpy(hostname, ptr);
00316 nptr = (char *)strchr(ptr, ':');
00317 if (!nptr) {
00318 *port = 80;
00319 nptr = (char *)strchr(hostname, '/');
00320 } else {
00321 sscanf(nptr, ":%d", port);
00322 nptr = (char *)strchr(hostname, ':');
00323 }
00324
00325 if (nptr)
00326 *nptr = '\0';
00327
00328 nptr = (char *)strchr(ptr, '/');
00329 if (!nptr) {
00330 throw runtime_error("[ parse_URL() ] Wrong url: no file specified");
00331 }
00332 strcpy(identifier, nptr);
00333 }
00334
00335
00336 void apmon_utils::freeMat(char **mat, int nRows) {
00337 int i;
00338 for (i = 0; i < nRows; i++)
00339 free(mat[i]);
00340 free(mat);
00341 }
00342
00343 char *apmon_utils::trimString(char *s) {
00344 unsigned int i, j, firstpos, lastpos;
00345 char *ret = (char *)malloc((strlen(s) + 1) * sizeof(char));
00346 j = 0;
00347
00348
00349 for (i = 0; i < strlen(s); i++)
00350 if (!isspace(s[i]))
00351 break;
00352 firstpos = i;
00353
00354 if (firstpos == strlen(s)) {
00355 ret[0] = 0;
00356 return ret;
00357 }
00358
00359
00360 for (i = strlen(s) ; i > 0; i--)
00361 if (!isspace(s[i-1]))
00362 break;
00363 lastpos = i;
00364
00365 for (i = firstpos; i <= lastpos; i++)
00366 ret[j++] = s[i];
00367
00368 ret[j++] = 0;
00369 return ret;
00370 }
00371
00372 int apmon_utils::xdrSize(int type, char *value) {
00373 int size;
00374
00375 switch (type) {
00376
00377 case XDR_INT32:
00378 case XDR_REAL32:
00379 return 4;
00380
00381 case XDR_REAL64:
00382 return 8;
00383 case XDR_STRING:
00384
00385
00386 if (value == NULL) {
00387 logger(WARNING, "[ xdrSize() ] null string argument");
00388 size = 4;
00389 } else {
00390 size = strlen(value) + 4;
00391
00392
00393 if (size % 4 != 0)
00394 size += (4 - size % 4);
00395 return size;
00396 }
00397 }
00398
00399 return RET_ERROR;
00400 }
00401
00402 int apmon_utils::sizeEval(int type, char *value) {
00403
00404 switch (type) {
00405
00406 case XDR_INT32:
00407 case XDR_REAL32:
00408 return 4;
00409
00410 case XDR_REAL64:
00411 return 8;
00412 case XDR_STRING:
00413 return (strlen(value) + 1);
00414 }
00415
00416 return RET_ERROR;
00417 }
00418
00419
00420
00421 void apmon_utils::logParameters(int level, int nParams, char **paramNames,
00422 int *valueTypes, char **paramValues) {
00423 int i;
00424 char typeNames[][15] = {"XDR_STRING", "", "XDR_INT32", "", "XDR_REAL32",
00425 "XDR_REAL64"};
00426 char logmsg[200], val[100];
00427
00428 for (i = 0; i < nParams; i++) {
00429 if (paramNames[i] == NULL || (valueTypes[i] == XDR_STRING &&
00430 paramValues[i] == NULL))
00431 continue;
00432 sprintf(logmsg, "%s (%s) ", paramNames[i], typeNames[valueTypes[i]]);
00433
00434 switch(valueTypes[i]) {
00435 case XDR_STRING:
00436 sprintf(val, "%s", paramValues[i]);
00437 break;
00438 case XDR_INT32:
00439 sprintf(val, "%d", *(int *)paramValues[i]);
00440 break;
00441 case XDR_REAL32:
00442 sprintf(val, "%f", *(float *)paramValues[i]);
00443 break;
00444 case XDR_REAL64:
00445 sprintf(val, "%f", *(double *)(paramValues[i]));
00446 break;
00447 }
00448 strcat(logmsg, val);
00449 logger(level, logmsg);
00450 }
00451 }
00452
00453
00454 bool apmon_utils::isPrivateAddress(char *addr) {
00455 char *s1, *s2;
00456 int n1, n2;
00457 char tmp[MAX_STRING_LEN];
00458
00459
00460
00461 strcpy(tmp, addr);
00462 s1 = strtok(tmp,".");
00463 n1 = atoi(s1);
00464
00465 s2 = strtok(NULL, ".");
00466 n2 = atoi(s2);
00467
00468 if (n1 == 10)
00469 return true;
00470 if (n1 == 172 && n2 >= 16 && n2 <= 31)
00471 return true;
00472 if (n1 == 192 && n2 == 168)
00473 return true;
00474
00475 return false;
00476 }
00477
00478 int apmon_utils::getVectIndex(char *item, char **vect, int vectDim) {
00479 int i;
00480
00481 for (i = 0; i < vectDim; i++)
00482 if (strcmp(item, vect[i]) == 0)
00483 return i;
00484 return -1;
00485 }
00486
00487 void apmon_utils::logger(int msgLevel, const char *msg, int newLevel) {
00488 char time_s[30];
00489 int len;
00490 long crtTime = time(NULL);
00491 char *levels[5] = {(char*)"FATAL",
00492 (char*)"WARNING",
00493 (char*)"INFO",
00494 (char*)"FINE",
00495 (char*)"DEBUG"};
00496 static int loglevel = INFO;
00497 #ifndef WIN32
00498 static pthread_mutex_t logger_mutex;
00499 #else
00500 static HANDLE logger_mutex;
00501 #endif
00502 static bool firstTime = true;
00503
00504 if (firstTime) {
00505 #ifndef WIN32
00506 pthread_mutex_init(&logger_mutex, NULL);
00507 #else
00508 logger_mutex = CreateMutex(NULL, FALSE, NULL);
00509 #endif
00510 firstTime = false;
00511 }
00512
00513 pthread_mutex_lock(&logger_mutex);
00514
00515 #ifndef WIN32
00516 char cbuf[50];
00517 strcpy(time_s, ctime_r(&crtTime, cbuf));
00518 #else
00519 strcpy(time_s, ctime(&crtTime));
00520 #endif
00521 len = strlen(time_s); time_s[len - 1] = 0;
00522
00523 if (newLevel >= 0 && newLevel <=4) {
00524 loglevel = newLevel;
00525 if (loglevel>=2)
00526 printf("[TIME: %s] Changed the logging level to %s\n", time_s, levels[newLevel]);
00527 } else {
00528 if (msgLevel >= 0 && msgLevel <= 4) {
00529 if (msgLevel <= loglevel)
00530 printf("[TIME: %s] [%s] %s\n",time_s, levels[msgLevel], msg);
00531 } else
00532 printf("[WARNING] Invalid logging level %d!\n", msgLevel);
00533 }
00534 pthread_mutex_unlock(&logger_mutex);
00535 }