loaders.c
上传用户:qunlip
上传日期:2007-01-04
资源大小:203k
文件大小:24k
源码类别:

代理服务器

开发平台:

Visual C++

  1. char *loaders_rcs = "$Id: loaders.c,v 1.24 1998/10/22 15:30:38 ACJC Exp $";
  2. /* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
  3.  * Distributed under the GNU General Public License; see the README file.
  4.  * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
  5.  */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <sys/types.h>
  9. #include <string.h>
  10. #include <malloc.h>
  11. #include <errno.h>
  12. #include <sys/stat.h>
  13. #include <ctype.h>
  14. #ifndef _WIN32
  15. #include <unistd.h>
  16. #endif
  17. #ifdef REGEX
  18. #include <gnu_regex.h>
  19. #endif
  20. #include "jcc.h"
  21. /* sweep() is basically a mark and sweep garbage collector.
  22.  * it is run (by the parent thread) every once in a while to reclaim memory.
  23.  *
  24.  * it uses a mark and sweep strategy:
  25.  *   1) mark all files as inactive
  26.  *
  27.  *   2) check with each client:
  28.  *       if it is active,   mark its files as active
  29.  *       if it is inactive, free its resources
  30.  *
  31.  *   3) free the resources of all of the files that
  32.  *      are still marked as inactive (and are obsolete).
  33.  *
  34.  *   N.B. files that are not obsolete don't have an unloader defined.
  35.  */
  36. void
  37. sweep()
  38. {
  39. struct file_list *fl, *nfl;
  40. struct client_state *csp, *ncsp;
  41. /* clear all of the file's active flags */
  42. for(fl = files->next; fl ; fl = fl->next) {
  43. fl->active = 0;
  44. }
  45. for(csp = clients; csp && (ncsp = csp->next) ; csp = csp->next) {
  46. if(ncsp->active) {
  47. /* mark this client's files as active */
  48. if(ncsp->alist) ncsp->alist->active = 1;
  49. if(ncsp->blist) ncsp->blist->active = 1;
  50. if(ncsp->clist) ncsp->clist->active = 1;
  51. if(ncsp->tlist) ncsp->tlist->active = 1;
  52. } else {
  53. /* this client one is not active,
  54.  * release its resources
  55.  */
  56. csp->next = ncsp->next;
  57. freez(ncsp->ip_addr_str);
  58. freez(ncsp->referrer);
  59. freez(ncsp->x_forwarded);
  60. freez(ncsp->ip_addr_str);
  61. freez(ncsp->iob->buf);
  62. free_http_request(ncsp->http);
  63. destroy_list(ncsp->headers);
  64. destroy_list(ncsp->cookie_list);
  65. freez(ncsp);
  66. }
  67. }
  68. for(fl = files; fl && (nfl = fl->next) ; fl = fl->next) {
  69. if(nfl->active == 0) {
  70. if(nfl->unloader) {
  71. fl->next = nfl->next;
  72. (nfl->unloader)(nfl->f);
  73. freez(nfl->proxy_args);
  74. freez(nfl);
  75. }
  76. }
  77. }
  78. }
  79. void
  80. unload_url(struct url_spec *url)
  81. {
  82. if(url == NULL) return;
  83. freez(url->spec);
  84. freez(url->domain);
  85. freez(url->dbuf);
  86. freez(url->dvec);
  87. freez(url->path);
  88. #ifdef REGEX
  89. if(url->preg) {
  90. regfree(url->preg);
  91. freez(url->preg);
  92. }
  93. #endif
  94. }
  95. void
  96. unload_blockfile(struct block_spec *b)
  97. {
  98. if(b == NULL) return;
  99. unload_blockfile(b->next);
  100. unload_url(b->url);
  101. freez(b);
  102. }
  103. void
  104. unload_cookiefile(struct cookie_spec *b)
  105. {
  106. if(b == NULL) return;
  107. unload_cookiefile(b->next);
  108. unload_url(b->url);
  109. freez(b);
  110. }
  111. void
  112. unload_trustfile(struct block_spec *b)
  113. {
  114. if(b == NULL) return;
  115. unload_trustfile(b->next);
  116. unload_url(b->url);
  117. freez(b);
  118. }
  119. void
  120. unload_forwardfile(struct forward_spec *b)
  121. {
  122. if(b == NULL) return;
  123. unload_forwardfile(b->next);
  124. unload_url(b->url);
  125. freez(b->gw->gateway_host);
  126. freez(b->gw->forward_host);
  127. freez(b);
  128. }
  129. static struct file_list *current_blockfile;
  130. static struct file_list *current_cookiefile;
  131. static struct file_list *current_trustfile;
  132. static struct file_list *current_forwardfile;
  133. int
  134. load_blockfile(struct client_state *csp)
  135. {
  136. FILE *fp;
  137. struct block_spec *b, *bl;
  138. char  buf[BUFSIZ], *p, *q;
  139. int port, reject;
  140. struct file_list *fs;
  141. static struct stat prev[1], curr[1];
  142. struct url_spec url[1];
  143. if(stat(blockfile, curr) < 0) {
  144. goto load_blockfile_error;
  145. }
  146. if(current_blockfile && (prev->st_mtime == curr->st_mtime)) {
  147. csp->blist = current_blockfile;
  148. return(0);
  149. }
  150. fs = (struct file_list  *) zalloc(sizeof(*fs));
  151. bl = (struct block_spec *) zalloc(sizeof(*bl));
  152. if((fs == NULL) || (bl == NULL)) {
  153. goto load_blockfile_error;
  154. }
  155. fs->f = bl;
  156. fs->next    = files->next;
  157. files->next = fs;
  158. if(csp) {
  159. csp->blist = fs;
  160. }
  161. *prev = *curr;
  162. if((fp = fopen(blockfile, "r")) == NULL) {
  163. goto load_blockfile_error;
  164. }
  165. p = url_encode(html_code_map, blockfile);
  166. sprintf(buf, "<h2>The file `%s' contains the following patterns</h2>n", p);
  167. freez(p);
  168. fs->proxy_args = strsav(fs->proxy_args, buf);
  169. fs->proxy_args = strsav(fs->proxy_args, "<pre>");
  170. while(fgets(buf, sizeof(buf), fp)) {
  171. if((p = url_encode(html_code_map, buf))) {
  172. fs->proxy_args = strsav(fs->proxy_args, p);
  173. }
  174. freez(p);
  175. fs->proxy_args = strsav(fs->proxy_args, "<br>");
  176. if((p = strpbrk(buf, "rn")) != NULL) {
  177. *p = '';
  178. }
  179. /* comments */
  180. if((p = strchr(buf, '#'))) *p = '';
  181. /* elide white-space */
  182. for(p = q = buf; *q ; q++) {
  183. if(!isspace(*q)) *p++ = *q;
  184. }
  185. *p = '';
  186. reject = 1;
  187. if(*buf == '~') {
  188. reject = 0;
  189. p = buf;
  190. q = p+1;
  191. while ((*p++ = *q++)) {
  192. /* nop */
  193. }
  194. }
  195. /* skip blank lines */
  196. if(*buf == '') continue;
  197. /* allocate a new node */
  198. if(((b            = zalloc(sizeof(*b)))            == NULL)
  199. #ifdef REGEX
  200. || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
  201. #endif
  202. ) {
  203. fclose(fp);
  204. goto load_blockfile_error;
  205. }
  206. /* add it to the list */
  207. b->next  = bl->next;
  208. bl->next = b;
  209. /* save a copy of the orignal specification */
  210. if((b->url->spec = strdup(buf)) == NULL) {
  211. fclose(fp);
  212. goto load_blockfile_error;
  213. }
  214. b->reject = reject;
  215. if((p = strchr(buf, '/'))) {
  216. b->url->path    = strdup(p);
  217. b->url->pathlen = strlen(b->url->path);
  218. *p = '';
  219. } else {
  220. b->url->path    = NULL;
  221. b->url->pathlen = 0;
  222. }
  223. #ifdef REGEX
  224. if(b->url->path) {
  225. int errcode;
  226. char rebuf[BUFSIZ];
  227. sprintf(rebuf, "^(%s)", b->url->path);
  228. errcode = regcomp(b->url->preg, rebuf,
  229. (REG_EXTENDED|REG_NOSUB|REG_ICASE));
  230. if(errcode) {
  231. size_t errlen =
  232. regerror(errcode,
  233. b->url->preg, buf, sizeof(buf));
  234. buf[errlen] = '';
  235. fprintf(logfp,
  236. "%s: error compiling %s: %sn",
  237. prog, b->url->spec, buf);
  238. fclose(fp);
  239. goto load_blockfile_error;
  240. }
  241. } else {
  242. freez(b->url->preg);
  243. }
  244. #endif
  245. if((p = strchr(buf, ':')) == NULL) {
  246. port = 0;
  247. } else {
  248. *p++ = '';
  249. port = atoi(p);
  250. }
  251. b->url->port = port;
  252. if((b->url->domain = strdup(buf)) == NULL) {
  253. fclose(fp);
  254. goto load_blockfile_error;
  255. }
  256. /* split domain into components */
  257. *url = dsplit(b->url->domain);
  258. b->url->dbuf = url->dbuf;
  259. b->url->dcnt = url->dcnt;
  260. b->url->dvec = url->dvec;
  261. }
  262. fs->proxy_args = strsav(fs->proxy_args, "</pre>");
  263. fclose(fp);
  264. /* the old one is now obsolete */
  265. if(current_blockfile) {
  266. current_blockfile->unloader = unload_blockfile;
  267. }
  268. current_blockfile = fs;
  269. return(0);
  270. load_blockfile_error:
  271. fprintf(logfp, "%s: can't load blockfile '%s': ",
  272. prog, blockfile);
  273. fperror(logfp, "");
  274. return(-1);
  275. }
  276. int
  277. load_cookiefile(struct client_state *csp)
  278. {
  279. FILE *fp;
  280. struct cookie_spec *b, *bl;
  281. char  buf[BUFSIZ], *p, *q;
  282. char *tmp_vec[BUFSIZ];
  283. int port, user_cookie, server_cookie;
  284. static struct stat prev[1], curr[1];
  285. static struct file_list *fs;
  286. struct url_spec url[1];
  287. if(stat(cookiefile, curr) < 0) {
  288. goto load_cookie_error;
  289. }
  290. if(current_cookiefile && (prev->st_mtime == curr->st_mtime)) {
  291. csp->clist = current_cookiefile;
  292. return(0);
  293. }
  294. fs = (struct file_list   *) zalloc(sizeof(*fs));
  295.         bl = (struct cookie_spec *) zalloc(sizeof(*bl));
  296. if((fs == NULL) || (bl == NULL)) {
  297. goto load_cookie_error;
  298. }
  299. fs->f = bl;
  300. fs->next    = files->next;
  301. files->next = fs;
  302. if(csp) {
  303. csp->clist = fs;
  304. }
  305. *prev = *curr;
  306. if((fp = fopen(cookiefile, "r")) == NULL) {
  307. goto load_cookie_error;
  308. }
  309. p = url_encode(html_code_map, cookiefile);
  310. sprintf(buf, "<h2>The file `%s' contains the following patterns</h2>n", p);
  311. freez(p);
  312. fs->proxy_args = strsav(fs->proxy_args, buf);
  313. fs->proxy_args = strsav(fs->proxy_args, "<pre>");
  314. while(fgets(buf, sizeof(buf), fp)) {
  315. if((p = url_encode(html_code_map, buf))) {
  316. fs->proxy_args = strsav(fs->proxy_args, p);
  317. }
  318. freez(p);
  319. fs->proxy_args = strsav(fs->proxy_args, "<br>");
  320. if((p = strpbrk(buf, "rn")) != NULL) {
  321. *p = '';
  322. }
  323. /* comments */
  324. if((p = strchr(buf, '#'))) *p = '';
  325. /* elide white-space */
  326. for(p = q = buf; *q ; q++) {
  327. if(!isspace(*q)) *p++ = *q;
  328. }
  329. *p = '';
  330. p = buf;
  331. switch((int)*p) {
  332. case '>':
  333. server_cookie = 0;
  334. user_cookie   = 1;
  335. p++;
  336. break;
  337. case '<':
  338. server_cookie = 1;
  339. user_cookie   = 0;
  340. p++;
  341. break;
  342. case '~':
  343. server_cookie = 0;
  344. user_cookie   = 0;
  345. p++;
  346. break;
  347. default:
  348. server_cookie = 1;
  349. user_cookie   = 1;
  350. break;
  351. }
  352. /* elide any of the "special" chars from the
  353.  * front of the pattern
  354.  */
  355. q = buf;
  356. if(p > q) while ((*q++ = *p++)) {
  357. /* nop */
  358. }
  359. /* skip blank lines */
  360. if(*buf == '') continue;
  361. /* allocate a new node */
  362. if(((b            = zalloc(sizeof(*b)))            == NULL)
  363. #ifdef REGEX
  364. || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
  365. #endif
  366. ) {
  367. fclose(fp);
  368. goto load_cookie_error;
  369. }
  370. /* add it to the list */
  371. b->next  = bl->next;
  372. bl->next = b;
  373. /* save a copy of the orignal specification */
  374. if((b->url->spec = strdup(buf)) == NULL) {
  375. fclose(fp);
  376. goto load_cookie_error;
  377. }
  378. b->send_user_cookie     = user_cookie;
  379. b->accept_server_cookie = server_cookie;
  380. if((p = strchr(buf, '/'))) {
  381. b->url->path    = strdup(p);
  382. b->url->pathlen = strlen(b->url->path);
  383. *p = '';
  384. } else {
  385. b->url->path    = NULL;
  386. b->url->pathlen = 0;
  387. }
  388. #ifdef REGEX
  389. if(b->url->path) {
  390. int errcode;
  391. char rebuf[BUFSIZ];
  392. sprintf(rebuf, "^(%s)", b->url->path);
  393. errcode = regcomp(b->url->preg, rebuf,
  394. (REG_EXTENDED|REG_NOSUB|REG_ICASE));
  395. if(errcode) {
  396. size_t errlen =
  397. regerror(errcode,
  398. b->url->preg, buf, sizeof(buf));
  399. buf[errlen] = '';
  400. fprintf(logfp,
  401. "%s: error compiling %s: %sn",
  402. prog, b->url->spec, buf);
  403. fclose(fp);
  404. goto load_cookie_error;
  405. }
  406. } else {
  407. freez(b->url->preg);
  408. }
  409. #endif
  410. if((p = strchr(buf, ':')) == NULL) {
  411. port = 0;
  412. } else {
  413. *p++ = '';
  414. port = atoi(p);
  415. }
  416. b->url->port = port;
  417. if((b->url->domain = strdup(buf)) == NULL) {
  418. fclose(fp);
  419. goto load_cookie_error;
  420. }
  421. /* split domain into components */
  422. *url = dsplit(b->url->domain, tmp_vec);
  423. b->url->dbuf = url->dbuf;
  424. b->url->dcnt = url->dcnt;
  425. b->url->dvec = url->dvec;
  426. }
  427. fs->proxy_args = strsav(fs->proxy_args, "</pre>");
  428. fclose(fp);
  429. /* the old one is now obsolete */
  430. if(current_cookiefile) {
  431. current_cookiefile->unloader = unload_cookiefile;
  432. }
  433. current_cookiefile = fs;
  434. return(0);
  435. load_cookie_error:
  436. fprintf(logfp, "%s: can't load cookiefile '%s': ",
  437. prog, cookiefile);
  438. fperror(logfp, "");
  439. return(-1);
  440. }
  441. int
  442. load_trustfile(struct client_state *csp)
  443. {
  444. FILE *fp;
  445. struct block_spec *b, *bl;
  446. struct url_spec **tl;
  447. char  buf[BUFSIZ], *p, *q;
  448. int port, reject, trusted;
  449. struct file_list *fs;
  450. static struct stat prev[1], curr[1];
  451. struct url_spec url[1];
  452. if(stat(trustfile, curr) < 0) {
  453. goto load_trustfile_error;
  454. }
  455. if(current_trustfile && (prev->st_mtime == curr->st_mtime)) {
  456. csp->tlist = current_trustfile;
  457. return(0);
  458. }
  459. fs = (struct file_list  *) zalloc(sizeof(*fs));
  460. bl = (struct block_spec *) zalloc(sizeof(*bl));
  461. if((fs == NULL) || (bl == NULL)) {
  462. goto load_trustfile_error;
  463. }
  464. fs->f = bl;
  465. fs->next    = files->next;
  466. files->next = fs;
  467. if(csp) {
  468. csp->tlist = fs;
  469. }
  470. *prev = *curr;
  471. if((fp = fopen(trustfile, "r")) == NULL) {
  472. goto load_trustfile_error;
  473. }
  474. p = url_encode(html_code_map, trustfile);
  475. sprintf(buf, "<h2>The file `%s' contains the following patterns</h2>n", p);
  476. freez(p);
  477. fs->proxy_args = strsav(fs->proxy_args, buf);
  478. fs->proxy_args = strsav(fs->proxy_args, "<pre>");
  479. tl = trust_list;
  480. while(fgets(buf, sizeof(buf), fp)) {
  481. if((p = url_encode(html_code_map, buf))) {
  482. fs->proxy_args = strsav(fs->proxy_args, p);
  483. }
  484. freez(p);
  485. fs->proxy_args = strsav(fs->proxy_args, "<br>");
  486. if((p = strpbrk(buf, "rn")) != NULL) {
  487. *p = '';
  488. }
  489. /* comments */
  490. if((p = strchr(buf, '#'))) *p = '';
  491. /* elide white-space */
  492. for(p = q = buf; *q ; q++) {
  493. if(!isspace(*q)) *p++ = *q;
  494. }
  495. *p = '';
  496. trusted = 0;
  497. reject  = 1;
  498. if(*buf == '+') {
  499. trusted = 1;
  500. *buf = '~';
  501. }
  502. if(*buf == '~') {
  503. reject = 0;
  504. p = buf;
  505. q = p+1;
  506. while ((*p++ = *q++)) {
  507. /* nop */
  508. }
  509. }
  510. /* skip blank lines */
  511. if(*buf == '') continue;
  512. /* allocate a new node */
  513. if(((b            = zalloc(sizeof(*b)))            == NULL)
  514. #ifdef REGEX
  515. || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
  516. #endif
  517. ) {
  518. fclose(fp);
  519. goto load_trustfile_error;
  520. }
  521. /* add it to the list */
  522. b->next  = bl->next;
  523. bl->next = b;
  524. /* save a copy of the orignal specification */
  525. if((b->url->spec = strdup(buf)) == NULL) {
  526. fclose(fp);
  527. goto load_trustfile_error;
  528. }
  529. b->reject = reject;
  530. if((p = strchr(buf, '/'))) {
  531. b->url->path    = strdup(p);
  532. b->url->pathlen = strlen(b->url->path);
  533. *p = '';
  534. } else {
  535. b->url->path    = NULL;
  536. b->url->pathlen = 0;
  537. }
  538. #ifdef REGEX
  539. if(b->url->path) {
  540. int errcode;
  541. char rebuf[BUFSIZ];
  542. sprintf(rebuf, "^(%s)", b->url->path);
  543. errcode = regcomp(b->url->preg, rebuf,
  544. (REG_EXTENDED|REG_NOSUB|REG_ICASE));
  545. if(errcode) {
  546. size_t errlen =
  547. regerror(errcode,
  548. b->url->preg, buf, sizeof(buf));
  549. buf[errlen] = '';
  550. fprintf(logfp,
  551. "%s: error compiling %s: %sn",
  552. prog, b->url->spec, buf);
  553. fclose(fp);
  554. goto load_trustfile_error;
  555. }
  556. } else {
  557. freez(b->url->preg);
  558. }
  559. #endif
  560. if((p = strchr(buf, ':')) == NULL) {
  561. port = 0;
  562. } else {
  563. *p++ = '';
  564. port = atoi(p);
  565. }
  566. b->url->port = port;
  567. if((b->url->domain = strdup(buf)) == NULL) {
  568. fclose(fp);
  569. goto load_trustfile_error;
  570. }
  571. /* split domain into components */
  572. *url = dsplit(b->url->domain);
  573. b->url->dbuf = url->dbuf;
  574. b->url->dcnt = url->dcnt;
  575. b->url->dvec = url->dvec;
  576. /* save a pointer to URL's spec
  577.  * in the list of trusted URL's, too
  578.  */
  579. if(trusted) *tl++ = b->url;
  580. }
  581. fs->proxy_args = strsav(fs->proxy_args, "</pre>");
  582. *tl = NULL;
  583. fclose(fp);
  584. /* the old one is now obsolete */
  585. if(current_trustfile) {
  586. current_trustfile->unloader = unload_trustfile;
  587. }
  588. current_trustfile = fs;
  589. return(0);
  590. load_trustfile_error:
  591. fprintf(logfp, "%s: can't load trustfile '%s': ",
  592. prog, trustfile);
  593. fperror(logfp, "");
  594. return(-1);
  595. }
  596. int
  597. load_forwardfile(struct client_state *csp)
  598. {
  599. FILE *fp;
  600. struct forward_spec *b, *bl;
  601. char  buf[BUFSIZ], *p, *q, *tmp;
  602. char  *vec[4];
  603. int port, n, reject;
  604. struct file_list *fs;
  605. struct gateway *gw;
  606. static struct stat prev[1], curr[1];
  607. struct url_spec url[1];
  608. if(stat(forwardfile, curr) < 0) {
  609. goto load_forwardfile_error;
  610. }
  611. if(current_forwardfile && (prev->st_mtime == curr->st_mtime)) {
  612. csp->flist = current_forwardfile;
  613. return(0);
  614. }
  615. fs = (struct file_list    *) zalloc(sizeof(*fs));
  616. bl = (struct forward_spec *) zalloc(sizeof(*bl));
  617. if((fs == NULL) || (bl == NULL)) {
  618. goto load_forwardfile_error;
  619. }
  620. memset(fs, '', sizeof(*fs));
  621. memset(bl, '', sizeof(*bl));
  622. fs->f = bl;
  623. fs->next    = files->next;
  624. files->next = fs;
  625. if(csp) {
  626. csp->flist = fs;
  627. }
  628. *prev = *curr;
  629. if((fp = fopen(forwardfile, "r")) == NULL) {
  630. goto load_forwardfile_error;
  631. }
  632. p = url_encode(html_code_map, forwardfile);
  633. sprintf(buf, "<h2>The file `%s' contains the following patterns</h2>n", p);
  634. freez(p);
  635. fs->proxy_args = strsav(fs->proxy_args, buf);
  636. tmp = NULL;
  637. fs->proxy_args = strsav(fs->proxy_args, "<pre>");
  638. while(fgets(buf, sizeof(buf), fp)) {
  639. freez(tmp);
  640. if((p = url_encode(html_code_map, buf))) {
  641. fs->proxy_args = strsav(fs->proxy_args, p);
  642. }
  643. freez(p);
  644. fs->proxy_args = strsav(fs->proxy_args, "<br>");
  645. if((p = strpbrk(buf, "rn")) != NULL) {
  646. *p = '';
  647. }
  648. /* comments */
  649. if((p = strchr(buf, '#'))) *p = '';
  650. /* skip blank lines */
  651. if(*buf == '') continue;
  652. tmp = strdup(buf);
  653. n = ssplit(tmp, " t", vec, SZ(vec), 1, 1);
  654. if(n != 4) {
  655. fprintf(stderr, "error in forwardfile: %sn", buf);
  656. continue;
  657. }
  658. strcpy(buf, vec[0]);
  659. reject = 1;
  660. if(*buf == '~') {
  661. reject = 0;
  662. p = buf;
  663. q = p+1;
  664. while ((*p++ = *q++)) {
  665. /* nop */
  666. }
  667. }
  668. /* skip blank lines */
  669. if(*buf == '') continue;
  670. /* allocate a new node */
  671. if(((b            = zalloc(sizeof(*b)))            == NULL)
  672. #ifdef REGEX
  673. || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
  674. #endif
  675. ) {
  676. fclose(fp);
  677. goto load_forwardfile_error;
  678. }
  679. /* add it to the list */
  680. b->next  = bl->next;
  681. bl->next = b;
  682. /* save a copy of the orignal specification */
  683. if((b->url->spec = strdup(buf)) == NULL) {
  684. fclose(fp);
  685. goto load_forwardfile_error;
  686. }
  687. b->reject = reject;
  688. if((p = strchr(buf, '/'))) {
  689. b->url->path    = strdup(p);
  690. b->url->pathlen = strlen(b->url->path);
  691. *p = '';
  692. } else {
  693. b->url->path    = NULL;
  694. b->url->pathlen = 0;
  695. }
  696. #ifdef REGEX
  697. if(b->url->path) {
  698. int errcode;
  699. char rebuf[BUFSIZ];
  700. sprintf(rebuf, "^(%s)", b->url->path);
  701. errcode = regcomp(b->url->preg, rebuf,
  702. (REG_EXTENDED|REG_NOSUB|REG_ICASE));
  703. if(errcode) {
  704. size_t errlen =
  705. regerror(errcode,
  706. b->url->preg, buf, sizeof(buf));
  707. buf[errlen] = '';
  708. fprintf(logfp,
  709. "%s: error compiling %s: %sn",
  710. prog, b->url->spec, buf);
  711. fclose(fp);
  712. goto load_forwardfile_error;
  713. }
  714. } else {
  715. freez(b->url->preg);
  716. }
  717. #endif
  718. if((p = strchr(buf, ':')) == NULL) {
  719. port = 0;
  720. } else {
  721. *p++ = '';
  722. port = atoi(p);
  723. }
  724. b->url->port = port;
  725. if((b->url->domain = strdup(buf)) == NULL) {
  726. fclose(fp);
  727. goto load_forwardfile_error;
  728. }
  729. /* split domain into components */
  730. *url = dsplit(b->url->domain);
  731. b->url->dbuf = url->dbuf;
  732. b->url->dcnt = url->dcnt;
  733. b->url->dvec = url->dvec;
  734. /* now parse the gateway specs */
  735. p = vec[2];
  736. for(gw = gateways; gw->name; gw++) {
  737. if(strcmp(gw->name, p) == 0) {
  738. break;
  739. }
  740. }
  741. if(gw->name == NULL) {
  742. goto load_forwardfile_error;
  743. }
  744. /* save this as the gateway type */
  745. *b->gw = *gw;
  746. /* now parse the gateway host[:port] spec */
  747. p = vec[3];
  748. if(strcmp(p, ".") != 0) {
  749. b->gw->gateway_host = strdup(p);
  750. if((p = strchr(b->gw->gateway_host, ':'))) {
  751. *p++ = '';
  752. b->gw->gateway_port = atoi(p);
  753. }
  754. if(b->gw->gateway_port <= 0) {
  755. goto load_forwardfile_error;
  756. }
  757. }
  758. /* now parse the forwarding spec */
  759. p = vec[1];
  760. if(strcmp(p, ".") != 0) {
  761. b->gw->forward_host = strdup(p);
  762. if((p = strchr(b->gw->forward_host, ':'))) {
  763. *p++ = '';
  764. b->gw->forward_port = atoi(p);
  765. }
  766. if(b->gw->forward_port <= 0) {
  767. b->gw->forward_port = 8000;
  768. }
  769. }
  770. }
  771. fs->proxy_args = strsav(fs->proxy_args, "</pre>");
  772. freez(tmp);
  773. fclose(fp);
  774. /* the old one is now obsolete */
  775. if(current_forwardfile) {
  776. current_forwardfile->unloader = unload_forwardfile;
  777. }
  778. current_forwardfile = fs;
  779. return(0);
  780. load_forwardfile_error:
  781. fprintf(logfp, "%s: can't load forwardfile '%s': ",
  782. prog, forwardfile);
  783. fperror(logfp, "");
  784. return(-1);
  785. }
  786. #define JUNKBUSTERS "http://www.junkbusters.com"
  787. #define OPT "href="" JUNKBUSTERS "/ht/en/ijb" VERSION_MAJOR "man.html#"
  788. /* strsav() takes a pointer to a string stored in a dynamically allocated
  789.  * buffer and a pointer to a string and returns a pointer to a new dynamically
  790.  * allocated space that contains the concatenation of the two input strings
  791.  * the previous space is free()'d by realloc().
  792.  */
  793. char *
  794. strsav(char *old, char *text_to_append)
  795. {
  796. int old_len, new_len;
  797. char *p;
  798. if(( text_to_append == NULL)
  799. || (*text_to_append == '')) {
  800. return(old);
  801. }
  802. if(old) {
  803. old_len = strlen(old);
  804. } else {
  805. old_len = 0;
  806. }
  807. new_len = old_len + strlen(text_to_append) + 1;
  808. if(old) {
  809. if((p = realloc(old, new_len)) == NULL) {
  810. fprintf(logfp, "%s: realloc(%d) bytes for proxy_args failed!n", prog, new_len);
  811. exit(1);
  812. }
  813. } else {
  814. if((p = malloc(new_len)) == NULL) {
  815. fprintf(logfp, "%s: malloc(%d) bytes for proxy_args failed!n", prog, new_len);
  816. exit(1);
  817. }
  818. }
  819. strcpy(p + old_len, text_to_append);
  820. return(p);
  821. }
  822. void
  823. savearg(char *c, char *o)
  824. {
  825. char buf[BUFSIZ];
  826. static int one_shot = 1;
  827. if(one_shot) {
  828. one_shot = 0;
  829. proxy_args->invocation = strsav(proxy_args->invocation,
  830. "<br>n"
  831. "and the following options were set "
  832. "in the configuration file"
  833. "<br><br>n"
  834. );
  835. }
  836. *buf = '';
  837. if(c && *c) {
  838. if((c = url_encode(html_code_map, c))) {
  839. sprintf(buf, "<a " OPT "%s">%s</a> ", c, c);
  840. }
  841. freez(c);
  842. }
  843. if(o && *o) { 
  844. if((o = url_encode(html_code_map, o))) {
  845. if(strncmpic(o, "http://", 7) == 0) {
  846. strcat(buf, "<a href="");
  847. strcat(buf, o);
  848. strcat(buf, "">");
  849. strcat(buf, o);
  850. strcat(buf, "</a>");
  851. } else {
  852. strcat(buf, o);
  853. }
  854. }
  855. freez(o);
  856. }
  857. strcat(buf, "<br>n");
  858. proxy_args->invocation = strsav(proxy_args->invocation, buf);
  859. }
  860. void
  861. init_proxy_args(int argc, char *argv[])
  862. {
  863. struct gateway *g;
  864. int i;
  865. proxy_args->header = strsav(proxy_args->header,
  866. "HTTP/1.0 200 OKn"
  867. "Server: IJ/" VERSION "n"
  868. "Content-type: text/htmlnn"
  869. "<html>"
  870. "<head>"
  871. "<title>Internet Junkbuster Proxy Status</title>"
  872. "</head>n"
  873. "<body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink="#787878">n"
  874. "<center>n"
  875. "<h1>" BANNER "n"
  876. "<a href="" JUNKBUSTERS "/ht/en/ijb" VERSION_MAJOR "faq.html#show">Proxy Status</a>n"
  877. "</h1></center>n"
  878. "<h2>You are using the " BANNER " <sup><small><small>TM</small></small></sup></h2>n"
  879. "Version: IJ/" VERSION "n"
  880. "<p>n"
  881. );
  882. proxy_args->header = strsav(proxy_args->header,
  883. "<h2>The program was invoked as follows</h2>n");
  884. for(i=0; i < argc; i++) {
  885. proxy_args->header = strsav(proxy_args->header, argv[i]);
  886. proxy_args->header = strsav(proxy_args->header, " ");
  887. }
  888. proxy_args->header = strsav(proxy_args->header, "<br>n");
  889. proxy_args->gateways = strsav(proxy_args->gateways,
  890. "<h2>It supports the following gateway protocols:</h2>n");
  891. for(g = gateways; g->name; g++) {
  892. proxy_args->gateways = strsav(proxy_args->gateways, g->name);
  893. proxy_args->gateways = strsav(proxy_args->gateways, " ");
  894. }
  895. proxy_args->gateways = strsav(proxy_args->gateways, "<br>n");
  896. }
  897. void
  898. end_proxy_args()
  899. {
  900. char buf[BUFSIZ];
  901. char *b = NULL;
  902. extern char *acl_rcs, *bind_rcs, *conn_rcs, *encode_rcs,
  903. *jcc_rcs, *loaders_rcs, *parsers_rcs, *filters_rcs,
  904. *socks4_rcs, *ssplit_rcs, *gnu_regex_rcs, *win32_rcs;
  905. b = strsav(b, "<h2>Source versions:</h2>n");
  906. b = strsav(b, "<pre>");
  907. sprintf(buf, "%sn", jcc_rcs       ); b = strsav(b, buf);
  908. sprintf(buf, "%sn", parsers_rcs   ); b = strsav(b, buf);
  909. sprintf(buf, "%sn", filters_rcs   ); b = strsav(b, buf);
  910. sprintf(buf, "%sn", loaders_rcs   ); b = strsav(b, buf);
  911. sprintf(buf, "%sn", conn_rcs      ); b = strsav(b, buf);
  912. sprintf(buf, "%sn", bind_rcs      ); b = strsav(b, buf);
  913. sprintf(buf, "%sn", encode_rcs    ); b = strsav(b, buf);
  914. sprintf(buf, "%sn", socks4_rcs    ); b = strsav(b, buf);
  915. sprintf(buf, "%sn", ssplit_rcs    ); b = strsav(b, buf);
  916. sprintf(buf, "%sn", acl_rcs       ); b = strsav(b, buf);
  917. sprintf(buf, "%sn", gnu_regex_rcs ); b = strsav(b, buf);
  918. sprintf(buf, "%sn", win32_rcs     ); b = strsav(b, buf);
  919. b = strsav(b, "</pre>");
  920. #ifdef REGEX
  921. b = strsav(b, "<p>This " BANNER " supports POSIX regular expressions in the path specs.n");
  922. #endif
  923. b = strsav(b,
  924. "<small><small><p>n"
  925. "Code and documentation of the " BANNER " Proxy"
  926. "<sup><small>TM</small></sup>n"
  927. "<a href=""  JUNKBUSTERS "/ht/en/legal.html#copy">n" "Copyright</a>&#169; 1997 Junkbusters Corporationn"
  928. "<a href="" JUNKBUSTERS "/ht/en/legal.html#marks"><sup><small>TM</small></sup></a><br>n"
  929. "Copying and distribution permitted under the"
  930. "<a href=""  JUNKBUSTERS "/ht/en/gpl.html">n"
  931. "<small>GNU</small></a> "
  932. "General Public License.n"
  933. "</small>"
  934. "<address><kbd>webmaster@junkbusters.com</kbd></address>"
  935. "</small>"
  936. "</body></html>n"
  937. );
  938. proxy_args->trailer = b;
  939. }
  940. void
  941. add_loader(int (*loader)())
  942. {
  943. int i;
  944. for(i=0; i < NLOADERS; i++) {
  945. if(loaders[i] == NULL) {
  946. loaders[i] = loader;
  947. break;
  948. }
  949. }
  950. }
  951. int
  952. run_loader(struct client_state *csp)
  953. {
  954. int ret = 0;
  955. int i;
  956. for(i=0; i < NLOADERS; i++) {
  957. if(loaders[i] == NULL) break;
  958. ret |= (loaders[i])(csp);
  959. }
  960. return(ret);
  961. }
  962. /* the way calloc() ought to be -acjc */
  963. void *
  964. zalloc(int size)
  965. {
  966. void *ret;
  967. if((ret = malloc(size))) {
  968. memset(ret, '', size);
  969. }
  970. return(ret);
  971. }