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 }

Generated at Thu Jul 29 10:12:49 2010 for Gaudi Framework, version v21r10p1 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004