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