"Fossies" - the Fresh Open Source Software Archive

Member "srg-1.3.6/src/utils.cc" (5 Aug 2009, 13438 Bytes) of package /linux/privat/old/srg-1.3.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2     SRG - Squid Report Generator
    3     Copyright 2005 University of Waikato
    4 
    5     This file is part of SRG.
    6 
    7     SRG is free software; you can redistribute it and/or modify
    8     it under the terms of the GNU General Public License as published by
    9     the Free Software Foundation; either version 2 of the License, or
   10     (at your option) any later version.
   11 
   12     SRG is distributed in the hope that it will be useful,
   13     but WITHOUT ANY WARRANTY; without even the implied warranty of
   14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15     GNU General Public License for more details.
   16 
   17     You should have received a copy of the GNU General Public License
   18     along with SRG; if not, write to the Free Software
   19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   20 
   21 */
   22 #include "srg.h"
   23 #include "config.h"
   24 #include "prototypes.h"
   25 
   26 /* Compares two date strings of the format YYYYMMMDD-YYYYMMDD. Returns true if
   27  * date1 is less than date2.
   28  * Dates are compared on the start date first and then the end date if
   29  * necessary
   30  */
   31 int compare_datename(const char *date1, const char *date2)
   32 {
   33     
   34     int rv=0;
   35     char tmp1[10];
   36     char tmp2[10];
   37 
   38     /* Exit Immediately if we weren't passed valid dates */
   39     if(date1==NULL || date2==NULL)
   40         return -1;
   41     if (strlen(date1) != 19 || strlen(date2) != 19)
   42         return -1;
   43 
   44     /* Extract the start dates */
   45     strncpy(tmp1, date1, 9);
   46     strncpy(tmp2, date2, 9);
   47     tmp1[9] = tmp2[9] = '\0';
   48     
   49     rv = compare_datepart(tmp1, tmp2);
   50     
   51     /* If start dates were identical, compare end dates */
   52     if (rv==0) {
   53         strncpy(tmp1, date1+10, 9);
   54         strncpy(tmp2, date2+10, 9);
   55         tmp1[9] = tmp2[9] = '\0';
   56     
   57         rv = compare_datepart(tmp1, tmp2);
   58     }
   59 
   60     /* Convert greater than to false */
   61     if (rv==-1)
   62         rv=0;
   63     
   64     return rv;
   65     
   66 }
   67 
   68 /* Compares two date strings of the format YYYYMMMDD. Returns true if date1 is
   69  * less than date2 false if they are equal or -1 if date1 is greater than 
   70  * date2.
   71  */
   72 int compare_datepart(const char *date1, const char *date2) {
   73 
   74     char year1[5], year2[5];
   75     char month1[4], month2[4];
   76     char day1[3], day2[3];
   77     int month1_num, month2_num;
   78     
   79     /* Exit Immediately if we weren't passed valid dates */
   80     if(date1==NULL || date2==NULL)
   81         return -1;
   82     if (strlen(date1) != 9 || strlen(date2) != 9)
   83         return -1;
   84     
   85     /* Break the start dates out into their components */
   86     strncpy(year1, date1, 4);
   87     year1[4] = '\0';
   88     strncpy(month1, date1+4, 3);
   89     month1[3] = '\0';
   90     strncpy(day1, date1+7, 2);
   91     day1[2] = '\0';
   92     strncpy(year2, date2, 4);
   93     year2[4] = '\0';
   94     strncpy(month2, date2+4, 3);
   95     month2[3] = '\0';
   96     strncpy(day2, date2+7, 2);
   97     day2[2] = '\0';
   98 
   99     /* Compare Years */
  100     if (atoi(year1) < atoi(year2))
  101         return 1;
  102     else if (atoi(year1) > atoi(year2))
  103         return -1;
  104     
  105     month1_num = getMonthByName(month1);
  106     month2_num = getMonthByName(month2);
  107     /* Compare Months */
  108     if (month1_num < month2_num)
  109         return 1;
  110     else if (month1_num > month2_num)
  111         return -1;
  112     
  113     /* Compare Days */
  114     if (atoi(day1) < atoi(day2))
  115         return 1;
  116     else if (atoi(day1) > atoi(day2))
  117         return -1;
  118     
  119     /* Greater than or Equal */
  120     return 0;
  121 }
  122 
  123 /* Generates a suitable date string from the specified start and end times.
  124  * The generated string will be in the format YYYYMMMDD-YYYYMMDD and will be
  125  * asprintf'd in to the supplied char* 
  126  *
  127  * Returns 0 on success, > 0 on failure
  128  */
  129 char *generate_datename(const time_t start, const time_t end) {
  130 
  131     if (start < 1 || end < 1)
  132         return NULL;
  133 
  134     char *outstr = NULL;
  135     char sday[3];
  136     char eday[3];
  137     sprintf(sday, "%02d", localtime(&start)->tm_mday);
  138     sprintf(eday, "%02d", localtime(&end)->tm_mday);
  139     asprintf(&outstr, "%d%s%s-%d%s%s", localtime(&start)->tm_year+1900, 
  140             month_names[localtime(&start)->tm_mon], sday,
  141             localtime(&end)->tm_year+1900, 
  142             month_names[localtime(&end)->tm_mon], eday);
  143 
  144     return outstr;  
  145 }
  146 
  147 /* Parses a string in the format YYYY-MM-DD:HH:MM:SS into a unix timestamp 
  148  *
  149  * Only YYYY-MM-DD is required. The rest is optional.
  150  * 
  151  * Returns the timestamp on success, (time_t)-1 on failure
  152  */
  153 time_t parse_timestring(const char *tstring)
  154 {
  155 
  156     struct tm rTime;
  157     char *tDate=NULL;
  158     char *tTime=NULL;
  159     char *tmp=NULL;
  160 
  161     /* Clear memory */
  162     bzero((void *)&rTime, sizeof(struct tm));
  163     rTime.tm_isdst = -1;
  164 
  165     /* Extract date and time parts */
  166     tmp = strdup(tstring);
  167     tTime = break_string(tmp, ':');
  168     tDate = tmp;
  169     
  170     /* Parse the date part */
  171     if (strlen(tDate)!=10) {
  172         fprintf(stderr, "%s: %s is not a valid date!\n", progname, tDate);
  173         free(tmp);
  174         return (time_t)-1;
  175     }
  176     if (sscanf(tDate, "%u-%u-%u", &rTime.tm_year, &rTime.tm_mon, 
  177                 &rTime.tm_mday) != 3) {
  178         fprintf(stderr, "%s: could not parse %s to a valid date!\n",
  179                     progname, tDate);
  180         free(tmp);
  181         return (time_t)-1;
  182     }
  183     /* Conversions */
  184     rTime.tm_year -= 1900;  // tm_year is years since 1900
  185     rTime.tm_mon -= 1;      // tm_mon starts at 0 for Jan
  186     
  187     /* If no time part is present return now */
  188     if (tTime==NULL) {
  189         free(tmp);
  190         return mktime(&rTime);
  191     }
  192 
  193     /* Otherwise parse the time part too */
  194     if (strlen(tTime)!=8) {
  195         fprintf(stderr, "%s: %s is not a valid time!\n", progname, tTime);
  196         free(tmp);
  197         return (time_t)-1;
  198     }
  199     if (sscanf(tTime, "%u:%u:%u", &rTime.tm_hour, &rTime.tm_min, 
  200                 &rTime.tm_sec)!=3) {
  201         fprintf(stderr, "%s: could not parse %s to a valid time!\n", progname,
  202                 tTime);
  203         exit(1);
  204     }
  205 
  206     /* Return it */
  207     return mktime(&rTime);
  208     
  209 }
  210 
  211 /* Determines whether the specified Cache Result Code is a cache hit */
  212 bool is_cache_hit(const char * inputCode) {
  213 
  214     // Extract the result code from the status code
  215     bool hit=false;
  216     char *resultCode;
  217     char *tmp = strdup(inputCode);
  218 
  219     break_string(tmp, '/');
  220     resultCode = tmp;
  221     if (!resultCode) {
  222         fprintf(stderr, "Incorrect result code! %s\n", inputCode);
  223         exit(1);
  224     }
  225 
  226     if (srg.debug)
  227         fprintf(stderr, "Checking if %s is a cache hit\n", 
  228             inputCode);
  229 
  230     if (strcasecmp(resultCode, "TCP_HIT")==0)
  231         hit = true;
  232     else if (strcasecmp(resultCode, "TCP_REFRESH_HIT")==0)
  233         hit = true;
  234     else if (strcasecmp(resultCode, "TCP_REF_FAIL_HIT")==0)
  235         hit = true;
  236     else if (strcasecmp(resultCode, "TCP_IMS_HIT")==0)
  237         hit = true;
  238     else if (strcasecmp(resultCode, "TCP_NEGATIVE_HIT")==0)
  239         hit = true;
  240     else if (strcasecmp(resultCode, "TCP_MEM_HIT")==0)
  241         hit = true;
  242     else if (strcasecmp(resultCode, "TCP_OFFLINE_HIT")==0)
  243         hit = true;
  244     else if (strcasecmp(resultCode, "UDP_HIT")==0)
  245         hit = true;
  246 
  247     resultCode = NULL;
  248     free(tmp);
  249 
  250     return hit;
  251 
  252 }
  253 
  254 /* Determines whether the specified Cache Result Code was a deny */
  255 bool is_cache_denied(const char * inputCode) {
  256 
  257     // Extract the result code from the status code
  258     bool denied=false;
  259     char *resultCode;
  260     char *tmp = strdup(inputCode);
  261 
  262     break_string(tmp, '/');
  263     resultCode = tmp;
  264     if (!resultCode) {
  265         fprintf(stderr, "Incorrect result code! %s\n", inputCode);
  266         exit(1);
  267     }
  268 
  269     if (srg.debug)
  270         fprintf(stderr, "Checking if %s is a cache denied\n", 
  271             inputCode);
  272 
  273     if (strcasecmp(resultCode, "TCP_DENIED")==0)
  274         denied = true;
  275     else if (strcasecmp(resultCode, "UDP_DENIED")==0)
  276         denied = true;
  277 
  278     resultCode = NULL;
  279     free(tmp);
  280 
  281     return denied;
  282 
  283 }
  284 
  285 /* Converts a short 3-char month abbreviation into it's numerical equivalent */
  286 int getMonthByName(const char *month_name) {
  287 
  288     if (strcmp(month_name,"Jan")==0) 
  289         return 0;
  290     else if (strcmp(month_name,"Feb")==0) 
  291         return 1;
  292     else if (strcmp(month_name,"Mar")==0) 
  293         return 2;
  294     else if (strcmp(month_name,"Apr")==0) 
  295         return 3;
  296     else if (strcmp(month_name,"May")==0) 
  297         return 4;
  298     else if (strcmp(month_name,"Jun")==0) 
  299         return 5;
  300     else if (strcmp(month_name,"Jul")==0) 
  301         return 6;
  302     else if (strcmp(month_name,"Aug")==0) 
  303         return 7;
  304     else if (strcmp(month_name,"Sep")==0) 
  305         return 8;
  306     else if (strcmp(month_name,"Oct")==0) 
  307         return 9;
  308     else if (strcmp(month_name,"Nov")==0) 
  309         return 10;
  310     else if (strcmp(month_name,"Dec")==0) 
  311         return 11;  
  312 
  313     assert(0);  
  314     return -1;
  315 }
  316 
  317 unsigned int getNumericalIP(const char *IPAddress) {
  318 
  319     unsigned int address=0;
  320 
  321     /* Get the four components of the IP Address */
  322     unsigned int o1, o2, o3, o4;
  323     if (sscanf(IPAddress, "%i.%i.%i.%i", &o1, &o2, &o3, &o4) != 4) {
  324         fprintf(stderr, "Invalid IP Address: %s\n", IPAddress);
  325         exit(1);
  326     }
  327     assert(o1<256 && o2 <256 && o3<256 && o4<256);
  328     /* Convert it to decimal */
  329     address = (o1<<24)&(o2<<16)&(o3<<8)&(o4);
  330 
  331     return address;
  332 
  333 }
  334 
  335 char *getStringIP(const unsigned int IPAddress) {
  336 
  337     char *address;
  338     
  339     asprintf(&address, "%i.%i.%i.%i", (IPAddress>>24)&0xff, 
  340             (IPAddress>>16)&0xff, (IPAddress>>8)&0xff, (IPAddress)&0xff);
  341 
  342     return address;
  343 
  344 }
  345 
  346 void getNetworkAddress(const in_addr clientAddress, 
  347         const in_addr netmask, in_addr *network) {
  348 
  349     network->s_addr = ((clientAddress.s_addr|(~netmask.s_addr))&
  350             netmask.s_addr);
  351 
  352 }
  353 
  354 char * cleanseStr(char * dirty) {
  355     
  356     for (unsigned int i = 0; i < strlen(dirty); i++) {
  357         if (dirty[i] == ' ' || dirty[i] == '\t' || dirty[i] == '\n') {
  358             dirty[i] = '_';
  359         } else {
  360             switch(dirty[i]) {
  361                 case '/': dirty[i] = '^'; break;
  362                 case '.': dirty[i] = '_'; break;
  363                 case '?': dirty[i] = '^'; break;
  364                 case '|': dirty[i] = '^'; break;
  365                 case '&': dirty[i] = '^'; break;
  366                 case ';': dirty[i] = '^'; break;
  367                 case '(': dirty[i] = '^'; break;
  368                 case ')': dirty[i] = '^'; break;
  369                 case '*': dirty[i] = '^'; break;                         
  370                 case '@': dirty[i] = '^'; break;
  371                 case '$': dirty[i] = '^'; break;
  372                 case '`': dirty[i] = '^'; break;
  373                 case '"': dirty[i] = '^'; break;
  374                 case '#': dirty[i] = '^'; break;
  375                 case '!': dirty[i] = '^'; break;
  376                 case '[': dirty[i] = '^'; break;
  377                 case ']': dirty[i] = '^'; break;
  378                 //dirty.insert(i-1, "\\"); break; <- no good
  379             }
  380         }
  381     }
  382     return dirty;
  383 
  384 }
  385 
  386 char * FormatOutput(unsigned long long num) {
  387 
  388     int SrcLen;
  389     int ExtLen;
  390     int c;
  391     int d;
  392     int grp;
  393     int group = 3;
  394     char sep_char = ',';
  395     char buf[50];
  396     sprintf(buf, "%llu", num);
  397 
  398     SrcLen  = strlen(buf)-1;
  399     ExtLen  = SrcLen+(SrcLen/group);
  400 
  401     char *Work = (char *)malloc(ExtLen+2);
  402 
  403     grp = 0;
  404     c   = ExtLen;
  405     d   = SrcLen;
  406     if (c > grp) {
  407         while (c >= 0) {
  408             if (grp == group) {
  409                 Work[c]= sep_char;
  410                 --c;
  411                 grp = 0;
  412             }
  413             Work[c] = buf[d];
  414             --c;
  415             --d;
  416             ++grp;
  417         }
  418         Work[ExtLen+1] = '\0';
  419     } else {
  420         free(Work);
  421         Work = strdup(buf);
  422     }
  423 
  424     return Work;
  425 
  426 }
  427 
  428 /* Return the MD5 Hash of the specified string */
  429 char *md5this(const char plaintextstr[])
  430 {
  431     
  432     md5_state_t hash_state;
  433     md5_byte_t digest[16];
  434     char hex_output[64];
  435     int di;
  436 
  437     md5_init(&hash_state);
  438     md5_append(&hash_state, (const md5_byte_t *) plaintextstr, 
  439             strlen(plaintextstr));
  440     md5_finish(&hash_state, digest);
  441 
  442     for (di = 0; di < 16; ++di) {
  443         sprintf(hex_output + di*2, "%02x", digest[di]);
  444     }
  445 
  446     return strdup(hex_output);
  447 
  448 }
  449 
  450 /* Replaces the first occurence of delim with a null character and returns a 
  451  * pointer to the next character after it or NULL if there is no more string 
  452  * left. */
  453 char *break_string(char *string, char delim) 
  454 {
  455 
  456     unsigned int i=0;
  457     bool delimfound=false;
  458 
  459     while (string[i] != '\0') {
  460         if (string[i] == delim) {
  461             string[i] = '\0';
  462             delimfound = true;
  463         }
  464         i++;
  465         if (delimfound) {
  466             return &string[i];
  467         }
  468     }
  469 
  470     return NULL;
  471 
  472 }
  473 /* Checks whether the specified file is "present".
  474  *
  475  * This function takes into account both the existance of the file
  476  * and a special version string to be found on the first line in determining
  477  * whether a file is "present" or not. 
  478  *
  479  * If a file exists on the filesystem, but the versionkey string is not found
  480  * on the first line the file is assumed to be user modified. If the versionkey
  481  * string is found, but the version immediately following it does not match the
  482  * version of the executable the file is "not present" and will be replaced.
  483  *
  484  * Returns 0 (false), 1 (true)
  485  * 
  486  */
  487 int file_present(const char *filename, const char *versionkey)
  488 {
  489 
  490     char tfilename[1024] = {'\0'};
  491     char fileversion[100] = {'\0'};
  492     int rv=0;
  493     
  494     /* Location of file */
  495     snprintf(&tfilename[0], 1023, "%s/%s", srg.outputDir, filename);
  496 
  497     /* Check if file is present */
  498     rv = access(tfilename, R_OK);
  499     if (rv==-1 && errno==ENOENT) {
  500         /* No file present */
  501         return 0;
  502     }
  503 
  504     /* file present, can be read, check if it needs updating */
  505     get_file_version(tfilename, versionkey, &fileversion[0], 99);
  506 
  507     if (strlen(fileversion)<=0) {
  508         /* Version could not be retrieved, assume modified file present */
  509         return 1;
  510     }
  511     
  512     /* Check version matches current program */
  513     if (strcasecmp(version, fileversion)==0) {
  514         return 1;
  515     } else {
  516         return 0;
  517     }
  518     
  519 }
  520 
  521 /* Retrieve the file version.
  522  *
  523  * The file version is found immediately following the versionkey string
  524  * on the first line of the file. If the versionkey string cannot be found
  525  * the file is modified and no version is returned. 
  526  */
  527 void get_file_version(const char *filename, const char *versionkey, 
  528         char *fileversion, int fvlen)
  529 {
  530 
  531     FILE *fp = NULL;
  532     char lbuf[1024] = {'\0'};
  533     char *vstart = NULL;
  534     char *space = NULL;
  535     
  536     /* Open the file */
  537     fp = fopen(filename, "r");
  538     if (!fp)
  539         return;
  540 
  541     /* Read the first line */
  542     if (!fgets(&lbuf[0], 1023, fp)) {
  543         fclose(fp);
  544         return;
  545     }
  546     fclose(fp);
  547 
  548     /* Look for the versionkey string in the first line */
  549     vstart = strstr(lbuf, versionkey);
  550     if (vstart == NULL)
  551         return;
  552     
  553     /* Skip the version key, position at start of version */
  554     vstart += strlen(versionkey);
  555     
  556     /* Look for a space after the version */
  557     space = strstr(vstart, " ");
  558     if (space == NULL) {
  559         /* Check for newline instead */
  560         space = strstr(vstart, "\n");
  561         if (space == NULL)
  562             return;
  563     }
  564 
  565     /* Copy version into string to be returned */
  566     strncpy(&fileversion[0], vstart, fvlen);
  567 
  568     return;
  569             
  570 }
  571 
  572