"Fossies" - the Fresh Open Source Software Archive

Member "sarg-2.4.0/exclude.c" (22 Dec 2019, 10352 Bytes) of package /linux/privat/sarg-2.4.0.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. For more information about "exclude.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.11_vs_2.4.0.

    1 /*
    2  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
    3  *                                                            1998, 2015
    4  *
    5  * SARG donations:
    6  *      please look at http://sarg.sourceforge.net/donations.php
    7  * Support:
    8  *     http://sourceforge.net/projects/sarg/forums/forum/363374
    9  * ---------------------------------------------------------------------
   10  *
   11  *  This program is free software; you can redistribute it and/or modify
   12  *  it under the terms of the GNU General Public License as published by
   13  *  the Free Software Foundation; either version 2 of the License, or
   14  *  (at your option) any later version.
   15  *
   16  *  This program is distributed in the hope that it will be useful,
   17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19  *  GNU General Public License for more details.
   20  *
   21  *  You should have received a copy of the GNU General Public License
   22  *  along with this program; if not, write to the Free Software
   23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   24  *
   25  */
   26 
   27 #include "include/conf.h"
   28 #include "include/defs.h"
   29 
   30 struct hostip4struct
   31 {
   32     //! The IP address.
   33     unsigned long int address;
   34     //! The mask to match the address of the URL.
   35     unsigned long int mask;
   36 };
   37 
   38 struct hostip6struct
   39 {
   40     //! The IP address.
   41     unsigned short int address[8];
   42     //! The number of bits in the prefix.
   43     int nbits;
   44 };
   45 
   46 struct hostnamestruct
   47 {
   48     //! The URL to match without any leading wildcard.
   49     char *url;
   50     //! The number of dots in the url if a wildcard is present or -1 if the address is complete (no wildcard)
   51     int ndots;
   52 };
   53 
   54 static struct hostip4struct *exclude_ip4=NULL;
   55 static int num_exclude_ip4=0;
   56 static struct hostip6struct *exclude_ip6=NULL;
   57 static int num_exclude_ip6=0;
   58 static struct hostnamestruct *exclude_name=NULL;
   59 static int num_exclude_name=0;
   60 static int ip4allocated=0;
   61 static int ip6allocated=0;
   62 static int nameallocated=0;
   63 
   64 static char *excludeuser=NULL;
   65 
   66 /*!
   67   Store a IPv4 address to exclude from the reported URL.
   68 
   69   \param addr The 4 char of the address.
   70   \param nbits The number of bits to keep in the prefix.
   71  */
   72 static void store_exclude_ip4(unsigned char *addr,int nbits)
   73 {
   74     int i;
   75 
   76     if (num_exclude_ip4>=ip4allocated) {
   77         struct hostip4struct *temp;
   78 
   79         ip4allocated+=5;
   80         temp=realloc(exclude_ip4,ip4allocated*sizeof(*temp));
   81         if (temp==NULL) {
   82             debuga(__FILE__,__LINE__,_("Not enough memory to store the exlcluded IP addresses\n"));
   83             exit(EXIT_FAILURE);
   84         }
   85         exclude_ip4=temp;
   86     }
   87     exclude_ip4[num_exclude_ip4].address=0UL;
   88     for (i=0 ; i<4 ; i++)
   89         exclude_ip4[num_exclude_ip4].address=(exclude_ip4[num_exclude_ip4].address<<8) | (unsigned char)(addr[i] & 0xFFU);
   90     exclude_ip4[num_exclude_ip4].mask=(0xFFFFFFFFUL << (32-nbits));
   91     num_exclude_ip4++;
   92 }
   93 
   94 /*!
   95   Store a IPv6 address to exclude from the reported URL.
   96 
   97   \param addr The 8 short int of the address.
   98   \param nbits The number of bits to keep in the prefix.
   99  */
  100 static void store_exclude_ip6(unsigned short *addr,int nbits)
  101 {
  102     int i;
  103 
  104     if (num_exclude_ip6>=ip6allocated) {
  105         struct hostip6struct *temp;
  106 
  107         ip6allocated+=5;
  108         temp=realloc(exclude_ip6,ip6allocated*sizeof(*temp));
  109         if (temp==NULL) {
  110             debuga(__FILE__,__LINE__,_("Not enough memory to store the exlcluded IP addresses\n"));
  111             exit(EXIT_FAILURE);
  112         }
  113         exclude_ip6=temp;
  114     }
  115     for (i=0 ; i<8 ; i++)
  116         exclude_ip6[num_exclude_ip6].address[i]=addr[i];
  117     exclude_ip6[num_exclude_ip6].nbits=nbits;
  118     num_exclude_ip6++;
  119 }
  120 
  121 /*!
  122   Store a host name to exclude from the report.
  123 
  124   \param url The host name to exclude.
  125  */
  126 static void store_exclude_url(const char *url,const char *next)
  127 {
  128     int start;
  129     int i;
  130     int length;
  131     int ndots, firstdot;
  132     struct hostnamestruct *item;
  133 
  134     start=0;
  135     ndots=-1;
  136     firstdot=0;
  137     length=next-url;
  138     for (i=0 ; i<length ; i++)
  139         if (url[i]=='*') {
  140             firstdot=1;
  141         } else if (url[i]=='.') {
  142             if (firstdot) {
  143                 firstdot=0;
  144                 ndots=1;
  145                 start=i+1;
  146             } else if (ndots>=0)
  147                 ndots++;
  148         }
  149     if (start>=length || firstdot) return;
  150     if (start>0) {
  151         url+=start;
  152         length-=start;
  153     }
  154 
  155     if (num_exclude_name>=nameallocated) {
  156         struct hostnamestruct *temp;
  157 
  158         nameallocated+=5;
  159         temp=realloc(exclude_name,nameallocated*sizeof(*temp));
  160         if (temp==NULL) {
  161             debuga(__FILE__,__LINE__,_("Not enough memory to store the excluded URLs\n"));
  162             exit(EXIT_FAILURE);
  163         }
  164         exclude_name=temp;
  165     }
  166 
  167     item=exclude_name+num_exclude_name;
  168     num_exclude_name++;
  169     item->url=malloc(length+1);
  170     if (!item->url) {
  171         debuga(__FILE__,__LINE__,_("Not enough memory to store the excluded URLs\n"));
  172         exit(EXIT_FAILURE);
  173     }
  174     safe_strcpy(item->url,url,length+1);
  175     item->ndots=(ndots>0) ? ndots : -1;
  176 }
  177 
  178 /*!
  179   Read the file listing the host to exclude from the report.
  180 
  181   \param hexfile The name of the file.
  182   \param debug \c True to print debug information.
  183  */
  184 void gethexclude(const char *hexfile, int debug)
  185 {
  186     FILE *fp_ex;
  187     char buf[255];
  188     int type;
  189     const char *name;
  190     unsigned char ipv4[4];
  191     unsigned short int ipv6[8];
  192     int nbits;
  193     const char *next;
  194 
  195     if (access(hexfile, R_OK) != 0) {
  196         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),hexfile,strerror(errno));
  197         exit(EXIT_FAILURE);
  198     }
  199     if (debug)
  200         debuga(__FILE__,__LINE__,_("Loading exclude host file from \"%s\"\n"),hexfile);
  201 
  202     if ((fp_ex = fopen(hexfile, "r")) == NULL) {
  203         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),hexfile,strerror(errno));
  204         exit(EXIT_FAILURE);
  205     }
  206 
  207     while(fgets(buf,sizeof(buf),fp_ex)!=NULL){
  208         if (buf[0]=='#')
  209             continue;
  210         fixendofline(buf);
  211 
  212         type=extract_address_mask(buf,&name,ipv4,ipv6,&nbits,&next);
  213         if (type<0) {
  214             debuga(__FILE__,__LINE__,_("While reading \"%s\"\n"),hexfile);
  215             exit(EXIT_FAILURE);
  216         }
  217 
  218         if (type==1) {
  219             store_exclude_url(name,next);
  220         } else if (type==2) {
  221                 store_exclude_ip4(ipv4,nbits);
  222         } else if (type==3) {
  223                 store_exclude_ip6(ipv6,nbits);
  224         }
  225     }
  226 
  227     if (fclose(fp_ex)==EOF) {
  228         debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),hexfile,strerror(errno));
  229         exit(EXIT_FAILURE);
  230     }
  231     return;
  232 }
  233 
  234 /*!
  235   Check if the URL is excluded as per the host exclusion list.
  236 
  237   \param url The URL to check.
  238 
  239   \retval 1 Keep the URL.
  240   \retval 0 Exclude the URL.
  241  */
  242 int vhexclude(const char *url)
  243 {
  244     int i, j;
  245     int length;
  246     int type;
  247     const char *name;
  248     unsigned char ipv4[4];
  249     unsigned short int ipv6[8];
  250     unsigned long int addr4;
  251     int dotpos[50];
  252     int ndots;
  253 
  254     type=extract_address_mask(url,&name,ipv4,ipv6,NULL,NULL);
  255     if (type==1) {
  256         if (exclude_name == NULL) return(1);
  257         ndots=0;
  258         for (length=0 ; (unsigned char)name[length]>' ' && name[length]!=':' && name[length]!='/' && name[length]!='?' ; length++)
  259             if (name[length]=='.') {
  260                 /*
  261                 We store the position of each dots of the URL to match it against any
  262                 wildcard in the excluded list. The size of dotpos is big enough for the most
  263                 ambitious URL but we have a safety mechanism that shift the positions should there be too
  264                 many dots in the URL.
  265                 */
  266                 if (ndots<sizeof(dotpos)/sizeof(dotpos[0]))
  267                     dotpos[ndots++]=length+1;
  268                 else {
  269                     for (j=1 ; j<ndots ; j++) dotpos[j-1]=dotpos[j];
  270                     dotpos[ndots-1]=length+1;
  271                 }
  272             }
  273         if (length>0) {
  274             for (i=0 ; i<num_exclude_name ; i++) {
  275                 if (exclude_name[i].ndots>0) {
  276                     const char *wurl=name;
  277                     int len=length;
  278                     if (exclude_name[i].ndots<=ndots) {
  279                         wurl+=dotpos[ndots-exclude_name[i].ndots];
  280                         len-=dotpos[ndots-exclude_name[i].ndots];
  281                     }
  282                     if (strncmp(exclude_name[i].url,wurl,len)==0 && exclude_name[i].url[len]=='\0') return(0);
  283                 } else {
  284                     if (strncmp(exclude_name[i].url,url,length)==0 && exclude_name[i].url[length]=='\0') return(0);
  285                 }
  286             }
  287         }
  288     } else if (type==2) {
  289         if (exclude_ip4 == NULL) return(1);
  290         addr4=0UL;
  291         for (i=0 ; i<4 ; i++) addr4=(addr4 << 8) | ipv4[i];
  292         for (i=0 ; i<num_exclude_ip4 ; i++) {
  293             if (((exclude_ip4[i].address ^ addr4) & exclude_ip4[i].mask)==0) return(0);
  294         }
  295     } else if (type==3) {
  296         if (exclude_ip6 == NULL) return(1);
  297         for (i=0 ; i<num_exclude_ip6 ; i++) {
  298             length=exclude_ip6[i].nbits;
  299             for (j=length/16-1 ; j>=0 && ipv6[j]==exclude_ip6[i].address[j] ; j--);
  300             if (j>=0) return(1);
  301             j=length/16;
  302             if (j>=8 || length%16==0 || ((ipv6[j] ^ exclude_ip6[i].address[j]) & (0xFFFF<<(length-j*16)))==0)
  303                 return(0);
  304         }
  305     }
  306     return(1);
  307 }
  308 
  309 
  310 void getuexclude(const char *uexfile, int debug)
  311 {
  312     FILE *fp_ex;
  313     char buf[255];
  314     long int nreg=0;
  315 
  316     if (debug)
  317         debuga(__FILE__,__LINE__,_("Loading exclude file from \"%s\"\n"),uexfile);
  318 
  319     if ((fp_ex = fopen(uexfile, "r")) == NULL) {
  320         debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),uexfile,strerror(errno));
  321         exit(EXIT_FAILURE);
  322     }
  323 
  324     if (fseek(fp_ex, 0, SEEK_END)==-1) {
  325         debuga(__FILE__,__LINE__,_("Failed to move till the end of file \"%s\": %s\n"),uexfile,strerror(errno));
  326         exit(EXIT_FAILURE);
  327     }
  328     nreg = ftell(fp_ex);
  329     if (nreg<0) {
  330         debuga(__FILE__,__LINE__,_("Cannot get the size of file \"%s\"\n"),uexfile);
  331         exit(EXIT_FAILURE);
  332     }
  333     nreg += 11;
  334     if (fseek(fp_ex, 0, SEEK_SET)==-1) {
  335         debuga(__FILE__,__LINE__,_("Failed to rewind file \"%s\": %s\n"),uexfile,strerror(errno));
  336         exit(EXIT_FAILURE);
  337     }
  338 
  339     if ((excludeuser=(char *) malloc(nreg))==NULL){
  340         debuga(__FILE__,__LINE__,_("malloc error (%ld bytes required)\n"),nreg);
  341         exit(EXIT_FAILURE);
  342     }
  343 
  344     memset(excludeuser,0,nreg);
  345 
  346     while(fgets(buf,sizeof(buf),fp_ex)!=NULL){
  347         if (strchr(buf,'#') != NULL)
  348             continue;
  349         fixendofline(buf);
  350         strcat(excludeuser,buf);
  351         strcat(excludeuser," ");
  352     }
  353 
  354     strcat(excludeuser,"*END* ");
  355 
  356     if (fclose(fp_ex)==EOF) {
  357         debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),uexfile,strerror(errno));
  358         exit(EXIT_FAILURE);
  359     }
  360 
  361     return;
  362 }
  363 
  364 int vuexclude(const char *user)
  365 {
  366     const char *wuser;
  367     int len;
  368 
  369     if (excludeuser) {
  370         len=strlen(user);
  371         wuser=excludeuser;
  372         while ((wuser=strstr(wuser,user))!=NULL) {
  373             if (wuser[len]==' ') return(0);
  374             wuser+=len;
  375         }
  376     }
  377 
  378     return(1);
  379 }
  380 
  381 bool is_indexonly(void)
  382 {
  383     if (excludeuser==NULL) return(false);
  384     return(strstr(excludeuser,"indexonly") != NULL);
  385 }
  386 
  387 void free_exclude(void)
  388 {
  389     int i;
  390 
  391     if (exclude_ip4) {
  392         free(exclude_ip4);
  393         exclude_ip4=NULL;
  394     }
  395 
  396     if (exclude_name) {
  397         for (i=0 ; i<num_exclude_name ; i++)
  398             if (exclude_name[i].url) free(exclude_name[i].url);
  399         free(exclude_name);
  400         exclude_name=NULL;
  401     }
  402 
  403     if (excludeuser) {
  404         free(excludeuser);
  405         excludeuser=NULL;
  406     }
  407 }