/* -- NB -- This code has been modified from the original
 * Internet Junkbuster Proxy (TM) - see attached 'README' file for details
 */

/* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
 * Distributed under the GNU General Public License; see the README file.
 * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
 */

#include "zlib.h"	/*  For gzFile data type */

#define GPC		0x0001
#define CON		0x0002
#define IO		0x0004
#define HDR		0x0008
#define LOG		0x0010

#define DEBUG(X)	(debug & X)
#define freez(X)	if(X) free(X); X = NULL

#define VERSION_MAJOR "2"
#define VERSION_MINOR "0"
#define VERSION_POINT "2"

#define VERSION VERSION_MAJOR "." VERSION_MINOR "." VERSION_POINT

extern int debug;

extern FILE *logfp;

extern char *prog;

extern char *blockfile;
extern char *cookiefile;
extern char *trustfile;
extern char *forwardfile;
extern char *aclfile;

extern char *jarfile;
extern FILE *jar;

extern char *referrer;
extern char *uagent;
extern char *from;

extern struct list       wafer_list[];
extern struct list        xtra_list[];
extern struct list       trust_info[];
extern struct url_spec * trust_list[];

extern int add_forwarded;

typedef struct http_request	*dummy_predecl1;
typedef struct client_state	*dummy_predecl2;
typedef struct block_spec	*dummy_predecl3;

struct gateway {
	/* generic attributes */
        char *name;
        int (*conn)(
		struct gateway *gw,
		struct http_request *http,
		struct client_state *csp);
        int   type;

	/* domain specific attributes */
        char *gateway_host;
        int   gateway_port;

	char *forward_host;
	int   forward_port;
};

struct proxy_args {
	char *header;
	char *invocation;
	char *gateways;
	char *trailer;
};

struct iob {
	char *buf;
	char *cur;
	char *eod;
};

struct http_request {
	char *cmd;
	char *gpc;
	char *host;
	int   port;
	char *path;
	char *ver;
	char *hostport; /* "host[:port]" */
	int   ssl;
};

struct list {
	char *str;
	struct list *last;
	struct list *next;
};

#define IOB_PEEK(CSP) ((CSP->iob->cur > CSP->iob->eod) ? (CSP->iob->eod - CSP->iob->cur) : 0)
#define IOB_RESET(CSP) if(CSP->iob->buf) free(CSP->iob->buf); memset(CSP->iob, '\0', sizeof(CSP->iob));

struct client_state {
	int  send_user_cookie;
	int  accept_server_cookie;
	int  cfd;
	int  sfd;
	char *ip_addr_str;
	long  ip_addr_long;
	char *referrer;

	struct gateway *gw;
	struct http_request http[1];

	struct iob iob[1];

	struct list headers[1];
	struct list cookie_list[1];
	char   *x_forwarded;

	int active;

	int compressing_content;
	int gz_debug_fd;
	z_stream *gz_stream;	/* compression stream */
	z_stream gz_stream_struct;
	char *gz_buffer;
	int gz_buffer_size;
	uLong gz_crc;     /* crc32 of uncompressed data */

	/* files associated with this client */
	struct file_list *alist;
	struct file_list *blist;
	struct file_list *clist;
	struct file_list *tlist;
	struct file_list *flist;

	struct client_state *next;
};

extern struct client_state clients[];

extern char *remote_ip_str;
extern long  remote_ip_long;

struct parsers {
	char *str;
	char  len;
	char *(*parser)(
		struct parsers *v,
		char *s,
		struct client_state *csp);
};

struct interceptors {
	char *str;
	char  len;
	char *(*interceptor)(
		struct http_request *http,
		struct client_state *csp);
};

/* this allows the proxy to permit/block access to any host and/or path */
struct url_spec {
	char  *spec;
	char  *domain;
	char  *dbuf;
	char **dvec;
	int    dcnt;
	int    toplevel;

	char *path;
	int   pathlen;
	int   port;
#ifdef REGEX
	regex_t *preg;
#endif
};

struct file_list {
	void *f; /* this is a pointer to the data structures
		  * associated with the file
		  */
	void (*unloader)(void *b);
	int active;
	char *proxy_args;
	struct file_list *next;
};

struct block_spec {
	struct url_spec url[1];
	int   reject;
	struct block_spec *next;
};

struct cookie_spec {
	struct url_spec url[1];
	int   send_user_cookie;
	int   accept_server_cookie;
	struct cookie_spec *next;
};

struct forward_spec {
	struct url_spec url[1];
	int   reject;
	struct gateway gw[1];
	struct forward_spec *next;
};

#define ACL_PERMIT	1	/* accept connection request */
#define ACL_DENY  	2	/* reject connection request */

struct access_control_addr {
	unsigned long	addr;
	unsigned long	mask;
	unsigned long   port;
};

struct access_control_list {
	struct access_control_addr src[1];
	struct access_control_addr dst[1];

	short	action;
	struct access_control_list *next;
};

extern struct file_list files[];
extern struct proxy_args proxy_args[];

extern int (*loaders[])(struct client_state *csp);

/* Prototypes from bind.c
*/
extern int bind_port(char *haddr, int hport);
extern int accept_connection(int fd);

#define NLOADERS 8
#define SZ(X)	(sizeof(X) / sizeof(*X))

extern char *url_code_map[];
extern char *html_code_map[];
extern char *cookie_code_map[];

/* Prototypes from encode.c
*/
extern char *url_encode(char **code_map, unsigned char *s);
extern char *url_decode(char *str);

/* Prototypes from parsers.c
*/
extern char *sed(
    struct parsers pats[],
    void (*more_headers[])(struct client_state *csp),
    struct client_state *csp);
extern char *get_header(struct client_state *csp);
extern void enlist(struct list *h, char *s);
extern void destroy_list(struct list *h);
extern void parse_http_request(
    char *req,
    struct http_request *http,
    struct client_state *csp);
extern void free_http_request(struct http_request *http);
extern int flush_buffer(struct client_state *csp, char **pbuf);
extern int strcmpic(char *s1, char *s2);
extern int strncmpic(char *s1, char *s2, size_t n);
extern int add_to_iob(struct client_state *csp, char *buf, int n);

/* Prototypes from loaders.c
*/
extern char *strsav(char *old, char *text_to_append);
extern int run_loader(struct client_state *csp);
extern void add_loader(int (*loader)(struct client_state *csp));
extern void unload_url(struct url_spec *url);
extern void *zalloc(int size);
extern void init_proxy_args(int argc, char *argv[]);
extern void end_proxy_args();
extern void savearg(char *c, char *o);
extern void sweep();

/* Prototypes from jcc.c
*/
extern void fperror(FILE *fp, char *str);
extern char *safe_strerror(int err);
extern int main(int argc, char *argv[]);
extern int write_socket(int fd, char *buf, int n);
extern int read_socket(int fd, char *buf, int n);
extern void close_socket(int fd);

/* Prototypes from filters.c
*/
extern int domaincmp(struct url_spec *pattern, struct url_spec *fqdn);
extern struct url_spec dsplit(char *domain);

/* Prototypes from ssplit.c
*/
extern int ssplit(char *s, char *c, char *v[], int n, int m, int l);

/* Prototypes from conn.c
*/
extern int connect_to(char *host, int portnum, struct client_state *csp);
extern int direct_connect(
	struct gateway *gw,
	struct http_request *http,
	struct client_state *csp);
extern int atoip(char *host);

/* Prototypes from acl.c
*/
extern int block_acl(
    struct access_control_addr *src,
    struct access_control_addr *dst,
    struct client_state *csp);

/* parsers from parsers.c
*/
extern char *crumble
	(struct parsers *v, char *s, struct client_state *csp);
extern char *client_referrer
	(struct parsers *v, char *s, struct client_state *csp);
extern char *client_uagent
	(struct parsers *v, char *s, struct client_state *csp);
extern char *client_ua
	(struct parsers *v, char *s, struct client_state *csp);
extern char *client_x_forwarded
	(struct parsers *v, char *s, struct client_state *csp);
extern char *client_from
	(struct parsers *v, char *s, struct client_state *csp);
extern char *client_send_cookie
	(struct parsers *v, char *s, struct client_state *csp);
extern char *server_set_cookie
	(struct parsers *v, char *s, struct client_state *csp);

/* adders from parsers.c
*/
extern void client_cookie_adder(struct client_state *csp);
extern void client_xtra_adder(struct client_state *csp);
extern void client_x_forwarded_adder(struct client_state *csp);

/* interceptors from filters.c
*/
extern char *show_proxy_args
	(struct http_request *http, struct client_state *csp);
extern char *ij_blocked_url
	(struct http_request *http, struct client_state *csp);
extern char *ij_untrusted_url
	(struct http_request *http, struct client_state *csp);

/* loaders from loaders.c
*/
extern int load_blockfile(struct client_state *csp);
extern int load_cookiefile(struct client_state *csp);
extern int load_trustfile(struct client_state *csp);
extern int load_forwardfile(struct client_state *csp);

/* loaders from acl.c
*/
extern int load_aclfile(struct client_state *csp);

/* filters from filters.c
*/
extern char *intercept_url
	(struct http_request *http, struct client_state *csp);
extern char *block_url
	(struct http_request *http, struct client_state *csp);
extern char *trust_url
	(struct http_request *http, struct client_state *csp);
extern struct cookie_spec *cookie_url
	(struct http_request *http, struct client_state *csp);
extern struct gateway *forward_url
	(struct http_request *http, struct client_state *csp);

extern struct gateway gateways[], *gw_default;
extern struct parsers url_patterns[];
extern struct parsers client_patterns[];
extern struct parsers server_patterns[];
extern struct interceptors intercept_patterns[];

extern void (*add_client_headers[])(struct client_state *csp);
extern void (*add_server_headers[])();

extern char DEFAULT_USER_AGENT[];

/* Prototypes from socks4.c
*/
extern int socks4_connect(
	struct gateway *gw,
	struct http_request *http,
	struct client_state *csp);

#define SOCKS_4		40	/* original SOCKS 4 protocol */
#define SOCKS_4A	41	/* as modified for hosts w/o external DNS */

#define WHITEBG	"<body bgcolor=\"#ffffff\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"

#define BODY	"<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"

#define BANNER "<strong>Internet J<small>UNK<i><font color=\"red\">BUSTER</font></i></small></strong>"

