#include <stdio.h>
#include <pcre.h>

#define VERSION "3.2.11"
#define DEFAULT_CONFIG "/usr/local/rejik3/redirector.conf"

/*** Print debug info for develop ***/
//#define DEBUG_ERR_MES
//#define DEBUG_CFG
//#define DEBUG_CYCLE
//#define DEBUG_MAKE_CACHE
//#define DEBUG_URLS_LOAD
//#define DEBUG_PCRE
//#define DEBUG_PARSE_URL
//#define DEBUG_PRUNE_URLS
//#define DEBUG_CACHE2URL
//#define DEBUG_WRITE_CACHE
//#define DEBUG_LOAD_CACHE
//#define DEBUG_PARSE_UNPUT
//#define DEBUG_CHECK_URLS
//#define DEBUG_URLS_CMP
//#define DEBUG_RUN_MAKE_CACHE
//#define DEBUG_IP
//#define DEBUG_ID
//#define DEBUG_NEW_URL
//#define DEBUG_RAW_CHANGE
//#define DEBUG_PASS


// Uncoment next line for case independent
//#define CASE_INDEPENDENT

// MAX LENS OF SOME VARS
#define ML_CFG 200
#define ML_FILE_NAME 200
#define ML_ETMP 7168
#define ML_PCRE_VARS 512

#define ML_URL 6144
#define ML_HOST 100
#define ML_IDENT 100
#define ML_METHOD 10


#define ML_PROTOKOL 20
#define ML_DIRS 4096
#define ML_PORT 10
#define ML_2LD 200
#define ML_SUBDOMEN 512

FILE *change_log;

char *input_ident;
char *input_ident_un;
char *input_ip;
char *input_url;
char *input_url_un;

#ifdef CASE_INDEPENDENT
char *input_url_uc;
#endif

char *input_method;
char *input_host;
struct p_url  *i_url;

char *change_reason;


 /*****************************************************************
  *    http://sub.sub.sub.domen2levelname.ru:45433/dir/dir/file   *
  *    |     |           |                  |    |            |   *
  * protocol | subdomen  |   twoleveldomen  |port|    dirs        *
  *****************************************************************/
struct p_url
    {
     char protocol[ML_PROTOKOL];
     char twoleveldomen[ML_2LD];
     char port[ML_PORT];
     char subdomen[ML_SUBDOMEN];
     char dirs[ML_DIRS];
    };

//GLOBAL OPTIONS
char *err_log;   // Error log path
char *chg_log;   // Change log path
char *makecache; // make-cache program

char *work_ip; 	       //Work ip
int  work_ip_count;    //Work ip count
int  work_ip_flag;     //Work ip flag

char *allow_ip; 	//Allow ip
int  allow_ip_count;  	//Allow ip count

char **work_id;	//Work id
int  work_id_count;	//Work id count
int  work_id_flag;	//Work id flag

char **allow_id;	//Allow id
int  allow_id_count;	//Allow id count

char *allow_urls_file;  //Allow urls file name
char **allow_urls;	//Allow urls
int allow_urls_count;	//Allow urls count

char **change_from;      //
char **change_to;        // Change data
int change_count;        //
int raw_change_log_flag; //

int sections_count;    //Count of sections in config

int write_hostname_to_log; // Write hostname to log flag

//SECTIONS OPTIONS
int sections_count;    //Count of sections in config
struct section
     {
	char *name;	        //Header name
	char *ban_dir;		//Ban lists dir
	char *url;		//Url to change
	char revers;		// revers flag

	char **new_url;		// Block of urls
	char *new_url_inset;    // to change with
	int new_url_count;      // change #*# elements

	char log_flag;		//Write to log or not

	char *work_ip; 	        //Work ip
	int  work_ip_count;  	//Work ip count
        int  work_ip_flag;      //Work ip flag

	char *allow_ip; 	//Allow ip
	int  allow_ip_count;  	//Allow ip count

	char **work_id;	        //Work id
	int  work_id_count;	//Work id count
	int  work_id_flag;      //Work id flag

	char **allow_id;	//Allow id
	int  allow_id_count;	//Allow id count

	pcre **ban_pcre;	    	//Ban PCRE patterns
	pcre_extra **ban_pcre_s; 	//Ban PCRE optimization
	int ban_pcre_count;     //Ban PCRE patterns count

	char **ban_urls;	//Ban urls lists area
	int ban_urls_count;	//Counter urls elements

	char action;		// Action for section:
	                        // 0 - redirect
	                        // 1 - pass

     } **redir;

char *now (void);
void err_mes(char*);
void get_opt(char*);

int load_urls(int,char *);
int parse_urls(struct p_url *,char *);
int prune_urls(int);
int cmp_urls(const void *, const void *);
int cache2url(struct p_url *,char *);
int need_cache_update(char*,char*);
int write_cache(int,char*,char*);
int load_cache(char ***,int*,char *);
int load_pcre_file(int);
int check_pcre(int);
int parse_input(char *);
void init_vars(void);
int check_url(char**,int count);
int cmp_urls_bs(const void *, const void *);
int cmp_urls_sub(const void *, const void *);
int cmp_urls_dirs(const void *, const void *);
int cmp_urls_port(const void *, const void *);
int run_make_cache(char*);
int add_ip(char *,char **,int* );
int check_ip(char *,int );
int add_id(char *,char ***,int* );
int sort_id(char ***,int* );
int check_id(char **,int);
int prepare_new_url(int);
int add_new_url (int, char *, int);
int redirect(int);
int raw_change(void);
int pass(void);
