⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jcc.c

📁 一个不错的服务代理器
💻 C
📖 第 1 页 / 共 2 页
字号:
char *jcc_rcs = "$Id: jcc.c,v 3.42 1998/10/29 03:11:21 ACJC Exp $";/* 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 <stdio.h>#include <sys/types.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <signal.h>#include <fcntl.h>#include <errno.h>#ifdef _WIN32#include <sys/timeb.h>#include <windows.h>#include <io.h>#include <process.h>#else#include <unistd.h>#include <sys/time.h>#include <sys/wait.h>#include <sys/stat.h>#ifdef __BEOS__#include <socket.h>	/* BeOS has select() for sockets only. */#include <OS.h>		/* declarations for threads and stuff. */#endif#ifndef FD_ZERO#include <select.h>#endif#endif#ifdef REGEX#include <gnu_regex.h>#endif#include "jcc.h"char *prog;#define BODY	"<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"char CFAIL[]   = "HTTP/1.0 503 Connect failed\n"		 "Content-Type: text/html\n\n"		 "<html>\n"		 "<head>\n"		 "<title>Internet Junkbuster: Connect failed</title>\n"		 "</head>\n"		 BODY		 "<h1><center>"		 BANNER		 "</center></h1>"		 "TCP connection to '%s' failed: %s.\n<br>"		 "</body>\n"		 "</html>\n"		 ;char CNXDOM[]  = "HTTP/1.0 404 Non-existent domain\n"		 "Content-Type: text/html\n\n"		 "<html>\n"		 "<head>\n"		 "<title>Internet Junkbuster: Non-existent domain</title>\n"		 "</head>\n"		 BODY		 "<h1><center>"		 BANNER		 "</center></h1>"		 "No such domain: %s\n"		 "</body>\n"		 "</html>\n"		 ;char CSUCCEED[] = "HTTP/1.0 200 Connection established\n"		  "Proxy-Agent: IJ/" VERSION "\n\n"		  ;char CHEADER[] = "HTTP/1.0 400 Invalid header received from browser\n\n";char SHEADER[] = "HTTP/1.0 502 Invalid header received from server\n\n";char VANILLA_WAFER[] =	"NOTICE=TO_WHOM_IT_MAY_CONCERN_"	"Do_not_send_me_any_copyrighted_information_other_than_the_"	"document_that_I_am_requesting_or_any_of_its_necessary_components._"	"In_particular_do_not_send_me_any_cookies_that_"	"are_subject_to_a_claim_of_copyright_by_anybody._"	"Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"	"(copyright_or_otherwise)_applying_to_any_cookie._";char DEFAULT_USER_AGENT[] ="User-Agent: Mozilla/3.01Gold (Macintosh; I; 68K)";int debug           = 0;int multi_threaded  = 1;int hideConsole     = 0;#ifdef _WIN32#define sleep(N)	Sleep(((N) * 1000))#endifchar *logfile = NULL;FILE *logfp;char *blockfile    = NULL;char *cookiefile   = NULL;char *trustfile    = NULL;char *forwardfile  = NULL;char *aclfile      = NULL;char *jarfile = NULL;FILE *jar;char *referrer   = NULL;char *uagent     = NULL;char *from       = NULL;int suppress_vanilla_wafer = 0;int add_forwarded      = 0;struct client_state clients[1];struct file_list    files[1];struct list wafer_list[1];struct list xtra_list[1];struct list trust_info[1];struct url_spec * trust_list[64];int (*loaders[NLOADERS])();struct gateway gateways[] = {/* type         function        gw type/host/port,    fw host/port*/{ "direct",	direct_connect, 0,        NULL, 0,     NULL, 0    },{ ".",		direct_connect, 0,        NULL, 0,     NULL, 0    },{ "socks",	socks4_connect, SOCKS_4,  NULL, 1080,  NULL, 0    },{ "socks4",	socks4_connect, SOCKS_4,  NULL, 1080,  NULL, 0    },{ "socks4a",	socks4_connect, SOCKS_4A, NULL, 1080,  NULL, 0    },{ NULL,		NULL,           0,        NULL, 0,     NULL, 0    }};struct gateway *gw_default = gateways;char *haddr = "127.0.0.1";	/* default binding to localhost */int   hport = 8000;struct proxy_args proxy_args[1];intwrite_socket(int fd, char *buf, int n){	if(n <= 0) return(0);	if(DEBUG(LOG)) fwrite(buf, n, 1, logfp);#if defined(_WIN32) || defined(__BEOS__)	return send(fd, buf, n, 0);#else	return write(fd, buf, n);#endif}intread_socket(int fd, char *buf, int n){	if(n <= 0) return(0);#if defined(_WIN32) || defined(__BEOS__)	return recv(fd, buf, n, 0);#else	return read(fd, buf, n);#endif}voidclose_socket(int fd){#if defined(_WIN32) || defined(__BEOS__)	closesocket(fd);#else	close(fd);#endif}voidchat(struct client_state *csp){	char buf[BUFSIZ], *hdr, *p, *req;	char *err = NULL;	char *eno;	fd_set rfds;	int n, maxfd, server_body;	struct cookie_spec *cs;	struct gateway *gw;	struct http_request *http;	http = csp->http;	/* read the client's request.	 * note that since we're not using select()	 * we could get blocked here if a client 	 * connected, then didn't say anything!	 */	for(;;) {		n = read_socket(csp->cfd, buf, sizeof(buf));		if(n <= 0) break;		/* error! */		add_to_iob(csp, buf, n);		req = get_header(csp);		if(req == NULL) break;		/* no HTTP request! */		if(*req == '\0') continue;	/* more to come! */		parse_http_request(req, http, csp);		freez(req);		break;	}	if(http->cmd == NULL) {		strcpy(buf, CHEADER);		write_socket(csp->cfd, buf, strlen(buf));		return;	}	/* decide how to route the HTTP request */	if((gw = forward_url(http, csp)) == NULL) {		fprintf(logfp,			"%s: gateway spec is NULL!?!?  This can't happen!\n", prog);		abort();	}	/* build the http request to send to the server	 * we have to do one of the following:	 *	 * create = use the original HTTP request to create a new	 *          HTTP request that has only the path component	 *          without the http://domainspec	 * pass   = pass the original HTTP request unchanged	 *	 * drop   = drop the HTTP request	 *	    	 * here's the matrix:	 *                        SSL	 *                    0        1         *                +--------+--------+         *                |        |        |         *             0  | create | drop   |         *                |        |        |         *  Forwarding    +--------+--------+         *                |        |        |         *             1  | pass   | pass   |         *                |        |        |         *                +--------+--------+         *         */	if(gw->forward_host) {			/* if forwarding, just pass the request as is */			enlist(csp->headers, http->cmd);	} else {		if(http->ssl == 0) {			/* otherwise elide the host information from the url */			p = NULL;			p = strsav(p, http->gpc);			p = strsav(p, " ");			p = strsav(p, http->path);			p = strsav(p, " ");			p = strsav(p, http->ver);			enlist(csp->headers, p);			freez(p);		}	}	/* decide what we're to do with cookies */	if((cs = cookie_url(http, csp))) {		csp->accept_server_cookie  = cs->accept_server_cookie;		csp->send_user_cookie      = cs->send_user_cookie;	} else {		csp->accept_server_cookie  = 0;		csp->send_user_cookie      = 0;	}	/* grab the rest of the client's headers */	for(;;) {		if(( p = get_header(csp))		&& (*p == '\0')) {			n = read_socket(csp->cfd, buf, sizeof(buf));			if(n <= 0) {				fprintf(logfp,					"%s: read from client failed: ", prog);				fperror(logfp, "");				return;			}			add_to_iob(csp, buf, n);			continue;		}		if(p == NULL) break;		enlist(csp->headers, p);		freez(p);	}	/* filter it as required */	hdr = sed(client_patterns, add_client_headers, csp);	destroy_list(csp->headers);	if((p = intercept_url(http, csp))	|| (p =     block_url(http, csp))	|| (p =     trust_url(http, csp))) {		if(DEBUG(GPC)) {			fprintf(logfp, "%s: GPC\t%s%s crunch!\n",				prog, http->hostport, http->path);		}		write_socket(csp->cfd, p, strlen(p));		if(DEBUG(LOG)) fwrite(p, strlen(p), 1, logfp);		freez(p);		freez(hdr);		return;	}	if(DEBUG(GPC)) {		fprintf(logfp, "%s: GPC\t%s%s\n",			prog, http->hostport, http->path);	}	if(DEBUG(CON)) {		if(gw->forward_host) {			fprintf(logfp,				"%s: connect via %s:%d to: %s ... ",					prog,					gw->forward_host,					gw->forward_port,					http->hostport);		} else {			fprintf(logfp,				"%s: connect to: %s ... ",					prog, http->hostport);		}	}	/* here we connect to the server, gateway, or the forwarder */	csp->sfd = (gw->conn)(gw, http, csp);	if(csp->sfd < 0) {		if(DEBUG(CON)) {			fprintf(logfp, "%s: connect to: %s failed: ",					prog, http->hostport);			fperror(logfp, "");		}		if(errno == EINVAL) {			err = zalloc(strlen(CNXDOM) + strlen(http->host));			sprintf(err, CNXDOM, http->host);		} else {			eno = safe_strerror(errno);			err = zalloc(strlen(CFAIL) + strlen(http->hostport) + strlen(eno));			sprintf(err, CFAIL, http->hostport, eno);		}		write_socket(csp->cfd, err, strlen(err));		if(DEBUG(LOG)) fwrite(err, strlen(err), 1, logfp);		freez(err);		freez(hdr);		return;	}	if(DEBUG(CON)) {		fprintf(logfp, "OK\n");	}	if(gw->forward_host || (http->ssl == 0)) {		/* write the client's (modified) header to the server		 * (along with anything else that may be in the buffer)		 */		n = strlen(hdr);		if((write_socket(csp->sfd, hdr, n) != n)		|| (flush_socket(csp->sfd, csp   ) <  0)) {			if(DEBUG(CON)) {				fprintf(logfp, "%s: write header to: %s failed: ",					prog, http->hostport);				fperror(logfp, "");			}			eno = safe_strerror(errno);			err = zalloc(strlen(CFAIL) + strlen(http->hostport) + strlen(eno));			sprintf(err, CFAIL, http->hostport, eno);			write_socket(csp->cfd, err, strlen(err));			freez(err);			freez(hdr);			return;		}	} else {		/* we're running an SSL tunnel and we're not		 * forwarding, so just send the "connect succeeded"		 * message to the client, flush the rest, and		 * get out of the way.		 */		if(write_socket(csp->cfd, CSUCCEED, sizeof(CSUCCEED)-1) < 0) {			freez(hdr);			return;		}		IOB_RESET(csp);	}	/* we're finished with the client's header */	freez(hdr);	maxfd = ( csp->cfd > csp->sfd ) ? csp->cfd : csp->sfd;	/* pass data between the client and server	 * until one or the other shuts down the connection.	 */	server_body = 0;	for(;;) {		FD_ZERO(&rfds);		FD_SET(csp->cfd, &rfds);		FD_SET(csp->sfd, &rfds);		n = select(maxfd+1, &rfds, NULL, NULL, NULL);		if(n < 0) {			fprintf(logfp, "%s: select() failed!: ", prog);			fperror(logfp, "");			return;		}		/* this is the body of the browser's request		 * just read it and write it.		 */		if(FD_ISSET(csp->cfd, &rfds)) {			n = read_socket(csp->cfd, buf, sizeof(buf));			if(n <= 0) break; /* "game over, man" */			if(write_socket(csp->sfd, buf, n) != n) {				fprintf(logfp, "%s: write to: %s failed: ",						prog, http->host);				fperror(logfp, "");				return;			}			continue;		}		/* the server wants to talk.		 * it could be the header or the body.		 * if `hdr' is null, then it's the header		 * otherwise it's the body		 */		if(FD_ISSET(csp->sfd, &rfds)) {			n = read_socket(csp->sfd, buf, sizeof(buf));			if(n < 0) {				fprintf(logfp, "%s: read from: %s failed: ",						prog, http->host);				fperror(logfp, "");				eno = safe_strerror(errno);				sprintf(buf, CFAIL, http->hostport, eno);				freez(eno);				write_socket(csp->cfd, buf, strlen(buf));				return;			}			if(n == 0) break; /* "game over, man" */			/* if this is an SSL connection or we're in the body			 * of the server document, just write it to the client.			 */			if(server_body || http->ssl) {				/* just write */				if(write_socket(csp->cfd, buf, n) != n) {					fprintf(logfp, "%s: write to client failed: ",							prog);					fperror(logfp, "");					return;				}				continue;			} else {				/* we're still looking for the end of the				 * server's header ... (does that make header				 * parsing an "out of body experience" ?				 */				/* buffer up the data we just read */				add_to_iob(csp, buf, n);				/* get header lines from the iob */				while((p = get_header(csp))) {					if(*p == '\0') {						/* see following note */						break;					}					enlist(csp->headers, p);					freez(p);				}				/* NOTE: there are no "empty" headers so				 * if the pointer `p' is not NULL we must				 * assume that we reached the end of the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -