Only show "Local support" on templates conditionally:
[privoxy.git] / cgisimple.c
1 const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.5 2001/10/07 15:30:41 oes 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.5  2001/10/07 15:30:41  oes
40  *    Removed FEATURE_DENY_GZIP
41  *
42  *    Revision 1.4  2001/10/02 15:31:12  oes
43  *    Introduced show-request cgi
44  *
45  *    Revision 1.3  2001/09/22 16:34:44  jongfoster
46  *    Removing unneeded #includes
47  *
48  *    Revision 1.2  2001/09/19 18:01:11  oes
49  *    Fixed comments; cosmetics
50  *
51  *    Revision 1.1  2001/09/16 17:08:54  jongfoster
52  *    Moving simple CGI functions from cgi.c to new file cgisimple.c
53  *
54  *
55  **********************************************************************/
56 \f
57
58 #include "config.h"
59
60 #include <stdio.h>
61 #include <sys/types.h>
62 #include <stdlib.h>
63 #include <ctype.h>
64 #include <string.h>
65 #include <assert.h>
66
67 #ifdef _WIN32
68 #define snprintf _snprintf
69 #endif /* def _WIN32 */
70
71 #include "project.h"
72 #include "cgi.h"
73 #include "cgisimple.h"
74 #include "list.h"
75 #include "encode.h"
76 #include "jcc.h"
77 #include "filters.h"
78 #include "actions.h"
79 #include "miscutil.h"
80 #include "loadcfg.h"
81 #include "parsers.h"
82
83 const char cgisimple_h_rcs[] = CGISIMPLE_H_VERSION;
84
85
86 static char *show_rcs(void);
87 static void show_defines(struct map *exports);
88
89
90 /*********************************************************************
91  *
92  * Function    :  cgi_default
93  *
94  * Description :  CGI function that is called if no action was given.
95  *                Lists menu of available unhidden CGIs.
96  *               
97  * Parameters  :
98  *           1 :  csp = Current client state (buffers, headers, etc...)
99  *           2 :  rsp = http_response data structure for output
100  *           3 :  parameters = map of cgi parameters
101  *
102  * Returns     :  0
103  *
104  *********************************************************************/
105 int cgi_default(struct client_state *csp, struct http_response *rsp,
106                 struct map *parameters)
107 {
108    char *p;
109    char *tmp = NULL;
110    struct map *exports = default_exports(csp, "");
111
112    /* If there were other parameters, export a dump as "cgi-parameters" */
113    if(parameters)
114    {
115       p = dump_map(parameters);
116       tmp = strsav(tmp, "<p>What made you think this cgi takes parameters?\n"
117                         "Anyway, here they are, in case you're interested:</p>\n");
118       tmp = strsav(tmp, p);
119       map(exports, "cgi-parameters", 1, tmp, 0);
120       free(p);
121    }
122    else
123    {
124       map(exports, "cgi-parameters", 1, "", 1);
125    }
126
127    rsp->body = template_load(csp, "default");
128    template_fill(&rsp->body, exports);
129    free_map(exports);
130    return(0);
131
132 }
133
134
135
136
137 /*********************************************************************
138  *
139  * Function    :  cgi_error_404
140  *
141  * Description :  CGI function that is called if an unknow action was
142  *                given.
143  *               
144  * Parameters  :
145  *           1 :  csp = Current client state (buffers, headers, etc...)
146  *           2 :  rsp = http_response data structure for output
147  *           3 :  parameters = map of cgi parameters
148  *
149  * Returns     :  0
150  *
151  *********************************************************************/
152 int cgi_error_404(struct client_state *csp,
153                   struct http_response *rsp,
154                   struct map *parameters)
155 {
156    struct map *exports = default_exports(csp, NULL);
157
158    rsp->status = strdup("404 JunkBuster configuration page not found");
159    rsp->body = template_load(csp, "cgi-error-404");
160    template_fill(&rsp->body, exports);
161    free_map(exports);
162    return 0;
163 }
164
165
166 /*********************************************************************
167  *
168  * Function    :  cgi_show_request
169  *
170  * Description :  Show the client's request and what sed() would have
171  *                made of it.
172  *               
173  * Parameters  :
174  *           1 :  csp = Current client state (buffers, headers, etc...)
175  *           2 :  rsp = http_response data structure for output
176  *           3 :  parameters = map of cgi parameters
177  *
178  * Returns     :  0
179  *
180  *********************************************************************/
181 int cgi_show_request(struct client_state *csp, struct http_response *rsp,
182                 struct map *parameters)
183 {
184    char *p;
185    struct map *exports = default_exports(csp, "show-request");
186    
187    /*
188     * Repair the damage done to the IOB by get_header()
189     */
190    for (p = csp->iob->buf; p < csp->iob->eod; p++)
191    {
192       if (*p == '\0') *p = '\n';
193    }
194
195    /*
196     * Export the original client's request and the one we would
197     * be sending to the server if this wasn't a CGI call
198     */
199    map(exports, "client-request", 1, csp->iob->buf, 1);
200    map(exports, "processed-request", 1, sed(client_patterns, add_client_headers, csp), 0);
201    
202    rsp->body = template_load(csp, "show-request");
203    template_fill(&rsp->body, exports);
204    free_map(exports);
205    return(0);
206  
207 }
208
209
210 /*********************************************************************
211  *
212  * Function    :  cgi_send_banner
213  *
214  * Description :  CGI function that returns a banner. 
215  *
216  * Parameters  :
217  *           1 :  csp = Current client state (buffers, headers, etc...)
218  *           2 :  rsp = http_response data structure for output
219  *           3 :  parameters = map of cgi parameters
220  *
221  * CGI Parameters :
222  *           type : Selects the type of banner between "trans" and "jb".
223  *                  Defaults to "jb" if absent or != "trans".
224  *
225  * Returns     :  0
226  *
227  *********************************************************************/
228 int cgi_send_banner(struct client_state *csp, struct http_response *rsp,
229                     struct map *parameters)
230 {
231    if(strcmp(lookup(parameters, "type"), "trans"))
232    {
233       rsp->body = bindup(image_junkbuster_gif_data, image_junkbuster_gif_length);
234       rsp->content_length = image_junkbuster_gif_length;
235    }
236    else
237    {
238       rsp->body = bindup(image_blank_gif_data, image_blank_gif_length);
239       rsp->content_length = image_blank_gif_length;
240    }   
241
242    enlist(rsp->headers, "Content-Type: image/gif");
243    rsp->is_static = 1;
244
245    return(0);
246
247 }
248
249
250 /*********************************************************************
251  *
252  * Function    :  cgi_show_version
253  *
254  * Description :  CGI function that returns a a web page describing the
255  *                file versions of IJB.
256  *
257  * Parameters  :
258  *           1 :  csp = Current client state (buffers, headers, etc...)
259  *           2 :  rsp = http_response data structure for output
260  *           3 :  parameters = map of cgi parameters
261  *
262  * CGI Parameters : none
263  *
264  * Returns     :  0
265  *
266  *********************************************************************/
267 int cgi_show_version(struct client_state *csp, struct http_response *rsp,
268                      struct map *parameters)
269 {
270    struct map * exports = default_exports(csp, "show-version");
271
272    map(exports, "sourceversions", 1, show_rcs(), 0);  
273
274    rsp->body = template_load(csp, "show-version");
275    template_fill(&rsp->body, exports);
276    free_map(exports);
277
278    return(0);
279
280 }
281
282  
283 /*********************************************************************
284  *
285  * Function    :  cgi_show_status
286  *
287  * Description :  CGI function that returns a a web page describing the
288  *                current status of IJB.
289  *
290  * Parameters  :
291  *           1 :  csp = Current client state (buffers, headers, etc...)
292  *           2 :  rsp = http_response data structure for output
293  *           3 :  parameters = map of cgi parameters
294  *
295  * CGI Parameters : none
296  *
297  * Returns     :  0
298  *
299  *********************************************************************/
300 int cgi_show_status(struct client_state *csp, struct http_response *rsp,
301                     struct map *parameters)
302 {
303    char *s = NULL;
304    int i;
305
306    FILE * fp;
307    char buf[BUFFER_SIZE];
308    char * p;
309    const char * filename = NULL;
310    char * file_description = NULL;
311 #ifdef FEATURE_STATISTICS
312    float perc_rej;   /* Percentage of http requests rejected */
313    int local_urls_read;
314    int local_urls_rejected;
315 #endif /* ndef FEATURE_STATISTICS */
316
317    struct map * exports = default_exports(csp, "show-status");
318
319    switch (*(lookup(parameters, "file")))
320    {
321    case 'p':
322       if (csp->actions_list)
323       {
324          filename = csp->actions_list->filename;
325          file_description = "Actions List";
326       }
327       break;
328
329    case 'r':
330       if (csp->rlist)
331       {
332          filename = csp->rlist->filename;
333          file_description = "Regex Filter List";
334       }
335       break;
336
337 #ifdef FEATURE_TRUST
338    case 't':
339       if (csp->tlist)
340       {
341          filename = csp->tlist->filename;
342          file_description = "Trust List";
343       }
344       break;
345 #endif /* def FEATURE_TRUST */
346    }
347
348    if (NULL != filename)
349    {
350       map(exports, "file-description", 1, file_description, 1);
351       map(exports, "filepath", 1, html_encode(filename), 0);
352
353       if ((fp = fopen(filename, "r")) == NULL)
354       {
355          map(exports, "content", 1, "<h1>ERROR OPENING FILE!</h1>", 1);
356       }
357       else
358       {
359          while (fgets(buf, sizeof(buf), fp))
360          {
361             p = html_encode(buf);
362             if (p)
363             {
364                s = strsav(s, p);
365                freez(p);
366                s = strsav(s, "<br>");
367             }
368          }
369          fclose(fp);
370          map(exports, "contents", 1, s, 0);
371       }
372       rsp->body = template_load(csp, "show-status-file");
373       template_fill(&rsp->body, exports);
374       free_map(exports);
375       return(0);
376
377    }
378
379    map(exports, "redirect-url", 1, REDIRECT_URL, 1);
380    
381    s = NULL;
382    for (i=0; i < Argc; i++)
383    {
384       s = strsav(s, Argv[i]);
385       s = strsav(s, " ");
386    }
387    map(exports, "invocation", 1, s, 0);
388
389    map(exports, "options", 1, csp->config->proxy_args, 1);
390    show_defines(exports);
391
392 #ifdef FEATURE_STATISTICS
393    local_urls_read     = urls_read;
394    local_urls_rejected = urls_rejected;
395
396    /*
397     * Need to alter the stats not to include the fetch of this
398     * page.
399     *
400     * Can't do following thread safely! doh!
401     *
402     * urls_read--;
403     * urls_rejected--; * This will be incremented subsequently *
404     */
405
406    if (local_urls_read == 0)
407    {
408       map_block_killer(exports, "have-stats");
409    }
410    else
411    {
412       map_block_killer(exports, "have-no-stats");
413
414       perc_rej = (float)local_urls_rejected * 100.0F /
415             (float)local_urls_read;
416
417       sprintf(buf, "%d", local_urls_read);
418       map(exports, "requests-received", 1, buf, 1);
419
420       sprintf(buf, "%d", local_urls_rejected);
421       map(exports, "requests-blocked", 1, buf, 1);
422
423       sprintf(buf, "%6.2f", perc_rej);
424       map(exports, "percent-blocked", 1, buf, 1);
425    }
426
427 #else /* ndef FEATURE_STATISTICS */
428    map_block_killer(exports, "statistics");
429 #endif /* ndef FEATURE_STATISTICS */
430
431    if (csp->actions_list)
432    {
433       map(exports, "actions-filename", 1,  csp->actions_list->filename, 1);
434    }
435    else
436    {
437       map(exports, "actions-filename", 1, "None specified", 1);
438    }
439
440    if (csp->rlist)
441    {
442       map(exports, "re-filter-filename", 1,  csp->rlist->filename, 1);
443    }
444    else
445    {
446       map(exports, "re-filter-filename", 1, "None specified", 1);
447    }
448
449 #ifdef FEATURE_TRUST
450    if (csp->tlist)
451    {
452       map(exports, "trust-filename", 1,  csp->tlist->filename, 1);
453    }
454    else
455    {
456        map(exports, "trust-filename", 1, "None specified", 1);
457    }
458 #else
459    map_block_killer(exports, "trust-support");
460 #endif /* ndef FEATURE_TRUST */
461
462    rsp->body = template_load(csp, "show-status");
463    template_fill(&rsp->body, exports);
464    free_map(exports);
465    return(0);
466
467 }
468
469  
470 /*********************************************************************
471  *
472  * Function    :  cgi_show_url_info
473  *
474  * Description :  CGI function that determines and shows which actions
475  *                junkbuster will perform for a given url, and which
476  *                matches starting from the defaults have lead to that.
477  *
478  * Parameters  :
479  *           1 :  csp = Current client state (buffers, headers, etc...)
480  *           2 :  rsp = http_response data structure for output
481  *           3 :  parameters = map of cgi parameters
482  *
483  * CGI Parameters :
484  *            url : The url whose actions are to be determined.
485  *                  If url is unset, the url-given conditional will be
486  *                  set, so that all but the form can be suppressed in
487  *                  the template.
488  *
489  * Returns     :  0
490  *
491  *********************************************************************/
492 int cgi_show_url_info(struct client_state *csp, struct http_response *rsp,
493                       struct map *parameters)
494 {
495    char *url_param;
496    char *host = NULL;
497    struct map * exports = default_exports(csp, "show-url-info");
498
499    if (NULL == (url_param = strdup(lookup(parameters, "url"))) || *url_param == '\0')
500    {
501       map_block_killer(exports, "url-given");
502       map(exports, "url", 1, "", 1);
503    }
504    else
505    {
506       char *matches = NULL;
507       char *path;
508       char *s;
509       int port = 80;
510       int hits = 0;
511       struct file_list *fl;
512       struct url_actions *b;
513       struct url_spec url[1];
514       struct current_action_spec action[1];
515       
516       host = url_param;
517       host += (strncmp(url_param, "http://", 7)) ? 0 : 7;
518
519       map(exports, "url", 1, host, 1);
520       map(exports, "url-html", 1, html_encode(host), 0);
521
522       init_current_action(action);
523
524       s = current_action_to_text(action);
525       map(exports, "default", 1, s , 0);
526
527       if (((fl = csp->actions_list) == NULL) || ((b = fl->f) == NULL))
528       {
529          map(exports, "matches", 1, "none" , 1);
530          map(exports, "final", 1, lookup(exports, "default"), 1);
531
532          freez(url_param);
533          free_current_action(action);
534
535          rsp->body = template_load(csp, "show-url-info");
536          template_fill(&rsp->body, exports);
537          free_map(exports);
538
539          return 0;
540       }
541
542       s = strchr(host, '/');
543       if (s != NULL)
544       {
545          path = strdup(s);
546          *s = '\0';
547       }
548       else
549       {
550          path = strdup("");
551       }
552       s = strchr(host, ':');
553       if (s != NULL)
554       {
555          *s++ = '\0';
556          port = atoi(s);
557          s = NULL;
558       }
559
560       *url = dsplit(host);
561
562       /* if splitting the domain fails, punt */
563       if (url->dbuf == NULL)
564       {
565          map(exports, "matches", 1, "none" , 1);
566          map(exports, "final", 1, lookup(exports, "default"), 1);
567
568          freez(url_param);
569          freez(path);
570          free_current_action(action);
571
572          rsp->body = template_load(csp, "show-url-info");
573          template_fill(&rsp->body, exports);
574          free_map(exports);
575
576          return 0;
577       }
578
579       for (b = b->next; NULL != b; b = b->next)
580       {
581          if ((b->url->port == 0) || (b->url->port == port))
582          {
583             if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
584             {
585                if ((b->url->path == NULL) ||
586 #ifdef REGEX
587                   (regexec(b->url->preg, path, 0, NULL, 0) == 0)
588 #else
589                   (strncmp(b->url->path, path, b->url->pathlen) == 0)
590 #endif
591                )
592                {
593                   s = actions_to_text(b->action);
594                   matches = strsav(matches, "<b>{");
595                   matches = strsav(matches, s);
596                   matches = strsav(matches, " }</b><br>\n<code>");
597                   matches = strsav(matches, b->url->spec);
598                   matches = strsav(matches, "</code><br>\n<br>\n");
599                   freez(s);
600
601                   merge_current_action(action, b->action);
602                   hits++;
603                }
604             }
605          }
606       }
607
608       if (hits)
609       {
610          map(exports, "matches", 1, matches , 0);
611       }
612       else
613       {
614          map(exports, "matches", 1, "none", 1);
615       }
616       matches = NULL;
617
618       freez(url->dbuf);
619       freez(url->dvec);
620
621       freez(url_param);
622       freez(path);
623
624       s = current_action_to_text(action);
625       map(exports, "final", 1, s, 0);
626       s = NULL;
627
628       free_current_action(action);
629    }
630
631    rsp->body = template_load(csp, "show-url-info");
632    template_fill(&rsp->body, exports);
633    free_map(exports);
634    return 0;
635
636 }
637
638
639 /*********************************************************************
640  *
641  * Function    :  cgi_robots_txt
642  *
643  * Description :  CGI function to return "/robots.txt".
644  *
645  * Parameters  :
646  *           1 :  csp = Current client state (buffers, headers, etc...)
647  *           2 :  rsp = http_response data structure for output
648  *           3 :  parameters = map of cgi parameters
649  *
650  * CGI Parameters : None
651  *
652  * Returns     :  0
653  *
654  *********************************************************************/
655 int cgi_robots_txt(struct client_state *csp, struct http_response *rsp,
656                    struct map *parameters)
657 {
658    char buf[100];
659
660    rsp->body = strdup(
661       "# This is the Internet Junkbuster control interface.\n"
662       "# It isn't very useful to index it, and you're likely to break stuff.\n"
663       "# So go away!\n"
664       "\n"
665       "User-agent: *\n"
666       "Disallow: /\n"
667       "\n");
668
669    enlist_unique(rsp->headers, "Content-Type: text/plain", 13);
670
671    rsp->is_static = 1;
672
673    get_http_time(7 * 24 * 60 * 60, buf); /* 7 days into future */
674    enlist_unique_header(rsp->headers, "Expires", buf);
675
676    return 0;
677
678 }
679
680
681 /*********************************************************************
682  *
683  * Function    :  show_defines
684  *
685  * Description :  Create a string with all conditional #defines used
686  *                when building
687  *
688  * Parameters  :  None
689  *
690  * Returns     :  string 
691  *
692  *********************************************************************/
693 static void show_defines(struct map *exports)
694 {
695
696 #ifdef FEATURE_ACL
697    map_conditional(exports, "FEATURE_ACL", 1);
698 #else /* ifndef FEATURE_ACL */
699    map_conditional(exports, "FEATURE_ACL", 0);
700 #endif /* ndef FEATURE_ACL */
701
702 #ifdef FEATURE_COOKIE_JAR
703    map_conditional(exports, "FEATURE_COOKIE_JAR", 1);
704 #else /* ifndef FEATURE_COOKIE_JAR */
705    map_conditional(exports, "FEATURE_COOKIE_JAR", 0);
706 #endif /* ndef FEATURE_COOKIE_JAR */
707
708 #ifdef FEATURE_FAST_REDIRECTS
709    map_conditional(exports, "FEATURE_FAST_REDIRECTS", 1);
710 #else /* ifndef FEATURE_FAST_REDIRECTS */
711    map_conditional(exports, "FEATURE_FAST_REDIRECTS", 0);
712 #endif /* ndef FEATURE_FAST_REDIRECTS */
713
714 #ifdef FEATURE_FORCE_LOAD
715    map_conditional(exports, "FEATURE_FORCE_LOAD", 1);
716 #else /* ifndef FEATURE_FORCE_LOAD */
717    map_conditional(exports, "FEATURE_FORCE_LOAD", 0);
718 #endif /* ndef FEATURE_FORCE_LOAD */
719
720 #ifdef FEATURE_IMAGE_BLOCKING
721    map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 1);
722 #else /* ifndef FEATURE_IMAGE_BLOCKING */
723    map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 0);
724 #endif /* ndef FEATURE_IMAGE_BLOCKING */
725
726 #ifdef FEATURE_IMAGE_DETECT_MSIE
727    map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 1);
728 #else /* ifndef FEATURE_IMAGE_DETECT_MSIE */
729    map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 0);
730 #endif /* ndef FEATURE_IMAGE_DETECT_MSIE */
731
732 #ifdef FEATURE_KILL_POPUPS
733    map_conditional(exports, "FEATURE_KILL_POPUPS", 1);
734 #else /* ifndef FEATURE_KILL_POPUPS */
735    map_conditional(exports, "FEATURE_KILL_POPUPS", 0);
736 #endif /* ndef FEATURE_KILL_POPUPS */
737
738 #ifdef FEATURE_PTHREAD
739    map_conditional(exports, "FEATURE_PTHREAD", 1);
740 #else /* ifndef FEATURE_PTHREAD */
741    map_conditional(exports, "FEATURE_PTHREAD", 0);
742 #endif /* ndef FEATURE_PTHREAD */
743
744 #ifdef FEATURE_STATISTICS
745    map_conditional(exports, "FEATURE_STATISTICS", 1);
746 #else /* ifndef FEATURE_STATISTICS */
747    map_conditional(exports, "FEATURE_STATISTICS", 0);
748 #endif /* ndef FEATURE_STATISTICS */
749
750 #ifdef FEATURE_TOGGLE
751    map_conditional(exports, "FEATURE_TOGGLE", 1);
752 #else /* ifndef FEATURE_TOGGLE */
753    map_conditional(exports, "FEATURE_TOGGLE", 0);
754 #endif /* ndef FEATURE_TOGGLE */
755
756 #ifdef FEATURE_TRUST
757    map_conditional(exports, "FEATURE_TRUST", 1);
758 #else /* ifndef FEATURE_TRUST */
759    map_conditional(exports, "FEATURE_TRUST", 0);
760 #endif /* ndef FEATURE_TRUST */
761
762 #ifdef REGEX_GNU
763    map_conditional(exports, "REGEX_GNU", 1);
764 #else /* ifndef REGEX_GNU */
765    map_conditional(exports, "REGEX_GNU", 0);
766 #endif /* def REGEX_GNU */
767
768 #ifdef REGEX_PCRE
769    map_conditional(exports, "REGEX_PCRE", 1);
770 #else /* ifndef REGEX_PCRE */
771    map_conditional(exports, "REGEX_PCRE", 0);
772 #endif /* def REGEX_PCRE */
773
774 #ifdef STATIC_PCRE
775    map_conditional(exports, "STATIC_PCRE", 1);
776 #else /* ifndef STATIC_PCRE */
777    map_conditional(exports, "STATIC_PCRE", 0);
778 #endif /* ndef STATIC_PCRE */
779
780 #ifdef STATIC_PCRS
781    map_conditional(exports, "STATIC_PCRS", 1);
782 #else /* ifndef STATIC_PCRS */
783    map_conditional(exports, "STATIC_PCRS", 0);
784 #endif /* ndef STATIC_PCRS */
785
786    map(exports, "FORCE_PREFIX", 1, FORCE_PREFIX, 1);
787
788 }
789
790
791 /*********************************************************************
792  *
793  * Function    :  show_rcs
794  *
795  * Description :  Create a string with the rcs info for all sourcefiles
796  *
797  * Parameters  :  None
798  *
799  * Returns     :  string 
800  *
801  *********************************************************************/
802 static char *show_rcs(void)
803 {
804    char *b = NULL;
805    char buf[BUFFER_SIZE];
806
807    /* Instead of including *all* dot h's in the project (thus creating a
808     * tremendous amount of dependencies), I will concede to declaring them
809     * as extern's.  This forces the developer to add to this list, but oh well.
810     */
811
812 #define SHOW_RCS(__x)            \
813    {                             \
814       extern const char __x[];   \
815       sprintf(buf, "%s\n", __x); \
816       b = strsav(b, buf);        \
817    }
818
819    /* In alphabetical order */
820    SHOW_RCS(actions_h_rcs)
821    SHOW_RCS(actions_rcs)
822    SHOW_RCS(cgi_h_rcs)
823    SHOW_RCS(cgi_rcs)
824 #ifdef FEATURE_CGI_EDIT_ACTIONS
825    SHOW_RCS(cgiedit_h_rcs)
826    SHOW_RCS(cgiedit_rcs)
827 #endif /* def FEATURE_CGI_EDIT_ACTIONS */
828    SHOW_RCS(cgisimple_h_rcs)
829    SHOW_RCS(cgisimple_rcs)
830 #ifdef __MINGW32__
831    SHOW_RCS(cygwin_h_rcs)
832 #endif
833    SHOW_RCS(deanimate_h_rcs)
834    SHOW_RCS(deanimate_rcs)
835    SHOW_RCS(encode_h_rcs)
836    SHOW_RCS(encode_rcs)
837    SHOW_RCS(errlog_h_rcs)
838    SHOW_RCS(errlog_rcs)
839    SHOW_RCS(filters_h_rcs)
840    SHOW_RCS(filters_rcs)
841    SHOW_RCS(gateway_h_rcs)
842    SHOW_RCS(gateway_rcs)
843 #ifdef GNU_REGEX
844    SHOW_RCS(gnu_regex_h_rcs)
845    SHOW_RCS(gnu_regex_rcs)
846 #endif /* def GNU_REGEX */
847    SHOW_RCS(jbsockets_h_rcs)
848    SHOW_RCS(jbsockets_rcs)
849    SHOW_RCS(jcc_h_rcs)
850    SHOW_RCS(jcc_rcs)
851 #ifdef FEATURE_KILL_POPUPS
852    SHOW_RCS(killpopup_h_rcs)
853    SHOW_RCS(killpopup_rcs)
854 #endif /* def FEATURE_KILL_POPUPS */
855    SHOW_RCS(list_h_rcs)
856    SHOW_RCS(list_rcs)
857    SHOW_RCS(loadcfg_h_rcs)
858    SHOW_RCS(loadcfg_rcs)
859    SHOW_RCS(loaders_h_rcs)
860    SHOW_RCS(loaders_rcs)
861    SHOW_RCS(miscutil_h_rcs)
862    SHOW_RCS(miscutil_rcs)
863    SHOW_RCS(parsers_h_rcs)
864    SHOW_RCS(parsers_rcs)
865    SHOW_RCS(pcrs_rcs)
866    SHOW_RCS(pcrs_h_rcs)
867    SHOW_RCS(project_h_rcs)
868    SHOW_RCS(ssplit_h_rcs)
869    SHOW_RCS(ssplit_rcs)
870 #ifdef _WIN32
871 #ifndef _WIN_CONSOLE
872    SHOW_RCS(w32log_h_rcs)
873    SHOW_RCS(w32log_rcs)
874    SHOW_RCS(w32res_h_rcs)
875    SHOW_RCS(w32taskbar_h_rcs)
876    SHOW_RCS(w32taskbar_rcs)
877 #endif /* ndef _WIN_CONSOLE */
878    SHOW_RCS(win32_h_rcs)
879    SHOW_RCS(win32_rcs)
880 #endif /* def _WIN32 */
881
882 #undef SHOW_RCS
883
884    return(b);
885
886 }
887
888
889 /*
890   Local Variables:
891   tab-width: 3
892   end:
893 */