#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pcre.h>
#include "vars.h"

/************************************
 ********* Load PCRE file ***********/

int load_pcre_file(int section)
{
    FILE *fp;
    char tmp[ML_URL],etmp[ML_ETMP];
    const char *errstr; 
    int errchar; 


    //Set pointer
    redir[section]->ban_pcre=NULL;
    redir[section]->ban_pcre_s=NULL;
    redir[section]->ban_pcre_count=0;

    // Load pcre file
    sprintf(tmp,"%s/pcre",redir[section]->ban_dir);

    #ifdef DEBUG_PCRE
    fprintf(stderr,"=== %s ===\n",tmp);
    #endif

    // File exist?
    if (access(tmp,F_OK)) return(1);

    // Open file
    if ((fp=fopen(tmp,"r"))==NULL)
	{ // Open error
          sprintf(etmp,"ERROR: Can't open file %s/pcre: %s, exit",redir[section]->ban_dir,strerror(errno));
          err_mes(etmp);

	  #ifdef DEBUG_PCRE
          fprintf(stderr,"%s\n",tmp);
	  #endif

	  exit(-1);
        }
    // Read file
     while(!feof(fp))
      {
        //Get
        if (fgets(tmp,ML_URL,fp)==NULL) continue;


    	//Chomp
	if (tmp[strlen(tmp)-1]=='\n' || tmp[strlen(tmp)-1]=='\r') tmp[strlen(tmp)-1]=0;
	if (tmp[strlen(tmp)-1]=='\n' || tmp[strlen(tmp)-1]=='\r') tmp[strlen(tmp)-1]=0;
	if (strlen(tmp)<=0) continue;

    	#ifdef DEBUG_PCRE
    	fprintf(stderr,"%s\n",tmp);
    	#endif

        //Add memory line
        redir[section]->ban_pcre=(pcre **)realloc(redir[section]->ban_pcre,(1+redir[section]->ban_pcre_count)*sizeof(pcre *));
        redir[section]->ban_pcre_s=(pcre_extra **)realloc(redir[section]->ban_pcre_s,(1+redir[section]->ban_pcre_count)*sizeof(pcre_extra *));
        if (redir[section]->ban_pcre==NULL || redir[section]->ban_pcre_s==NULL)
            {
             err_mes("Error: Can't allocate memory for pcre\n");
             exit(-1);
            }

       // Compile pattern
       if((redir[section]->ban_pcre[redir[section]->ban_pcre_count]=pcre_compile(tmp,PCRE_CASELESS,&errstr,&errchar,NULL))==NULL)
       {
        sprintf(etmp,"ERROR: Can't compile pattern in %s/pcre line:%i %s",redir[section]->ban_dir,redir[section]->ban_pcre_count+1,errstr);
        err_mes(etmp);
	exit(-1);
       }

       // Optimize pattern ***************/
       redir[section]->ban_pcre_s[redir[section]->ban_pcre_count]=pcre_study(redir[section]->ban_pcre[redir[section]->ban_pcre_count],0,&errstr);    
       redir[section]->ban_pcre_count++;

     }//while

    fclose(fp);

    sprintf(etmp,"Load %i pattern from %s pcre",redir[section]->ban_pcre_count,redir[section]->name);
    err_mes(etmp);
    return (0);
}


/******************************************
 ******** Check url by pcre rules *********/

 int check_pcre(int section)
 {
   int i;
   int vector[ML_PCRE_VARS];
   int vecsize=ML_PCRE_VARS;

    for (i=0;i<redir[section]->ban_pcre_count;i++)

    #ifdef CASE_INDEPENDENT
    if(pcre_exec(redir[section]->ban_pcre[i],redir[section]->ban_pcre_s[i],input_url_uc,strlen(input_url_uc),0,PCRE_NOTEMPTY,vector,vecsize)>=0)
    #else
    if(pcre_exec(redir[section]->ban_pcre[i],redir[section]->ban_pcre_s[i],input_url_un,strlen(input_url_un),0,PCRE_NOTEMPTY,vector,vecsize)>=0)
    #endif
    {
     sprintf(change_reason,"(pcre rule#: %d)",(unsigned char)(i+1));
     return(1);
    }
    return(0);
 }
