Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011

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

Generated at Fri Sep 2 2011 16:24:46 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004