/[MITgcm]/mitgcm.org/devel/buildweb/pkg/swish-e/src/parse_conffile.c
ViewVC logotype

Annotation of /mitgcm.org/devel/buildweb/pkg/swish-e/src/parse_conffile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (hide annotations) (download) (vendor branch)
Fri Sep 20 19:47:29 2002 UTC (22 years, 10 months ago) by adcroft
Branch: Import, MAIN
CVS Tags: baseline, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
Importing web-site building process.

1 adcroft 1.1 /*
2     $Id: parse_conffile.c,v 1.77 2002/08/22 22:58:39 whmoseley Exp $
3     **
4     ** Copyright (C) 1995, 1996, 1997, 1998 Hewlett-Packard Company
5     ** Originally by Kevin Hughes, kev@kevcom.com, 3/11/94
6     **
7     ** This program and library is free software; you can redistribute it and/or
8     ** modify it under the terms of the GNU (Library) General Public License
9     ** as published by the Free Software Foundation; either version 2
10     ** of the License, or any later version.
11     **
12     ** This program is distributed in the hope that it will be useful,
13     ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14     ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     ** GNU (Library) General Public License for more details.
16     **
17     ** You should have received a copy of the GNU (Library) General Public License
18     ** along with this program; if not, write to the Free Software
19     ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20     */
21    
22     /* New file created from file.c 02/2001 jmruiz */
23     /* Contains routines for parsing the configuration file */
24    
25     /*
26     ** 2001-02-15 rasc ResultExtFormatName
27     ** 2001-03-03 rasc EnableAltaVistaSyntax
28     ** code optimize: getYesNoOrAbort
29     ** 2001-03-13 rasc SwishSearchOperators, SwishSearchDefaultRule
30     ** 2001-03-16 rasc TruncateDocSize nbytes
31     ** 2001-04-09 rasc Filters: options (opt.)
32     **
33     */
34    
35    
36     #include <limits.h> // for ULONG_MAX
37    
38     #include "swish.h"
39     #include "string.h"
40     #include "mem.h"
41     #include "list.h"
42     #include "file.h"
43     #include "metanames.h"
44     #include "hash.h"
45     #include "error.h"
46     #include "entities.h"
47     #include "filter.h"
48     #include "result_output.h"
49     #include "index.h"
50     #include "search.h"
51     #include "search_alt.h"
52     #include "parse_conffile.h"
53     #include "merge.h" /* Argh, needed for docprop.h */
54     #include "docprop.h"
55     /* removed stuff
56     #include "deflate.h"
57     */
58     #include "result_sort.h"
59     #include "db.h"
60     #include "extprog.h"
61     #ifdef HAVE_ZLIB
62     #include <zlib.h>
63     #endif
64    
65    
66    
67    
68     static int read_integer( char *string, char *message, int low, int high );
69     static void Build_ReplaceRules( char *name, char **params, regex_list **reg_list );
70     static void add_ExtractPath( char * name, SWISH *sw, struct metaEntry *m, char **params );
71     static int getDocTypeOrAbort(StringList * sl, int n);
72     static void readstopwordsfile(SWISH *, IndexFILE *, char *);
73     static void readusewordsfile(SWISH *, IndexFILE *, char *);
74     static void readbuzzwordsfile(SWISH *, IndexFILE *, char *);
75     static int parseconfline(SWISH *, StringList *);
76     static void get_undefined_meta_flags( char *w0, StringList * sl, UndefMetaFlag *setting );
77    
78    
79    
80    
81     /* Reads the configuration file and puts all the right options
82     ** in the right variables and structures.
83     */
84    
85     void getdefaults(SWISH * sw, char *conffile, int *hasdir, int *hasindex, int hasverbose)
86     {
87     int i,
88     gotdir,
89     gotindex;
90     char line[MAXSTRLEN];
91     FILE *fp;
92     int linenumber = 0;
93     int baddirective = 0;
94     StringList *sl;
95     IndexFILE *indexf = NULL;
96     unsigned char *StringValue = NULL;
97     struct swline *tmplist;
98     char *w0;
99    
100     gotdir = gotindex = 0;
101    
102     if ((fp = fopen(conffile, F_READ_TEXT)) == NULL || !isfile(conffile))
103     progerrno("Couldn't open the configuration file '%s': ", conffile);
104    
105     if ( sw->verbose >= 2 )
106     printf("Parsing config file '%s'\n", conffile );
107    
108    
109     /* Init default index file */
110     indexf = sw->indexlist = (IndexFILE *) addindexfile(sw->indexlist, INDEXFILE);
111    
112    
113     sl = NULL;
114    
115     while (fgets(line, MAXSTRLEN, fp) != NULL)
116     {
117     linenumber++;
118    
119     if ( sl )
120     freeStringList(sl);
121    
122     /* Parse line */
123     if (!(sl = parse_line(line)))
124     continue;
125    
126     if (!sl->n)
127     continue;
128    
129     w0 = sl->word[0]; /* Config Direct. = 1. word */
130    
131     if (w0[0] == '#')
132     continue; /* comment */
133    
134    
135    
136     if (strcasecmp(w0, "IndexDir") == 0)
137     {
138     if (sl->n > 1)
139     {
140     if (!*hasdir)
141     {
142     gotdir = 1;
143     grabCmdOptions(sl, 1, &sw->dirlist);
144     }
145     }
146     else
147     progerr("%s: requires at least one value", w0);
148    
149     continue;
150     }
151    
152    
153     if (strcasecmp(w0, "IncludeConfigFile") == 0)
154     {
155     if (sl->n == 2)
156     {
157     normalize_path( sl->word[1] );
158     getdefaults(sw, sl->word[1], hasdir, hasindex, hasverbose);
159     }
160     else
161     progerr("%s: requires one value", w0);
162    
163     continue;
164     }
165    
166    
167     if (strcasecmp(w0, "NoContents") == 0)
168     {
169     if (sl->n > 1)
170     {
171     grabCmdOptions(sl, 1, &sw->nocontentslist);
172     }
173     else
174     progerr("%s: requires at least one value", w0);
175    
176     continue;
177     }
178    
179    
180     if (strcasecmp(w0, "IndexFile") == 0)
181     {
182     if (!(*hasindex))
183     {
184     if (sl->n == 2)
185     {
186     gotindex = 1;
187     if (indexf->line)
188     efree(indexf->line);
189     indexf->line = estrdup(sl->word[1]);
190     normalize_path( indexf->line );
191     }
192     else
193     progerr("%s: requires one value", w0);
194     }
195    
196     continue;
197     }
198    
199    
200     if (strcasecmp(w0, "IndexReport") == 0)
201     {
202     if (sl->n == 2)
203     {
204     if (!hasverbose)
205     sw->verbose = read_integer( sl->word[1], w0, 0, 4 );
206     }
207     else
208     progerr("%s: requires one value", w0);
209     continue;
210     }
211    
212     if (strcasecmp(w0, "ParserWarnLevel") == 0)
213     {
214     if (sl->n == 2)
215     sw->parser_warn_level = read_integer( sl->word[1], w0, 0, 9 );
216     else
217     progerr("%s: requires one value", w0);
218     continue;
219     }
220    
221    
222     if (strcasecmp(w0, "obeyRobotsNoIndex") == 0)
223     {
224     sw->obeyRobotsNoIndex = getYesNoOrAbort(sl, 1, 1);
225     continue;
226     }
227    
228    
229     if (strcasecmp(w0, "AbsoluteLinks") == 0)
230     {
231     sw->AbsoluteLinks = getYesNoOrAbort(sl, 1, 1);
232     continue;
233     }
234    
235    
236    
237    
238     if (strcasecmp(w0, "MinWordLimit") == 0)
239     {
240     if (sl->n == 2)
241     {
242     indexf->header.minwordlimit = read_integer( sl->word[1], w0, 0, INT_MAX );
243     }
244     else
245     progerr("%s: requires one value", w0);
246     continue;
247     }
248    
249     if (strcasecmp(w0, "MaxWordLimit") == 0)
250     {
251     if (sl->n == 2)
252     {
253     indexf->header.maxwordlimit = read_integer( sl->word[1], w0, 0, INT_MAX );
254     }
255     else
256     progerr("%s: requires one value", w0);
257    
258     continue;
259     }
260    
261    
262     if (strcasecmp(w0, "IndexComments") == 0)
263     {
264     sw->indexComments = getYesNoOrAbort(sl, 1, 1);
265     continue;
266     }
267    
268    
269     if (strcasecmp(w0, "IgnoreNumberChars") == 0)
270     {
271     if (sl->n == 2)
272     {
273     indexf->header.numberchars = SafeStrCopy(indexf->header.numberchars, sl->word[1], &indexf->header.lennumberchars);
274     sortstring(indexf->header.numberchars);
275     makelookuptable(indexf->header.numberchars, indexf->header.numbercharslookuptable);
276     indexf->header.numberchars_used_flag = 1; /* Flag that it is used */
277     }
278     else
279     progerr("%s: requires one value (a set of characters)", w0);
280    
281     continue;
282     }
283    
284    
285     if (strcasecmp(w0, "WordCharacters") == 0)
286     {
287     if (sl->n == 2)
288     {
289     indexf->header.wordchars = SafeStrCopy(indexf->header.wordchars, sl->word[1], &indexf->header.lenwordchars);
290     sortstring(indexf->header.wordchars);
291     makelookuptable(indexf->header.wordchars, indexf->header.wordcharslookuptable);
292     }
293     else
294     progerr("%s: requires one value", w0);
295    
296     continue;
297     }
298    
299    
300     if (strcasecmp(w0, "BeginCharacters") == 0)
301     {
302     if (sl->n == 2)
303     {
304     indexf->header.beginchars = SafeStrCopy(indexf->header.beginchars, sl->word[1], &indexf->header.lenbeginchars);
305     sortstring(indexf->header.beginchars);
306     makelookuptable(indexf->header.beginchars, indexf->header.begincharslookuptable);
307     }
308     else
309     progerr("%s: requires one value", w0);
310     continue;
311     }
312    
313     if (strcasecmp(w0, "EndCharacters") == 0)
314     {
315     if (sl->n == 2)
316     {
317     indexf->header.endchars = SafeStrCopy(indexf->header.endchars, sl->word[1], &indexf->header.lenendchars);
318     sortstring(indexf->header.endchars);
319     makelookuptable(indexf->header.endchars, indexf->header.endcharslookuptable);
320     }
321     else
322     progerr("%s: requires one value", w0);
323    
324     continue;
325     }
326    
327    
328     if (strcasecmp(w0, "IgnoreLastChar") == 0)
329     {
330     if (sl->n == 2)
331     {
332     indexf->header.ignorelastchar = SafeStrCopy(indexf->header.ignorelastchar, sl->word[1], &indexf->header.lenignorelastchar);
333     sortstring(indexf->header.ignorelastchar);
334     makelookuptable(indexf->header.ignorelastchar, indexf->header.ignorelastcharlookuptable);
335     } /* Do nothing */
336     /* else progerr("%s: requires one value",w0); */
337    
338     continue;
339     }
340    
341     if (strcasecmp(w0, "IgnoreFirstChar") == 0)
342     {
343     if (sl->n == 2)
344     {
345     indexf->header.ignorefirstchar = SafeStrCopy(indexf->header.ignorefirstchar, sl->word[1], &indexf->header.lenignorefirstchar);
346     sortstring(indexf->header.ignorefirstchar);
347     makelookuptable(indexf->header.ignorefirstchar, indexf->header.ignorefirstcharlookuptable);
348     } /* Do nothing */
349     /* else progerr("%s: requires one value",w0); */
350    
351     continue;
352     }
353    
354    
355     if (strcasecmp(w0, "ReplaceRules") == 0)
356     {
357     if (sl->n > 2)
358     Build_ReplaceRules( w0, sl->word, &sw->replaceRegexps );
359     else
360     progerr("%s: requires at least two values", w0);
361    
362     continue;
363     }
364    
365    
366     if (strcasecmp(w0, "IndexName") == 0)
367     {
368     if (sl->n > 1)
369     {
370     StringValue = StringListToString(sl, 1);
371     indexf->header.indexn = SafeStrCopy(indexf->header.indexn, (char *)StringValue, &indexf->header.lenindexn);
372     efree(StringValue);
373     }
374     else
375     progerr("%s: requires a value", w0);
376     continue;
377     }
378    
379    
380     if (strcasecmp(w0, "IndexDescription") == 0)
381     {
382     if (sl->n > 1)
383     {
384     StringValue = StringListToString(sl, 1);
385     indexf->header.indexd = SafeStrCopy(indexf->header.indexd, (char *)StringValue, &indexf->header.lenindexd);
386     efree(StringValue);
387     }
388     else
389     progerr("%s: requires a value", w0);
390    
391     continue;
392     }
393    
394    
395     if (strcasecmp(w0, "IndexPointer") == 0)
396     {
397     if (sl->n > 1)
398     {
399     StringValue = StringListToString(sl, 1);
400     indexf->header.indexp = SafeStrCopy(indexf->header.indexp, (char *)StringValue, &indexf->header.lenindexp);
401     efree(StringValue);
402     }
403     else
404     progerr("%s: requires a value", w0);
405    
406     continue;
407     }
408    
409    
410     if (strcasecmp(w0, "IndexAdmin") == 0)
411     {
412     if (sl->n > 1)
413     {
414     StringValue = StringListToString(sl, 1);
415     indexf->header.indexa = SafeStrCopy(indexf->header.indexa, (char *)StringValue, &indexf->header.lenindexa);
416     efree(StringValue);
417     }
418     else
419     progerr("%s: requires one value", w0);
420    
421     continue;
422     }
423    
424    
425     if (strcasecmp(w0, "UseStemming") == 0)
426     {
427     if ( getYesNoOrAbort(sl, 1, 1) )
428     indexf->header.fuzzy_mode = set_fuzzy_mode( "Stemming" );
429    
430     continue;
431     }
432    
433     if (strcasecmp(w0, "UseSoundex") == 0)
434     {
435     if ( getYesNoOrAbort(sl, 1, 1) )
436     indexf->header.fuzzy_mode = set_fuzzy_mode( "Soundex" );
437    
438     continue;
439     }
440    
441    
442     if (strcasecmp(w0, "FuzzyIndexingMode") == 0)
443     {
444     if (sl->n != 2)
445     progerr("%s: requires one value", w0);
446    
447     indexf->header.fuzzy_mode = set_fuzzy_mode( sl->word[1] );
448     continue;
449     }
450    
451    
452    
453    
454    
455    
456    
457     if (strcasecmp(w0, "IgnoreTotalWordCountWhenRanking") == 0)
458     {
459     indexf->header.ignoreTotalWordCountWhenRanking = getYesNoOrAbort(sl, 1, 1);
460     continue;
461     }
462    
463    
464    
465     if (strcasecmp(w0, "TranslateCharacters") == 0)
466     {
467     if (sl->n >= 2)
468     {
469     if (!BuildTranslateChars(indexf->header.translatecharslookuptable, (unsigned char *)sl->word[1], (unsigned char *)sl->word[2]))
470     {
471     progerr("%s: requires two values (same length) or one translation rule", w0);
472     }
473     }
474     continue;
475     }
476    
477    
478     if (strcasecmp(w0, "ExtractPath") == 0)
479     {
480     struct metaEntry *m;
481     char **words;
482    
483     if (sl->n < 4)
484     progerr("%s: requires at least three values: metaname expression type and a expression/strings", w0);
485    
486     if ( !( m = getMetaNameByName( &indexf->header, sl->word[1])) )
487     m = addMetaEntry(&indexf->header, sl->word[1], META_INDEX, 0);
488    
489     words = sl->word;
490     words++; /* past metaname */
491     add_ExtractPath( w0, sw, m, words );
492    
493     continue;
494     }
495    
496     if (strcasecmp(w0, "ExtractPathDefault") == 0)
497     {
498     struct metaEntry *m;
499    
500     if (sl->n != 3)
501     progerr("%s: requires two values: metaname default_value", w0);
502    
503     if ( !( m = getMetaNameByName( &indexf->header, sl->word[1])) )
504     m = addMetaEntry(&indexf->header, sl->word[1], META_INDEX, 0);
505    
506     if ( m->extractpath_default )
507     progerr("%s already defined for meta '%s' as '%s'", w0, m->metaName, m->extractpath_default );
508    
509     m->extractpath_default = estrdup( sl->word[2] );
510    
511     continue;
512     }
513    
514    
515    
516    
517     if (strcasecmp(w0, "MetaNames") == 0)
518     {
519     if (sl->n <= 1)
520     progerr("%s: requires at least one value", w0);
521    
522     for (i = 1; i < sl->n; i++)
523     {
524     if ( getMetaNameByName( &indexf->header, sl->word[i]) )
525     progerr("%s - name '%s' is already a MetaName", w0, sl->word[i] );
526    
527     addMetaEntry(&indexf->header, sl->word[i], META_INDEX, 0);
528     }
529    
530     continue;
531     }
532    
533    
534    
535     if (strcasecmp(w0, "MetaNameAlias") == 0)
536     {
537     struct metaEntry *meta_entry;
538     struct metaEntry *new_meta;
539    
540     if (sl->n < 3)
541     progerr("%s: requires at least two values", w0);
542    
543    
544     /* Make sure first entry is not an alias */
545     /* Lookup entry, and do not follow alias */
546     if ( !(meta_entry = getMetaNameByNameNoAlias( &indexf->header, sl->word[1]) ) )
547     progerr("%s - name '%s' not a MetaName", w0, sl->word[1] );
548    
549    
550     if ( meta_entry->alias )
551     progerr("%s - name '%s' must not be an alias", w0, sl->word[1] );
552    
553    
554     for (i = 2; i < sl->n; i++)
555     {
556     if ( getMetaNameByNameNoAlias( &indexf->header, sl->word[i]) )
557     progerr("%s - name '%s' is already a MetaName or MetaNameAlias", w0, sl->word[i] );
558    
559     new_meta = addMetaEntry(&indexf->header, sl->word[i], meta_entry->metaType, 0);
560     new_meta->alias = meta_entry->metaID;
561     }
562    
563     continue;
564     }
565    
566    
567     /* Allow setting a bias on MetaNames */
568    
569     if (strcasecmp(w0, "MetaNamesRank") == 0)
570     {
571     struct metaEntry *meta_entry;
572     int rank = 0;
573    
574     if (sl->n < 3)
575     progerr("%s: requires only two or more values, a rank (integer) and a list of property names", w0);
576    
577    
578     rank = read_integer( sl->word[1], w0, -RANK_BIAS_RANGE, RANK_BIAS_RANGE ); // NOTE: if this is changed db.c must match
579    
580    
581     for (i = 2; i < sl->n; i++)
582     {
583     /* already exists? */
584     if ( (meta_entry = getMetaNameByNameNoAlias( &indexf->header, sl->word[i])) )
585     {
586     if ( meta_entry->alias )
587     progerr("Can't assign a rank to metaname '%s': it is an alias", meta_entry->metaName );
588    
589     if ( meta_entry->rank_bias )
590     progwarn("Why are you redefining the rank of metaname '%s'?", meta_entry->metaName );
591     }
592     else
593     meta_entry = addMetaEntry(&indexf->header, sl->word[i], META_INDEX, 0);
594    
595    
596     meta_entry->rank_bias = rank;
597     }
598    
599     continue;
600     }
601    
602    
603    
604    
605    
606     /* Meta name to extract out <a href> links */
607     if (strcasecmp(w0, "HTMLLinksMetaName") == 0)
608     {
609     if (sl->n <= 1)
610     progerr("%s: requires one value", w0);
611    
612     if ( !( sw->links_meta = getMetaNameByName( &indexf->header, sl->word[1]) ))
613     sw->links_meta = addMetaEntry(&indexf->header, sl->word[1], META_INDEX, 0);
614    
615     continue;
616     }
617    
618    
619     /* What to do with IMG ATL tags? */
620     if (strcasecmp(w0, "IndexAltTagMetaName") == 0)
621     {
622     if (sl->n <= 1)
623     progerr("%s: requires one value", w0);
624    
625     if ( strcasecmp( sl->word[1], "as-text" ) == 0)
626     {
627     sw->IndexAltTag = 1;
628     if ( sw->IndexAltTagMeta )
629     {
630     efree( sw->IndexAltTagMeta );
631     sw->IndexAltTagMeta = NULL;
632     }
633     }
634     else
635     {
636     sw->IndexAltTag = 1;
637     if ( sw->IndexAltTagMeta )
638     {
639     efree( sw->IndexAltTagMeta );
640     sw->IndexAltTagMeta = NULL;
641     }
642     sw->IndexAltTagMeta = estrdup( sl->word[1] );
643     }
644     continue;
645     }
646    
647    
648    
649    
650     /* Meta name to extract out <img src> links */
651     if (strcasecmp(w0, "ImageLinksMetaName") == 0)
652     {
653     if (sl->n <= 1)
654     progerr("%s: requires one value", w0);
655    
656     if ( !( sw->images_meta = getMetaNameByName( &indexf->header, sl->word[1]) ))
657     sw->images_meta = addMetaEntry(&indexf->header, sl->word[1], META_INDEX, 0);
658    
659     continue;
660     }
661    
662    
663    
664    
665    
666     if (strcasecmp(w0, "PropCompressionLevel") == 0)
667     {
668    
669     #ifdef HAVE_ZLIB
670     if (sl->n == 2)
671     {
672     sw->PropCompressionLevel = read_integer( sl->word[1], w0, 0, 9 );
673     }
674     else
675     progerr("%s: requires one value", w0);
676     #else
677     progwarn("%s: Swish not built with zlib support -- cannot compress", w0);
678     #endif
679     continue;
680     }
681    
682    
683     if (strcasecmp(w0, "PropertyNames") == 0)
684     {
685     if (sl->n <= 1)
686     progerr("%s: requires at least one value", w0);
687    
688     for (i = 1; i < sl->n; i++)
689     {
690     if ( getPropNameByName( &indexf->header, sl->word[i]) )
691     progerr("%s - name '%s' is already a PropertyName", w0, sl->word[i] );
692    
693     addMetaEntry(&indexf->header, sl->word[i], META_PROP|META_STRING|META_IGNORE_CASE, 0);
694     }
695    
696     continue;
697     }
698    
699    
700     if (strcasecmp(w0, "PropertyNamesIgnoreCase") == 0)
701     {
702     struct metaEntry *m;
703    
704     if (sl->n <= 1)
705     progerr("%s: requires at least one value", w0);
706    
707     for (i = 1; i < sl->n; i++)
708     {
709     if ( !(m = getPropNameByName( &indexf->header, sl->word[i])) )
710     addMetaEntry(&indexf->header, sl->word[i], META_PROP|META_STRING|META_IGNORE_CASE, 0);
711     else
712     {
713     if ( !is_meta_string( m ) )
714     progerr("%s - name '%s' is not a STRING type of Property", w0, sl->word[i] );
715    
716     m->metaType |= META_IGNORE_CASE;
717     }
718     }
719    
720     continue;
721     }
722    
723    
724    
725     if (strcasecmp(w0, "PropertyNamesCompareCase") == 0)
726     {
727     struct metaEntry *m;
728    
729     if (sl->n <= 1)
730     progerr("%s: requires at least one value", w0);
731    
732     for (i = 1; i < sl->n; i++)
733     {
734     if ( !(m = getPropNameByName( &indexf->header, sl->word[i])) )
735     addMetaEntry(&indexf->header, sl->word[i], META_PROP|META_STRING, 0);
736     else
737     {
738    
739     if ( !is_meta_string( m ) )
740     progerr("%s - name '%s' is not a STRING type of Property", w0, sl->word[i] );
741    
742     m->metaType &= ~META_IGNORE_CASE;
743     }
744     }
745    
746     continue;
747     }
748    
749    
750    
751     if (strcasecmp(w0, "PropertyNamesNumeric") == 0)
752     {
753     if (sl->n <= 1)
754     progerr("%s: requires at least one value", w0);
755    
756     for (i = 1; i < sl->n; i++)
757     {
758     if ( getPropNameByName( &indexf->header, sl->word[i]) )
759     progerr("%s - name '%s' is already a PropertyName", w0, sl->word[i] );
760    
761     addMetaEntry(&indexf->header, sl->word[i], META_PROP|META_NUMBER, 0);
762     }
763    
764     continue;
765     }
766     if (strcasecmp(w0, "PropertyNamesDate") == 0)
767     {
768     if (sl->n <= 1)
769     progerr("%s: requires at least one value", w0);
770    
771     for (i = 1; i < sl->n; i++)
772     {
773     if ( getPropNameByName( &indexf->header, sl->word[i]) )
774     progerr("%s - name '%s' is already a PropertyName", w0, sl->word[i] );
775    
776     addMetaEntry(&indexf->header, sl->word[i], META_PROP|META_DATE, 0);
777     }
778    
779     continue;
780     }
781    
782    
783     if (strcasecmp(w0, "PropertyNameAlias") == 0)
784     {
785     struct metaEntry *meta_entry;
786     struct metaEntry *new_meta;
787    
788     if (sl->n < 3)
789     progerr("%s: requires at least two values", w0);
790    
791    
792     /* Make sure first entry is not an alias */
793     /* Lookup entry, and do not follow alias */
794     if ( !(meta_entry = getPropNameByNameNoAlias( &indexf->header, sl->word[1]) ) )
795     progerr("%s - name '%s' not a PropertyName", w0, sl->word[1] );
796    
797    
798     if ( meta_entry->alias )
799     progerr("%s - name '%s' must not be an alias", w0, sl->word[1] );
800    
801    
802     for (i = 2; i < sl->n; i++)
803     {
804     if ( getPropNameByNameNoAlias( &indexf->header, sl->word[i]) )
805     progerr("%s - name '%s' is already a PropertyName or PropertyNameAlias", w0, sl->word[i] );
806    
807     new_meta = addMetaEntry(&indexf->header, sl->word[i], meta_entry->metaType, 0);
808     new_meta->alias = meta_entry->metaID;
809     }
810    
811     continue;
812     }
813    
814    
815     /* This allows setting a limit on a property's string length */
816     // One question would be if this should set the length on the alias, or the real property. */
817     // If on the alias then you could really fine tune:
818     // PropertyNames description
819     // PropertyNameAlias description td h1 h2 h3
820     // PropertyNameMaxLength 5000 description
821     // PropertyNameMaxLength 100 td
822     // PropertyNameMaxLength 10 h1 h2 h3
823     // then the total length would be 5000, but each one would be limited, too. I find that hard to imagine
824     // it would be useful. So the current design is you can only assign to a non-alias.
825    
826    
827     if (strcasecmp(w0, "PropertyNamesMaxLength") == 0)
828     {
829     struct metaEntry *meta_entry;
830     int max_length = 0;
831    
832     if (sl->n < 3)
833     progerr("%s: requires only two or more values, a length and a list of property names", w0);
834    
835    
836     max_length = read_integer( sl->word[1], w0, 0, INT_MAX );
837    
838    
839     for (i = 2; i < sl->n; i++)
840     {
841     /* already exists? */
842     if ( (meta_entry = getPropNameByNameNoAlias( &indexf->header, sl->word[i])) )
843     {
844     if ( meta_entry->alias )
845     progerr("Can't assign a length to property '%s': it is an alias", meta_entry->metaName );
846    
847     if ( meta_entry->max_len )
848     progwarn("Why are you redefining the max length of property '%s'?", meta_entry->metaName );
849    
850     if ( !is_meta_string( meta_entry ) )
851     progerr("%s - name '%s' is not a STRING type of Property", w0, sl->word[i] );
852     }
853     else
854     meta_entry = addMetaEntry(&indexf->header, sl->word[i], META_PROP|META_STRING, 0);
855    
856    
857     meta_entry->max_len = max_length;
858     }
859    
860     continue;
861     }
862    
863    
864    
865    
866    
867     if (strcasecmp(w0, "IgnoreWords") == 0)
868     {
869     if (sl->n > 1)
870     {
871     if (lstrstr(sl->word[1], "SwishDefault"))
872     {
873     progwarn("SwishDefault is obsolete. See the CHANGES file.");
874     }
875     else if (lstrstr(sl->word[1], "File:"))
876     { /* 2000-06-15 rasc */
877     if (sl->n == 3)
878     {
879     normalize_path( sl->word[2] );
880     readstopwordsfile(sw, indexf, sl->word[2]);
881     }
882     else
883     progerr("IgnoreWords File: requires path");
884     }
885     else
886     for (i = 1; i < sl->n; i++)
887     {
888     addstophash(&indexf->header, sl->word[i]);
889     }
890     }
891     else
892     progerr("%s: requires at least one value", w0);
893    
894     continue;
895     }
896    
897    
898     if (strcasecmp(w0, "BuzzWords") == 0) /* 2001-04-24 moseley */
899     {
900     if (sl->n > 1)
901     {
902     if (lstrstr(sl->word[1], "File:"))
903     {
904     if (sl->n == 3)
905     {
906     normalize_path( sl->word[2] );
907     readbuzzwordsfile(sw, indexf, sl->word[2]);
908     }
909     else
910     progerr("BuzzWords File: requires path");
911     }
912     else
913     for (i = 1; i < sl->n; i++)
914     {
915     addbuzzwordhash(&indexf->header, sl->word[i]);
916     }
917     }
918     else
919     progerr("%s: requires at least one value", w0);
920    
921     continue;
922     }
923    
924    
925     if (strcasecmp(w0, "UseWords") == 0)
926     { /* 11/00 Jmruiz */
927     indexf->header.is_use_words_flag = 1;
928     if (sl->n > 1)
929     {
930     if (lstrstr(sl->word[1], "File:"))
931     { /* 2000-06-15 rasc */
932     if (sl->n == 3)
933     {
934     normalize_path( sl->word[2] );
935     readusewordsfile(sw, indexf, sl->word[2]);
936     }
937     else
938     progerr("UseWords File: requires path");
939     }
940     else
941     for (i = 1; i < sl->n; i++)
942     {
943     addusehash(&indexf->header, sl->word[i]);
944     }
945     }
946     else
947     progerr("%s: requires at least one value", w0);
948    
949     continue;
950     }
951    
952    
953     /* IndexVerbose is supported for backwards compatibility */
954     if (strcasecmp(w0, "IndexVerbose") == 0)
955     {
956     sw->verbose = getYesNoOrAbort(sl, 1, 1);
957     if (sw->verbose)
958     sw->verbose = 3;
959    
960     continue;
961     }
962    
963    
964     if (strcasecmp(w0, "IndexOnly") == 0)
965     {
966     if (sl->n > 1)
967     {
968     grabCmdOptions(sl, 1, &sw->suffixlist);
969     }
970     else
971     progerr("%s: requires at least one value", w0);
972    
973     continue;
974     }
975    
976    
977     if (strcasecmp(w0, "IndexContents") == 0)
978     {
979     if (sl->n > 2)
980     {
981     struct IndexContents *ic = (struct IndexContents *) emalloc(sizeof(struct IndexContents));
982    
983     ic->DocType = getDocTypeOrAbort(sl, 1);
984     ic->patt = NULL;
985    
986     for (i = 2; i < sl->n; i++)
987     ic->patt = addswline(ic->patt, sl->word[i]);
988    
989     if (sw->indexcontents)
990     ic->next = sw->indexcontents;
991     else
992     ic->next = NULL;
993    
994     sw->indexcontents = ic;
995     }
996     else
997     progerr("%s: requires at least two values", w0);
998    
999     continue;
1000     }
1001    
1002    
1003     /* $$$ this needs fixing */
1004     if (strcasecmp(w0, "StoreDescription") == 0)
1005     {
1006     if (sl->n == 3 || sl->n == 4)
1007     {
1008     struct StoreDescription *sd = (struct StoreDescription *) emalloc(sizeof(struct StoreDescription));
1009    
1010     sd->DocType = getDocTypeOrAbort(sl, 1);
1011     sd->size = 0;
1012     sd->field = NULL;
1013     i = 2;
1014    
1015     if (sl->word[i][0] == '<' && sl->word[i][strlen(sl->word[i]) - 1] == '>')
1016     {
1017     sl->word[i][strlen(sl->word[i]) - 1] = '\0';
1018     sd->field = estrdup(sl->word[i] + 1);
1019     i++;
1020     }
1021    
1022     if (i < sl->n && isnumstring( (unsigned char *)sl->word[i] ))
1023     {
1024     sd->size = read_integer( sl->word[i], w0, 0, INT_MAX );
1025     }
1026     if (sl->n == 3 && !sd->field && !sd->size)
1027     progerr("%s: second parameter must be <fieldname> or a number", w0);
1028     if (sl->n == 4 && sd->field && !sd->size)
1029     progerr("%s: third parameter must be empty or a number", w0);
1030     if (sw->storedescription)
1031     sd->next = sw->storedescription;
1032     else
1033     sd->next = NULL;
1034    
1035     sw->storedescription = sd;
1036    
1037     /* Make sure there's a property name */
1038     if ( !getPropNameByName( &indexf->header, AUTOPROPERTY_SUMMARY) )
1039     addMetaEntry(&indexf->header, AUTOPROPERTY_SUMMARY, META_PROP|META_STRING, 0);
1040     }
1041     else
1042     progerr("%s: requires two or three values", w0);
1043    
1044     continue;
1045     }
1046    
1047    
1048     if (strcasecmp(w0, "DefaultContents") == 0)
1049     {
1050     if (sl->n > 1)
1051     {
1052     sw->DefaultDocType = getDocTypeOrAbort(sl, 1);
1053     }
1054     else
1055     progerr("%s: requires at least one value", w0);
1056    
1057     continue;
1058     }
1059    
1060    
1061     if (strcasecmp(w0, "BumpPositionCounterCharacters") == 0)
1062     {
1063     if (sl->n > 1)
1064     {
1065     indexf->header.bumpposchars = SafeStrCopy(indexf->header.bumpposchars, sl->word[1], &indexf->header.lenbumpposchars);
1066     sortstring(indexf->header.bumpposchars);
1067     makelookuptable(indexf->header.bumpposchars, indexf->header.bumpposcharslookuptable);
1068     }
1069     else
1070     progerr("%s: requires at least one value", w0);
1071    
1072     continue;
1073     }
1074    
1075    
1076     /* #### Added UndefinedMetaTags as defined by Bill Moseley */
1077     if (strcasecmp(w0, "UndefinedMetaTags") == 0)
1078     {
1079     get_undefined_meta_flags( w0, sl, &sw->UndefinedMetaTags );
1080     if ( !sw->UndefinedMetaTags )
1081     progerr("%s: possible values are error, ignore, index or auto", w0);
1082    
1083     continue;
1084     }
1085    
1086    
1087     if (strcasecmp(w0, "UndefinedXMLAttributes") == 0)
1088     {
1089     get_undefined_meta_flags( w0, sl, &sw->UndefinedXMLAttributes );
1090     continue;
1091     }
1092    
1093    
1094    
1095     if (strcasecmp(w0, "IgnoreMetaTags") == 0)
1096     {
1097     if (sl->n > 1)
1098     {
1099     grabCmdOptions(sl, 1, &sw->ignoremetalist);
1100     /* Go lowercase */
1101     for (tmplist = sw->ignoremetalist; tmplist; tmplist = tmplist->next)
1102     tmplist->line = strtolower(tmplist->line);
1103     }
1104     else
1105     progerr("%s: requires at least one value", w0);
1106    
1107     continue;
1108     }
1109    
1110    
1111     if (strcasecmp(w0, "XMLClassAttributes") == 0)
1112     {
1113     if (sl->n > 1)
1114     {
1115     grabCmdOptions(sl, 1, &sw->XMLClassAttributes);
1116     /* Go lowercase */
1117     for (tmplist = sw->XMLClassAttributes; tmplist; tmplist = tmplist->next)
1118     tmplist->line = strtolower(tmplist->line);
1119     }
1120     else
1121     progerr("%s: requires at least one value", w0);
1122    
1123     continue;
1124     }
1125    
1126    
1127     if (strcasecmp(w0, "DontBumpPositionOnStartTags") == 0)
1128     {
1129     if (sl->n > 1)
1130     grabCmdOptions(sl, 1, &sw->dontbumpstarttagslist);
1131     else
1132     progerr("%s: requires at least one value", w0);
1133    
1134     continue;
1135     }
1136    
1137     if (strcasecmp(w0, "DontBumpPositionOnEndTags") == 0)
1138     {
1139     if (sl->n > 1)
1140     grabCmdOptions(sl, 1, &sw->dontbumpendtagslist);
1141     else
1142     progerr("%s: requires at least one value", w0);
1143    
1144     continue;
1145     }
1146    
1147     if (strcasecmp(w0, "TruncateDocSize") == 0)
1148     { /* rasc 2001-03 */
1149     if (sl->n == 2 && isnumstring( (unsigned char *)sl->word[1] ))
1150     sw->truncateDocSize = atol(sl->word[1]);
1151     else
1152     progerr("%s: requires size parameter in bytes", w0);
1153    
1154     continue;
1155     }
1156    
1157    
1158     else if (configModule_Entities(sw, sl));
1159     else if (configModule_Filter(sw, sl)); /* rasc */
1160     else if (configModule_ResultOutput(sw, sl)); /* rasc */
1161     else if (configModule_SearchAlt(sw, sl)); /* rasc */
1162     /* Removed , patents ...
1163     else if (configModule_Deflate(sw, sl));*/ /* jmruiz */
1164     else if (configModule_ResultSort(sw, sl)); /* jmruiz */
1165     else if (configModule_DB(sw, sl)); /* jmruiz */
1166     else if (configModule_Search(sw, sl)); /* jmruiz */
1167     else if (configModule_Index(sw, sl)); /* jmruiz */
1168     else if (configModule_Prog(sw, sl));
1169     else if (!parseconfline(sw, sl))
1170     {
1171     printf("Bad directive on line #%d of file %s: %s\n", linenumber, conffile, line);
1172     if ( ++baddirective > 30 )
1173     progerr("Too many errors. Can not continue.");
1174     }
1175    
1176     }
1177    
1178     freeStringList(sl);
1179    
1180     fclose(fp);
1181    
1182     if (baddirective)
1183     exit(1);
1184     if (gotdir && !(*hasdir))
1185     *hasdir = 1;
1186     if (gotindex && !(*hasindex))
1187     *hasindex = 1;
1188     }
1189    
1190     /*************************************************************************
1191     * Fetch a integer
1192     *
1193     *************************************************************************/
1194    
1195     static int read_integer( char *string, char *message, int low, int high )
1196     {
1197     char *badchar;
1198     long num;
1199     int result;
1200    
1201     if ( !string )
1202     progerr("'%s' requires an integer between %d and %d.", message, low, high );
1203    
1204     num = strtol( string, &badchar, 10 );
1205    
1206     if ( num == LONG_MAX || num == LONG_MIN )
1207     progerrno("'%s': Failed to convert '%s' to a number: ", message, string );
1208    
1209     if ( *badchar )
1210     progerr("Invalid char '%c' found in argument to '%s %s'", badchar[0], message, string);
1211    
1212     result = (int)num;
1213    
1214    
1215     if ( result < low || result > high )
1216     progerr("'%s' value of '%d' is not an integer between %d and %d.", message, result, low, high );
1217    
1218    
1219     return result;
1220     }
1221    
1222    
1223    
1224    
1225     /*
1226     -- some config helper routines
1227     */
1228    
1229     /*
1230     -- check if word "n" in StringList is yes/no
1231     -- "lastparam": 0/1 = is param last one for config directive?
1232     -- returns 1 (yes) or 0 (no)
1233     -- aborts if not "yes" or "no" (and prints first word of array)
1234     -- aborts if lastparam set and is not last param...
1235     -- 2001-03-04 rasc
1236     */
1237    
1238     int getYesNoOrAbort(StringList * sl, int n, int lastparam)
1239     {
1240     if (lastparam && n < (sl->n - 1))
1241     {
1242     progerr("%s has too many paramter", sl->word[0], n);
1243     return 0;
1244     }
1245    
1246     if (n < sl->n)
1247     {
1248     if (!strcasecmp(sl->word[n], "yes") || !strcasecmp(sl->word[n], "on") || !strcasecmp(sl->word[n], "1") )
1249     return 1;
1250    
1251     if (!strcasecmp(sl->word[n], "no") || !strcasecmp(sl->word[n], "off") ||!strcasecmp(sl->word[n], "0"))
1252     return 0;
1253     }
1254     progerr("%s requires parameter #%d of yes|on|1 or no|off|0", sl->word[0], n);
1255     return 0;
1256     }
1257    
1258    
1259     static void add_ExtractPath( char *name, SWISH *sw, struct metaEntry *m, char **params )
1260     {
1261     path_extract_list *list = sw->pathExtractList;
1262     path_extract_list *last = NULL;
1263    
1264    
1265     while ( list && list->meta_entry != m )
1266     {
1267     last = list;
1268     list = list->next;
1269     }
1270    
1271    
1272     /* need to create a meta entry */
1273     if ( !list )
1274     {
1275     list = emalloc( sizeof( path_extract_list ));
1276     if ( last )
1277     last->next = list;
1278     else
1279     sw->pathExtractList = list;
1280    
1281     list->meta_entry = m;
1282     list->regex = NULL;
1283     list->next = NULL;
1284     }
1285    
1286     /* now add regular expression to list */
1287     Build_ReplaceRules( name, params, &list->regex ); /* compile and add to list of expression */
1288     }
1289    
1290    
1291     /********************************************************
1292     * Free a ExtractPath list
1293     *
1294     *********************************************************/
1295     void free_Extracted_Path( SWISH *sw )
1296     {
1297     path_extract_list *list = sw->pathExtractList;
1298     path_extract_list *next;
1299    
1300     while ( list )
1301     {
1302     next = list->next;
1303     free_regex_list( &list->regex );
1304     efree( list );
1305     list = next;
1306     }
1307    
1308     sw->pathExtractList = NULL;
1309     }
1310    
1311     /*********************************************************************
1312     * Builds regex substitution strings of the FileRules type
1313     * But also includex ExtractPath
1314     *
1315     *********************************************************************/
1316    
1317     static void Build_ReplaceRules( char *name, char **params, regex_list **reg_list )
1318     {
1319     char *pattern = NULL;
1320     char *replace = NULL;
1321     int cflags = REG_EXTENDED;
1322     int global = 0;
1323    
1324     params++;
1325    
1326     /* these two could be optimized, of course */
1327    
1328     if ( strcasecmp( params[0], "append") == 0 )
1329     {
1330     pattern = estrdup("$");
1331     replace = estrdup( params[1] );
1332     }
1333    
1334     else if ( strcasecmp( params[0], "prepend") == 0 )
1335     {
1336     pattern = estrdup("^");
1337     replace = estrdup(params[1]);
1338     }
1339    
1340    
1341     else if ( strcasecmp( params[0], "remove") == 0 )
1342     {
1343     pattern = estrdup(params[1]);
1344     replace = estrdup( "" );
1345     global++;
1346     }
1347    
1348    
1349     else if ( strcasecmp( params[0], "replace") == 0 )
1350     {
1351     pattern = estrdup(params[1]);
1352     replace = estrdup(params[2]);
1353     global++;
1354     }
1355    
1356    
1357     /* This should probably be moved to swregex.c */
1358     else if ( strcasecmp( params[0], "regex") == 0 )
1359     {
1360     add_replace_expression( name, reg_list, params[1] );
1361     return;
1362     }
1363    
1364    
1365     else
1366     progerr("%s: unknown argument '%s'. Must be prepend|append|remove|replace|regex.", name, params[0] );
1367    
1368    
1369     add_regular_expression( reg_list, pattern, replace, cflags, global, 0 );
1370    
1371     efree( pattern );
1372     efree( replace );
1373     }
1374    
1375    
1376    
1377    
1378     /*
1379     -- check if word "n" in StringList is a DocumentType
1380     -- returns (doctype-id)
1381     -- aborts if not a DocumentType, or no param
1382     -- 2001-03-04 rasc
1383     */
1384    
1385    
1386     int strtoDocType( char * s )
1387     {
1388     static struct
1389     {
1390     char *type;
1391     int id;
1392     }
1393     doc_map[] =
1394     {
1395     {"TXT", TXT},
1396     {"HTML", HTML},
1397     #ifdef HAVE_LIBXML2
1398     {"XML2", XML2 },
1399     {"HTML2", HTML2 },
1400     {"TXT2", TXT2 },
1401     #endif
1402     {"XML", XML},
1403     {"WML", WML}
1404     };
1405     int i;
1406    
1407     for (i = 0; i < sizeof(doc_map) / sizeof(doc_map[0]); i++)
1408     if ( strcasecmp(doc_map[i].type, s) == 0 )
1409     return doc_map[i].id;
1410    
1411     return 0;
1412     }
1413    
1414     static int getDocTypeOrAbort(StringList * sl, int n)
1415     {
1416     int doctype;
1417    
1418     if (n < sl->n)
1419     {
1420     doctype = strtoDocType( sl->word[n] );
1421    
1422     if (!doctype )
1423     progerr("%s: Unknown document type \"%s\"", sl->word[0], sl->word[n]);
1424     else
1425     return doctype;
1426     }
1427    
1428     progerr("%s: missing %d. parameter", sl->word[0], n);
1429     return 0; /* never happens */
1430     }
1431    
1432    
1433     /*
1434     -- helper routine for misc. indexing methods
1435     -- (called via "jump" function array)
1436     02/2001 Rewritten Jmruiz
1437     */
1438    
1439     void grabCmdOptions(StringList * sl, int start, struct swline **listOfWords)
1440     {
1441     int i;
1442    
1443     for (i = start; i < sl->n; i++)
1444     *listOfWords = (struct swline *) addswline(*listOfWords, sl->word[i]);
1445     return;
1446     }
1447    
1448    
1449    
1450     /* --------------------------------------------------------- */
1451    
1452    
1453    
1454    
1455     /*
1456     read stop words from file
1457     lines beginning with # are comments
1458     2000-06-15 rasc
1459    
1460     */
1461    
1462     static void readstopwordsfile(SWISH * sw, IndexFILE * indexf, char *stopw_file)
1463     {
1464     char line[MAXSTRLEN];
1465     FILE *fp;
1466     StringList *sl;
1467     int i;
1468    
1469    
1470     /* Not this reports "Sucess" on trying to open a directory. to lazy to fix now */
1471    
1472     if ((fp = fopen(stopw_file, F_READ_TEXT)) == NULL || !isfile(stopw_file))
1473     {
1474     progerrno("Couldn't open the stopword file '%s': ", stopw_file);
1475     }
1476    
1477    
1478     /* read all lines and store each word as stopword */
1479    
1480     while (fgets(line, MAXSTRLEN, fp) != NULL)
1481     {
1482     if (line[0] == '#' || line[0] == '\n')
1483     continue;
1484    
1485     sl = parse_line(line);
1486     if (sl && sl->n)
1487     {
1488     for (i = 0; i < sl->n; i++)
1489     {
1490     addstophash(&indexf->header, sl->word[i]);
1491     }
1492     freeStringList(sl);
1493     }
1494     }
1495    
1496     fclose(fp);
1497     return;
1498     }
1499    
1500     /* Read in buzzwords from file -- based on Rainer's readstopwordsfile, of course. */
1501     /* Might be nice to combine all these routines that do the same thing */
1502    
1503    
1504     static void readbuzzwordsfile(SWISH * sw, IndexFILE * indexf, char *stopw_file)
1505     {
1506     char line[MAXSTRLEN];
1507     FILE *fp;
1508     StringList *sl;
1509     int i;
1510    
1511    
1512     if ((fp = fopen(stopw_file, F_READ_TEXT)) == NULL || !isfile(stopw_file))
1513     {
1514     progerrno("Couldn't open the buzzword file '%s': ", stopw_file);
1515     }
1516    
1517    
1518     /* read all lines and store each word as stopword */
1519    
1520     while (fgets(line, MAXSTRLEN, fp) != NULL)
1521     {
1522     if (line[0] == '#' || line[0] == '\n')
1523     continue;
1524    
1525     sl = parse_line(line);
1526     if (sl && sl->n)
1527     {
1528     for (i = 0; i < sl->n; i++)
1529     {
1530     addbuzzwordhash(&indexf->header, sl->word[i]);
1531     }
1532     freeStringList(sl);
1533     }
1534     }
1535    
1536     fclose(fp);
1537     return;
1538     }
1539    
1540    
1541     static int parseconfline(SWISH * sw, StringList * sl)
1542     {
1543     /* invoke routine to parse config file lines */
1544     return (*IndexingDataSource->parseconfline_fn) (sw, (void *) sl);
1545     }
1546    
1547    
1548     /*
1549     read "use" words from file
1550     lines beginning with # are comments
1551     2000-11 jmruiz
1552    
1553     Based on readstopwordsfile (from rasc)
1554    
1555     */
1556    
1557     static void readusewordsfile(SWISH * sw, IndexFILE * indexf, char *usew_file)
1558     {
1559     char line[MAXSTRLEN];
1560     FILE *fp;
1561     StringList *sl;
1562     int i;
1563    
1564    
1565     if ((fp = fopen(usew_file, F_READ_TEXT)) == NULL || !isfile(usew_file))
1566     {
1567     progerrno("Couldn't open the useword file '%s': ", usew_file);
1568     }
1569    
1570    
1571     /* read all lines and store each word as useword */
1572    
1573     while (fgets(line, MAXSTRLEN, fp) != NULL)
1574     {
1575     if (line[0] == '#' || line[0] == '\n')
1576     continue;
1577    
1578     sl = parse_line(line);
1579     if (sl && sl->n)
1580     {
1581     for (i = 0; i < sl->n; i++)
1582     {
1583     addusehash(&indexf->header, sl->word[i]);
1584     }
1585     freeStringList(sl);
1586     }
1587     }
1588    
1589     fclose(fp);
1590     return;
1591     }
1592    
1593     static void get_undefined_meta_flags( char *w0, StringList * sl, UndefMetaFlag *setting )
1594     {
1595     if (sl->n != 2)
1596     progerr("%s: requires one value", w0);
1597    
1598     if (strcasecmp(sl->word[1], "error") == 0)
1599     *setting = UNDEF_META_ERROR;
1600    
1601     else if (strcasecmp(sl->word[1], "ignore") == 0)
1602     *setting = UNDEF_META_IGNORE;
1603    
1604     else if (strcasecmp(sl->word[1], "disable") == 0) // default for xml attributes
1605     *setting = UNDEF_META_DISABLE;
1606    
1607     else if (strcasecmp(sl->word[1], "auto") == 0)
1608     *setting = UNDEF_META_AUTO;
1609    
1610     else if (strcasecmp(sl->word[1], "index") == 0)
1611     *setting = UNDEF_META_INDEX;
1612     else
1613     progerr("%s: possible values are error, ignore, index or auto", w0);
1614     }
1615    
1616    
1617     void freeSwishConfigOptions( SWISH *sw )
1618     {
1619     /** Ah, these should all be in their own structure **/
1620    
1621     /* string lists */
1622     if (sw->dirlist)
1623     freeswline(sw->dirlist);
1624    
1625     if (sw->suffixlist)
1626     freeswline(sw->suffixlist);
1627    
1628     if (sw->nocontentslist)
1629     freeswline(sw->nocontentslist);
1630    
1631     if (sw->ignoremetalist)
1632     freeswline(sw->ignoremetalist);
1633    
1634     if (sw->XMLClassAttributes)
1635     freeswline(sw->XMLClassAttributes);
1636    
1637     if (sw->dontbumpstarttagslist)
1638     freeswline(sw->dontbumpstarttagslist);
1639    
1640     if (sw->dontbumpendtagslist)
1641     freeswline(sw->dontbumpendtagslist);
1642    
1643    
1644     /* IndexContents */
1645     {
1646     struct IndexContents *next;
1647     while ( sw->indexcontents )
1648     {
1649     next = sw->indexcontents->next;
1650    
1651     if ( sw->indexcontents->patt )
1652     freeswline( sw->indexcontents->patt );
1653    
1654     efree( sw->indexcontents );
1655     sw->indexcontents = next;
1656     }
1657     }
1658    
1659    
1660     /* StoreDescription */
1661     {
1662     struct StoreDescription *next;
1663     while ( sw->storedescription )
1664     {
1665     next = sw->storedescription->next;
1666     if ( sw->storedescription->field )
1667     efree( sw->storedescription->field );
1668    
1669     efree( sw->storedescription );
1670     sw->storedescription = next;
1671     }
1672     }
1673    
1674    
1675     }
1676    
1677    

  ViewVC Help
Powered by ViewVC 1.1.22