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

Contents 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 - (show 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 /*
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