Gaudi Framework, version v20r2

Generated: 18 Jul 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 }

Generated at Fri Jul 18 11:59:23 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004