📄 loaders.c
字号:
char *loaders_rcs = "$Id: loaders.c,v 1.24 1998/10/22 15:30:38 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 <stdlib.h>#include <sys/types.h>#include <string.h>#include <malloc.h>#include <errno.h>#include <sys/stat.h>#include <ctype.h>#ifndef _WIN32#include <unistd.h>#endif#ifdef REGEX#include <gnu_regex.h>#endif#include "jcc.h"/* sweep() is basically a mark and sweep garbage collector. * it is run (by the parent thread) every once in a while to reclaim memory. * * it uses a mark and sweep strategy: * 1) mark all files as inactive * * 2) check with each client: * if it is active, mark its files as active * if it is inactive, free its resources * * 3) free the resources of all of the files that * are still marked as inactive (and are obsolete). * * N.B. files that are not obsolete don't have an unloader defined. */voidsweep(){ struct file_list *fl, *nfl; struct client_state *csp, *ncsp; /* clear all of the file's active flags */ for(fl = files->next; fl ; fl = fl->next) { fl->active = 0; } for(csp = clients; csp && (ncsp = csp->next) ; csp = csp->next) { if(ncsp->active) { /* mark this client's files as active */ if(ncsp->alist) ncsp->alist->active = 1; if(ncsp->blist) ncsp->blist->active = 1; if(ncsp->clist) ncsp->clist->active = 1; if(ncsp->tlist) ncsp->tlist->active = 1; } else { /* this client one is not active, * release its resources */ csp->next = ncsp->next; freez(ncsp->ip_addr_str); freez(ncsp->referrer); freez(ncsp->x_forwarded); freez(ncsp->ip_addr_str); freez(ncsp->iob->buf); free_http_request(ncsp->http); destroy_list(ncsp->headers); destroy_list(ncsp->cookie_list); freez(ncsp); } } for(fl = files; fl && (nfl = fl->next) ; fl = fl->next) { if(nfl->active == 0) { if(nfl->unloader) { fl->next = nfl->next; (nfl->unloader)(nfl->f); freez(nfl->proxy_args); freez(nfl); } } }}voidunload_url(struct url_spec *url){ if(url == NULL) return; freez(url->spec); freez(url->domain); freez(url->dbuf); freez(url->dvec); freez(url->path);#ifdef REGEX if(url->preg) { regfree(url->preg); freez(url->preg); }#endif}voidunload_blockfile(struct block_spec *b){ if(b == NULL) return; unload_blockfile(b->next); unload_url(b->url); freez(b);}voidunload_cookiefile(struct cookie_spec *b){ if(b == NULL) return; unload_cookiefile(b->next); unload_url(b->url); freez(b);}voidunload_trustfile(struct block_spec *b){ if(b == NULL) return; unload_trustfile(b->next); unload_url(b->url); freez(b);}voidunload_forwardfile(struct forward_spec *b){ if(b == NULL) return; unload_forwardfile(b->next); unload_url(b->url); freez(b->gw->gateway_host); freez(b->gw->forward_host); freez(b);}static struct file_list *current_blockfile;static struct file_list *current_cookiefile;static struct file_list *current_trustfile;static struct file_list *current_forwardfile;intload_blockfile(struct client_state *csp){ FILE *fp; struct block_spec *b, *bl; char buf[BUFSIZ], *p, *q; int port, reject; struct file_list *fs; static struct stat prev[1], curr[1]; struct url_spec url[1]; if(stat(blockfile, curr) < 0) { goto load_blockfile_error; } if(current_blockfile && (prev->st_mtime == curr->st_mtime)) { csp->blist = current_blockfile; return(0); } fs = (struct file_list *) zalloc(sizeof(*fs)); bl = (struct block_spec *) zalloc(sizeof(*bl)); if((fs == NULL) || (bl == NULL)) { goto load_blockfile_error; } fs->f = bl; fs->next = files->next; files->next = fs; if(csp) { csp->blist = fs; } *prev = *curr; if((fp = fopen(blockfile, "r")) == NULL) { goto load_blockfile_error; } p = url_encode(html_code_map, blockfile); sprintf(buf, "<h2>The file `%s' contains the following patterns</h2>\n", p); freez(p); fs->proxy_args = strsav(fs->proxy_args, buf); fs->proxy_args = strsav(fs->proxy_args, "<pre>"); while(fgets(buf, sizeof(buf), fp)) { if((p = url_encode(html_code_map, buf))) { fs->proxy_args = strsav(fs->proxy_args, p); } freez(p); fs->proxy_args = strsav(fs->proxy_args, "<br>"); if((p = strpbrk(buf, "\r\n")) != NULL) { *p = '\0'; } /* comments */ if((p = strchr(buf, '#'))) *p = '\0'; /* elide white-space */ for(p = q = buf; *q ; q++) { if(!isspace(*q)) *p++ = *q; } *p = '\0'; reject = 1; if(*buf == '~') { reject = 0; p = buf; q = p+1; while ((*p++ = *q++)) { /* nop */ } } /* skip blank lines */ if(*buf == '\0') continue; /* allocate a new node */ if(((b = zalloc(sizeof(*b))) == NULL)#ifdef REGEX || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)#endif ) { fclose(fp); goto load_blockfile_error; } /* add it to the list */ b->next = bl->next; bl->next = b; /* save a copy of the orignal specification */ if((b->url->spec = strdup(buf)) == NULL) { fclose(fp); goto load_blockfile_error; } b->reject = reject; if((p = strchr(buf, '/'))) { b->url->path = strdup(p); b->url->pathlen = strlen(b->url->path); *p = '\0'; } else { b->url->path = NULL; b->url->pathlen = 0; }#ifdef REGEX if(b->url->path) { int errcode; char rebuf[BUFSIZ]; sprintf(rebuf, "^(%s)", b->url->path); errcode = regcomp(b->url->preg, rebuf, (REG_EXTENDED|REG_NOSUB|REG_ICASE)); if(errcode) { size_t errlen = regerror(errcode, b->url->preg, buf, sizeof(buf)); buf[errlen] = '\0'; fprintf(logfp, "%s: error compiling %s: %s\n", prog, b->url->spec, buf); fclose(fp); goto load_blockfile_error; } } else { freez(b->url->preg); }#endif if((p = strchr(buf, ':')) == NULL) { port = 0; } else { *p++ = '\0'; port = atoi(p); } b->url->port = port; if((b->url->domain = strdup(buf)) == NULL) { fclose(fp); goto load_blockfile_error; } /* split domain into components */ *url = dsplit(b->url->domain); b->url->dbuf = url->dbuf; b->url->dcnt = url->dcnt; b->url->dvec = url->dvec; } fs->proxy_args = strsav(fs->proxy_args, "</pre>"); fclose(fp); /* the old one is now obsolete */ if(current_blockfile) { current_blockfile->unloader = unload_blockfile; } current_blockfile = fs; return(0);load_blockfile_error: fprintf(logfp, "%s: can't load blockfile '%s': ", prog, blockfile); fperror(logfp, ""); return(-1);}intload_cookiefile(struct client_state *csp){ FILE *fp; struct cookie_spec *b, *bl; char buf[BUFSIZ], *p, *q; char *tmp_vec[BUFSIZ]; int port, user_cookie, server_cookie; static struct stat prev[1], curr[1]; static struct file_list *fs; struct url_spec url[1]; if(stat(cookiefile, curr) < 0) { goto load_cookie_error; } if(current_cookiefile && (prev->st_mtime == curr->st_mtime)) { csp->clist = current_cookiefile; return(0); } fs = (struct file_list *) zalloc(sizeof(*fs)); bl = (struct cookie_spec *) zalloc(sizeof(*bl)); if((fs == NULL) || (bl == NULL)) { goto load_cookie_error; } fs->f = bl; fs->next = files->next; files->next = fs; if(csp) { csp->clist = fs; } *prev = *curr; if((fp = fopen(cookiefile, "r")) == NULL) { goto load_cookie_error; } p = url_encode(html_code_map, cookiefile); sprintf(buf, "<h2>The file `%s' contains the following patterns</h2>\n", p); freez(p); fs->proxy_args = strsav(fs->proxy_args, buf); fs->proxy_args = strsav(fs->proxy_args, "<pre>"); while(fgets(buf, sizeof(buf), fp)) { if((p = url_encode(html_code_map, buf))) { fs->proxy_args = strsav(fs->proxy_args, p); } freez(p); fs->proxy_args = strsav(fs->proxy_args, "<br>"); if((p = strpbrk(buf, "\r\n")) != NULL) { *p = '\0'; } /* comments */ if((p = strchr(buf, '#'))) *p = '\0'; /* elide white-space */ for(p = q = buf; *q ; q++) { if(!isspace(*q)) *p++ = *q; } *p = '\0'; p = buf; switch((int)*p) { case '>': server_cookie = 0; user_cookie = 1; p++; break; case '<': server_cookie = 1; user_cookie = 0; p++; break; case '~': server_cookie = 0; user_cookie = 0; p++; break; default: server_cookie = 1; user_cookie = 1; break; } /* elide any of the "special" chars from the * front of the pattern */ q = buf; if(p > q) while ((*q++ = *p++)) { /* nop */ } /* skip blank lines */ if(*buf == '\0') continue; /* allocate a new node */ if(((b = zalloc(sizeof(*b))) == NULL)#ifdef REGEX || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)#endif ) { fclose(fp); goto load_cookie_error; } /* add it to the list */ b->next = bl->next; bl->next = b; /* save a copy of the orignal specification */ if((b->url->spec = strdup(buf)) == NULL) { fclose(fp); goto load_cookie_error; } b->send_user_cookie = user_cookie; b->accept_server_cookie = server_cookie; if((p = strchr(buf, '/'))) { b->url->path = strdup(p); b->url->pathlen = strlen(b->url->path); *p = '\0'; } else { b->url->path = NULL; b->url->pathlen = 0; }#ifdef REGEX if(b->url->path) { int errcode; char rebuf[BUFSIZ]; sprintf(rebuf, "^(%s)", b->url->path); errcode = regcomp(b->url->preg, rebuf, (REG_EXTENDED|REG_NOSUB|REG_ICASE)); if(errcode) { size_t errlen = regerror(errcode, b->url->preg, buf, sizeof(buf)); buf[errlen] = '\0'; fprintf(logfp, "%s: error compiling %s: %s\n", prog, b->url->spec, buf); fclose(fp); goto load_cookie_error; } } else { freez(b->url->preg); }#endif if((p = strchr(buf, ':')) == NULL) { port = 0; } else { *p++ = '\0'; port = atoi(p); } b->url->port = port; if((b->url->domain = strdup(buf)) == NULL) { fclose(fp); goto load_cookie_error; } /* split domain into components */ *url = dsplit(b->url->domain, tmp_vec); b->url->dbuf = url->dbuf; b->url->dcnt = url->dcnt; b->url->dvec = url->dvec; } fs->proxy_args = strsav(fs->proxy_args, "</pre>"); fclose(fp); /* the old one is now obsolete */ if(current_cookiefile) { current_cookiefile->unloader = unload_cookiefile; } current_cookiefile = fs; return(0);load_cookie_error: fprintf(logfp, "%s: can't load cookiefile '%s': ", prog, cookiefile); fperror(logfp, ""); return(-1);}intload_trustfile(struct client_state *csp){ FILE *fp; struct block_spec *b, *bl; struct url_spec **tl; char buf[BUFSIZ], *p, *q; int port, reject, trusted; struct file_list *fs; static struct stat prev[1], curr[1]; struct url_spec url[1]; if(stat(trustfile, curr) < 0) { goto load_trustfile_error; } if(current_trustfile && (prev->st_mtime == curr->st_mtime)) { csp->tlist = current_trustfile; return(0); } fs = (struct file_list *) zalloc(sizeof(*fs)); bl = (struct block_spec *) zalloc(sizeof(*bl)); if((fs == NULL) || (bl == NULL)) { goto load_trustfile_error; } fs->f = bl; fs->next = files->next; files->next = fs; if(csp) { csp->tlist = fs; } *prev = *curr; if((fp = fopen(trustfile, "r")) == NULL) { goto load_trustfile_error; } p = url_encode(html_code_map, trustfile); sprintf(buf, "<h2>The file `%s' contains the following patterns</h2>\n", p); freez(p); fs->proxy_args = strsav(fs->proxy_args, buf); fs->proxy_args = strsav(fs->proxy_args, "<pre>"); tl = trust_list; while(fgets(buf, sizeof(buf), fp)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -