1##---------------------------------------------------------------------------##
2##  File:
3##	$Id: mhrcfile.pl,v 2.48 2010/12/31 21:37:00 ehood Exp $
4##  Author:
5##      Earl Hood       mhonarc@mhonarc.org
6##  Description:
7##      Routines for parsing resource files
8##---------------------------------------------------------------------------##
9##    MHonArc -- Internet mail-to-HTML converter
10##    Copyright (C) 1996-2001	Earl Hood, mhonarc@mhonarc.org
11##
12##    This program is free software; you can redistribute it and/or modify
13##    it under the terms of the GNU General Public License as published by
14##    the Free Software Foundation; either version 2 of the License, or
15##    (at your option) any later version.
16##
17##    This program is distributed in the hope that it will be useful,
18##    but WITHOUT ANY WARRANTY; without even the implied warranty of
19##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20##    GNU General Public License for more details.
21##
22##    You should have received a copy of the GNU General Public License
23##    along with this program; if not, write to the Free Software
24##    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25##    02111-1307, USA
26##---------------------------------------------------------------------------##
27
28package mhonarc;
29
30##---------------------------------------------------------------------------
31##	read_resource_file() reads the specifed resource file and any
32##	language variations.
33##
34sub read_resource_file {
35    my $filename = shift;
36    my $nowarn   = shift;
37    my $lang     = shift || $Lang;
38
39    my $file;
40    my $found = 0;
41    foreach $file (get_lang_file_list($filename, $lang)) {
42        if (-r $file) {
43            parse_resource_file($file);
44            ++$found;
45        } elsif (-e _) {
46            warn qq/Warning: "$file" is not readable\n/;
47        }
48    }
49    if (!$found && !$nowarn) {
50        warn qq/Warning: Unable to read resource file "$filename"\n/;
51    }
52    $found;
53}
54
55##---------------------------------------------------------------------------
56##	get_lang_file_list() returns list of filenames that include
57##	language setting.
58##
59sub get_lang_file_list {
60    my $pathname = shift;
61    my $lang = lc(shift || $Lang);
62    $lang =~ s/\s+//g;
63    return ($pathname) unless $lang;
64
65    my $codeset = '';
66    if ($lang =~ s/\.(.*)$//) {
67        $codeset = '.' . lc($1);
68    }
69
70    my @files   = ($pathname);
71    my $curbase = $pathname . '.';
72    my $tag;
73    foreach $tag (split(/[\-_]/, $lang)) {
74        next unless $tag =~ /\S/;
75        $curbase .= $tag;
76        push(@files, $curbase);
77        push(@files, $curbase . $codeset) if ($codeset);
78        $curbase .= '_';
79    }
80    @files;
81}
82
83##---------------------------------------------------------------------------
84##	parse_resource_file() parses the resource file.
85##	(The code for this routine could probably be simplified).
86##
87sub parse_resource_file {
88    my ($file) = shift;
89    my ($line,    $tag,    $label, $acro, $hr,  $type,
90        $routine, $plfile, $url,   $arg,  $tmp, @a
91    );
92    my ($elem, $attr, $override, $handle, $pathhead, $chop);
93    local ($_);
94    $override = 0;
95
96    $handle = &file_open($file);
97
98    if ($file =~ m%(.*)[$DIRSEPREX]%o) {
99        $pathhead = $1;
100        $MainRcDir = $pathhead unless defined $MainRcDir;
101        $pathhead .= $DIRSEP;    # for INCLUDE resource
102    } else {
103        $pathhead = '';
104    }
105
106    print STDOUT "Reading resource file: $file ...\n" unless $QUIET;
107    while (defined($line = <$handle>)) {
108        next unless $line =~ /^\s*<([^>]+)>/;
109        $attr = '';
110        ($elem, $attr) = split(' ', $1, 2);
111        $attr = '' unless defined($attr);
112        $elem =~ tr/A-Z/a-z/;
113        $override = ($attr =~ /override/i);
114        $chop     = ($attr =~ /chop/i);
115
116    FMTSW: {
117            if ($elem eq 'addressmodifycode') {    # Code to strip subjects
118                $AddressModify = &get_elem_content($handle, $elem, $chop);
119                last FMTSW;
120            }
121            if ($elem eq 'attachmentdir') {        # Attachments directory
122                if ($line = &get_elem_last_line($handle, $elem)) {
123                    $AttachmentDir = $line;
124                }
125                last FMTSW;
126            }
127            if ($elem eq 'attachmenturl') {        # Attachments URL
128                if ($line = &get_elem_last_line($handle, $elem)) {
129                    $AttachmentUrl = $line;
130                }
131                last FMTSW;
132            }
133            if (   $elem eq 'authorbegin'
134                || $elem eq 'authorbeg') {         # Begin for author group
135                $AUTHBEG = &get_elem_content($handle, $elem, $chop);
136                last FMTSW;
137            }
138            if ($elem eq 'authorend') {            # End for author group
139                $AUTHEND = &get_elem_content($handle, $elem, $chop);
140                last FMTSW;
141            }
142            if ($elem eq 'authsort') {             # Sort msgs by author
143                $AUTHSORT = 1;
144                $NOSORT   = 0;
145                $SUBSORT  = 0;
146                last FMTSW;
147            }
148            if ($elem eq 'botlinks') {             # Bottom links in message
149                $BOTLINKS = &get_elem_content($handle, $elem, $chop);
150                last FMTSW;
151            }
152            if ($elem eq 'charsetaliases') {       # Charset aliases
153                $IsDefault{'CHARSETALIASES'} = 0;
154                readmail::MAILset_charset_aliases({}, $override);
155                while (defined($line = <$handle>)) {
156                    last if $line =~ /^\s*<\/charsetaliases\s*>/i;
157                    next unless $line =~ /\S/;
158                    $line =~ s/\s//g;
159                    ($name, $aliases) = split(/;/, $line, 2);
160                    readmail::MAILset_charset_aliases(
161                        {$name => [split(/,/, $aliases)]});
162                }
163                last FMTSW;
164            }
165            if ($elem eq 'charsetconverters') {    # Charset filters
166                $IsDefault{'CHARSETCONVERTERS'} = 0;
167                if ($override) {
168                    %readmail::MIMECharSetConverters    = ();
169                    %readmail::MIMECharSetConvertersSrc = ();
170                }
171                while (defined($line = <$handle>)) {
172                    last if $line =~ /^\s*<\/charsetconverters\s*>/i;
173                    next if $line =~ /^\s*$/;
174                    $line =~ s/\s//g;
175                    ($type, $routine, $plfile) = split(/;/, $line, 3);
176                    $type                                      = lc($type);
177                    $readmail::MIMECharSetConverters{$type}    = $routine;
178                    $readmail::MIMECharSetConvertersSrc{$type} = $plfile
179                        if defined($plfile)
180                        and $plfile =~ /\S/;
181                }
182                last FMTSW;
183            }
184            if ($elem eq 'checknoarchive') {
185                $CheckNoArchive = 1;
186                last FMTSW;
187            }
188            if ($elem eq 'conlen') {
189                $CONLEN = 1;
190                last FMTSW;
191            }
192            if ($elem eq 'datefields') {
193                @a = &get_list_content($handle, $elem);
194                if (@a) { @DateFields = @a; }
195                last FMTSW;
196            }
197            if (   $elem eq 'daybegin'
198                || $elem eq 'daybeg') {    # Begin for day group
199                $DAYBEG = &get_elem_content($handle, $elem, $chop);
200                last FMTSW;
201            }
202            if ($elem eq 'dayend') {       # End for day group
203                $DAYEND = &get_elem_content($handle, $elem, $chop);
204                last FMTSW;
205            }
206            if ($elem eq 'dbfileperms') {    # DBFILE creation permissions
207                if ($line = &get_elem_last_line($handle, $elem)) {
208                    $line =~ s/\s//g;
209                    $DbFilePerms = $line;
210                }
211                last FMTSW;
212            }
213            if ($elem eq 'decodeheads') {
214                $DecodeHeads = 1;
215                last FMTSW;
216            }
217            if ($elem eq 'definederived') {    # Custom derived file
218                %UDerivedFile = () if $override;
219                $line = <$handle>;
220                last FMTSW if $line =~ /^\s*<\/definederived\s*>/i;
221                $line =~ s/\s//g;
222                $UDerivedFile{$line} =
223                    &get_elem_content($handle, $elem, $chop);
224                last FMTSW;
225            }
226            if ($elem eq 'definevar') {        # Custom resource variable
227                %CustomRcVars = () if $override;
228                $line = <$handle>;
229                last FMTSW if $line =~ /^\s*<\/definevar\s*>/i;
230                $line =~ s/\s//g;
231                $CustomRcVars{$line} =
232                    &get_elem_content($handle, $elem, $chop);
233                last FMTSW;
234            }
235            if ($elem eq 'doc') {              # Link to documentation
236                $NODOC = 0;
237                last FMTSW;
238            }
239            if ($elem eq 'docurl') {           # Doc URL
240                if ($line = &get_elem_last_line($handle, $elem)) {
241                    $DOCURL = $line;
242                }
243                last FMTSW;
244            }
245            if ($elem eq 'excs') {             # Exclude header fields
246                %HFieldsExc = () if $override;
247                while (defined($line = <$handle>)) {
248                    last if $line =~ /^\s*<\/excs\s*>/i;
249                    next unless $line =~ /\S/;
250                    $line =~ s/\s//g;
251                    $line =~ tr/A-Z/a-z/;
252                    $HFieldsExc{$line} = 1 if $line;
253                }
254                last FMTSW;
255            }
256            if ($elem eq 'expireage') {        # Time in seconds until expire
257                if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
258                    $ExpireTime = $tmp;
259                }
260                last FMTSW;
261            }
262            if ($elem eq 'expiredate') {       # Expiration date
263                if ($line = &get_elem_last_line($handle, $elem)) {
264                    $ExpireDate = $line;
265                }
266                last FMTSW;
267            }
268            if ($elem eq 'fasttempfiles') {    # Non-random temp files
269                $FastTempFiles = 1;
270                last FMTSW;
271            }
272            if ($elem eq 'followsymlinks') {    # Allow/follow symlinks
273                $FollowSymlinks = 1;
274                last FMTSW;
275            }
276            if ($elem eq 'fieldstore') {        # Fields to store
277                @ExtraHFields = () if $override;
278                while (defined($line = <$handle>)) {
279                    last if $line =~ /^\s*<\/fieldstore\s*>/i;
280                    next unless $line =~ /\S/;
281                    $line =~ s/\s+//g;
282                    $line =~ tr/A-Z/a-z/;
283                    push(@ExtraHFields, $line);
284                }
285                last FMTSW;
286            }
287            if ($elem eq 'fieldstyles') {       # Field text style
288                while (defined($line = <$handle>)) {
289                    last if $line =~ /^\s*<\/fieldstyles\s*>/i;
290                    next if $line =~ /^\s*$/;
291                    $line =~ s/\s//g;
292                    $line =~ tr/A-Z/a-z/;
293                    ($label, $tag) = split(/:/, $line);
294                    $HeadFields{$label} = $tag;
295                }
296                last FMTSW;
297            }
298            if ($elem eq 'fieldorder') {        # Field order
299                @FieldOrder = ();
300                %FieldODefs = ();
301                while (defined($line = <$handle>)) {
302                    last if $line =~ /^\s*<\/fieldorder\s*>/i;
303                    next if $line =~ /^\s*$/;
304                    $line =~ s/\s//g;
305                    $line =~ tr/A-Z/a-z/;
306                    push(@FieldOrder, $line);
307                    $FieldODefs{$line} = 1;
308                }
309                # push(@FieldOrder,'-extra-')  if (!$FieldODefs{'-extra-'});
310                last FMTSW;
311            }
312            if (   $elem eq 'fieldsbeg'
313                || $elem eq 'fieldsbegin') {    # Begin markup of mail head
314                $FIELDSBEG = &get_elem_content($handle, $elem, $chop);
315                last FMTSW;
316            }
317            if ($elem eq 'fieldsend') {         # End markup of mail head
318                $FIELDSEND = &get_elem_content($handle, $elem, $chop);
319                last FMTSW;
320            }
321            if ($elem eq 'fileperms') {         # File creation permissions
322                if ($line = &get_elem_last_line($handle, $elem)) {
323                    $line =~ s/\s//g;
324                    $FilePerms = $line;
325                }
326                last FMTSW;
327            }
328            if ($elem eq 'firstpglink') {       # First page link in index
329                $FIRSTPGLINK = &get_elem_content($handle, $elem, $chop);
330                last FMTSW;
331            }
332            if (   $elem eq 'fldbeg'
333                || $elem eq 'fldbegin') {       # Begin markup of field text
334                $FLDBEG = &get_elem_content($handle, $elem, $chop);
335                last FMTSW;
336            }
337            if ($elem eq 'fldend') {            # End markup of field text
338                $FLDEND = &get_elem_content($handle, $elem, $chop);
339                last FMTSW;
340            }
341            if ($elem eq 'folrefs') {           # Print explicit fol/refs
342                $DoFolRefs = 1;
343                last FMTSW;
344            }
345            if (   $elem eq 'folupbegin'
346                || $elem eq 'folupbeg') {       # Begin markup for follow-ups
347                $FOLUPBEGIN = &get_elem_content($handle, $elem, $chop);
348                last FMTSW;
349            }
350            if ($elem eq 'folupend') {          # End markup for follow-ups
351                $FOLUPEND = &get_elem_content($handle, $elem, $chop);
352                last FMTSW;
353            }
354            if ($elem eq 'foluplitxt') {        # Follow-up link markup
355                $FOLUPLITXT = &get_elem_content($handle, $elem, $chop);
356                last FMTSW;
357            }
358            if ($elem eq 'fromfields') {        # Fields to get author
359                @a = &get_list_content($handle, $elem);
360                if (@a) { @FromFields = @a; }
361                last FMTSW;
362            }
363            if ($elem eq 'gmtdatefmt') {        # GMT date format
364                if ($line = &get_elem_last_line($handle, $elem)) {
365                    $GMTDateFmt = $line;
366                }
367                last FMTSW;
368            }
369            if ($elem eq 'gzipexe') {           # Gzip executable
370                if ($line = &get_elem_last_line($handle, $elem)) {
371                    $line =~ s/\s+$//g;
372                    $GzipExe = $line;
373                }
374                last FMTSW;
375            }
376            if ($elem eq 'gzipfiles') {
377                $GzipFiles = 1;
378                last FMTSW;
379            }
380            if ($elem eq 'gziplinks') {
381                $GzipLinks = 1;
382                last FMTSW;
383            }
384            if ($elem eq 'headbodysep') {
385                $HEADBODYSEP = &get_elem_content($handle, $elem, $chop);
386                last FMTSW;
387            }
388            if ($elem eq 'htmlext') {    # Extension for HTML files
389                if ($line = &get_elem_last_line($handle, $elem)) {
390                    $line =~ s/\s//g;
391                    $HtmlExt = $line;
392                }
393                last FMTSW;
394            }
395            if ($elem eq 'icons') {      # Icons
396                %Icons = () if $override;
397                while (defined($line = <$handle>)) {
398                    last if $line =~ /^\s*<\/icons\s*>/i;
399                    next if $line =~ /^\s*$/;
400                    $line =~ s/\s//g;
401                    ($type, $url) = split(/[;:]/, $line, 2);
402                    $type =~ tr/A-Z/a-z/;
403                    $Icons{$type} = $url;
404                }
405                last FMTSW;
406            }
407            if ($elem eq 'iconurlprefix') {    # Prefix for ICON urls
408                if ($line = &get_elem_last_line($handle, $elem)) {
409                    $line =~ s/\s+//g;
410                    $IconURLPrefix = $line;
411                }
412                last FMTSW;
413            }
414            if ($elem eq 'idxfname') {         # Index filename
415                if ($line = &get_elem_last_line($handle, $elem)) {
416                    $line =~ s/\s//g;
417                    $IDXNAME = $line;
418                }
419                last FMTSW;
420            }
421            if ($elem eq 'idxlabel') {         # Index label
422                $IDXLABEL = &get_elem_content($handle, $elem, $chop);
423                last FMTSW;
424            }
425            if (   $elem eq 'idxpgbegin'
426                || $elem eq 'idxpgbeg') {      # Opening markup of index
427                $IDXPGBEG = &get_elem_content($handle, $elem, $chop);
428                last FMTSW;
429            }
430            if ($elem eq 'idxpgend') {         # Closing markup of index
431                $IDXPGEND = &get_elem_content($handle, $elem, $chop);
432                last FMTSW;
433            }
434            if ($elem eq 'idxprefix') {        # Prefix for main idx pages
435                if ($line = &get_elem_last_line($handle, $elem)) {
436                    $line =~ s/\s//g;
437                    $IDXPREFIX = $line;
438                }
439                last FMTSW;
440            }
441            if ($elem eq 'idxsize') {          # Size of index
442                if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
443                    $IDXSIZE = $tmp;
444                }
445                last FMTSW;
446            }
447            if ($elem eq 'include') {          # Include other rc files
448                while (defined($line = <$handle>)) {
449                    last if $line =~ /^\s*<\/include\s*>/i;
450                    next if $line =~ /^\s*$/;
451                    $line =~ s/\s+$//;
452                    $line = $pathhead . $line if ($line !~ /$DIRSEPREX/o);
453                    &read_resource_file($line);
454                }
455                last FMTSW;
456            }
457            if ($elem eq 'keeponrmm') {        # Keep files on rmm
458                $KeepOnRmm = 1;
459                last FMTSW;
460            }
461            if ($elem eq 'lang') {             # Locale/language
462                $Lang = &get_elem_last_line($handle, $elem);
463                $Lang =~ s/\s+//g;
464                last FMTSW;
465            }
466            if (   $elem eq 'labelbeg'
467                || $elem eq 'labelbegin') {    # Begin markup of label
468                $LABELBEG = &get_elem_content($handle, $elem, $chop);
469                last FMTSW;
470            }
471            if ($elem eq 'labelend') {         # End markup of label
472                $LABELEND = &get_elem_content($handle, $elem, $chop);
473                last FMTSW;
474            }
475            if ($elem eq 'labelstyles') {      # Field label style
476                while (defined($line = <$handle>)) {
477                    last if $line =~ /^\s*<\/labelstyles\s*>/i;
478                    next if $line =~ /^\s*$/;
479                    $line =~ s/\s//g;
480                    $line =~ tr/A-Z/a-z/;
481                    ($label, $tag) = split(/:/, $line);
482                    $HeadHeads{$label} = $tag;
483                }
484                last FMTSW;
485            }
486            if ($elem eq 'lastpglink') {       # Last page link in index
487                $LASTPGLINK = &get_elem_content($handle, $elem, $chop);
488                last FMTSW;
489            }
490            if (   $elem eq 'listbegin'
491                || $elem eq 'listbeg') {       # List begin
492                $LIBEG = &get_elem_content($handle, $elem, $chop);
493                last FMTSW;
494            }
495            if ($elem eq 'listend') {          # List end
496                $LIEND = &get_elem_content($handle, $elem, $chop);
497                last FMTSW;
498            }
499            if ($elem eq 'litemplate') {       # List item template
500                $LITMPL = &get_elem_content($handle, $elem, $chop);
501                last FMTSW;
502            }
503            if ($elem eq 'localdatefmt') {     # Local date format
504                if ($line = &get_elem_last_line($handle, $elem)) {
505                    $LocalDateFmt = $line;
506                }
507                last FMTSW;
508            }
509            if ($elem eq 'lockmethod') {       # Locking method
510                if ($line = &get_elem_last_line($handle, $elem)) {
511                    $LockMethod = &set_lock_mode($line);
512                }
513                last FMTSW;
514            }
515            if ($elem eq 'mailto') {           # Convert e-mail addrs
516                $NOMAILTO = 0;
517                last FMTSW;
518            }
519            if ($elem eq 'mailtourl') {        # mailto URL
520                while (defined($line = <$handle>)) {
521                    last if $line =~ /^\s*<\/mailtourl\s*>/i;
522                    next if $line =~ /^\s*$/;
523                    $line =~ s/\s//g;
524                    $MAILTOURL = $line;
525                }
526                last FMTSW;
527            }
528            if ($elem eq 'main') {             # Print main index
529                $MAIN = 1;
530                last FMTSW;
531            }
532            if ($elem eq 'maxpgs') {           # Max number of index pages
533                if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
534                    $MAXPGS = $tmp;
535                }
536                last FMTSW;
537            }
538            if ($elem eq 'maxsize') {          # Size of archive
539                if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
540                    $MAXSIZE = $tmp;
541                }
542                last FMTSW;
543            }
544            if ($elem eq 'msgbodyend') {       # Markup after message body
545                $MSGBODYEND = &get_elem_content($handle, $elem, $chop);
546                last FMTSW;
547            }
548            if ($elem eq 'msgexcfilter') {     # Code selectively exclude msgs
549                $MsgExcFilter = &get_elem_content($handle, $elem, $chop);
550                last FMTSW;
551            }
552            if ($elem eq 'msgpgs') {           # Output message pages
553                $NoMsgPgs = 0;
554                last FMTSW;
555            }
556            if ($elem eq 'msgprefix') {        # Prefix for message files
557                if ($line = &get_elem_last_line($handle, $elem)) {
558                    $line =~ s/\s//g;
559                    $MsgPrefix = $line;
560                }
561                last FMTSW;
562            }
563            if ($elem eq 'mhpattern') {        # File pattern MH-like dirs
564                if ($line = &get_elem_last_line($handle, $elem)) {
565                    $MHPATTERN = $line;
566                }
567                last FMTSW;
568            }
569            if ($elem eq 'mimealtprefs') {     # Mime alternative prefs
570                $IsDefault{'MIMEALTPREFS'} = 0;
571                @MIMEAltPrefs = ();
572                while (defined($line = <$handle>)) {
573                    last if $line =~ /^\s*<\/mimealtprefs\s*>/i;
574                    $line =~ s/\s//g;
575                    push(@MIMEAltPrefs, lc($line)) if $line;
576                }
577                last FMTSW;
578            }
579            if ($elem eq 'mimedecoders') {     # Mime decoders
580                $IsDefault{'MIMEDECODERS'} = 0;
581                if ($override) {
582                    %readmail::MIMEDecoders    = ();
583                    %readmail::MIMEDecodersSrc = ();
584                }
585                while (defined($line = <$handle>)) {
586                    last if $line =~ /^\s*<\/mimedecoders\s*>/i;
587                    next unless $line =~ /\S/;
588                    $line =~ s/\s//g;
589                    ($type, $routine, $plfile) = split(/;/, $line, 3);
590                    $type =~ tr/A-Z/a-z/;
591                    $readmail::MIMEDecoders{$type}    = $routine;
592                    $readmail::MIMEDecodersSrc{$type} = $plfile
593                        if $plfile =~ /\S/;
594                }
595                last FMTSW;
596            }
597            if ($elem eq 'mimefilters') {    # Mime filters
598                $IsDefault{'MIMEFILTERS'} = 0;
599                if ($override) {
600                    %readmail::MIMEFilters    = ();
601                    %readmail::MIMEFiltersSrc = ();
602                }
603                while (defined($line = <$handle>)) {
604                    last if $line =~ /^\s*<\/mimefilters\s*>/i;
605                    next if $line =~ /^\s*$/;
606                    $line =~ s/\s//g;
607                    ($type, $routine, $plfile) = split(/;/, $line, 3);
608                    $type =~ tr/A-Z/a-z/;
609                    $readmail::MIMEFilters{$type}    = $routine;
610                    $readmail::MIMEFiltersSrc{$type} = $plfile
611                        if $plfile =~ /\S/;
612                }
613                last FMTSW;
614            }
615            if ($elem eq 'mimeargs') {    # Mime arguments
616                $IsDefault{'MIMEARGS'} = 0;
617                %readmail::MIMEFiltersArgs = () if $override;
618                while (defined($line = <$handle>)) {
619                    last if $line =~ /^\s*<\/mimeargs\s*>/i;
620                    next unless $line =~ /\S/;
621                    $line =~ s/^\s+//;
622                    if ($line =~ /;/) {
623                        ($type, $arg) = split(/;/, $line, 2);
624                    } else {
625                        ($type, $arg) = split(/:/, $line, 2);
626                    }
627                    $type =~ tr/A-Z/a-z/ if $type =~ m%/%;
628                    $readmail::MIMEFiltersArgs{$type} = $arg;
629                }
630                last FMTSW;
631            }
632            if ($elem eq 'mimeexcs') {    # Mime exclusions
633                $IsDefault{'MIMEEXCS'} = 0;
634                %readmail::MIMEExcs = () if $override;
635                while (defined($line = <$handle>)) {
636                    last if $line =~ /^\s*<\/mimeexcs\s*>/i;
637                    $line =~ s/\s//g;
638                    $line =~ tr/A-Z/a-z/;
639                    $readmail::MIMEExcs{$line} = 1 if $line;
640                }
641                last FMTSW;
642            }
643            if ($elem eq 'mimeincs') {    # Mime includes
644                $IsDefault{'MIMEINCS'} = 0;
645                %readmail::MIMEIncs = () if $override;
646                while (defined($line = <$handle>)) {
647                    last if $line =~ /^\s*<\/mimeincs\s*>/i;
648                    $line =~ s/\s//g;
649                    $line =~ tr/A-Z/a-z/;
650                    $readmail::MIMEIncs{$line} = 1 if $line;
651                }
652                last FMTSW;
653            }
654            if ($elem eq 'modifybodyaddresses') { # Modify addresses in bodies
655                $AddrModifyBodies = 1;
656                last FMTSW;
657            }
658            if ($elem eq 'months') {              # Full month names
659                @a = &get_list_content($handle, $elem);
660                if (scalar(@a)) {
661                    @Months = @a;
662                }
663                last FMTSW;
664            }
665            if ($elem eq 'monthsabr') {           # Abbreviated month names
666                @a = &get_list_content($handle, $elem);
667                if (scalar(@a)) {
668                    @months = @a;
669                }
670                last FMTSW;
671            }
672            if ($elem eq 'modtime') {             # Mod time same as msg date
673                $MODTIME = 1;
674                last FMTSW;
675            }
676            if ($elem eq 'msgfoot') {             # Message footer text
677                $MSGFOOT = &get_elem_content($handle, $elem, $chop);
678                last FMTSW;
679            }
680            if ($elem eq 'msggmtdatefmt') {       # Message GMT date format
681                if ($line = &get_elem_last_line($handle, $elem)) {
682                    $MsgGMTDateFmt = $line;
683                }
684                last FMTSW;
685            }
686            if ($elem eq 'msghead') {             # Message header text
687                $MSGHEAD = &get_elem_content($handle, $elem, $chop);
688                last FMTSW;
689            }
690            if ($elem eq 'msgidlink') {
691                $MSGIDLINK = &get_elem_content($handle, $elem, $chop);
692                last FMTSW;
693            }
694            if ($elem eq 'msglocaldatefmt') {     # Message local date format
695                if ($line = &get_elem_last_line($handle, $elem)) {
696                    $MsgLocalDateFmt = $line;
697                }
698                last FMTSW;
699            }
700            if (   $elem eq 'msgpgbegin'
701                || $elem eq 'msgpgbeg') {         # Opening markup of message
702                $MSGPGBEG = &get_elem_content($handle, $elem, $chop);
703                last FMTSW;
704            }
705            if ($elem eq 'msgpgend') {            # Closing markup of message
706                $MSGPGEND = &get_elem_content($handle, $elem, $chop);
707                last FMTSW;
708            }
709            if ($elem eq 'msgsep') {              # Message separator
710                if ($line = &get_elem_last_line($handle, $elem)) {
711                    $FROM = $line;
712                }
713                last FMTSW;
714            }
715            if ($elem eq 'multipg') {             # Print multi-page indexes
716                $MULTIIDX = 1;
717                last FMTSW;
718            }
719            if ($elem eq 'newsurl') {             # News URL
720                while (defined($line = <$handle>)) {
721                    last if $line =~ /^\s*<\/newsurl\s*>/i;
722                    next if $line =~ /^\s*$/;
723                    $line =~ s/\s//g;
724                    $NewsUrl = $line;
725                }
726                last FMTSW;
727            }
728            if ($elem eq 'nextbutton') {    # Next button link in message
729                $NEXTBUTTON = &get_elem_content($handle, $elem, $chop);
730                last FMTSW;
731            }
732            if ($elem eq 'nextbuttonia') {
733                $NEXTBUTTONIA = &get_elem_content($handle, $elem, $chop);
734                last FMTSW;
735            }
736            if ($elem eq 'nextlink') {      # Next link in message
737                $NEXTLINK = &get_elem_content($handle, $elem, $chop);
738                last FMTSW;
739            }
740            if ($elem eq 'nextlinkia') {
741                $NEXTLINKIA = &get_elem_content($handle, $elem, $chop);
742                last FMTSW;
743            }
744            if ($elem eq 'nextpglink') {    # Next page link in index
745                $NEXTPGLINK = &get_elem_content($handle, $elem, $chop);
746                last FMTSW;
747            }
748            if ($elem eq 'nextpglinkia') {
749                $NEXTPGLINKIA = &get_elem_content($handle, $elem, $chop);
750                last FMTSW;
751            }
752            if ($elem eq 'news') {          # News for linking
753                $NONEWS = 0;
754                last FMTSW;
755            }
756            if ($elem eq 'noauthsort') {    # Do not sort msgs by author
757                $AUTHSORT = 0;
758                last FMTSW;
759            }
760            if ($elem eq 'nochecknoarchive') {
761                $CheckNoArchive = 0;
762                last FMTSW;
763            }
764            if ($elem eq 'noconlen') {      # Ignore content-length
765                $CONLEN = 0;
766                last FMTSW;
767            }
768            if ($elem eq 'nodecodeheads') {    # Don't decode charsets
769                $DecodeHeads = 0;
770                last FMTSW;
771            }
772            if ($elem eq 'nodoc') {            # Do not link to docs
773                $NODOC = 1;
774                last FMTSW;
775            }
776            if ($elem eq 'nofasttempfiles') {    # Random temp files
777                $FastTempFiles = 0;
778                last FMTSW;
779            }
780            if ($elem eq 'nofollowsymlinks') {  # Do not allow/follow symlinks
781                $FollowSymlinks = 0;
782                last FMTSW;
783            }
784            if ($elem eq 'nofolrefs') {    # Don't print explicit fol/refs
785                $DoFolRefs = 0;
786                last FMTSW;
787            }
788            if ($elem eq 'nomodifybodyaddresses') {   # Don't modify addresses
789                $AddrModifyBodies = 0;
790                last FMTSW;
791            }
792            if ($elem eq 'nogzipfiles') {             # Don't gzip files
793                $GzipFiles = 0;
794                last FMTSW;
795            }
796            if ($elem eq 'nogziplinks') {    # Don't add ".gz" to links
797                $GzipLinks = 0;
798                last FMTSW;
799            }
800            if ($elem eq 'nokeeponrmm') {    # Remove files on rmm
801                $KeepOnRmm = 0;
802                last FMTSW;
803            }
804            if ($elem eq 'nomailto') {       # Do not convert e-mail addrs
805                $NOMAILTO = 1;
806                last FMTSW;
807            }
808            if ($elem eq 'nomain') {         # No main index
809                $MAIN = 0;
810                last FMTSW;
811            }
812            if ($elem eq 'nomodtime') {      # Do not change mod times
813                $MODTIME = 0;
814                last FMTSW;
815            }
816            if ($elem eq 'nomsgpgs') {       # Do not print message pages
817                $NoMsgPgs = 1;
818                last FMTSW;
819            }
820            if ($elem eq 'nomultipg') {      # Single page index
821                $MULTIIDX = 0;
822                last FMTSW;
823            }
824            if ($elem eq 'nonews') {         # Ignore news for linking
825                $NONEWS = 1;
826                last FMTSW;
827            }
828            if ($elem eq 'noposixstrftime') {   # Do not use POSIX::strftime()
829                $POSIXstrftime = 0;
830                last FMTSW;
831            }
832            if ($elem eq 'noreverse') {         # Sort in normal order
833                $REVSORT = 0;
834                last FMTSW;
835            }
836            if ($elem eq 'nosaveresources') {    # Do not save resources
837                $SaveRsrcs = 0;
838                last FMTSW;
839            }
840            if ($elem eq 'nosort') {             # Do not sort messages
841                $NOSORT = 1;
842                last FMTSW;
843            }
844            if ($elem eq 'nospammode') {         # Do not do anti-spam stuff
845                $SpamMode = 0;
846                last FMTSW;
847            }
848            if ($elem eq 'nosubjectthreads') { # No check subjects for threads
849                $NoSubjectThreads = 1;
850                last FMTSW;
851            }
852            if ($elem eq 'nosubjecttxt') {     # Text to use if no subject
853                $NoSubjectTxt = &get_elem_content($handle, $elem, $chop);
854                last FMTSW;
855            }
856            if ($elem eq 'nosubsort') {        # Do not sort msgs by subject
857                $SUBSORT = 0;
858                last FMTSW;
859            }
860            if ($elem eq 'note') {             # Annotation markup
861                $NOTE = &get_elem_content($handle, $elem, $chop);
862                last FMTSW;
863            }
864            if ($elem eq 'notedir') {          # Notes directory
865                if ($line = &get_elem_last_line($handle, $elem)) {
866                    $NoteDir = $line;
867                }
868                last FMTSW;
869            }
870            if ($elem eq 'noteia') {           # No Annotation markup
871                $NOTEIA = &get_elem_content($handle, $elem, $chop);
872                last FMTSW;
873            }
874            if ($elem eq 'noteicon') {         # Note icon
875                $NOTEICON = &get_elem_content($handle, $elem, $chop);
876                last FMTSW;
877            }
878            if ($elem eq 'noteiconia') {       # Note icon when no annotation
879                $NOTEICONIA = &get_elem_content($handle, $elem, $chop);
880                last FMTSW;
881            }
882            if ($elem eq 'nothread') {         # No thread index
883                $THREAD = 0;
884                last FMTSW;
885            }
886            if ($elem eq 'notreverse') {       # Thread sort in normal order
887                $TREVERSE = 0;
888                last FMTSW;
889            }
890            if (   $elem eq 'notsubsort'
891                || $elem eq 'tnosubsort') {    # No subject order for threads
892                $TSUBSORT = 0;
893                last FMTSW;
894            }
895            if (   $elem eq 'notsort'
896                || $elem eq 'tnosort') {       # Raw order for threads
897                $TNOSORT  = 1;
898                $TSUBSORT = 0;
899                last FMTSW;
900            }
901            if ($elem eq 'nourl') {            # Ignore URLs
902                $NOURL = 1;
903                last FMTSW;
904            }
905            if ($elem eq 'nouselocaltime') {    # Not using localtime
906                $UseLocalTime = 0;
907                last FMTSW;
908            }
909            if ($elem eq 'nousinglastpg') {     # Not using $LASTPG$
910                $UsingLASTPG = 0;
911                last FMTSW;
912            }
913            if ($elem eq 'otherindexes') {      # Other indexes
914                @OtherIdxs = () if $override;
915                unshift(@OtherIdxs, &get_pathname_content($handle, $elem));
916                last FMTSW;
917            }
918            if ($elem eq 'perlinc') {           # Define perl search paths
919                @PerlINC = () if $override;
920                unshift(@PerlINC, &get_pathname_content($handle, $elem));
921                last FMTSW;
922            }
923            if ($elem eq 'posixstrftime') {     # Use POSIX::strftime()
924                $POSIXstrftime = 1;
925                last FMTSW;
926            }
927            if ($elem eq 'prevbutton') {        # Prev button link in message
928                $PREVBUTTON = &get_elem_content($handle, $elem, $chop);
929                last FMTSW;
930            }
931            if ($elem eq 'prevbuttonia') {      # Prev i/a button link
932                $PREVBUTTONIA = &get_elem_content($handle, $elem, $chop);
933                last FMTSW;
934            }
935            if ($elem eq 'prevlink') {          # Prev link in message
936                $PREVLINK = &get_elem_content($handle, $elem, $chop);
937                last FMTSW;
938            }
939            if ($elem eq 'prevlinkia') {        # Prev i/a link
940                $PREVLINKIA = &get_elem_content($handle, $elem, $chop);
941                last FMTSW;
942            }
943            if ($elem eq 'prevpglink') {        # Prev page link for index
944                $PREVPGLINK = &get_elem_content($handle, $elem, $chop);
945                last FMTSW;
946            }
947            if ($elem eq 'prevpglinkia') {
948                $PREVPGLINKIA = &get_elem_content($handle, $elem, $chop);
949                last FMTSW;
950            }
951            if ($elem eq 'printxcomments') {    # Print info X- comments
952                $PrintXComments = 1;
953                last FMTSW;
954            }
955            if ($elem eq 'noprintxcomments') {  # Don't print info X- comments
956                $PrintXComments = 0;
957                last FMTSW;
958            }
959            if (   $elem eq 'refsbegin'
960                || $elem eq 'refsbeg') {        # Explicit ref links begin
961                $REFSBEGIN = &get_elem_content($handle, $elem, $chop);
962                last FMTSW;
963            }
964            if ($elem eq 'refsend') {           # Explicit ref links end
965                $REFSEND = &get_elem_content($handle, $elem, $chop);
966                last FMTSW;
967            }
968            if ($elem eq 'refslitxt') {         # Explicit ref link
969                $REFSLITXT = &get_elem_content($handle, $elem, $chop);
970                last FMTSW;
971            }
972            if ($elem eq 'reverse') {           # Reverse sort
973                $REVSORT = 1;
974                last FMTSW;
975            }
976            if ($elem eq 'saveresources') {     # Save resources in db
977                $SaveRsrcs = 1;
978                last FMTSW;
979            }
980            if ($elem eq 'sort') {              # Sort messages by date
981                $NOSORT   = 0;
982                $AUTHSORT = 0;
983                $SUBSORT  = 0;
984                last FMTSW;
985            }
986            if ($elem eq 'spammode') {          # Obfsucate/hide addresses
987                $SpamMode = 1;
988                last FMTSW;
989            }
990            if ($elem eq 'ssmarkup') {          # Initial page markup
991                $SSMARKUP = &get_elem_content($handle, $elem, $chop);
992                last FMTSW;
993            }
994            if ($elem eq 'msgpgssmarkup') {     # Initial message page markup
995                $MSGPGSSMARKUP = &get_elem_content($handle, $elem, $chop);
996                last FMTSW;
997            }
998            if ($elem eq 'idxpgssmarkup') {     # Initial index page markup
999                $IDXPGSSMARKUP = &get_elem_content($handle, $elem, $chop);
1000                last FMTSW;
1001            }
1002            if ($elem eq 'tidxpgssmarkup') {  # Initial thread idx page markup
1003                $TIDXPGSSMARKUP = &get_elem_content($handle, $elem, $chop);
1004                last FMTSW;
1005            }
1006            if ($elem eq 'subjectarticlerxp') {  # Regex for language articles
1007                if ($line = &get_elem_last_line($handle, $elem)) {
1008                    $SubArtRxp = $line;
1009                }
1010                last FMTSW;
1011            }
1012            if ($elem eq 'subjectreplyrxp') {    # Regex for reply text
1013                if ($line = &get_elem_last_line($handle, $elem)) {
1014                    $SubReplyRxp = $line;
1015                }
1016                last FMTSW;
1017            }
1018            if ($elem eq 'subjectstripcode') {    # Code to strip subjects
1019                $SubStripCode = &get_elem_content($handle, $elem, $chop);
1020                last FMTSW;
1021            }
1022            if ($elem eq 'subjectthreads') {      # Check subjects for threads
1023                $NoSubjectThreads = 0;
1024                last FMTSW;
1025            }
1026            if ($elem eq 'subsort') {             # Sort messages by subject
1027                $SUBSORT  = 1;
1028                $AUTHSORT = 0;
1029                $NOSORT   = 0;
1030                last FMTSW;
1031            }
1032            if (   $elem eq 'subjectbegin'
1033                || $elem eq 'subjectbeg') {       # Begin for subject group
1034                $SUBJECTBEG = &get_elem_content($handle, $elem, $chop);
1035                last FMTSW;
1036            }
1037            if ($elem eq 'subjectend') {          # End for subject group
1038                $SUBJECTEND = &get_elem_content($handle, $elem, $chop);
1039                last FMTSW;
1040            }
1041            if ($elem eq 'subjectheader') {
1042                $SUBJECTHEADER = &get_elem_content($handle, $elem, $chop);
1043                last FMTSW;
1044            }
1045            if (   $elem eq 'tcontbegin'
1046                || $elem eq 'tcontbeg') {         # Thread cont. start
1047                $TCONTBEG = &get_elem_content($handle, $elem, $chop);
1048                last FMTSW;
1049            }
1050            if ($elem eq 'tcontend') {            # Thread cont. end
1051                $TCONTEND = &get_elem_content($handle, $elem, $chop);
1052                last FMTSW;
1053            }
1054            if ($elem eq 'textclipfunc') {        # Text clipping function
1055                $TextClipFunc = undef;
1056                $TextClipSrc  = undef;
1057                while (defined($line = <$handle>)) {
1058                    last if $line =~ /^\s*<\/textclipfunc\s*>/i;
1059                    next if $line =~ /^\s*$/;
1060                    $line =~ s/\s//g;
1061                    ($TextClipFunc, $TextClipSrc) = split(/;/, $line, 2);
1062                }
1063            }
1064            if ($elem eq 'defcharset') {          # Default charset
1065                $readmail::TextDefCharset =
1066                    lc get_elem_last_line($handle, $elem);
1067                $readmail::TextDefCharset =~ s/\s//g;
1068                $readmail::TextDefCharset = 'us-ascii'
1069                    if $readmail::TextDefCharset eq '';
1070            }
1071            if ($elem eq 'tendbutton') {          # End of thread button
1072                $TENDBUTTON = &get_elem_content($handle, $elem, $chop);
1073                last FMTSW;
1074            }
1075            if ($elem eq 'tendbuttonia') {
1076                $TENDBUTTONIA = &get_elem_content($handle, $elem, $chop);
1077                last FMTSW;
1078            }
1079            if ($elem eq 'tendlink') {            # End of thread link
1080                $TENDLINK = &get_elem_content($handle, $elem, $chop);
1081                last FMTSW;
1082            }
1083            if ($elem eq 'tendlinkia') {
1084                $TENDLINKIA = &get_elem_content($handle, $elem, $chop);
1085                last FMTSW;
1086            }
1087            if ($elem eq 'textencode') {          # Text encoder
1088                $readmail::TextEncode      = undef;
1089                $readmail::TextEncoderFunc = undef;
1090                $readmail::TextEncoderSrc  = undef;
1091                while (defined($line = <$handle>)) {
1092                    last if $line =~ /^\s*<\/textencode\s*>/i;
1093                    next unless $line =~ /\S/;
1094                    ($type, $routine, $plfile) = split(/;/, $line, 3);
1095                    $type =~ s/\s//g;
1096                    $routine =~ s/\s//g;
1097                    $plfile =~ s/^\s+//;
1098                    $plfile =~ s/\s+\z//g;
1099                    $readmail::TextEncode      = lc $type;
1100                    $readmail::TextEncoderFunc = $routine;
1101                    $readmail::TextEncoderSrc  = $plfile
1102                        if defined($plfile)
1103                        and $plfile =~ /\S/;
1104                    $IsDefault{'TEXTENCODE'} = 0;
1105                }
1106                last FMTSW;
1107            }
1108            if ($elem eq 'tfirstpglink') {    # First thread page link
1109                $TFIRSTPGLINK = &get_elem_content($handle, $elem, $chop);
1110                last FMTSW;
1111            }
1112            if ($elem eq 'tfoot') {           # Thread idx foot
1113                $TFOOT = &get_elem_content($handle, $elem, $chop);
1114                last FMTSW;
1115            }
1116            if ($elem eq 'thead') {           # Thread idx head
1117                $THEAD = &get_elem_content($handle, $elem, $chop);
1118                last FMTSW;
1119            }
1120            if ($elem eq 'tidxfname') {       # Threaded idx filename
1121                if ($line = &get_elem_last_line($handle, $elem)) {
1122                    $line =~ s/\s//g;
1123                    $TIDXNAME = $line;
1124                }
1125                last FMTSW;
1126            }
1127            if ($elem eq 'tidxlabel') {       # Thread index label
1128                $TIDXLABEL = &get_elem_content($handle, $elem, $chop);
1129                last FMTSW;
1130            }
1131            if (   $elem eq 'tidxpgbegin'
1132                || $elem eq 'tidxpgbeg') {    # Opening markup of thread idx
1133                $TIDXPGBEG = &get_elem_content($handle, $elem, $chop);
1134                last FMTSW;
1135            }
1136            if ($elem eq 'tidxpgend') {       # Closing markup of thread idx
1137                $TIDXPGEND = &get_elem_content($handle, $elem, $chop);
1138                last FMTSW;
1139            }
1140            if ($elem eq 'tidxprefix') {      # Prefix for thread idx pages
1141                if ($line = &get_elem_last_line($handle, $elem)) {
1142                    $line =~ s/\s//g;
1143                    $TIDXPREFIX = $line;
1144                }
1145                last FMTSW;
1146            }
1147            if ($elem eq 'timezones') {       # Time zones
1148                if ($override) { %ZoneUD = (); }
1149                while (defined($line = <$handle>)) {
1150                    last if $line =~ /^\s*<\/timezones\s*>/i;
1151                    $line =~ s/\s//g;
1152                    $line =~ tr/a-z/A-Z/;
1153                    ($acro, $hr) = split(/:/, $line);
1154                    $acro =~ tr/a-z/A-Z/;
1155                    $ZoneUD{$acro} = $hr;
1156                }
1157                last FMTSW;
1158            }
1159            if (   $elem eq 'tindentbegin'
1160                || $elem eq 'tindentbeg') {    # Thread indent start
1161                $TINDENTBEG = &get_elem_content($handle, $elem, $chop);
1162                last FMTSW;
1163            }
1164            if ($elem eq 'tindentend') {       # Thread indent end
1165                $TINDENTEND = &get_elem_content($handle, $elem, $chop);
1166                last FMTSW;
1167            }
1168            if ($elem eq 'title') {            # Title of index page
1169                $TITLE = &get_elem_content($handle, $elem, $chop);
1170                last FMTSW;
1171            }
1172            if ($elem eq 'tlastpglink') {      # Last thread page link
1173                $TLASTPGLINK = &get_elem_content($handle, $elem, $chop);
1174                last FMTSW;
1175            }
1176            if ($elem eq 'tlevels') {          # Level of threading
1177                if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
1178                    $TLEVELS = $tmp;
1179                }
1180                last FMTSW;
1181            }
1182            if ($elem eq 'tlinone') {          # Markup for missing message
1183                $TLINONE = &get_elem_content($handle, $elem, $chop);
1184                last FMTSW;
1185            }
1186            if ($elem eq 'tlinoneend') {       # End markup for missing msg
1187                $TLINONEEND = &get_elem_content($handle, $elem, $chop);
1188                last FMTSW;
1189            }
1190            if ($elem eq 'tlitxt') {           # Thread idx list item
1191                $TLITXT = &get_elem_content($handle, $elem, $chop);
1192                last FMTSW;
1193            }
1194            if ($elem eq 'tliend') {           # Thread idx list item end
1195                $TLIEND = &get_elem_content($handle, $elem, $chop);
1196                last FMTSW;
1197            }
1198            if ($elem eq 'toplinks') {         # Top links in message
1199                $TOPLINKS = &get_elem_content($handle, $elem, $chop);
1200                last FMTSW;
1201            }
1202            if ($elem eq 'tslice') {
1203                ($TSliceNBefore, $TSliceNAfter, $TSliceInclusive) =
1204                    &get_list_content($handle, $elem);
1205                last FMTSW;
1206            }
1207            if (   $elem eq 'tslicebeg'
1208                || $elem eq 'tslicebegin') {    # Start of thread slice
1209                $TSLICEBEG = &get_elem_content($handle, $elem, $chop);
1210                last FMTSW;
1211            }
1212            if ($elem eq 'tsliceend') {         # End of thread slice
1213                $TSLICEEND = &get_elem_content($handle, $elem, $chop);
1214                last FMTSW;
1215            }
1216            if ($elem eq 'tslicelevels') {      # Level of slice threading
1217                if (($tmp = &get_elem_int($handle, $elem, 1)) ne '') {
1218                    $TSLICELEVELS = $tmp;
1219                }
1220                last FMTSW;
1221            }
1222            if ($elem eq 'tslicesingletxt') {
1223                $TSLICESINGLETXT = &get_elem_content($handle, $elem, $chop);
1224                last FMTSW;
1225            }
1226            if (   $elem eq 'tslicetopbegin'
1227                || $elem eq 'tslicetopbeg') {
1228                $TSLICETOPBEG = &get_elem_content($handle, $elem, $chop);
1229                last FMTSW;
1230            }
1231            if ($elem eq 'tslicetopend') {
1232                $TSLICETOPEND = &get_elem_content($handle, $elem, $chop);
1233                last FMTSW;
1234            }
1235            if (   $elem eq 'tslicesublistbeg'
1236                || $elem eq 'tslicesublistbegin') {
1237                $TSLICESUBLISTBEG = &get_elem_content($handle, $elem, $chop);
1238                last FMTSW;
1239            }
1240            if ($elem eq 'tslicesublistend') {
1241                $TSLICESUBLISTEND = &get_elem_content($handle, $elem, $chop);
1242                last FMTSW;
1243            }
1244            if ($elem eq 'tslicelitxt') {
1245                $TSLICELITXT = &get_elem_content($handle, $elem, $chop);
1246                last FMTSW;
1247            }
1248            if ($elem eq 'tsliceliend') {
1249                $TSLICELIEND = &get_elem_content($handle, $elem, $chop);
1250                last FMTSW;
1251            }
1252            if ($elem eq 'tslicelinone') {
1253                $TSLICELINONE = &get_elem_content($handle, $elem, $chop);
1254                last FMTSW;
1255            }
1256            if ($elem eq 'tslicelinoneend') {
1257                $TSLICELINONEEND = &get_elem_content($handle, $elem, $chop);
1258                last FMTSW;
1259            }
1260            if (   $elem eq 'tslicesubjectbeg'
1261                || $elem eq 'tslicesubjectbegin') {
1262                $TSLICESUBJECTBEG = &get_elem_content($handle, $elem, $chop);
1263                last FMTSW;
1264            }
1265            if ($elem eq 'tslicesubjectend') {
1266                $TSLICESUBJECTEND = &get_elem_content($handle, $elem, $chop);
1267                last FMTSW;
1268            }
1269            if (   $elem eq 'tsliceindentbegin'
1270                || $elem eq 'tsliceindentbeg') {
1271                $TSLICEINDENTBEG = &get_elem_content($handle, $elem, $chop);
1272                last FMTSW;
1273            }
1274            if ($elem eq 'tsliceindentend') {
1275                $TSLICEINDENTEND = &get_elem_content($handle, $elem, $chop);
1276                last FMTSW;
1277            }
1278            if (   $elem eq 'tslicecontbegin'
1279                || $elem eq 'tslicecontbeg') {
1280                $TSLICECONTBEG = &get_elem_content($handle, $elem, $chop);
1281                last FMTSW;
1282            }
1283            if ($elem eq 'tslicecontend') {
1284                $TSLICECONTEND = &get_elem_content($handle, $elem, $chop);
1285                last FMTSW;
1286            }
1287            if ($elem eq 'tslicesingletxtcur') {
1288                $TSLICESINGLETXTCUR =
1289                    &get_elem_content($handle, $elem, $chop);
1290                last FMTSW;
1291            }
1292            if (   $elem eq 'tslicetopbegincur'
1293                || $elem eq 'tslicetopbegcur') {
1294                $TSLICETOPBEGCUR = &get_elem_content($handle, $elem, $chop);
1295                last FMTSW;
1296            }
1297            if ($elem eq 'tslicetopendcur') {
1298                $TSLICETOPENDCUR = &get_elem_content($handle, $elem, $chop);
1299                last FMTSW;
1300            }
1301            if ($elem eq 'tslicelitxtcur') {
1302                $TSLICELITXTCUR = &get_elem_content($handle, $elem, $chop);
1303                last FMTSW;
1304            }
1305            if ($elem eq 'tsliceliendcur') {
1306                $TSLICELIENDCUR = &get_elem_content($handle, $elem, $chop);
1307                last FMTSW;
1308            }
1309            if ($elem eq 'tsort') {    # Date order for threads
1310                $TNOSORT  = 0;
1311                $TSUBSORT = 0;
1312                last FMTSW;
1313            }
1314            if ($elem eq 'tsubsort') {    # Subject order for threads
1315                $TNOSORT  = 0;
1316                $TSUBSORT = 1;
1317                last FMTSW;
1318            }
1319            if (   $elem eq 'tsublistbeg'
1320                || $elem eq 'tsublistbegin') {    # List begin in sub-thread
1321                $TSUBLISTBEG = &get_elem_content($handle, $elem, $chop);
1322                last FMTSW;
1323            }
1324            if ($elem eq 'tsublistend') {         # List end in sub-thread
1325                $TSUBLISTEND = &get_elem_content($handle, $elem, $chop);
1326                last FMTSW;
1327            }
1328            if (   $elem eq 'tsubjectbeg'
1329                || $elem eq 'tsubjectbegin') {   # Begin markup for sub thread
1330                $TSUBJECTBEG = &get_elem_content($handle, $elem, $chop);
1331                last FMTSW;
1332            }
1333            if ($elem eq 'tsubjectend') {        # End markup for sub thread
1334                $TSUBJECTEND = &get_elem_content($handle, $elem, $chop);
1335                last FMTSW;
1336            }
1337            if ($elem eq 'tsingletxt') {         # Markup for single msg
1338                $TSINGLETXT = &get_elem_content($handle, $elem, $chop);
1339                last FMTSW;
1340            }
1341            if ($elem eq 'ttopbegin' ||          # Begin for top of a thread
1342                $elem eq 'ttopbeg'
1343                ) {                              # (more consistent name)
1344                $TTOPBEG = &get_elem_content($handle, $elem, $chop);
1345                last FMTSW;
1346            }
1347            if ($elem eq 'ttopend') {            # End for a thread
1348                $TTOPEND = &get_elem_content($handle, $elem, $chop);
1349                last FMTSW;
1350            }
1351            if ($elem eq 'ttitle') {             # Title of threaded idx
1352                $TTITLE = &get_elem_content($handle, $elem, $chop);
1353                last FMTSW;
1354            }
1355            if ($elem eq 'thread') {             # Create thread index
1356                $THREAD = 1;
1357                last FMTSW;
1358            }
1359            if ($elem eq 'tnextbutton') {        # Thread Next button link
1360                $TNEXTBUTTON = &get_elem_content($handle, $elem, $chop);
1361                last FMTSW;
1362            }
1363            if ($elem eq 'tnextbuttonia') {
1364                $TNEXTBUTTONIA = &get_elem_content($handle, $elem, $chop);
1365                last FMTSW;
1366            }
1367            if ($elem eq 'tnextinbutton') {   # Within Thread Next button link
1368                $TNEXTINBUTTON = &get_elem_content($handle, $elem, $chop);
1369                last FMTSW;
1370            }
1371            if ($elem eq 'tnextinbuttonia') {
1372                $TNEXTINBUTTONIA = &get_elem_content($handle, $elem, $chop);
1373                last FMTSW;
1374            }
1375            if ($elem eq 'tnextinlink') {     # Within Thread Next link
1376                $TNEXTINLINK = &get_elem_content($handle, $elem, $chop);
1377                last FMTSW;
1378            }
1379            if ($elem eq 'tnextinlinkia') {
1380                $TNEXTINLINKIA = &get_elem_content($handle, $elem, $chop);
1381                last FMTSW;
1382            }
1383            if ($elem eq 'tnextlink') {       # Thread Next link
1384                $TNEXTLINK = &get_elem_content($handle, $elem, $chop);
1385                last FMTSW;
1386            }
1387            if ($elem eq 'tnextlinkia') {
1388                $TNEXTLINKIA = &get_elem_content($handle, $elem, $chop);
1389                last FMTSW;
1390            }
1391            if ($elem eq 'tnextpglink') {     # Thread next page link
1392                $TNEXTPGLINK = &get_elem_content($handle, $elem, $chop);
1393                last FMTSW;
1394            }
1395            if ($elem eq 'tnextpglinkia') {
1396                $TNEXTPGLINKIA = &get_elem_content($handle, $elem, $chop);
1397                last FMTSW;
1398            }
1399            if ($elem eq 'tprevbutton') {     # Thread Prev button link
1400                $TPREVBUTTON = &get_elem_content($handle, $elem, $chop);
1401                last FMTSW;
1402            }
1403            if ($elem eq 'tprevbuttonia') {
1404                $TPREVBUTTONIA = &get_elem_content($handle, $elem, $chop);
1405                last FMTSW;
1406            }
1407            if ($elem eq 'tprevinbutton') {    # Within thread previous button
1408                $TPREVINBUTTON = &get_elem_content($handle, $elem, $chop);
1409                last FMTSW;
1410            }
1411            if ($elem eq 'tprevinbuttonia') {
1412                $TPREVINBUTTONIA = &get_elem_content($handle, $elem, $chop);
1413                last FMTSW;
1414            }
1415            if ($elem eq 'tprevinlink') {      # Within thread previous link
1416                $TPREVINLINK = &get_elem_content($handle, $elem, $chop);
1417                last FMTSW;
1418            }
1419            if ($elem eq 'tprevinlinkia') {
1420                $TPREVINLINKIA = &get_elem_content($handle, $elem, $chop);
1421                last FMTSW;
1422            }
1423            if ($elem eq 'tprevlink') {        # Thread previous link
1424                $TPREVLINK = &get_elem_content($handle, $elem, $chop);
1425                last FMTSW;
1426            }
1427            if ($elem eq 'tprevlinkia') {
1428                $TPREVLINKIA = &get_elem_content($handle, $elem, $chop);
1429                last FMTSW;
1430            }
1431            if ($elem eq 'tprevpglink') {      # Thread previous page link
1432                $TPREVPGLINK = &get_elem_content($handle, $elem, $chop);
1433                last FMTSW;
1434            }
1435            if ($elem eq 'tprevpglinkia') {
1436                $TPREVPGLINKIA = &get_elem_content($handle, $elem, $chop);
1437                last FMTSW;
1438            }
1439            if ($elem eq 'treverse') {         # Reverse order of threads
1440                $TREVERSE = 1;
1441                last FMTSW;
1442            }
1443            if ($elem eq 'tnexttopbutton') {    # Next thread button
1444                $TNEXTTOPBUTTON = &get_elem_content($handle, $elem, $chop);
1445                last FMTSW;
1446            }
1447            if ($elem eq 'tnexttopbuttonia') {
1448                $TNEXTTOPBUTTONIA = &get_elem_content($handle, $elem, $chop);
1449                last FMTSW;
1450            }
1451            if ($elem eq 'tnexttoplink') {      # Next thread link
1452                $TNEXTTOPLINK = &get_elem_content($handle, $elem, $chop);
1453                last FMTSW;
1454            }
1455            if ($elem eq 'tnexttoplinkia') {
1456                $TNEXTTOPLINKIA = &get_elem_content($handle, $elem, $chop);
1457                last FMTSW;
1458            }
1459            if ($elem eq 'tprevtopbutton') {    # Previous thread button
1460                $TPREVTOPBUTTON = &get_elem_content($handle, $elem, $chop);
1461                last FMTSW;
1462            }
1463            if ($elem eq 'tprevtopbuttonia') {
1464                $TPREVTOPBUTTONIA = &get_elem_content($handle, $elem, $chop);
1465                last FMTSW;
1466            }
1467            if ($elem eq 'tprevtoplink') {      # Previous thread link
1468                $TPREVTOPLINK = &get_elem_content($handle, $elem, $chop);
1469                last FMTSW;
1470            }
1471            if ($elem eq 'tprevtoplinkia') {
1472                $TPREVTOPLINKIA = &get_elem_content($handle, $elem, $chop);
1473                last FMTSW;
1474            }
1475            if ($elem eq 'ttopbutton') {        # Top of thread button
1476                $TTOPBUTTON = &get_elem_content($handle, $elem, $chop);
1477                last FMTSW;
1478            }
1479            if ($elem eq 'ttopbuttonia') {
1480                $TTOPBUTTONIA = &get_elem_content($handle, $elem, $chop);
1481                last FMTSW;
1482            }
1483            if ($elem eq 'ttoplink') {          # Top of thread link
1484                $TTOPLINK = &get_elem_content($handle, $elem, $chop);
1485                last FMTSW;
1486            }
1487            if ($elem eq 'ttoplinkia') {
1488                $TTOPLINKIA = &get_elem_content($handle, $elem, $chop);
1489                last FMTSW;
1490            }
1491            if ($elem eq 'umask') {             # Umask of process
1492                if ($line = &get_elem_last_line($handle, $elem)) {
1493                    $line =~ s/\s//g;
1494                    $UMASK = $line;
1495                }
1496                last FMTSW;
1497            }
1498            if ($elem eq 'uselocaltime') {      # Use localtime for day groups
1499                $UseLocalTime = 1;
1500                last FMTSW;
1501            }
1502            if ($elem eq 'usinglastpg') {
1503                $UsingLASTPG = 1;
1504                last FMTSW;
1505            }
1506            if ($elem eq 'varregex') {          # Regex matching rc vars
1507                $tmp = &get_elem_last_line($handle, $elem);
1508                # only take value if not blank
1509                $VarExp = $tmp if $tmp =~ /\S/;
1510                last FMTSW;
1511            }
1512            if ($elem eq 'weekdays') {          # Full weekday name
1513                @a = &get_list_content($handle, $elem);
1514                if (scalar(@a)) {
1515                    @Weekdays = @a;
1516                }
1517                last FMTSW;
1518            }
1519            if ($elem eq 'weekdaysabr') {       # Abbreviated weekday name
1520                @a = &get_list_content($handle, $elem);
1521                if (scalar(@a)) {
1522                    @weekdays = @a;
1523                }
1524                last FMTSW;
1525            }
1526
1527        }    ## End FMTSW
1528    }
1529    close($handle);
1530    1;
1531}
1532
1533##----------------------------------------------------------------------
1534sub get_elem_content {
1535    my ($filehandle, $gi, $chop) = @_;
1536    my ($ret) = '';
1537
1538    while (<$filehandle>) {
1539        last if /^\s*<\/$gi\s*>/i;
1540        $ret .= $_;
1541    }
1542    $ret =~ s/\r?\n?$// if $chop;
1543    $ret;
1544}
1545
1546##----------------------------------------------------------------------
1547sub get_elem_int {
1548    my ($filehandle, $gi, $abs) = @_;
1549    my ($ret) = '';
1550
1551    while (<$filehandle>) {
1552        last if /^\s*<\/$gi\s*>/i;
1553        next unless /^\s*[-+]?\d+\s*$/;
1554        s/[+\s]//g;
1555        s/-// if $abs;
1556        $ret = $_;
1557    }
1558    $ret;
1559}
1560
1561##----------------------------------------------------------------------
1562sub get_elem_last_line {
1563    my ($filehandle, $gi) = @_;
1564    my ($ret) = '';
1565
1566    while (<$filehandle>) {
1567        last if /^\s*<\/$gi\s*>/i;
1568        next unless /\S/;
1569        $ret = $_;
1570    }
1571    $ret =~ s/\r?\n?$//;
1572    $ret;
1573}
1574
1575##----------------------------------------------------------------------
1576sub get_list_content {
1577    my ($filehandle, $gi) = @_;
1578    my (@items) = ();
1579
1580    while (<$filehandle>) {
1581        last if /^\s*<\/$gi\s*>/i;
1582        next unless /\S/;
1583        s/\r?\n?$//;
1584        push(@items, split(/[:;]/, $_));
1585    }
1586    @items;
1587}
1588
1589##----------------------------------------------------------------------
1590sub get_pathname_content {
1591    my ($filehandle, $gi) = @_;
1592    my (@items) = ();
1593
1594    while (<$filehandle>) {
1595        last if /^\s*<\/$gi\s*>/i;
1596        next unless /\S/;
1597        s/\r?\n?$//;
1598        push(@items, split(/$PATHSEP/o, $_));
1599    }
1600    @items;
1601}
1602
1603##---------------------------------------------------------------------------##
16041;
1605