Change from "alpha" to "beta" in configure.in
[privoxy.git] / cgisimple.c
1 const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.8 2001/11/13 00:14:07 jongfoster Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/cgisimple.c,v $
5  *
6  * Purpose     :  Simple CGIs to get information about JunkBuster's
7  *                status.
8  *                
9  *                Functions declared include:
10  * 
11  *
12  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
13  *                IJBSWA team.  http://ijbswa.sourceforge.net
14  *
15  *                Based on the Internet Junkbuster originally written
16  *                by and Copyright (C) 1997 Anonymous Coders and 
17  *                Junkbusters Corporation.  http://www.junkbusters.com
18  *
19  *                This program is free software; you can redistribute it 
20  *                and/or modify it under the terms of the GNU General
21  *                Public License as published by the Free Software
22  *                Foundation; either version 2 of the License, or (at
23  *                your option) any later version.
24  *
25  *                This program is distributed in the hope that it will
26  *                be useful, but WITHOUT ANY WARRANTY; without even the
27  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
28  *                PARTICULAR PURPOSE.  See the GNU General Public
29  *                License for more details.
30  *
31  *                The GNU General Public License should be included with
32  *                this file.  If not, you can view it at
33  *                http://www.gnu.org/copyleft/gpl.html
34  *                or write to the Free Software Foundation, Inc., 59
35  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
36  *
37  * Revisions   :
38  *    $Log: cgisimple.c,v $
39  *    Revision 1.8  2001/11/13 00:14:07  jongfoster
40  *    Fixing stupid bug now I've figured out what || means.
41  *    (It always returns 0 or 1, not one of it's paramaters.)
42  *
43  *    Revision 1.7  2001/10/23 21:48:19  jongfoster
44  *    Cleaning up error handling in CGI functions - they now send back
45  *    a HTML error page and should never cause a FATAL error.  (Fixes one
46  *    potential source of "denial of service" attacks).
47  *
48  *    CGI actions file editor that works and is actually useful.
49  *
50  *    Ability to toggle JunkBuster remotely using a CGI call.
51  *
52  *    You can turn off both the above features in the main configuration
53  *    file, e.g. if you are running a multi-user proxy.
54  *
55  *    Revision 1.6  2001/10/14 22:00:32  jongfoster
56  *    Adding support for a 404 error when an invalid CGI page is requested.
57  *
58  *    Revision 1.5  2001/10/07 15:30:41  oes
59  *    Removed FEATURE_DENY_GZIP
60  *
61  *    Revision 1.4  2001/10/02 15:31:12  oes
62  *    Introduced show-request cgi
63  *
64  *    Revision 1.3  2001/09/22 16:34:44  jongfoster
65  *    Removing unneeded #includes
66  *
67  *    Revision 1.2  2001/09/19 18:01:11  oes
68  *    Fixed comments; cosmetics
69  *
70  *    Revision 1.1  2001/09/16 17:08:54  jongfoster
71  *    Moving simple CGI functions from cgi.c to new file cgisimple.c
72  *
73  *
74  **********************************************************************/
75 \f
76
77 #include "config.h"
78
79 #include <stdio.h>
80 #include <sys/types.h>
81 #include <stdlib.h>
82 #include <ctype.h>
83 #include <string.h>
84 #include <assert.h>
85
86 #ifdef _WIN32
87 #define snprintf _snprintf
88 #endif /* def _WIN32 */
89
90 #include "project.h"
91 #include "cgi.h"
92 #include "cgisimple.h"
93 #include "list.h"
94 #include "encode.h"
95 #include "jcc.h"
96 #include "filters.h"
97 #include "actions.h"
98 #include "miscutil.h"
99 #include "loadcfg.h"
100 #include "parsers.h"
101
102 const char cgisimple_h_rcs[] = CGISIMPLE_H_VERSION;
103
104
105 static char *show_rcs(void);
106 static jb_err show_defines(struct map *exports);
107
108
109 /*********************************************************************
110  *
111  * Function    :  cgi_default
112  *
113  * Description :  CGI function that is called if no action was given.
114  *                Lists menu of available unhidden CGIs.
115  *               
116  * Parameters  :
117  *           1 :  csp = Current client state (buffers, headers, etc...)
118  *           2 :  rsp = http_response data structure for output
119  *           3 :  parameters = map of cgi parameters
120  *
121  * CGI Parameters : none
122  *
123  * Returns     :  JB_ERR_OK on success
124  *                JB_ERR_MEMORY on out-of-memory
125  *                (Problems other than out-of-memory should be
126  *                handled by this routine - it should set the
127  *                rsp appropriately and return "success")
128  *
129  *********************************************************************/
130 jb_err cgi_default(struct client_state *csp,
131                    struct http_response *rsp,
132                    const struct map *parameters)
133 {
134    char *p;
135    char *tmp;
136    struct map *exports;
137
138    assert(csp);
139    assert(rsp);
140    assert(parameters);
141
142    if (NULL == (exports = default_exports(csp, "")))
143    {
144       return JB_ERR_MEMORY;
145    }
146
147    /* If there were other parameters, export a dump as "cgi-parameters" */
148    if (parameters->first)
149    {
150       if (NULL == (p = dump_map(parameters)))
151       {
152          free_map(exports);
153          return JB_ERR_MEMORY;
154       }
155       tmp = strdup("<p>What made you think this cgi takes parameters?\n"
156                    "Anyway, here they are, in case you're interested:</p>\n");
157       string_append(&tmp, p);
158       free(p);
159       if (tmp == NULL)
160       {
161          free_map(exports);
162          return JB_ERR_MEMORY;
163       }
164       if (map(exports, "cgi-parameters", 1, tmp, 0))
165       {
166          return JB_ERR_MEMORY;
167       }
168    }
169    else
170    {
171       if (map(exports, "cgi-parameters", 1, "", 1))
172       {
173          return JB_ERR_MEMORY;
174       }
175    }
176
177    return template_fill_for_cgi(csp, "default", exports, rsp);
178 }
179
180
181
182
183 /*********************************************************************
184  *
185  * Function    :  cgi_error_404
186  *
187  * Description :  CGI function that is called if an unknown action was
188  *                given.
189  *               
190  * Parameters  :
191  *           1 :  csp = Current client state (buffers, headers, etc...)
192  *           2 :  rsp = http_response data structure for output
193  *           3 :  parameters = map of cgi parameters
194  *
195  * CGI Parameters : none
196  *
197  * Returns     :  JB_ERR_OK on success
198  *                JB_ERR_MEMORY on out-of-memory error.  
199  *
200  *********************************************************************/
201 jb_err cgi_error_404(struct client_state *csp,
202                      struct http_response *rsp,
203                      const struct map *parameters)
204 {
205    struct map *exports;
206
207    assert(csp);
208    assert(rsp);
209    assert(parameters);
210
211    if (NULL == (exports = default_exports(csp, NULL)))
212    {
213       return JB_ERR_MEMORY;
214    }
215
216    rsp->status = strdup("404 JunkBuster configuration page not found");
217    if (rsp->status == NULL)
218    {
219       free_map(exports);
220       return JB_ERR_MEMORY;
221    }
222
223    return template_fill_for_cgi(csp, "cgi-error-404", exports, rsp);
224 }
225
226
227 /*********************************************************************
228  *
229  * Function    :  cgi_show_request
230  *
231  * Description :  Show the client's request and what sed() would have
232  *                made of it.
233  *               
234  * Parameters  :
235  *           1 :  csp = Current client state (buffers, headers, etc...)
236  *           2 :  rsp = http_response data structure for output
237  *           3 :  parameters = map of cgi parameters
238  *
239  * CGI Parameters : none
240  *
241  * Returns     :  JB_ERR_OK on success
242  *                JB_ERR_MEMORY on out-of-memory error.  
243  *
244  *********************************************************************/
245 jb_err cgi_show_request(struct client_state *csp,
246                         struct http_response *rsp,
247                         const struct map *parameters)
248 {
249    char *p;
250    struct map *exports;
251
252    assert(csp);
253    assert(rsp);
254    assert(parameters);
255
256    if (NULL == (exports = default_exports(csp, "show-request")))
257    {
258       return JB_ERR_MEMORY;
259    }
260    
261    /*
262     * Repair the damage done to the IOB by get_header()
263     */
264    for (p = csp->iob->buf; p < csp->iob->eod; p++)
265    {
266       if (*p == '\0') *p = '\n';
267    }
268
269    /*
270     * Export the original client's request and the one we would
271     * be sending to the server if this wasn't a CGI call
272     */
273
274    if (map(exports, "client-request", 1, csp->iob->buf, 1))
275    {
276       free_map(exports);
277       return JB_ERR_MEMORY;
278    }
279
280    if (map(exports, "processed-request", 1, sed(client_patterns, add_client_headers, csp), 0))
281    {
282       free_map(exports);
283       return JB_ERR_MEMORY;
284    }
285    
286    return template_fill_for_cgi(csp, "show-request", exports, rsp);
287 }
288
289
290 /*********************************************************************
291  *
292  * Function    :  cgi_send_banner
293  *
294  * Description :  CGI function that returns a banner. 
295  *
296  * Parameters  :
297  *           1 :  csp = Current client state (buffers, headers, etc...)
298  *           2 :  rsp = http_response data structure for output
299  *           3 :  parameters = map of cgi parameters
300  *
301  * CGI Parameters :
302  *           type : Selects the type of banner between "trans" and "jb".
303  *                  Defaults to "jb" if absent or != "trans".
304  *
305  * Returns     :  JB_ERR_OK on success
306  *                JB_ERR_MEMORY on out-of-memory error.  
307  *
308  *********************************************************************/
309 jb_err cgi_send_banner(struct client_state *csp,
310                        struct http_response *rsp,
311                        const struct map *parameters)
312 {
313    if (strcmp(lookup(parameters, "type"), "trans"))
314    {
315       rsp->body = bindup(image_junkbuster_gif_data, image_junkbuster_gif_length);
316       rsp->content_length = image_junkbuster_gif_length;
317    }
318    else
319    {
320       rsp->body = bindup(image_blank_gif_data, image_blank_gif_length);
321       rsp->content_length = image_blank_gif_length;
322    }   
323
324    if (rsp->body == NULL)
325    {
326       return JB_ERR_MEMORY;
327    }
328
329    if (enlist(rsp->headers, "Content-Type: image/gif"))
330    {
331       return JB_ERR_MEMORY;
332    }
333
334    rsp->is_static = 1;
335
336    return JB_ERR_OK;
337
338 }
339
340
341 /*********************************************************************
342  *
343  * Function    :  cgi_show_version
344  *
345  * Description :  CGI function that returns a a web page describing the
346  *                file versions of IJB.
347  *
348  * Parameters  :
349  *           1 :  csp = Current client state (buffers, headers, etc...)
350  *           2 :  rsp = http_response data structure for output
351  *           3 :  parameters = map of cgi parameters
352  *
353  * CGI Parameters : none
354  *
355  * Returns     :  JB_ERR_OK on success
356  *                JB_ERR_MEMORY on out-of-memory error.  
357  *
358  *********************************************************************/
359 jb_err cgi_show_version(struct client_state *csp,
360                         struct http_response *rsp,
361                         const struct map *parameters)
362 {
363    struct map *exports;
364
365    assert(csp);
366    assert(rsp);
367    assert(parameters);
368
369    if (NULL == (exports = default_exports(csp, "show-version")))
370    {
371       return JB_ERR_MEMORY;
372    }
373
374    if (map(exports, "sourceversions", 1, show_rcs(), 0))
375    {
376       free_map(exports);
377       return JB_ERR_MEMORY;
378    }
379
380    return template_fill_for_cgi(csp, "show-version", exports, rsp);
381 }
382
383  
384 /*********************************************************************
385  *
386  * Function    :  cgi_show_status
387  *
388  * Description :  CGI function that returns a a web page describing the
389  *                current status of IJB.
390  *
391  * Parameters  :
392  *           1 :  csp = Current client state (buffers, headers, etc...)
393  *           2 :  rsp = http_response data structure for output
394  *           3 :  parameters = map of cgi parameters
395  *
396  * CGI Parameters :
397  *        file :  Which file to show.  Only first letter is checked,
398  *                valid values are:
399  *                - "p"ermissions (actions) file
400  *                - "r"egex
401  *                - "t"rust
402  *                Default is to show menu and other information.
403  *
404  * Returns     :  JB_ERR_OK on success
405  *                JB_ERR_MEMORY on out-of-memory error.  
406  *
407  *********************************************************************/
408 jb_err cgi_show_status(struct client_state *csp,
409                        struct http_response *rsp,
410                        const struct map *parameters)
411 {
412    char *s = NULL;
413    int i;
414
415    FILE * fp;
416    char buf[BUFFER_SIZE];
417    char * p;
418    const char * filename = NULL;
419    char * file_description = NULL;
420 #ifdef FEATURE_STATISTICS
421    float perc_rej;   /* Percentage of http requests rejected */
422    int local_urls_read;
423    int local_urls_rejected;
424 #endif /* ndef FEATURE_STATISTICS */
425    jb_err err;
426
427    struct map *exports;
428
429    assert(csp);
430    assert(rsp);
431    assert(parameters);
432
433    if (NULL == (exports = default_exports(csp, "show-status")))
434    {
435       return JB_ERR_MEMORY;
436    }
437
438    switch (*(lookup(parameters, "file")))
439    {
440    case 'p':
441       if (csp->actions_list)
442       {
443          filename = csp->actions_list->filename;
444          file_description = "Actions List";
445       }
446       break;
447
448    case 'r':
449       if (csp->rlist)
450       {
451          filename = csp->rlist->filename;
452          file_description = "Regex Filter List";
453       }
454       break;
455
456 #ifdef FEATURE_TRUST
457    case 't':
458       if (csp->tlist)
459       {
460          filename = csp->tlist->filename;
461          file_description = "Trust List";
462       }
463       break;
464 #endif /* def FEATURE_TRUST */
465    }
466
467    if (NULL != filename)
468    {
469       if ( map(exports, "file-description", 1, file_description, 1)
470         || map(exports, "filepath", 1, html_encode(filename), 0) )
471       {
472          free_map(exports);
473          return JB_ERR_MEMORY;
474       }
475
476       if ((fp = fopen(filename, "r")) == NULL)
477       {
478          if (map(exports, "content", 1, "<h1>ERROR OPENING FILE!</h1>", 1))
479          {
480             free_map(exports);
481             return JB_ERR_MEMORY;
482          }
483       }
484       else
485       {
486          s = strdup("");
487          while ((s != NULL) && fgets(buf, sizeof(buf), fp))
488          {
489             p = html_encode(buf);
490             if (p)
491             {
492                string_append(&s, p);
493                freez(p);
494                string_append(&s, "<br>");
495             }
496          }
497          fclose(fp);
498
499          if (map(exports, "contents", 1, s, 0))
500          {
501             free_map(exports);
502             return JB_ERR_MEMORY;
503          }
504       }
505
506       return template_fill_for_cgi(csp, "show-status-file", exports, rsp);
507    }
508
509    if (map(exports, "redirect-url", 1, REDIRECT_URL, 1))
510    {
511       free_map(exports);
512       return JB_ERR_MEMORY;
513    }
514    
515    s = strdup("");
516    for (i=0; i < Argc; i++)
517    {
518       string_append(&s, Argv[i]);
519       string_append(&s, " ");
520    }
521    if (map(exports, "invocation", 1, s, 0))
522    {
523       free_map(exports);
524       return JB_ERR_MEMORY;
525    }
526
527    err = map(exports, "options", 1, csp->config->proxy_args, 1);
528    if (!err) err = show_defines(exports);
529
530 #ifdef FEATURE_STATISTICS
531    local_urls_read     = urls_read;
532    local_urls_rejected = urls_rejected;
533
534    /*
535     * Need to alter the stats not to include the fetch of this
536     * page.
537     *
538     * Can't do following thread safely! doh!
539     *
540     * urls_read--;
541     * urls_rejected--; * This will be incremented subsequently *
542     */
543
544    if (local_urls_read == 0)
545    {
546       if (!err) err = map_block_killer(exports, "have-stats");
547    }
548    else
549    {
550       if (!err) err = map_block_killer(exports, "have-no-stats");
551
552       perc_rej = (float)local_urls_rejected * 100.0F /
553             (float)local_urls_read;
554
555       sprintf(buf, "%d", local_urls_read);
556       if (!err) err = map(exports, "requests-received", 1, buf, 1);
557
558       sprintf(buf, "%d", local_urls_rejected);
559       if (!err) err = map(exports, "requests-blocked", 1, buf, 1);
560
561       sprintf(buf, "%6.2f", perc_rej);
562       if (!err) err = map(exports, "percent-blocked", 1, buf, 1);
563    }
564
565 #else /* ndef FEATURE_STATISTICS */
566    err = err || map_block_killer(exports, "statistics");
567 #endif /* ndef FEATURE_STATISTICS */
568
569    if (csp->actions_list)
570    {
571       if (!err) err = map(exports, "actions-filename", 1,  csp->actions_list->filename, 1);
572    }
573    else
574    {
575       if (!err) err = map(exports, "actions-filename", 1, "None specified", 1);
576    }
577
578    if (csp->rlist)
579    {
580       if (!err) err = map(exports, "re-filter-filename", 1,  csp->rlist->filename, 1);
581    }
582    else
583    {
584       if (!err) err = map(exports, "re-filter-filename", 1, "None specified", 1);
585    }
586
587 #ifdef FEATURE_TRUST
588    if (csp->tlist)
589    {
590       if (!err) err = map(exports, "trust-filename", 1,  csp->tlist->filename, 1);
591    }
592    else
593    {
594       if (!err) err = map(exports, "trust-filename", 1, "None specified", 1);
595    }
596 #else
597    if (!err) err = map_block_killer(exports, "trust-support");
598 #endif /* ndef FEATURE_TRUST */
599
600    if (err)
601    {
602       free_map(exports);
603       return JB_ERR_MEMORY;
604    }
605
606    return template_fill_for_cgi(csp, "show-status", exports, rsp);
607 }
608
609  
610 /*********************************************************************
611  *
612  * Function    :  cgi_show_url_info
613  *
614  * Description :  CGI function that determines and shows which actions
615  *                junkbuster will perform for a given url, and which
616  *                matches starting from the defaults have lead to that.
617  *
618  * Parameters  :
619  *           1 :  csp = Current client state (buffers, headers, etc...)
620  *           2 :  rsp = http_response data structure for output
621  *           3 :  parameters = map of cgi parameters
622  *
623  * CGI Parameters :
624  *            url : The url whose actions are to be determined.
625  *                  If url is unset, the url-given conditional will be
626  *                  set, so that all but the form can be suppressed in
627  *                  the template.
628  *
629  * Returns     :  JB_ERR_OK on success
630  *                JB_ERR_MEMORY on out-of-memory error.  
631  *
632  *********************************************************************/
633 jb_err cgi_show_url_info(struct client_state *csp,
634                          struct http_response *rsp,
635                          const struct map *parameters)
636 {
637    const char *url_param_const;
638    char *host = NULL;
639    struct map *exports;
640
641    assert(csp);
642    assert(rsp);
643    assert(parameters);
644
645    if (NULL == (exports = default_exports(csp, "show-url-info")))
646    {
647       return JB_ERR_MEMORY;
648    }
649
650    url_param_const = lookup(parameters, "url");
651    if (*url_param_const == '\0')
652    {
653       if (map_block_killer(exports, "url-given")
654         || map(exports, "url", 1, "", 1))
655       {
656          free_map(exports);
657          return JB_ERR_MEMORY;
658       }
659    }
660    else
661    {
662       char *url_param;
663       char *matches;
664       char *path;
665       char *s;
666       int port = 80;
667       int hits = 0;
668       struct file_list *fl;
669       struct url_actions *b;
670       struct url_spec url[1];
671       struct current_action_spec action[1];
672       
673       if (NULL == (url_param = strdup(url_param_const)))
674       {
675          free_map(exports);
676          return JB_ERR_MEMORY;
677       }
678
679       host = url_param;
680       host += (strncmp(url_param, "http://", 7)) ? 0 : 7;
681
682       if (map(exports, "url", 1, host, 1)
683        || map(exports, "url-html", 1, html_encode(host), 0))
684       {
685          free(url_param);
686          free_map(exports);
687          return JB_ERR_MEMORY;
688       }
689
690       init_current_action(action);
691
692       s = current_action_to_text(action);
693       if (map(exports, "default", 1, s , 0))
694       {
695          free_current_action(action);
696          free(url_param);
697          free_map(exports);
698          return JB_ERR_MEMORY;
699       }
700
701       if (((fl = csp->actions_list) == NULL) || ((b = fl->f) == NULL))
702       {
703          jb_err err;
704
705          err = map(exports, "matches", 1, "none" , 1)
706             || map(exports, "final", 1, lookup(exports, "default"), 1);
707
708          free_current_action(action);
709          free(url_param);
710
711          if (err)
712          {
713             free_map(exports);
714             return JB_ERR_MEMORY;
715          }
716
717          return template_fill_for_cgi(csp, "show-url-info", exports, rsp);
718       }
719
720       s = strchr(host, '/');
721       if (s != NULL)
722       {
723          path = strdup(s);
724          *s = '\0';
725       }
726       else
727       {
728          path = strdup("");
729       }
730       if (NULL == path)
731       {
732          free_current_action(action);
733          free(url_param);
734          free_map(exports);
735          return JB_ERR_MEMORY;
736       }
737
738       s = strchr(host, ':');
739       if (s != NULL)
740       {
741          *s++ = '\0';
742          port = atoi(s);
743          s = NULL;
744       }
745
746       *url = dsplit(host);
747
748       /* if splitting the domain fails, punt */
749       if (url->dbuf == NULL)
750       {
751          jb_err err;
752          
753          err = map(exports, "matches", 1, "none" , 1)
754             || map(exports, "final", 1, lookup(exports, "default"), 1);
755
756          freez(url_param);
757          freez(path);
758          free_current_action(action);
759
760          if (err)
761          {
762             free_map(exports);
763             return JB_ERR_MEMORY;
764          }
765
766          return template_fill_for_cgi(csp, "show-url-info", exports, rsp);
767       }
768
769       matches = strdup("");
770
771       for (b = b->next; NULL != b; b = b->next)
772       {
773          if ((b->url->port == 0) || (b->url->port == port))
774          {
775             if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
776             {
777                if ((b->url->path == NULL) ||
778 #ifdef REGEX
779                   (regexec(b->url->preg, path, 0, NULL, 0) == 0)
780 #else
781                   (strncmp(b->url->path, path, b->url->pathlen) == 0)
782 #endif
783                )
784                {
785                   s = actions_to_text(b->action);
786                   if (s == NULL)
787                   {
788                      freez(url->dbuf);
789                      freez(url->dvec);
790
791                      free(url_param);
792                      free(path);
793                      free_current_action(action);
794                      free_map(exports);
795                      return JB_ERR_MEMORY;
796                   }
797                   string_append(&matches, "<b>{");
798                   string_append(&matches, s);
799                   string_append(&matches, " }</b><br>\n<code>");
800                   string_append(&matches, b->url->spec);
801                   string_append(&matches, "</code><br>\n<br>\n");
802                   free(s);
803
804                   merge_current_action(action, b->action); /* FIXME: Add error checking */
805                   hits++;
806                }
807             }
808          }
809       }
810
811       freez(url->dbuf);
812       freez(url->dvec);
813
814       free(url_param);
815       free(path);
816
817       if (matches == NULL)
818       {
819          free_current_action(action);
820          free_map(exports);
821          return JB_ERR_MEMORY;
822       }
823
824       if (!hits)
825       {
826          free(matches);
827          matches = strdup("none");
828       }
829       if (map(exports, "matches", 1, matches , 0))
830       {
831          free_current_action(action);
832          free_map(exports);
833          return JB_ERR_MEMORY;
834       }
835
836       s = current_action_to_text(action);
837
838       free_current_action(action);
839
840       if (map(exports, "final", 1, s, 0))
841       {
842          free_map(exports);
843          return JB_ERR_MEMORY;
844       }
845    }
846
847    return template_fill_for_cgi(csp, "show-url-info", exports, rsp);
848 }
849
850
851 /*********************************************************************
852  *
853  * Function    :  cgi_robots_txt
854  *
855  * Description :  CGI function to return "/robots.txt".
856  *
857  * Parameters  :
858  *           1 :  csp = Current client state (buffers, headers, etc...)
859  *           2 :  rsp = http_response data structure for output
860  *           3 :  parameters = map of cgi parameters
861  *
862  * CGI Parameters : None
863  *
864  * Returns     :  JB_ERR_OK on success
865  *                JB_ERR_MEMORY on out-of-memory error.  
866  *
867  *********************************************************************/
868 jb_err cgi_robots_txt(struct client_state *csp,
869                       struct http_response *rsp,
870                       const struct map *parameters)
871 {
872    char buf[100];
873    jb_err err;
874
875    rsp->body = strdup(
876       "# This is the Internet Junkbuster control interface.\n"
877       "# It isn't very useful to index it, and you're likely to break stuff.\n"
878       "# So go away!\n"
879       "\n"
880       "User-agent: *\n"
881       "Disallow: /\n"
882       "\n");
883    if (rsp->body == NULL)
884    {
885       return JB_ERR_MEMORY;
886    }
887
888    err = enlist_unique(rsp->headers, "Content-Type: text/plain", 13);
889
890    rsp->is_static = 1;
891
892    get_http_time(7 * 24 * 60 * 60, buf); /* 7 days into future */
893    if (!err) err = enlist_unique_header(rsp->headers, "Expires", buf);
894
895    return (err ? JB_ERR_MEMORY : JB_ERR_OK);
896 }
897
898
899 /*********************************************************************
900  *
901  * Function    :  show_defines
902  *
903  * Description :  Add to a map the state od all conditional #defines
904  *                used when building
905  *
906  * Parameters  :
907  *           1 :  exports = map to extend
908  *
909  * Returns     :  JB_ERR_OK on success
910  *                JB_ERR_MEMORY on out-of-memory error.  
911  *
912  *********************************************************************/
913 static jb_err show_defines(struct map *exports)
914 {
915    jb_err err = JB_ERR_OK;
916
917 #ifdef FEATURE_ACL
918    if (!err) err = map_conditional(exports, "FEATURE_ACL", 1);
919 #else /* ifndef FEATURE_ACL */
920    if (!err) err = map_conditional(exports, "FEATURE_ACL", 0);
921 #endif /* ndef FEATURE_ACL */
922
923 #ifdef FEATURE_CGI_EDIT_ACTIONS
924    if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 1);
925 #else /* ifndef FEATURE_COOKIE_JAR */
926    if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 0);
927 #endif /* ndef FEATURE_COOKIE_JAR */
928
929 #ifdef FEATURE_COOKIE_JAR
930    if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 1);
931 #else /* ifndef FEATURE_COOKIE_JAR */
932    if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 0);
933 #endif /* ndef FEATURE_COOKIE_JAR */
934
935 #ifdef FEATURE_FAST_REDIRECTS
936    if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 1);
937 #else /* ifndef FEATURE_FAST_REDIRECTS */
938    if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 0);
939 #endif /* ndef FEATURE_FAST_REDIRECTS */
940
941 #ifdef FEATURE_FORCE_LOAD
942    if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 1);
943 #else /* ifndef FEATURE_FORCE_LOAD */
944    if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 0);
945 #endif /* ndef FEATURE_FORCE_LOAD */
946
947 #ifdef FEATURE_IMAGE_BLOCKING
948    if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 1);
949 #else /* ifndef FEATURE_IMAGE_BLOCKING */
950    if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 0);
951 #endif /* ndef FEATURE_IMAGE_BLOCKING */
952
953 #ifdef FEATURE_IMAGE_DETECT_MSIE
954    if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 1);
955 #else /* ifndef FEATURE_IMAGE_DETECT_MSIE */
956    if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 0);
957 #endif /* ndef FEATURE_IMAGE_DETECT_MSIE */
958
959 #ifdef FEATURE_KILL_POPUPS
960    if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 1);
961 #else /* ifndef FEATURE_KILL_POPUPS */
962    if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 0);
963 #endif /* ndef FEATURE_KILL_POPUPS */
964
965 #ifdef FEATURE_PTHREAD
966    if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 1);
967 #else /* ifndef FEATURE_PTHREAD */
968    if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 0);
969 #endif /* ndef FEATURE_PTHREAD */
970
971 #ifdef FEATURE_STATISTICS
972    if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 1);
973 #else /* ifndef FEATURE_STATISTICS */
974    if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 0);
975 #endif /* ndef FEATURE_STATISTICS */
976
977 #ifdef FEATURE_TOGGLE
978    if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 1);
979 #else /* ifndef FEATURE_TOGGLE */
980    if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 0);
981 #endif /* ndef FEATURE_TOGGLE */
982
983 #ifdef FEATURE_TRUST
984    if (!err) err = map_conditional(exports, "FEATURE_TRUST", 1);
985 #else /* ifndef FEATURE_TRUST */
986    if (!err) err = map_conditional(exports, "FEATURE_TRUST", 0);
987 #endif /* ndef FEATURE_TRUST */
988
989 #ifdef REGEX_GNU
990    if (!err) err = map_conditional(exports, "REGEX_GNU", 1);
991 #else /* ifndef REGEX_GNU */
992    if (!err) err = map_conditional(exports, "REGEX_GNU", 0);
993 #endif /* def REGEX_GNU */
994
995 #ifdef REGEX_PCRE
996    if (!err) err = map_conditional(exports, "REGEX_PCRE", 1);
997 #else /* ifndef REGEX_PCRE */
998    if (!err) err = map_conditional(exports, "REGEX_PCRE", 0);
999 #endif /* def REGEX_PCRE */
1000
1001 #ifdef STATIC_PCRE
1002    if (!err) err = map_conditional(exports, "STATIC_PCRE", 1);
1003 #else /* ifndef STATIC_PCRE */
1004    if (!err) err = map_conditional(exports, "STATIC_PCRE", 0);
1005 #endif /* ndef STATIC_PCRE */
1006
1007 #ifdef STATIC_PCRS
1008    if (!err) err = map_conditional(exports, "STATIC_PCRS", 1);
1009 #else /* ifndef STATIC_PCRS */
1010    if (!err) err = map_conditional(exports, "STATIC_PCRS", 0);
1011 #endif /* ndef STATIC_PCRS */
1012
1013    if (!err) err = map(exports, "FORCE_PREFIX", 1, FORCE_PREFIX, 1);
1014
1015    return err;
1016 }
1017
1018
1019 /*********************************************************************
1020  *
1021  * Function    :  show_rcs
1022  *
1023  * Description :  Create a string with the rcs info for all sourcefiles
1024  *
1025  * Parameters  :  None
1026  *
1027  * Returns     :  A string, or NULL on out-of-memory.
1028  *
1029  *********************************************************************/
1030 static char *show_rcs(void)
1031 {
1032    char *result = strdup("");
1033    char buf[BUFFER_SIZE];
1034
1035    /* Instead of including *all* dot h's in the project (thus creating a
1036     * tremendous amount of dependencies), I will concede to declaring them
1037     * as extern's.  This forces the developer to add to this list, but oh well.
1038     */
1039
1040 #define SHOW_RCS(__x)              \
1041    {                               \
1042       extern const char __x[];     \
1043       sprintf(buf, "%s\n", __x);   \
1044       string_append(&result, buf); \
1045    }
1046
1047    /* In alphabetical order */
1048    SHOW_RCS(actions_h_rcs)
1049    SHOW_RCS(actions_rcs)
1050    SHOW_RCS(cgi_h_rcs)
1051    SHOW_RCS(cgi_rcs)
1052 #ifdef FEATURE_CGI_EDIT_ACTIONS
1053    SHOW_RCS(cgiedit_h_rcs)
1054    SHOW_RCS(cgiedit_rcs)
1055 #endif /* def FEATURE_CGI_EDIT_ACTIONS */
1056    SHOW_RCS(cgisimple_h_rcs)
1057    SHOW_RCS(cgisimple_rcs)
1058 #ifdef __MINGW32__
1059    SHOW_RCS(cygwin_h_rcs)
1060 #endif
1061    SHOW_RCS(deanimate_h_rcs)
1062    SHOW_RCS(deanimate_rcs)
1063    SHOW_RCS(encode_h_rcs)
1064    SHOW_RCS(encode_rcs)
1065    SHOW_RCS(errlog_h_rcs)
1066    SHOW_RCS(errlog_rcs)
1067    SHOW_RCS(filters_h_rcs)
1068    SHOW_RCS(filters_rcs)
1069    SHOW_RCS(gateway_h_rcs)
1070    SHOW_RCS(gateway_rcs)
1071 #ifdef GNU_REGEX
1072    SHOW_RCS(gnu_regex_h_rcs)
1073    SHOW_RCS(gnu_regex_rcs)
1074 #endif /* def GNU_REGEX */
1075    SHOW_RCS(jbsockets_h_rcs)
1076    SHOW_RCS(jbsockets_rcs)
1077    SHOW_RCS(jcc_h_rcs)
1078    SHOW_RCS(jcc_rcs)
1079 #ifdef FEATURE_KILL_POPUPS
1080    SHOW_RCS(killpopup_h_rcs)
1081    SHOW_RCS(killpopup_rcs)
1082 #endif /* def FEATURE_KILL_POPUPS */
1083    SHOW_RCS(list_h_rcs)
1084    SHOW_RCS(list_rcs)
1085    SHOW_RCS(loadcfg_h_rcs)
1086    SHOW_RCS(loadcfg_rcs)
1087    SHOW_RCS(loaders_h_rcs)
1088    SHOW_RCS(loaders_rcs)
1089    SHOW_RCS(miscutil_h_rcs)
1090    SHOW_RCS(miscutil_rcs)
1091    SHOW_RCS(parsers_h_rcs)
1092    SHOW_RCS(parsers_rcs)
1093    SHOW_RCS(pcrs_rcs)
1094    SHOW_RCS(pcrs_h_rcs)
1095    SHOW_RCS(project_h_rcs)
1096    SHOW_RCS(ssplit_h_rcs)
1097    SHOW_RCS(ssplit_rcs)
1098 #ifdef _WIN32
1099 #ifndef _WIN_CONSOLE
1100    SHOW_RCS(w32log_h_rcs)
1101    SHOW_RCS(w32log_rcs)
1102    SHOW_RCS(w32res_h_rcs)
1103    SHOW_RCS(w32taskbar_h_rcs)
1104    SHOW_RCS(w32taskbar_rcs)
1105 #endif /* ndef _WIN_CONSOLE */
1106    SHOW_RCS(win32_h_rcs)
1107    SHOW_RCS(win32_rcs)
1108 #endif /* def _WIN32 */
1109
1110 #undef SHOW_RCS
1111
1112    return result;
1113
1114 }
1115
1116
1117 /*
1118   Local Variables:
1119   tab-width: 3
1120   end:
1121 */