| # Gaudi Framework, version v21r10p1 |

Home |  | Generated: 29 Jul 2010

# 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;
    00120   struct sockaddr_in servAddr;
    00121   struct hostent *h;
    00122   struct timeval optval;
    00123
    00124   char *request; // the HTTP request
    00125
    00126   char buffer[MAX_STRING_LEN]; // for reading from the socket
    00127   int totalSize; // the size of the remote file
    00128   FILE *tmp_file;
    00129
    00130   parse_URL(url, hostname, &port, filename);
    00131
    00132   sprintf(msg, "Sending HTTP %s request to: \n Hostname: %s , Port: %d , Filename: %s",
    00133          reqType, hostname, port, filename);
    00134   logger(INFO, msg);
    00135
    00136   request = (char *)malloc(MAX_STRING_LEN * sizeof(char));
    00137   strcpy(request, reqType);
    00138   strcat(request, " ");
    00139
    00140   request = (char *)strcat( request, filename);
    00141   request = (char *)strcat( request, " HTTP/1.0\r\nHOST: ");
    00142   request = (char *)strcat( request, hostname);
    00143   request = (char *)strcat( request, "\r\n\r\n");
    00144
    00145   h = gethostbyname(hostname);
    00146   if(h==NULL) {
    00147     free(request);
    00148     sprintf(msg,"[ httpRequest() ] Unknown host: %s ", hostname);
    00149     throw runtime_error(msg);
    00150   }
    00151
    00152   servAddr.sin_family = h->h_addrtype;
    00153   memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
    00154   servAddr.sin_port = htons(port);//(LOCAL_SERVER_PORT);
    00155
    00156   sd = socket(AF_INET, SOCK_STREAM, 0);
    00157   if(sd<0) {
    00158     free(request);
    00159     throw runtime_error(" [ httpRequest() ] Cannot open socket ");
    00160   }
    00161
    00162   /* set connection timeout */
    00163
    00164   optval.tv_sec = 10;
    00165   optval.tv_usec = 0;
    00166   //setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (char *) &optval,
    00167   //            sizeof(optval));
    00168   setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char *) &optval,
    00169                         sizeof(optval));
    00170
    00171   /*
    00172   localAddr.sin_family = AF_INET;
    00173   localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    00174   localAddr.sin_port = htons(0);
    00175
    00176   rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
    00177   if(rc<0) {
    00178     free(request);
    00179     close(sd);
    00180     sprintf(msg, "%s: cannot bind port TCP %u", url,port);
    00181     throw runtime_error(msg);
    00182   }
    00183   */
    00184
    00185   // connect to the server
    00186   rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
    00187   if(rc<0) {
    00188     free(request);
    00189 #ifndef WIN32
    00190     close(sd);
    00191 #else
    00192         closesocket(sd);
    00193 #endif
    00194     throw runtime_error("[ httpRequest() ] Cannot connect to http server");
    00195   }
    00196
    00197   // send the request
    00198   rc = send(sd, request, strlen(request), 0);
    00199   if(rc<0) {
    00200 #ifndef WIN32
    00201         close(sd);
    00202 #else
    00203         closesocket(sd);
    00204 #endif
    00205     free(request);
    00206     throw runtime_error("[ httpRequest() ] Cannot send the request to the http server");
    00207   }
    00208
    00209   free(request);
    00210
    00211   /* read the response and put it in a temporary file */
    00212   tmp_file = fopen(temp_filename, "wb");
    00213   if (tmp_file == NULL) {
    00214 #ifndef WIN32
    00215     close(sd);
    00216 #else
    00217         closesocket(sd);
    00218 #endif
    00219     throw runtime_error("[ httpRequest() ] Unable to open for writing temporary file");
    00220   }
    00221
    00222   rc = 0, totalSize = 0;
    00223   do {
    00224     memset(buffer,0x0,MAX_STRING_LEN);    //  init line
    00225     rc = recv(sd, buffer, MAX_STRING_LEN, 0);
    00226     if( rc > 0) {
    00227       fwrite(buffer, rc, 1, tmp_file);
    00228       totalSize +=rc;
    00229     }
    00230   }while(rc>0);
    00231
    00232   sprintf(msg, "Received response from  %s, response size is %d bytes",
    00233           hostname, totalSize);
    00234   logger(INFO, msg);
    00235
    00236 #ifndef WIN32
    00237   close(sd);
    00238 #else
    00239   closesocket(sd);
    00240 #endif
    00241   fclose(tmp_file);
    00242   return totalSize;
    00243 }
    00244
    00245 char *apmon_utils::findIP(char *address) throw(runtime_error) {
    00246   int isIP = 1;
    00247   char *destIP, *s;
    00248   struct in_addr addr;
    00249   unsigned int j;
    00250   bool ipFound;
    00251
    00252   for (j = 0; j < strlen(address); j++)
    00253       if (isalpha(address[j])) {
    00254         // if we found a letter, this is not an IP address
    00255         isIP = 0;
    00256         break;
    00257       }
    00258
    00259     if (!isIP) {  // the user provided a hostname, find the IP
    00260       struct hostent *he = gethostbyname(address);
    00261       if (he == NULL) {
    00262         char tmp_msg[40];
    00263         sprintf(tmp_msg, "[ findIP() ] Invalid destination address %s", address);
    00264         throw runtime_error(tmp_msg);
    00265       }
    00266       j = 0;
    00267       /* get from the list the first IP address
    00268          (which is not a loopback one) */
    00269       ipFound = false;
    00270       while ((he -> h_addr_list)[j] != NULL) {
    00271         memcpy(&(addr.s_addr), (he -> h_addr_list)[j], 4);
    00272         s = inet_ntoa(addr);
    00273         if (strcmp(s, "127.0.0.1") != 0) {
    00274           destIP = strdup(s);
    00275           ipFound = true;
    00276           break;
    00277         }
    00278         j++;
    00279       }
    00280       if (!ipFound) {
    00281         destIP = strdup("127.0.0.1");
    00282         fprintf(stderr, "The destination for datagrams is localhost\n");
    00283       }
    00284
    00285     } else // the string was an IP address
    00286       destIP = strdup(address);
    00287
    00288     return destIP;
    00289 }
    00290
    00291
    00292 void apmon_utils::parse_URL(char *url, char *hostname, int *port, char *identifier)
    00293 throw(runtime_error) {
    00294     char protocol[MAX_STRING_LEN], scratch[MAX_STRING_LEN], *ptr=0, *nptr=0;
    00295     char msg[MAX_STRING_LEN];
    00296
    00297     strcpy(scratch, url);
    00298     ptr = (char *)strchr(scratch, ':');
    00299     if (!ptr)
    00300         throw runtime_error("[ parse_URL() ] Wrong url: no protocol specified");
    00301
    00302     strcpy(ptr, "\0");
    00303     strcpy(protocol, scratch);
    00304     if (strcmp(protocol, "http")) {
    00305         sprintf(msg, "[ parse_URL() ] Wrong protocol in URL: %s", protocol);
    00306         throw runtime_error(msg);
    00307     }
    00308
    00309     strcpy(scratch, url);
    00310     ptr = (char *)strstr(scratch, "//");
    00311     if (!ptr) {
    00312         throw runtime_error("[ parse_URL() ] Wrong url: no server specified");
    00313     }
    00314     ptr += 2;
    00315
    00316     strcpy(hostname, ptr);
    00317     nptr = (char *)strchr(ptr, ':');
    00318     if (!nptr) {
    00319         *port = 80; /* use the default HTTP port number */
    00320         nptr = (char *)strchr(hostname, '/');
    00321     } else {
    00322         sscanf(nptr, ":%d", port);
    00323         nptr = (char *)strchr(hostname, ':');
    00324     }
    00325
    00326     if (nptr)
    00327       *nptr = '\0';
    00328
    00329     nptr = (char *)strchr(ptr, '/');
    00330     if (!nptr) {
    00331         throw runtime_error("[ parse_URL() ] Wrong url: no file specified");
    00332     }
    00333     strcpy(identifier, nptr);
    00334 }
    00335
    00336
    00337 void apmon_utils::freeMat(char **mat, int nRows) {
    00338   int i;
    00339   for (i = 0; i < nRows; i++)
    00340     free(mat[i]);
    00341   free(mat);
    00342 }
    00343
    00344 char *apmon_utils::trimString(char *s) {
    00345   unsigned int i, j, firstpos, lastpos;
    00346   char *ret = (char *)malloc((strlen(s) + 1) * sizeof(char));
    00347   j = 0;
    00348
    00349   // find the position of the first non-space character in the string
    00350   for (i = 0; i < strlen(s); i++)
    00351     if (!isspace(s[i]))
    00352       break;
    00353   firstpos = i;
    00354
    00355   if (firstpos == strlen(s)) {
    00356     ret[0] = 0;
    00357     return ret;
    00358   }
    00359
    00360   // find the position of the last non-space character in the string
    00361   for (i = strlen(s) ; i > 0; i--)
    00362     if (!isspace(s[i-1]))
    00363         break;
    00364   lastpos = i;
    00365
    00366   for (i = firstpos; i <= lastpos; i++)
    00367       ret[j++] = s[i];
    00368
    00369   ret[j++] = 0;
    00370   return ret;
    00371 }
    00372
    00373 int apmon_utils::xdrSize(int type, char *value) {
    00374   int size;
    00375
    00376   switch (type) {
    00377 //  case XDR_INT16: (not supported)
    00378   case XDR_INT32:
    00379   case XDR_REAL32:
    00380     return 4;
    00381 //  case XDR_INT64:  (not supported)
    00382   case XDR_REAL64:
    00383     return 8;
    00384   case XDR_STRING:
    00385     /* XDR adds 4 bytes to hold the length of the string */
    00386     //size = (strlen(value) + 1) + 4;
    00387     if (value == NULL) {
    00388       logger(WARNING, "[ xdrSize() ] null string argument");
    00389       size = 4;
    00390     } else {
    00391       size = strlen(value) + 4;
    00392       /* the length of the XDR representation must be a multiple of 4,
    00393          so there might be some extra bytes added*/
    00394       if (size % 4 != 0)
    00395         size += (4 - size % 4);
    00396       return size;
    00397     }
    00398   }
    00399
    00400   return RET_ERROR;
    00401 }
    00402
    00403 int apmon_utils::sizeEval(int type, char *value) {
    00404
    00405   switch (type) {
    00406 //  case XDR_INT16:
    00407   case XDR_INT32:
    00408   case XDR_REAL32:
    00409     return 4;
    00410 //  case XDR_INT64:
    00411   case XDR_REAL64:
    00412     return 8;
    00413   case XDR_STRING:
    00414     return (strlen(value) + 1);
    00415   }
    00416
    00417   return RET_ERROR;
    00418 }
    00419
    00420
    00421
    00422 void apmon_utils::logParameters(int level, int nParams, char **paramNames,
    00423                      int *valueTypes, char **paramValues) {
    00424   int i;
    00425   char typeNames[][15] = {"XDR_STRING", "", "XDR_INT32", "", "XDR_REAL32",
    00426                  "XDR_REAL64"};
    00427   char logmsg[200], val[100];
    00428
    00429   for (i = 0; i < nParams; i++) {
    00430     if (paramNames[i] == NULL || (valueTypes[i] == XDR_STRING &&
    00431                                   paramValues[i] == NULL))
    00432       continue;
    00433     sprintf(logmsg, "%s (%s) ", paramNames[i], typeNames[valueTypes[i]]);
    00434     //printf("%s () ", paramNames[i]);
    00435     switch(valueTypes[i]) {
    00436     case XDR_STRING:
    00437       sprintf(val, "%s", paramValues[i]);
    00438       break;
    00439     case XDR_INT32:
    00440       sprintf(val, "%d", *(int *)paramValues[i]);
    00441       break;
    00442     case XDR_REAL32:
    00443       sprintf(val, "%f", *(float *)paramValues[i]);
    00444       break;
    00445     case XDR_REAL64:
    00446       sprintf(val, "%f", *(double *)(paramValues[i]));
    00447       break;
    00448     }
    00449     strcat(logmsg, val);
    00450     logger(level, logmsg);
    00451   }
    00452 }
    00453
    00454
    00455 bool apmon_utils::isPrivateAddress(char *addr) {
    00456   char *s1, *s2;
    00457   int n1, n2;
    00458   char tmp[MAX_STRING_LEN];
    00459 //  char buf[MAX_STRING_LEN];
    00460 //  char *pbuf = buf;
    00461
    00462   strcpy(tmp, addr);
    00463   s1 = strtok/*_r*/(tmp,".");//, &pbuf);
    00464   n1 = atoi(s1);
    00465
    00466   s2 = strtok/*_r*/(NULL, ".");//, &pbuf);
    00467   n2 = atoi(s2);
    00468
    00469   if (n1 == 10)
    00470     return true;
    00471   if (n1 == 172 && n2 >= 16 && n2 <= 31)
    00472     return true;
    00473   if (n1 == 192 && n2 == 168)
    00474     return true;
    00475
    00476   return false;
    00477 }
    00478
    00479 int apmon_utils::getVectIndex(char *item, char **vect, int vectDim) {
    00480   int i;
    00481
    00482   for (i = 0; i < vectDim; i++)
    00483     if (strcmp(item, vect[i]) == 0)
    00484       return i;
    00485   return -1;
    00486 }
    00487
    00488 void apmon_utils::logger(int msgLevel, const char *msg, int newLevel) {
    00489   char time_s[30];
    00490   int len;
    00491   long crtTime = time(NULL);
    00492   char *levels[5] = {(char*)"FATAL",
    00493                      (char*)"WARNING",
    00494                      (char*)"INFO",
    00495                      (char*)"FINE",
    00496                      (char*)"DEBUG"};
    00497   static int loglevel = INFO;
    00498 #ifndef WIN32
    00499   static pthread_mutex_t logger_mutex;
    00500 #else
    00501   static HANDLE logger_mutex;
    00502 #endif
    00503   static bool firstTime = true;
    00504
    00505   if (firstTime) {
    00506 #ifndef WIN32
    00507     pthread_mutex_init(&logger_mutex, NULL);
    00508 #else
    00509         logger_mutex = CreateMutex(NULL, FALSE, NULL);
    00510 #endif
    00511     firstTime = false;
    00512   }
    00513
    00514   pthread_mutex_lock(&logger_mutex);
    00515
    00516 #ifndef WIN32
    00517   char cbuf[50];
    00518   strcpy(time_s, ctime_r(&crtTime, cbuf));
    00519 #else
    00520   strcpy(time_s, ctime(&crtTime));
    00521 #endif
    00522   len = strlen(time_s); time_s[len - 1] = 0;
    00523
    00524   if (newLevel >= 0 && newLevel <=4) {
    00525     loglevel = newLevel;
    00526     if (loglevel>=2)
    00527       printf("[TIME: %s] Changed the logging level to %s\n", time_s, levels[newLevel]);
    00528   } else {
    00529     if (msgLevel >= 0 && msgLevel <= 4) {
    00530       if (msgLevel <= loglevel)
    00531         printf("[TIME: %s] [%s] %s\n",time_s, levels[msgLevel], msg);
    00532     } else
    00533       printf("[WARNING] Invalid logging level %d!\n", msgLevel);
    00534   }
    00535   pthread_mutex_unlock(&logger_mutex);
    00536 }