| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# utils.cpp

Go to the documentation of this file.

    00001
    00006 /*
    00007  * ApMon - Application Monitoring Tool
    00008  * Version: 2.2.0
    00009  *
    00010  * Copyright (C) 2006 California Institute of Technology
    00011  *
    00012  * Permission is hereby granted, free of charge, to use, copy and modify
    00013  * this software and its documentation (the "Software") for any
    00014  * purpose, provided that existing copyright notices are retained in
    00015  * all copies and that this notice is included verbatim in any distributions
    00016  * or substantial portions of the Software.
    00017  * This software is a part of the MonALISA framework (http://monalisa.cacr.caltech.edu).
    00018  * Users of the Software are asked to feed back problems, benefits,
    00019  * and/or suggestions about the software to the MonALISA Development Team
    00020  * (developers@monalisa.cern.ch). Support for this software - fixing of bugs,
    00021  * incorporation of new features - is done on a best effort basis. All bug
    00022  * fixes and enhancements will be made available under the same terms and
    00023  * conditions as the original software,
    00024
    00025  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
    00026  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
    00027  * OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
    00028  * EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00029
    00030  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
    00031  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
    00032  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS
    00033  * PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
    00034  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
    00035  * MODIFICATIONS.
    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   /* get the HTTP header and put it in a temporary file */
    00066   httpRequest(url, (char*)"HEAD", temp_filename);
    00067
    00068    /* read the header from the temporary file */
    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   //line = (char*)malloc(MAX_STRING_LEN * sizeof(char));
    00074
    00075   //check if we got the page correctly
    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   // look for the "Last-Modified" line
    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     // if the line was not found we must assume the page was modified
    00104     return true;
    00105
    00106 }
    00107
    00108 int apmon_utils::httpRequest(char *url, char *reqType, char *temp_filename)
    00109 throw(runtime_error) {
    00110   // the server from which we get the configuration file
    00111   char hostname[MAX_STRING_LEN];
    00112   // the name of the remote file
    00113   char filename[MAX_STRING_LEN];
    00114   // the port on which the server listens (by default 80)
    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; // the HTTP request
    00124
    00125   char buffer[MAX_STRING_LEN]; // for reading from the socket
    00126   int totalSize; // the size of the remote file
    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);//(LOCAL_SERVER_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   /* set connection timeout */
    00162
    00163   optval.tv_sec = 10;
    00164   optval.tv_usec = 0;
    00165   //setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (char *) &optval,
    00166   //            sizeof(optval));
    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   rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
    00176   if(rc<0) {
    00177     free(request);
    00178     close(sd);
    00179     sprintf(msg, "%s: cannot bind port TCP %u", url,port);
    00180     throw runtime_error(msg);
    00181   }
    00182   */
    00183
    00184   // connect to the server
    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   // send the request
    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   /* read the response and put it in a temporary file */
    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);    //  init line
    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         // if we found a letter, this is not an IP address
    00254         isIP = 0;
    00255         break;
    00256       }
    00257
    00258     if (!isIP) {  // the user provided a hostname, find the IP
    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       /* get from the list the first IP address
    00267          (which is not a loopback one) */
    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 // the string was an IP address
    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; /* use the default HTTP port number */
    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   // find the position of the first non-space character in the string
    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   // find the position of the last non-space character in the string
    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 //  case XDR_INT16: (not supported)
    00377   case XDR_INT32:
    00378   case XDR_REAL32:
    00379     return 4;
    00380 //  case XDR_INT64:  (not supported)
    00381   case XDR_REAL64:
    00382     return 8;
    00383   case XDR_STRING:
    00384     /* XDR adds 4 bytes to hold the length of the string */
    00385     //size = (strlen(value) + 1) + 4;
    00386     if (value == NULL) {
    00387       logger(WARNING, "[ xdrSize() ] null string argument");
    00388       size = 4;
    00389     } else {
    00390       size = strlen(value) + 4;
    00391       /* the length of the XDR representation must be a multiple of 4,
    00392          so there might be some extra bytes added*/
    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 //  case XDR_INT16:
    00406   case XDR_INT32:
    00407   case XDR_REAL32:
    00408     return 4;
    00409 //  case XDR_INT64:
    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     //printf("%s () ", paramNames[i]);
    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 //  char buf[MAX_STRING_LEN];
    00459 //  char *pbuf = buf;
    00460
    00461   strcpy(tmp, addr);
    00462   s1 = strtok/*_r*/(tmp,".");//, &pbuf);
    00463   n1 = atoi(s1);
    00464
    00465   s2 = strtok/*_r*/(NULL, ".");//, &pbuf);
    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 }