| # 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