"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.6.0/src/attrib.c" (5 Jul 2021, 81830 Bytes) of package /linux/misc/tin-2.6.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "attrib.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.5_vs_2.6.0.

    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : attrib.c
    4  *  Author    : I. Lea
    5  *  Created   : 1993-12-01
    6  *  Updated   : 2021-07-06
    7  *  Notes     : Group attribute routines
    8  *
    9  * Copyright (c) 1993-2021 Iain Lea <iain@bricbrac.de>
   10  * All rights reserved.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  *
   16  * 1. Redistributions of source code must retain the above copyright notice,
   17  *    this list of conditions and the following disclaimer.
   18  *
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  *
   23  * 3. Neither the name of the copyright holder nor the names of its
   24  *    contributors may be used to endorse or promote products derived from
   25  *    this software without specific prior written permission.
   26  *
   27  * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 
   41 #ifndef TIN_H
   42 #   include "tin.h"
   43 #endif /* !TIN_H */
   44 #ifndef VERSION_H
   45 #   include "version.h"
   46 #endif /* !VERSION_H */
   47 #ifndef TCURSES_H
   48 #   include "tcurses.h"
   49 #endif /* !TCURSES_H */
   50 
   51 
   52 /*
   53  * Global file offset for local_attributes_file
   54  */
   55 int attrib_file_offset;
   56 
   57 
   58 /*
   59  * Local prototypes
   60  */
   61 static t_bool skip_scope(struct t_scope *scope);
   62 static void set_attrib(int type, const char *scope, const char *line, void *data);
   63 static void set_default_attributes(struct t_attribute *attributes, struct t_attribute *scope, t_bool global);
   64 static void set_default_state(struct t_attribute_state *state);
   65 #ifdef DEBUG
   66     static void dump_attributes(void);
   67     static void dump_scopes(const char *fname);
   68 #   if 0 /* unused */
   69         static void debug_print_filter_attributes(void);
   70 #   endif /* 0 */
   71 #endif /* DEBUG */
   72 
   73 #define CopyBits(target,source) attributes->target = CAST_BITS(source,target)
   74 #define CopyBool(target,source) attributes->target = CAST_BOOL(source)
   75 
   76 /*
   77  * Per group attributes. This fills out a basic template of defaults
   78  * before the attributes in the current scope are applied.
   79  */
   80 static void
   81 set_default_attributes(
   82     struct t_attribute *attributes,
   83     struct t_attribute *scope,
   84     t_bool global)
   85 {
   86     attributes->global = (global ? TRUE : FALSE);   /* global/group specific */
   87     attributes->maildir = (scope ? scope->maildir : (global ? tinrc.maildir : NULL));
   88     attributes->savedir = (scope ? scope->savedir : (global ? tinrc.savedir : NULL));
   89     attributes->savefile = NULL;
   90     attributes->sigfile = (scope ? scope->sigfile : (global ? tinrc.sigfile : NULL));
   91     attributes->group_format = (scope ? scope->group_format : (global ? tinrc.group_format : NULL));
   92     attributes->thread_format = (scope ? scope->thread_format : (global ? tinrc.thread_format : NULL));
   93     attributes->date_format = (scope ? scope->date_format : (global ? tinrc.date_format : NULL));
   94     attributes->editor_format = (scope ? scope->editor_format : (global ? tinrc.editor_format : NULL));
   95     attributes->organization = (scope ? scope->organization : (global ? (*default_organization ? default_organization : NULL) : NULL));
   96     attributes->followup_to = NULL;
   97     attributes->mailing_list = NULL;
   98     attributes->x_headers = NULL;
   99     attributes->x_body = NULL;
  100     attributes->from = (scope ? scope->from : (global ? tinrc.mail_address : NULL));
  101     attributes->news_quote_format = (scope ? scope->news_quote_format : (global ? tinrc.news_quote_format : NULL));
  102     attributes->quote_chars = (scope ? scope->quote_chars : (global ? tinrc.quote_chars : NULL));
  103     attributes->mime_types_to_save = (scope ? scope->mime_types_to_save : (global ? my_strdup("*/*") : NULL));
  104 #ifdef HAVE_ISPELL
  105     attributes->ispell = NULL;
  106 #endif /* HAVE_ISPELL */
  107     attributes->quick_kill_scope = (scope ? scope->quick_kill_scope : (global ? (tinrc.default_filter_kill_global ? my_strdup("*") : NULL) : NULL));
  108     CopyBits(quick_kill_header, tinrc.default_filter_kill_header);
  109     CopyBool(quick_kill_case, tinrc.default_filter_kill_case);
  110     CopyBool(quick_kill_expire, tinrc.default_filter_kill_expire);
  111     attributes->quick_select_scope = (scope ? scope->quick_select_scope : (global ? (tinrc.default_filter_select_global ? my_strdup("*") : NULL) : NULL));
  112     CopyBits(quick_select_header, tinrc.default_filter_select_header);
  113     CopyBool(quick_select_case, tinrc.default_filter_select_case);
  114     CopyBool(quick_select_expire, tinrc.default_filter_select_expire);
  115     CopyBool(show_only_unread_arts, tinrc.show_only_unread_arts);
  116     CopyBits(thread_articles, tinrc.thread_articles);
  117     CopyBool(thread_catchup_on_exit, tinrc.thread_catchup_on_exit);
  118     CopyBits(thread_perc, tinrc.thread_perc);
  119     CopyBits(sort_article_type, tinrc.sort_article_type);
  120     CopyBits(sort_threads_type, tinrc.sort_threads_type);
  121     CopyBits(show_author, tinrc.show_author);
  122     CopyBool(show_signatures, tinrc.show_signatures);
  123     CopyBits(trim_article_body, tinrc.trim_article_body);
  124     CopyBool(verbatim_handling, tinrc.verbatim_handling);
  125 #ifdef HAVE_COLOR
  126     CopyBool(extquote_handling, tinrc.extquote_handling);
  127 #endif /* HAVE_COLOR */
  128     CopyBool(wrap_on_next_unread, tinrc.wrap_on_next_unread);
  129     CopyBool(add_posted_to_filter, tinrc.add_posted_to_filter);
  130     CopyBool(advertising, tinrc.advertising);
  131     CopyBool(alternative_handling, tinrc.alternative_handling);
  132     CopyBool(ask_for_metamail, tinrc.ask_for_metamail);
  133     CopyBits(auto_cc_bcc, tinrc.auto_cc_bcc);
  134     CopyBool(auto_list_thread, tinrc.auto_list_thread);
  135     attributes->auto_select = FALSE;
  136     CopyBool(batch_save, tinrc.batch_save);
  137     attributes->delete_tmp_files = FALSE;
  138     CopyBool(group_catchup_on_exit, tinrc.group_catchup_on_exit);
  139     CopyBool(mail_8bit_header, tinrc.mail_8bit_header);
  140     CopyBits(mail_mime_encoding, tinrc.mail_mime_encoding);
  141     CopyBool(mark_ignore_tags, tinrc.mark_ignore_tags);
  142     CopyBool(mark_saved_read, tinrc.mark_saved_read);
  143     attributes->news_headers_to_display = (global ? tinrc.news_headers_to_display : NULL);
  144     attributes->headers_to_display = (scope ? (scope->headers_to_display ? scope->headers_to_display : NULL) : NULL);
  145     attributes->news_headers_to_not_display = (global ? tinrc.news_headers_to_not_display : NULL);
  146     attributes->headers_to_not_display = (scope ? (scope->headers_to_not_display ? scope->headers_to_not_display : NULL) : NULL);
  147     CopyBool(pos_first_unread, tinrc.pos_first_unread);
  148     CopyBool(post_8bit_header, tinrc.post_8bit_header);
  149     CopyBits(post_mime_encoding, tinrc.post_mime_encoding);
  150     CopyBool(post_process_view, tinrc.post_process_view);
  151     CopyBits(post_process_type, tinrc.post_process_type);
  152 #ifndef DISABLE_PRINTING
  153     CopyBool(print_header, tinrc.print_header);
  154 #endif /* !DISABLE_PRINTING */
  155     CopyBool(process_only_unread, tinrc.process_only_unread);
  156     CopyBool(prompt_followupto, tinrc.prompt_followupto);
  157     CopyBool(sigdashes, tinrc.sigdashes);
  158     CopyBool(signature_repost, tinrc.signature_repost);
  159     attributes->x_comment_to = FALSE;
  160     CopyBool(tex2iso_conv, tinrc.tex2iso_conv);
  161     attributes->mime_forward = FALSE;
  162     attributes->fcc = NULL;
  163 #ifdef CHARSET_CONVERSION
  164     CopyBits(mm_network_charset, tinrc.mm_network_charset);
  165     attributes->undeclared_charset = NULL;
  166 #endif /* CHARSET_CONVERSION */
  167 }
  168 
  169 
  170 static void
  171 set_default_state(
  172     struct t_attribute_state *state)
  173 {
  174     state->add_posted_to_filter = FALSE;
  175     state->advertising = FALSE;
  176     state->alternative_handling = FALSE;
  177     state->ask_for_metamail = FALSE;
  178     state->auto_cc_bcc = FALSE;
  179     state->auto_list_thread = FALSE;
  180     state->auto_select = FALSE;
  181     state->batch_save = FALSE;
  182     state->date_format = FALSE;
  183     state->delete_tmp_files = FALSE;
  184     state->editor_format = FALSE;
  185     state->fcc = FALSE;
  186     state->followup_to = FALSE;
  187     state->from = FALSE;
  188     state->group_catchup_on_exit = FALSE;
  189     state->group_format = FALSE;
  190 #ifdef HAVE_ISPELL
  191     state->ispell = FALSE;
  192 #endif /* HAVE_ISPELL */
  193     state->mail_8bit_header = FALSE;
  194     state->mail_mime_encoding = FALSE;
  195     state->maildir = FALSE;
  196     state->mailing_list = FALSE;
  197     state->mark_ignore_tags = FALSE;
  198     state->mark_saved_read = FALSE;
  199     state->mime_forward = FALSE;
  200     state->mime_types_to_save = FALSE;
  201     state->news_headers_to_display = FALSE;
  202     state->news_headers_to_not_display = FALSE;
  203     state->news_quote_format = FALSE;
  204     state->organization = FALSE;
  205     state->pos_first_unread = FALSE;
  206     state->post_8bit_header = FALSE;
  207     state->post_mime_encoding = FALSE;
  208     state->post_process_type = FALSE;
  209     state->post_process_view = FALSE;
  210 #ifndef DISABLE_PRINTING
  211     state->print_header = FALSE;
  212 #endif /* !DISABLE_PRINTING */
  213     state->process_only_unread = FALSE;
  214     state->prompt_followupto = FALSE;
  215     state->quick_kill_case = FALSE;
  216     state->quick_kill_expire = FALSE;
  217     state->quick_kill_header = FALSE;
  218     state->quick_kill_scope = FALSE;
  219     state->quick_select_case = FALSE;
  220     state->quick_select_expire = FALSE;
  221     state->quick_select_header = FALSE;
  222     state->quick_select_scope = FALSE;
  223     state->quote_chars = FALSE;
  224     state->savedir = FALSE;
  225     state->savefile = FALSE;
  226     state->show_author = FALSE;
  227     state->show_only_unread_arts = FALSE;
  228     state->show_signatures = FALSE;
  229     state->sigdashes = FALSE;
  230     state->sigfile = FALSE;
  231     state->signature_repost = FALSE;
  232     state->sort_article_type = FALSE;
  233     state->sort_threads_type = FALSE;
  234     state->tex2iso_conv = FALSE;
  235     state->thread_articles = FALSE;
  236     state->thread_catchup_on_exit = FALSE;
  237     state->thread_format = FALSE;
  238     state->thread_perc = FALSE;
  239     state->trim_article_body = FALSE;
  240 #ifdef CHARSET_CONVERSION
  241     state->undeclared_charset = FALSE;
  242     state->mm_network_charset = FALSE;
  243 #endif /* CHARSET_CONVERSION */
  244     state->verbatim_handling = FALSE;
  245 #ifdef HAVE_COLOR
  246     state->extquote_handling = FALSE;
  247 #endif /* HAVE_COLOR */
  248     state->wrap_on_next_unread = FALSE;
  249     state->x_body = FALSE;
  250     state->x_comment_to = FALSE;
  251     state->x_headers = FALSE;
  252 }
  253 
  254 
  255 #define MATCH_BOOLEAN(pattern, type) \
  256     if (match_boolean(line, pattern, &flag)) { \
  257         num = (flag != FALSE); \
  258         set_attrib(type, scope, line, &num); \
  259         found = TRUE; \
  260         break; \
  261     }
  262 #define MATCH_INTEGER(pattern, type, maxval) \
  263     if (match_integer(line, pattern, &num, maxval)) { \
  264         set_attrib(type, scope, line, &num); \
  265         found = TRUE; \
  266         break; \
  267     }
  268 #define MATCH_STRING(pattern, type) \
  269     if (match_string(line, pattern, buf, sizeof(buf) - strlen(pattern))) { \
  270         set_attrib(type, scope, line, buf); \
  271         found = TRUE; \
  272         break; \
  273     }
  274 #define MATCH_LIST(pattern, type, table) \
  275     if (match_list(line, pattern, table, &num)) { \
  276         set_attrib(type, scope, line, &num); \
  277         found = TRUE; \
  278         break; \
  279     }
  280 #if !defined(CHARSET_CONVERSION) || !defined(HAVE_ISPELL) || defined(DISABLE_PRINTING)
  281 #   define SKIP_ITEM(pattern) \
  282         if (!strncmp(line, pattern, strlen(pattern))) { \
  283             found = TRUE; \
  284             break; \
  285         }
  286 #endif /* !CHARSET_CONVERSION || !HAVE_ISPELL || DISABLE_PRINTING */
  287 
  288 
  289 /*
  290  * read global/local attributes file
  291  */
  292 void
  293 read_attributes_file(
  294     t_bool global_file)
  295 {
  296     FILE *fp;
  297     char *file;
  298     char buf[LEN];
  299     char line[LEN];
  300     char scope[LEN];
  301     int i, num;
  302     struct t_version *upgrade = NULL;
  303     static t_bool startup = TRUE;
  304     t_bool flag, found = FALSE;
  305 
  306     if (!batch_mode || verbose)
  307         wait_message(0, _(txt_reading_attributes_file), (global_file ? _(txt_global) : ""));
  308     /*
  309      * Initialize global attributes even if there is no global file
  310      * These setting are used as the default for all groups unless overridden
  311      */
  312     if (global_file) {
  313         i = add_scope("_default_");
  314         scopes[i].global = TRUE;
  315         set_default_attributes(scopes[i].attribute, NULL, TRUE);
  316         build_news_headers_array(scopes[i].attribute, TRUE);
  317         build_news_headers_array(scopes[i].attribute, FALSE);
  318         file = global_attributes_file;
  319     } else {
  320         attrib_file_offset = 1;
  321         file = local_attributes_file;
  322     }
  323 
  324     if ((fp = fopen(file, "r")) != NULL) {
  325         scope[0] = '\0';
  326         /*
  327          * TODO: use tin_fgets() instead to handle long lines
  328          * (e.g. buggy translation)
  329          */
  330         while (fgets(line, (int) sizeof(line), fp) != NULL) {
  331             if (line[0] == '\n')
  332                 continue;
  333             if (line[0] == '#') {
  334                 if (!global_file) {
  335                     if (scope[0] == '\0')
  336                         attrib_file_offset++;
  337                     if (startup && upgrade == NULL && match_string(line, "# Group attributes file V", NULL, 0)) {
  338                         upgrade = check_upgrade(line, "# Group attributes file V", ATTRIBUTES_VERSION);
  339                         if (upgrade->state != RC_IGNORE)
  340                             upgrade_prompt_quit(upgrade, file); /* TODO: do something (more) useful here */
  341                     }
  342                 }
  343                 continue;
  344             }
  345 
  346             switch (my_tolower((unsigned char) line[0])) {
  347                 case 'a':
  348                     MATCH_BOOLEAN("add_posted_to_filter=", OPT_ATTRIB_ADD_POSTED_TO_FILTER);
  349                     MATCH_BOOLEAN("advertising=", OPT_ATTRIB_ADVERTISING);
  350                     MATCH_BOOLEAN("alternative_handling=", OPT_ATTRIB_ALTERNATIVE_HANDLING);
  351                     MATCH_BOOLEAN("ask_for_metamail=", OPT_ATTRIB_ASK_FOR_METAMAIL);
  352                     MATCH_INTEGER("auto_cc_bcc=", OPT_ATTRIB_AUTO_CC_BCC, AUTO_CC_BCC);
  353                     MATCH_BOOLEAN("auto_list_thread=", OPT_ATTRIB_AUTO_LIST_THREAD);
  354                     MATCH_BOOLEAN("auto_select=", OPT_ATTRIB_AUTO_SELECT);
  355                     break;
  356 
  357                 case 'b':
  358                     MATCH_BOOLEAN("batch_save=", OPT_ATTRIB_BATCH_SAVE);
  359                     break;
  360 
  361                 case 'd':
  362                     MATCH_STRING("date_format=", OPT_ATTRIB_DATE_FORMAT);
  363                     MATCH_BOOLEAN("delete_tmp_files=", OPT_ATTRIB_DELETE_TMP_FILES);
  364                     break;
  365 
  366                 case 'e':
  367                     MATCH_STRING("editor_format=", OPT_ATTRIB_EDITOR_FORMAT);
  368 #ifdef HAVE_COLOR
  369                     MATCH_BOOLEAN("extquote_handling=", OPT_ATTRIB_EXTQUOTE_HANDLING);
  370 #endif /* HAVE_COLOR */
  371 
  372                     break;
  373 
  374                 case 'f':
  375                     MATCH_STRING("fcc=", OPT_ATTRIB_FCC);
  376                     MATCH_STRING("followup_to=", OPT_ATTRIB_FOLLOWUP_TO);
  377                     MATCH_STRING("from=", OPT_ATTRIB_FROM);
  378                     break;
  379 
  380                 case 'g':
  381                     MATCH_BOOLEAN("group_catchup_on_exit=", OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT);
  382                     MATCH_STRING("group_format=", OPT_ATTRIB_GROUP_FORMAT);
  383                     break;
  384 
  385                 case 'i':
  386 #ifdef HAVE_ISPELL
  387                     MATCH_STRING("ispell=", OPT_ATTRIB_ISPELL);
  388 #else
  389                     SKIP_ITEM("ispell=");
  390 #endif /* HAVE_ISPELL */
  391                     break;
  392 
  393                 case 'm':
  394                     MATCH_BOOLEAN("mail_8bit_header=", OPT_ATTRIB_MAIL_8BIT_HEADER);
  395                     MATCH_LIST("mail_mime_encoding=", OPT_ATTRIB_MAIL_MIME_ENCODING, txt_mime_encodings);
  396                     MATCH_STRING("maildir=", OPT_ATTRIB_MAILDIR);
  397                     MATCH_STRING("mailing_list=", OPT_ATTRIB_MAILING_LIST);
  398                     MATCH_BOOLEAN("mark_ignore_tags=", OPT_ATTRIB_MARK_IGNORE_TAGS);
  399                     MATCH_BOOLEAN("mark_saved_read=", OPT_ATTRIB_MARK_SAVED_READ);
  400                     MATCH_BOOLEAN("mime_forward=", OPT_ATTRIB_MIME_FORWARD);
  401                     MATCH_STRING("mime_types_to_save=", OPT_ATTRIB_MIME_TYPES_TO_SAVE);
  402 #ifdef CHARSET_CONVERSION
  403                     MATCH_LIST("mm_network_charset=", OPT_ATTRIB_MM_NETWORK_CHARSET, txt_mime_charsets);
  404 #else
  405                     SKIP_ITEM("mm_network_charset=");
  406 #endif /* CHARSET_CONVERSION */
  407                     break;
  408 
  409                 case 'n':
  410                     MATCH_STRING("news_headers_to_display=", OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY);
  411                     MATCH_STRING("news_headers_to_not_display=", OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY);
  412                     MATCH_STRING("news_quote_format=", OPT_ATTRIB_NEWS_QUOTE_FORMAT);
  413                     break;
  414 
  415                 case 'o':
  416                     MATCH_STRING("organization=", OPT_ATTRIB_ORGANIZATION);
  417                     break;
  418 
  419                 case 'p':
  420                     MATCH_BOOLEAN("pos_first_unread=", OPT_ATTRIB_POS_FIRST_UNREAD);
  421                     MATCH_BOOLEAN("post_8bit_header=", OPT_ATTRIB_POST_8BIT_HEADER);
  422                     MATCH_LIST("post_mime_encoding=", OPT_ATTRIB_POST_MIME_ENCODING, txt_mime_encodings);
  423                     MATCH_BOOLEAN("post_process_view=", OPT_ATTRIB_POST_PROCESS_VIEW);
  424                     MATCH_INTEGER("post_process_type=", OPT_ATTRIB_POST_PROCESS_TYPE, POST_PROC_YES);
  425 #ifndef DISABLE_PRINTING
  426                     MATCH_BOOLEAN("print_header=", OPT_ATTRIB_PRINT_HEADER);
  427 #else
  428                     SKIP_ITEM("print_header=");
  429 #endif /* !DISABLE_PRINTING */
  430                     MATCH_BOOLEAN("process_only_unread=", OPT_ATTRIB_PROCESS_ONLY_UNREAD);
  431                     MATCH_BOOLEAN("prompt_followupto=", OPT_ATTRIB_PROMPT_FOLLOWUPTO);
  432                     break;
  433 
  434                 case 'q':
  435                     MATCH_BOOLEAN("quick_kill_case=", OPT_ATTRIB_QUICK_KILL_CASE);
  436                     MATCH_BOOLEAN("quick_kill_expire=", OPT_ATTRIB_QUICK_KILL_EXPIRE);
  437                     MATCH_INTEGER("quick_kill_header=", OPT_ATTRIB_QUICK_KILL_HEADER, FILTER_LINES);
  438                     MATCH_STRING("quick_kill_scope=", OPT_ATTRIB_QUICK_KILL_SCOPE);
  439                     MATCH_BOOLEAN("quick_select_case=", OPT_ATTRIB_QUICK_SELECT_CASE);
  440                     MATCH_BOOLEAN("quick_select_expire=", OPT_ATTRIB_QUICK_SELECT_EXPIRE);
  441                     MATCH_INTEGER("quick_select_header=", OPT_ATTRIB_QUICK_SELECT_HEADER, FILTER_LINES);
  442                     MATCH_STRING("quick_select_scope=", OPT_ATTRIB_QUICK_SELECT_SCOPE);
  443                     if (match_string(line, "quote_chars=", buf, sizeof(buf))) {
  444                         if (upgrade && upgrade->file_version < 10010) { /* %s/%S changed to %I */
  445                             char *q = buf;
  446 
  447                             while (*q) {
  448                                 if (*q == '%' && (*(q + 1) == 's' || *(q + 1) == 'S'))
  449                                     *(++q) = 'I';
  450 
  451                                 q++;
  452                             }
  453                         }
  454                         quote_dash_to_space(buf);
  455                         set_attrib(OPT_ATTRIB_QUOTE_CHARS, scope, line, buf);
  456                         found = TRUE;
  457                         break;
  458                     }
  459                     break;
  460 
  461                 case 's':
  462                     MATCH_STRING("savedir=", OPT_ATTRIB_SAVEDIR);
  463                     MATCH_STRING("savefile=", OPT_ATTRIB_SAVEFILE);
  464                     if (match_string(line, "scope=", scope, sizeof(scope))) {
  465                         i = add_scope(scope);
  466                         scopes[i].global = global_file ? TRUE : FALSE;
  467                         found = TRUE;
  468                         break;
  469                     }
  470                     MATCH_INTEGER("show_author=", OPT_ATTRIB_SHOW_AUTHOR, SHOW_FROM_BOTH);
  471                     MATCH_BOOLEAN("show_only_unread_arts=", OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS);
  472                     MATCH_BOOLEAN("show_signatures=", OPT_ATTRIB_SHOW_SIGNATURES);
  473                     MATCH_BOOLEAN("sigdashes=", OPT_ATTRIB_SIGDASHES);
  474                     MATCH_BOOLEAN("signature_repost=", OPT_ATTRIB_SIGNATURE_REPOST);
  475                     MATCH_STRING("sigfile=", OPT_ATTRIB_SIGFILE);
  476                     MATCH_INTEGER("sort_article_type=", OPT_ATTRIB_SORT_ARTICLE_TYPE, SORT_ARTICLES_BY_LINES_ASCEND);
  477                     MATCH_INTEGER("sort_threads_type=", OPT_ATTRIB_SORT_THREADS_TYPE, SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND);
  478                     break;
  479 
  480                 case 't':
  481                     MATCH_BOOLEAN("tex2iso_conv=", OPT_ATTRIB_TEX2ISO_CONV);
  482                     MATCH_INTEGER("thread_articles=", OPT_ATTRIB_THREAD_ARTICLES, THREAD_MAX);
  483                     MATCH_BOOLEAN("thread_catchup_on_exit=", OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT);
  484                     MATCH_STRING("thread_format=", OPT_ATTRIB_THREAD_FORMAT);
  485                     MATCH_INTEGER("thread_perc=", OPT_ATTRIB_THREAD_PERC, 100);
  486                     MATCH_INTEGER("trim_article_body=", OPT_ATTRIB_TRIM_ARTICLE_BODY, 7);
  487                     break;
  488 
  489                 case 'u':
  490 #ifdef CHARSET_CONVERSION
  491                     MATCH_STRING("undeclared_charset=", OPT_ATTRIB_UNDECLARED_CHARSET);
  492 #else
  493                     SKIP_ITEM("undeclared_charset=");
  494 #endif /* CHARSET_CONVERSION */
  495                     break;
  496 
  497                 case 'v':
  498                     MATCH_BOOLEAN("verbatim_handling=", OPT_ATTRIB_VERBATIM_HANDLING);
  499                     break;
  500 
  501                 case 'w':
  502                     MATCH_BOOLEAN("wrap_on_next_unread=", OPT_ATTRIB_WRAP_ON_NEXT_UNREAD);
  503                     break;
  504 
  505                 case 'x':
  506                     MATCH_STRING("x_body=", OPT_ATTRIB_X_BODY);
  507                     MATCH_BOOLEAN("x_comment_to=", OPT_ATTRIB_X_COMMENT_TO);
  508                     MATCH_STRING("x_headers=", OPT_ATTRIB_X_HEADERS);
  509                     break;
  510 
  511                 default:
  512                     break;
  513             }
  514 
  515             if (!global_file && upgrade && upgrade->state == RC_UPGRADE) {
  516                 int auto_cc_bcc;
  517                 int show_info;
  518                 t_bool auto_bcc = FALSE;
  519                 t_bool auto_cc = FALSE;
  520 
  521                 switch (my_tolower((unsigned char) line[0])) {
  522                     case 'a':
  523                         if (match_boolean(line, "auto_bcc=", &auto_bcc)) {
  524                             if (scopes[num_scope - 1].attribute->auto_cc_bcc & AUTO_CC)
  525                                 auto_cc_bcc = (auto_bcc ? AUTO_CC_BCC : AUTO_CC);
  526                             else
  527                                 auto_cc_bcc = (auto_bcc ? AUTO_BCC : 0);
  528                             set_attrib(OPT_ATTRIB_AUTO_CC_BCC, scope, line, &auto_cc_bcc);
  529                             found = TRUE;
  530                             break;
  531                         }
  532                         if (match_boolean(line, "auto_cc=", &auto_cc)) {
  533                             if (scopes[num_scope - 1].attribute->auto_cc_bcc & AUTO_BCC)
  534                                 auto_cc_bcc = (auto_cc ? AUTO_CC_BCC : AUTO_BCC);
  535                             else
  536                                 auto_cc_bcc = (auto_cc ? AUTO_CC : 0);
  537                             set_attrib(OPT_ATTRIB_AUTO_CC_BCC, scope, line, &auto_cc_bcc);
  538                             found = TRUE;
  539                             break;
  540                         }
  541                         /* option removed */
  542                         if (upgrade && upgrade->file_version < 10011) {
  543                             t_bool ignore;
  544 
  545                             if (match_boolean(line, "auto_save=", &ignore))
  546                                 found = TRUE;
  547                             break;
  548                         }
  549                         break;
  550 
  551                     case 'p':
  552                         MATCH_INTEGER("post_proc_type=", OPT_ATTRIB_POST_PROCESS_TYPE, POST_PROC_YES);
  553                         break;
  554 
  555                     case 's':
  556                         if (match_integer(line, "show_info=", &show_info, 3)) {
  557                             char *gbuf = my_malloc(23);
  558                             char *tbuf = my_malloc(23);
  559 
  560                             switch (show_info) {
  561                                 case 0:
  562                                     strcpy(gbuf, "%n %m %R  %s  %F");
  563                                     strcpy(tbuf, "%n %m  %T  %F");
  564                                     break;
  565 
  566                                 case 2:
  567                                     strcpy(gbuf, "%n %m %R %S  %s  %F");
  568                                     strcpy(tbuf, "%n %m  [%S]  %T  %F");
  569                                     break;
  570 
  571                                 case 3:
  572                                     strcpy(gbuf, "%n %m %R %L %S  %s  %F");
  573                                     strcpy(tbuf, "%n %m  [%L,%S]  %T  %F");
  574                                     break;
  575 
  576                                 default:
  577                                     strcpy(gbuf, DEFAULT_GROUP_FORMAT);
  578                                     strcpy(tbuf, DEFAULT_THREAD_FORMAT);
  579                                     break;
  580                             }
  581                             set_attrib(OPT_ATTRIB_GROUP_FORMAT, scope, line, gbuf);
  582                             set_attrib(OPT_ATTRIB_THREAD_FORMAT, scope, line, tbuf);
  583                             free(gbuf);
  584                             free(tbuf);
  585                             found = TRUE;
  586                             break;
  587                         }
  588                         /*
  589                          * previous versions has always passed groupname to external
  590                          * commands, now we look for %G
  591                          *
  592                          * 8 == sizeof("sigfile=")
  593                          */
  594                         if (match_string(line, "sigfile=", buf, sizeof(buf) - 8) && buf[0] == '!') {
  595                             /* just append %G if ATTRIBUTES_VERSION <= 1.0.8 */
  596                             if (upgrade && upgrade->file_version < 10009) {
  597                                 char *newbuf = my_malloc(sizeof(buf) - 8 + 4);
  598 
  599                                 sprintf(newbuf, "%s %s", buf, "%G");
  600                                 set_attrib(OPT_ATTRIB_SIGFILE, scope, line, newbuf);
  601                                 free(newbuf);
  602                             }
  603                             break;
  604                         }
  605                         MATCH_BOOLEAN("show_only_unread=", OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS);
  606                         MATCH_INTEGER("sort_art_type=", OPT_ATTRIB_SORT_ARTICLE_TYPE, SORT_ARTICLES_BY_LINES_ASCEND);
  607                         break;
  608 
  609                     case 't':
  610                         MATCH_INTEGER("thread_arts=", OPT_ATTRIB_THREAD_ARTICLES, THREAD_MAX);
  611                         break;
  612 
  613                     default:
  614                         break;
  615                 }
  616             }
  617 
  618             if (found)
  619                 found = FALSE;
  620             else {
  621                 /* TODO: even without DEBUG? */
  622                 error_message(1, _(txt_bad_attrib), line);
  623 #ifdef DEBUG
  624                 if (debug & (DEBUG_ATTRIB))
  625                     debug_print_file("ATTRIBUTES", txt_bad_attrib, line);
  626 #endif /* DEBUG */
  627             }
  628         }
  629         fclose(fp);
  630 
  631         /*
  632          * TODO: do something useful for the other cases
  633          */
  634         if (!global_file && upgrade && upgrade->state == RC_UPGRADE)
  635             write_attributes_file(file);
  636 
  637         FreeAndNull(upgrade);
  638 
  639     } else if (!global_file && startup) {
  640         /* no local attributes file, add some useful defaults and write file */
  641 
  642         add_scope("*");
  643         snprintf(buf, sizeof(buf), "%s", "~/.tin/headers");
  644         set_attrib(OPT_ATTRIB_X_HEADERS, "*", "", buf);
  645 
  646         add_scope("*sources*");
  647         num = POST_PROC_SHAR;
  648         set_attrib(OPT_ATTRIB_POST_PROCESS_TYPE, "*sources*", "", &num);
  649 
  650         add_scope("*binaries*");
  651         num = POST_PROC_YES;
  652         set_attrib(OPT_ATTRIB_POST_PROCESS_TYPE, "*binaries*", "", &num);
  653         num = FALSE;
  654         set_attrib(OPT_ATTRIB_TEX2ISO_CONV, "*binaries*", "", &num);
  655         num = TRUE;
  656         set_attrib(OPT_ATTRIB_DELETE_TMP_FILES, "*binaries*", "", &num);
  657         snprintf(buf, sizeof(buf), "%s", "poster");
  658         set_attrib(OPT_ATTRIB_FOLLOWUP_TO, "*binaries*", "", buf);
  659 
  660         write_attributes_file(file);
  661     }
  662     if (!global_file && startup)
  663         startup = FALSE;
  664 #ifdef DEBUG
  665     if (!global_file)
  666         dump_scopes("SCOPES-R");
  667 #endif /* DEBUG */
  668 }
  669 
  670 
  671 #define SET_STRING(string) \
  672     FreeIfNeeded(curr_scope->attribute->string); \
  673     curr_scope->attribute->string = my_strdup((char *) data); \
  674     curr_scope->state->string = TRUE; \
  675     break
  676 
  677 #define SET_INTEGER(value) \
  678     curr_scope->attribute->value = CAST_BITS(*((int *) data), value); \
  679     curr_scope->state->value = TRUE; \
  680     break
  681 
  682 #define SET_BOOLEAN(value) \
  683     curr_scope->attribute->value = CAST_BOOL(*((int *) data)); \
  684     curr_scope->state->value = TRUE; \
  685     break
  686 
  687 static void
  688 set_attrib(
  689     int type,
  690     const char *scope,
  691     const char *line,
  692     void *data)
  693 {
  694     struct t_scope *curr_scope;
  695 
  696     if (scope == NULL || *scope == '\0') {  /* No active scope set yet */
  697         error_message(2, _(txt_attrib_no_scope), line);
  698 #ifdef DEBUG
  699         if (debug & DEBUG_ATTRIB)
  700             debug_print_file("ATTRIBUTES", txt_attrib_no_scope, line);
  701 #endif /* DEBUG */
  702         return;
  703     }
  704 
  705     if (num_scope > 1) {
  706         curr_scope = &scopes[num_scope - 1];
  707         /*
  708          * Now set the required attribute
  709          */
  710         switch (type) {
  711             case OPT_ATTRIB_MAILDIR:
  712                 SET_STRING(maildir);
  713 
  714             case OPT_ATTRIB_SAVEDIR:
  715                 SET_STRING(savedir);
  716 
  717             case OPT_ATTRIB_SAVEFILE:
  718                 SET_STRING(savefile);
  719 
  720             case OPT_ATTRIB_ORGANIZATION:
  721                 SET_STRING(organization);
  722 
  723             case OPT_ATTRIB_FROM:
  724                 SET_STRING(from);
  725 
  726             case OPT_ATTRIB_SIGFILE:
  727                 SET_STRING(sigfile);
  728 
  729             case OPT_ATTRIB_FOLLOWUP_TO:
  730                 SET_STRING(followup_to);
  731 
  732             case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
  733                 SET_BOOLEAN(add_posted_to_filter);
  734 
  735             case OPT_ATTRIB_ADVERTISING:
  736                 SET_BOOLEAN(advertising);
  737 
  738             case OPT_ATTRIB_ALTERNATIVE_HANDLING:
  739                 SET_BOOLEAN(alternative_handling);
  740 
  741             case OPT_ATTRIB_ASK_FOR_METAMAIL:
  742                 SET_BOOLEAN(ask_for_metamail);
  743 
  744             case OPT_ATTRIB_AUTO_CC_BCC:
  745                 SET_INTEGER(auto_cc_bcc);
  746 
  747             case OPT_ATTRIB_AUTO_LIST_THREAD:
  748                 SET_BOOLEAN(auto_list_thread);
  749 
  750             case OPT_ATTRIB_AUTO_SELECT:
  751                 SET_BOOLEAN(auto_select);
  752 
  753             case OPT_ATTRIB_BATCH_SAVE:
  754                 SET_BOOLEAN(batch_save);
  755 
  756             case OPT_ATTRIB_DATE_FORMAT:
  757                 SET_STRING(date_format);
  758 
  759             case OPT_ATTRIB_DELETE_TMP_FILES:
  760                 SET_BOOLEAN(delete_tmp_files);
  761 
  762             case OPT_ATTRIB_EDITOR_FORMAT:
  763                 SET_STRING(editor_format);
  764 
  765             case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
  766                 SET_BOOLEAN(group_catchup_on_exit);
  767 
  768             case OPT_ATTRIB_GROUP_FORMAT:
  769                 SET_STRING(group_format);
  770 
  771             case OPT_ATTRIB_MAIL_8BIT_HEADER:
  772                 SET_BOOLEAN(mail_8bit_header);
  773 
  774             case OPT_ATTRIB_MAIL_MIME_ENCODING:
  775                 SET_INTEGER(mail_mime_encoding);
  776 
  777             case OPT_ATTRIB_MARK_IGNORE_TAGS:
  778                 SET_BOOLEAN(mark_ignore_tags);
  779 
  780             case OPT_ATTRIB_MARK_SAVED_READ:
  781                 SET_BOOLEAN(mark_saved_read);
  782 
  783             case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
  784                 FreeIfNeeded(curr_scope->attribute->news_headers_to_display);
  785                 curr_scope->attribute->news_headers_to_display = my_strdup((char *) data);
  786                 build_news_headers_array(curr_scope->attribute, TRUE);
  787                 curr_scope->state->news_headers_to_display = TRUE;
  788                 break;
  789 
  790             case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
  791                 FreeIfNeeded(curr_scope->attribute->news_headers_to_not_display);
  792                 curr_scope->attribute->news_headers_to_not_display = my_strdup((char *) data);
  793                 build_news_headers_array(curr_scope->attribute, FALSE);
  794                 curr_scope->state->news_headers_to_not_display = TRUE;
  795                 break;
  796 
  797             case OPT_ATTRIB_POS_FIRST_UNREAD:
  798                 SET_BOOLEAN(pos_first_unread);
  799 
  800             case OPT_ATTRIB_POST_8BIT_HEADER:
  801                 SET_BOOLEAN(post_8bit_header);
  802 
  803             case OPT_ATTRIB_POST_MIME_ENCODING:
  804                 SET_INTEGER(post_mime_encoding);
  805 
  806             case OPT_ATTRIB_POST_PROCESS_VIEW:
  807                 SET_BOOLEAN(post_process_view);
  808 
  809 #ifndef DISABLE_PRINTING
  810             case OPT_ATTRIB_PRINT_HEADER:
  811                 SET_BOOLEAN(print_header);
  812 #endif /* !DISABLE_PRINTING */
  813 
  814             case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
  815                 SET_BOOLEAN(process_only_unread);
  816 
  817             case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
  818                 SET_BOOLEAN(prompt_followupto);
  819 
  820 #ifdef HAVE_COLOR
  821             case OPT_ATTRIB_EXTQUOTE_HANDLING:
  822                 SET_BOOLEAN(extquote_handling);
  823 #endif /* HAVE_COLOR */
  824 
  825             case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
  826                 SET_BOOLEAN(show_only_unread_arts);
  827 
  828             case OPT_ATTRIB_SIGDASHES:
  829                 SET_BOOLEAN(sigdashes);
  830 
  831             case OPT_ATTRIB_SIGNATURE_REPOST:
  832                 SET_BOOLEAN(signature_repost);
  833 
  834             case OPT_ATTRIB_THREAD_ARTICLES:
  835                 SET_INTEGER(thread_articles);
  836 
  837             case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
  838                 SET_BOOLEAN(thread_catchup_on_exit);
  839 
  840             case OPT_ATTRIB_THREAD_FORMAT:
  841                 SET_STRING(thread_format);
  842 
  843             case OPT_ATTRIB_THREAD_PERC:
  844                 SET_INTEGER(thread_perc);
  845 
  846             case OPT_ATTRIB_SHOW_AUTHOR:
  847                 SET_INTEGER(show_author);
  848 
  849             case OPT_ATTRIB_SHOW_SIGNATURES:
  850                 SET_BOOLEAN(show_signatures);
  851 
  852             case OPT_ATTRIB_TRIM_ARTICLE_BODY:
  853                 SET_INTEGER(trim_article_body);
  854 
  855             case OPT_ATTRIB_VERBATIM_HANDLING:
  856                 SET_BOOLEAN(verbatim_handling);
  857 
  858             case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
  859                 SET_BOOLEAN(wrap_on_next_unread);
  860 
  861             case OPT_ATTRIB_SORT_ARTICLE_TYPE:
  862                 SET_INTEGER(sort_article_type);
  863 
  864             case OPT_ATTRIB_SORT_THREADS_TYPE:
  865                 SET_INTEGER(sort_threads_type);
  866 
  867             case OPT_ATTRIB_POST_PROCESS_TYPE:
  868                 SET_INTEGER(post_process_type);
  869 
  870             case OPT_ATTRIB_QUICK_KILL_HEADER:
  871                 SET_INTEGER(quick_kill_header);
  872 
  873             case OPT_ATTRIB_QUICK_KILL_SCOPE:
  874                 SET_STRING(quick_kill_scope);
  875 
  876             case OPT_ATTRIB_QUICK_KILL_EXPIRE:
  877                 SET_BOOLEAN(quick_kill_expire);
  878 
  879             case OPT_ATTRIB_QUICK_KILL_CASE:
  880                 SET_BOOLEAN(quick_kill_case);
  881 
  882             case OPT_ATTRIB_QUICK_SELECT_HEADER:
  883                 SET_INTEGER(quick_select_header);
  884 
  885             case OPT_ATTRIB_QUICK_SELECT_SCOPE:
  886                 SET_STRING(quick_select_scope);
  887 
  888             case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
  889                 SET_BOOLEAN(quick_select_expire);
  890 
  891             case OPT_ATTRIB_QUICK_SELECT_CASE:
  892                 SET_BOOLEAN(quick_select_case);
  893 
  894             case OPT_ATTRIB_MAILING_LIST:
  895                 SET_STRING(mailing_list);
  896 
  897 #ifdef CHARSET_CONVERSION
  898             case OPT_ATTRIB_MM_NETWORK_CHARSET:
  899                 SET_INTEGER(mm_network_charset);
  900 
  901             case OPT_ATTRIB_UNDECLARED_CHARSET:
  902                 SET_STRING(undeclared_charset);
  903 #endif /* CHARSET_CONVERSION */
  904 
  905             case OPT_ATTRIB_X_HEADERS:
  906                 SET_STRING(x_headers);
  907 
  908             case OPT_ATTRIB_X_BODY:
  909                 SET_STRING(x_body);
  910 
  911             case OPT_ATTRIB_X_COMMENT_TO:
  912                 SET_BOOLEAN(x_comment_to);
  913 
  914             case OPT_ATTRIB_FCC:
  915                 SET_STRING(fcc);
  916 
  917             case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
  918                 SET_STRING(news_quote_format);
  919 
  920             case OPT_ATTRIB_QUOTE_CHARS:
  921                 SET_STRING(quote_chars);
  922 
  923             case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
  924                 SET_STRING(mime_types_to_save);
  925 
  926             case OPT_ATTRIB_MIME_FORWARD:
  927                 SET_BOOLEAN(mime_forward);
  928 
  929 #ifdef HAVE_ISPELL
  930             case OPT_ATTRIB_ISPELL:
  931                 SET_STRING(ispell);
  932 #endif /* HAVE_ISPELL */
  933 
  934             case OPT_ATTRIB_TEX2ISO_CONV:
  935                 SET_BOOLEAN(tex2iso_conv);
  936 
  937             default:
  938                 break;
  939         }
  940     }
  941 }
  942 
  943 
  944 /*
  945  * Insert a new scope entry into scopes[] and return the index.
  946  */
  947 int
  948 add_scope(
  949     const char *scope)
  950 {
  951     if (!scope || !*scope)
  952         return 0;
  953 
  954     if ((num_scope >= max_scope) || (num_scope < 0) || (scopes == NULL))
  955         expand_scope();
  956 
  957     scopes[num_scope].scope = my_strdup(scope);
  958     scopes[num_scope].attribute = my_malloc(sizeof(struct t_attribute));
  959     set_default_attributes(scopes[num_scope].attribute, NULL, FALSE);
  960     scopes[num_scope].state = my_malloc(sizeof(struct t_attribute_state));
  961     set_default_state(scopes[num_scope].state);
  962     scopes[num_scope].global = FALSE;
  963     return num_scope++;
  964 }
  965 
  966 
  967 #define SET_ATTRIB(attr) do { \
  968         if (curr_scope->state->attr) \
  969             group->attribute->attr = curr_scope->attribute->attr; \
  970     } while (0)
  971 
  972 
  973 /*
  974  * Set the attributes of all groups
  975  */
  976 void
  977 assign_attributes_to_groups(
  978     void)
  979 {
  980     struct t_group *group;
  981     struct t_scope *default_scope, *curr_scope;
  982     t_bool found;
  983     int i, j;
  984     long processed = 0L;
  985 #ifdef CHARSET_CONVERSION
  986     t_bool is_7bit;
  987 #endif /* CHARSET_CONVERSION */
  988 
  989     if (!batch_mode || verbose)
  990         wait_message(0, _("Processing attributes... ")); /* TODO: -> lang.c */
  991 
  992     default_scope = &scopes[0];
  993     for_each_group(i) {
  994         if (++processed % (MODULO_COUNT_NUM) == 0)
  995             spin_cursor();
  996         group = &active[i];
  997         found = FALSE;
  998         for (j = 1; j < num_scope; j++) {
  999             curr_scope = &scopes[j];
 1000             if (match_group_list(group->name, curr_scope->scope)) {
 1001                 if (group->attribute == NULL || group->attribute == default_scope->attribute) {
 1002                     group->attribute = my_malloc(sizeof(struct t_attribute));
 1003                     set_default_attributes(group->attribute, default_scope->attribute, FALSE);
 1004                     found = TRUE;
 1005                 }
 1006                 if (!found) {
 1007                     set_default_attributes(group->attribute, default_scope->attribute, FALSE);
 1008                     found = TRUE;
 1009                 }
 1010                 SET_ATTRIB(maildir);
 1011                 SET_ATTRIB(savedir);
 1012                 SET_ATTRIB(savefile);
 1013                 SET_ATTRIB(sigfile);
 1014                 SET_ATTRIB(group_format);
 1015                 SET_ATTRIB(thread_format);
 1016                 SET_ATTRIB(date_format);
 1017                 SET_ATTRIB(editor_format);
 1018                 SET_ATTRIB(organization);
 1019                 SET_ATTRIB(fcc);
 1020                 SET_ATTRIB(followup_to);
 1021                 SET_ATTRIB(mailing_list);
 1022                 SET_ATTRIB(x_headers);
 1023                 SET_ATTRIB(x_body);
 1024                 SET_ATTRIB(from);
 1025                 SET_ATTRIB(news_quote_format);
 1026                 SET_ATTRIB(quote_chars);
 1027                 SET_ATTRIB(mime_types_to_save);
 1028 #ifdef HAVE_ISPELL
 1029                 SET_ATTRIB(ispell);
 1030 #endif /* HAVE_ISPELL */
 1031 #ifdef CHARSET_CONVERSION
 1032                 SET_ATTRIB(mm_network_charset);
 1033                 SET_ATTRIB(undeclared_charset);
 1034 #endif /* CHARSET_CONVERSION */
 1035                 SET_ATTRIB(quick_kill_scope);
 1036                 SET_ATTRIB(quick_kill_header);
 1037                 SET_ATTRIB(quick_kill_case);
 1038                 SET_ATTRIB(quick_kill_expire);
 1039                 SET_ATTRIB(quick_select_scope);
 1040                 SET_ATTRIB(quick_select_header);
 1041                 SET_ATTRIB(quick_select_case);
 1042                 SET_ATTRIB(quick_select_expire);
 1043                 SET_ATTRIB(show_only_unread_arts);
 1044                 SET_ATTRIB(thread_articles);
 1045                 SET_ATTRIB(thread_catchup_on_exit);
 1046                 SET_ATTRIB(thread_perc);
 1047                 SET_ATTRIB(sort_article_type);
 1048                 SET_ATTRIB(sort_threads_type);
 1049                 SET_ATTRIB(show_author);
 1050                 SET_ATTRIB(show_signatures);
 1051                 SET_ATTRIB(trim_article_body);
 1052                 SET_ATTRIB(verbatim_handling);
 1053 #ifdef HAVE_COLOR
 1054                 SET_ATTRIB(extquote_handling);
 1055 #endif /* HAVE_COLOR */
 1056                 SET_ATTRIB(wrap_on_next_unread);
 1057                 SET_ATTRIB(add_posted_to_filter);
 1058                 SET_ATTRIB(advertising);
 1059                 SET_ATTRIB(alternative_handling);
 1060                 SET_ATTRIB(ask_for_metamail);
 1061                 SET_ATTRIB(auto_cc_bcc);
 1062                 SET_ATTRIB(auto_list_thread);
 1063                 SET_ATTRIB(auto_select);
 1064                 SET_ATTRIB(batch_save);
 1065                 SET_ATTRIB(delete_tmp_files);
 1066                 SET_ATTRIB(group_catchup_on_exit);
 1067                 SET_ATTRIB(mail_8bit_header);
 1068                 SET_ATTRIB(mail_mime_encoding);
 1069                 SET_ATTRIB(mark_ignore_tags);
 1070                 SET_ATTRIB(mark_saved_read);
 1071                 if (curr_scope->state->news_headers_to_display)
 1072                     group->attribute->headers_to_display = curr_scope->attribute->headers_to_display;
 1073                 if (curr_scope->state->news_headers_to_not_display)
 1074                     group->attribute->headers_to_not_display = curr_scope->attribute->headers_to_not_display;
 1075                 SET_ATTRIB(pos_first_unread);
 1076                 SET_ATTRIB(post_8bit_header);
 1077                 SET_ATTRIB(post_mime_encoding);
 1078                 SET_ATTRIB(post_process_view);
 1079                 SET_ATTRIB(post_process_type);
 1080 #ifndef DISABLE_PRINTING
 1081                 SET_ATTRIB(print_header);
 1082 #endif /* !DISABLE_PRINTING */
 1083                 SET_ATTRIB(process_only_unread);
 1084                 SET_ATTRIB(prompt_followupto);
 1085                 SET_ATTRIB(sigdashes);
 1086                 SET_ATTRIB(signature_repost);
 1087                 SET_ATTRIB(x_comment_to);
 1088                 SET_ATTRIB(tex2iso_conv);
 1089                 SET_ATTRIB(mime_forward);
 1090             }
 1091         }
 1092         if (found) {
 1093             /*
 1094              * sort out conflicting settings
 1095              */
 1096 #ifdef CHARSET_CONVERSION
 1097             /*
 1098              * check if we have a 7bit charset but a !7bit encoding
 1099              * or a 8bit charset but a !8bit encoding, update encoding if needed
 1100              */
 1101             is_7bit = FALSE;
 1102             for (j = 0; txt_mime_7bit_charsets[j] != NULL; j++) {
 1103                 if (!strcasecmp(txt_mime_charsets[group->attribute->mm_network_charset], txt_mime_7bit_charsets[j])) {
 1104                     is_7bit = TRUE;
 1105                     break;
 1106                 }
 1107             }
 1108             if (is_7bit) {
 1109                 group->attribute->mail_mime_encoding = group->attribute->post_mime_encoding = MIME_ENCODING_7BIT;
 1110             } else {
 1111                 if (group->attribute->mail_mime_encoding == MIME_ENCODING_7BIT)
 1112                     group->attribute->mail_mime_encoding = MIME_ENCODING_QP;
 1113                 if (group->attribute->post_mime_encoding == MIME_ENCODING_7BIT)
 1114                     group->attribute->post_mime_encoding = MIME_ENCODING_8BIT;
 1115             }
 1116 #endif /* CHARSET_CONVERSION */
 1117             /* do not use 8 bit headers if mime encoding is not 8bit */
 1118             if (group->attribute->mail_mime_encoding != MIME_ENCODING_8BIT)
 1119                 group->attribute->mail_8bit_header = FALSE;
 1120             if (group->attribute->post_mime_encoding != MIME_ENCODING_8BIT)
 1121                 group->attribute->post_8bit_header = FALSE;
 1122         } else {
 1123             if (group->attribute && !group->attribute->global)
 1124                 free(group->attribute);
 1125             group->attribute = default_scope->attribute;
 1126         }
 1127     }
 1128 #ifdef DEBUG
 1129     dump_attributes();
 1130 #   if 0
 1131     debug_print_filter_attributes();
 1132 #   endif /* 0 */
 1133 #endif /* DEBUG */
 1134 
 1135     if (!batch_mode || verbose)
 1136         my_fputc('\n', stdout);
 1137 
 1138     if (!cmd_line && !batch_mode)
 1139         clear_message();
 1140 }
 1141 
 1142 
 1143 /*
 1144  * (re)build scope->headers_to_[not_]display array
 1145  */
 1146 void
 1147 build_news_headers_array(
 1148     struct t_attribute *scope,
 1149     t_bool header_to_display)
 1150 {
 1151     if (header_to_display) {
 1152         if (scope->headers_to_display == NULL)
 1153             scope->headers_to_display = my_malloc(sizeof(struct t_newsheader));
 1154         else {
 1155             if (scope->headers_to_display->header)
 1156                 FreeIfNeeded(*scope->headers_to_display->header);
 1157             FreeIfNeeded(scope->headers_to_display->header);
 1158         }
 1159         scope->headers_to_display->header = ulBuildArgv(scope->news_headers_to_display, &scope->headers_to_display->num);
 1160     } else {
 1161         if (scope->headers_to_not_display == NULL)
 1162             scope->headers_to_not_display = my_malloc(sizeof(struct t_newsheader));
 1163         else {
 1164             if (scope->headers_to_not_display->header)
 1165                 FreeIfNeeded(*scope->headers_to_not_display->header);
 1166             FreeIfNeeded(scope->headers_to_not_display->header);
 1167         }
 1168         scope->headers_to_not_display->header = ulBuildArgv(scope->news_headers_to_not_display, &scope->headers_to_not_display->num);
 1169     }
 1170 }
 1171 
 1172 
 1173 /*
 1174  * Save the scope attributes from scopes[] to ~/.tin/attributes
 1175  */
 1176 void
 1177 write_attributes_file(
 1178     const char *file)
 1179 {
 1180     FILE *fp;
 1181     char *new_file;
 1182     int i;
 1183     long fpos;
 1184 
 1185     if ((batch_mode || no_write || num_scope < 1) && file_size(file) != -1L)
 1186         return;
 1187 
 1188     new_file = get_tmpfilename(file);
 1189 
 1190     if ((fp = fopen(new_file, "w+")) == NULL) {
 1191         error_message(2, _(txt_filesystem_full_backup), ATTRIBUTES_FILE);
 1192         free(new_file);
 1193         return;
 1194     }
 1195 
 1196     wait_message(0, _(txt_writing_attributes_file));
 1197 
 1198 #ifdef DEBUG
 1199     dump_scopes("SCOPES-W");
 1200 #endif /* DEBUG */
 1201 
 1202     /*
 1203      * TODO: sort in a useful order
 1204      *       move strings to lang.c
 1205      */
 1206     fprintf(fp, "# Group attributes file V%s for the TIN newsreader\n", ATTRIBUTES_VERSION);
 1207     fprintf(fp, _("# Do not edit this comment block\n#\n"));
 1208     fprintf(fp, _("#  scope=STRING (eg. alt.*,!alt.bin*) [mandatory]\n"));
 1209     fprintf(fp, _("#  add_posted_to_filter=ON/OFF\n"));
 1210     fprintf(fp, _("#  advertising=ON/OFF\n"));
 1211     fprintf(fp, _("#  alternative_handling=ON/OFF\n"));
 1212     fprintf(fp, _("#  ask_for_metamail=ON/OFF\n"));
 1213     fprintf(fp, _("#  auto_cc_bcc=NUM\n"));
 1214     fprintf(fp, _("#    0=No, 1=Cc, 2=Bcc, 3=Cc and Bcc\n"));
 1215     fprintf(fp, _("#  auto_list_thread=ON/OFF\n"));
 1216     fprintf(fp, _("#  auto_select=ON/OFF\n"));
 1217     fprintf(fp, _("#  batch_save=ON/OFF\n"));
 1218     fprintf(fp, _("#  date_format=STRING (eg. %%a, %%d %%b %%Y %%H:%%M:%%S)\n"));
 1219     fprintf(fp, _("#  delete_tmp_files=ON/OFF\n"));
 1220     fprintf(fp, _("#  editor_format=STRING (eg. %%E +%%N %%F)\n"));
 1221     fprintf(fp, _("#  fcc=STRING (eg. =mailbox)\n"));
 1222     fprintf(fp, _("#  followup_to=STRING\n"));
 1223     fprintf(fp, _("#  from=STRING (just append wanted From:-line, don't use quotes)\n"));
 1224     fprintf(fp, _("#  group_catchup_on_exit=ON/OFF\n"));
 1225     fprintf(fp, _("#  group_format=STRING (eg. %%n %%m %%R %%L  %%s  %%F)\n"));
 1226     fprintf(fp, _("#  mail_8bit_header=ON/OFF\n"));
 1227     fprintf(fp, _("#  mail_mime_encoding=supported_encoding"));
 1228     for (i = 0; txt_mime_encodings[i] != NULL; i++) {
 1229         if (!(i % 5))
 1230             fprintf(fp, "\n#    ");
 1231         fprintf(fp, "%s, ", txt_mime_encodings[i]);
 1232     }
 1233     fprintf(fp, "\n");
 1234 #ifdef HAVE_ISPELL
 1235     fprintf(fp, _("#  ispell=STRING\n"));
 1236 #endif /* HAVE_ISPELL */
 1237     fprintf(fp, _("#  maildir=STRING (eg. ~/Mail)\n"));
 1238     fprintf(fp, _("#  mailing_list=STRING (eg. majordomo@example.org)\n"));
 1239     fprintf(fp, _("#  mime_types_to_save=STRING (eg. image/*,!image/bmp)\n"));
 1240     fprintf(fp, _("#  mark_ignore_tags=ON/OFF\n"));
 1241     fprintf(fp, _("#  mark_saved_read=ON/OFF\n"));
 1242     fprintf(fp, _("#  mime_forward=ON/OFF\n"));
 1243 #ifdef CHARSET_CONVERSION
 1244     fprintf(fp, _("#  mm_network_charset=supported_charset"));
 1245     for (i = 0; txt_mime_charsets[i] != NULL; i++) {
 1246         if (!(i % 5)) /* start new line */
 1247             fprintf(fp, "\n#    ");
 1248         fprintf(fp, "%s, ", txt_mime_charsets[i]);
 1249     }
 1250     fprintf(fp, "\n");
 1251     fprintf(fp, _("#  undeclared_charset=STRING (default is US-ASCII)\n"));
 1252 #endif /* CHARSET_CONVERSION */
 1253     fprintf(fp, _("#  news_headers_to_display=STRING\n"));
 1254     fprintf(fp, _("#  news_headers_to_not_display=STRING\n"));
 1255     fprintf(fp, _("#  news_quote_format=STRING\n"));
 1256     fprintf(fp, _("#  organization=STRING (if beginning with '/' read from file)\n"));
 1257     fprintf(fp, _("#  pos_first_unread=ON/OFF\n"));
 1258     fprintf(fp, _("#  post_8bit_header=ON/OFF\n"));
 1259     fprintf(fp, _("#  post_mime_encoding=supported_encoding"));
 1260     for (i = 0; txt_mime_encodings[i] != NULL; i++) {
 1261         if (!(i % 5))
 1262             fprintf(fp, "\n#    ");
 1263         fprintf(fp, "%s, ", txt_mime_encodings[i]);
 1264     }
 1265     fprintf(fp, "\n");
 1266     fprintf(fp, _("#  post_process_type=NUM\n"));
 1267     fprintf(fp, "#    %d=%s, %d=%s, %d=%s\n",
 1268         POST_PROC_NO, _(txt_post_process_types[POST_PROC_NO]),
 1269         POST_PROC_SHAR, _(txt_post_process_types[POST_PROC_SHAR]),
 1270         POST_PROC_YES, _(txt_post_process_types[POST_PROC_YES]));
 1271     fprintf(fp, _("#  post_process_view=ON/OFF\n"));
 1272     fprintf(fp, _("#  quick_kill_scope=STRING (ie. talk.*)\n"));
 1273     fprintf(fp, _("#  quick_kill_expire=ON/OFF\n"));
 1274     fprintf(fp, _("#  quick_kill_case=ON/OFF\n"));
 1275     fprintf(fp, _("#  quick_kill_header=NUM\n"));
 1276     fprintf(fp, _("#    0=Subject: (case sensitive)  1=Subject: (ignore case)\n"));
 1277     fprintf(fp, _("#    2=From: (case sensitive)     3=From: (ignore case)\n"));
 1278     fprintf(fp, _("#    4=Message-ID: & full References: line\n"));
 1279     fprintf(fp, _("#    5=Message-ID: & last References: entry only\n"));
 1280     fprintf(fp, _("#    6=Message-ID: entry only     7=Lines:\n"));
 1281     fprintf(fp, _("#  quick_select_scope=STRING\n"));
 1282     fprintf(fp, _("#  quick_select_expire=ON/OFF\n"));
 1283     fprintf(fp, _("#  quick_select_case=ON/OFF\n"));
 1284     fprintf(fp, _("#  quick_select_header=NUM\n"));
 1285     fprintf(fp, _("#    0=Subject: (case sensitive)  1=Subject: (ignore case)\n"));
 1286     fprintf(fp, _("#    2=From: (case sensitive)     3=From: (ignore case)\n"));
 1287     fprintf(fp, _("#    4=Message-ID: & full References: line\n"));
 1288     fprintf(fp, _("#    5=Message-ID: & last References: entry only\n"));
 1289     fprintf(fp, _("#    6=Message-ID: entry only     7=Lines:\n"));
 1290     fprintf(fp, _("#  quote_chars=STRING (%%I for initials)\n"));
 1291 #ifndef DISABLE_PRINTING
 1292     fprintf(fp, _("#  print_header=ON/OFF\n"));
 1293 #endif /* !DISABLE_PRINTING */
 1294     fprintf(fp, _("#  process_only_unread=ON/OFF\n"));
 1295     fprintf(fp, _("#  prompt_followupto=ON/OFF\n"));
 1296     fprintf(fp, _("#  savedir=STRING (eg. ~user/News)\n"));
 1297     fprintf(fp, _("#  savefile=STRING (eg. =linux)\n"));
 1298     fprintf(fp, _("#  sigfile=STRING (eg. $var/sig)\n"));
 1299     fprintf(fp, _("#  show_author=NUM\n"));
 1300     fprintf(fp, "#    %d=%s, %d=%s, %d=%s, %d=%s\n",
 1301         SHOW_FROM_NONE, _(txt_show_from[SHOW_FROM_NONE]),
 1302         SHOW_FROM_ADDR, _(txt_show_from[SHOW_FROM_ADDR]),
 1303         SHOW_FROM_NAME, _(txt_show_from[SHOW_FROM_NAME]),
 1304         SHOW_FROM_BOTH, _(txt_show_from[SHOW_FROM_BOTH]));
 1305     fprintf(fp, _("#  show_signatures=ON/OFF\n"));
 1306     fprintf(fp, _("#  show_only_unread_arts=ON/OFF\n"));
 1307     fprintf(fp, _("#  sigdashes=ON/OFF\n"));
 1308     fprintf(fp, _("#  signature_repost=ON/OFF\n"));
 1309     fprintf(fp, _("#  sort_article_type=NUM\n"));
 1310     fprintf(fp, "#    %d=%s,\n",
 1311         SORT_ARTICLES_BY_NOTHING, _(txt_sort_a_type[SORT_ARTICLES_BY_NOTHING]));
 1312     fprintf(fp, "#    %d=%s, %d=%s,\n",
 1313         SORT_ARTICLES_BY_SUBJ_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SUBJ_DESCEND]),
 1314         SORT_ARTICLES_BY_SUBJ_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SUBJ_ASCEND]));
 1315     fprintf(fp, "#    %d=%s, %d=%s,\n",
 1316         SORT_ARTICLES_BY_FROM_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_FROM_DESCEND]),
 1317         SORT_ARTICLES_BY_FROM_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_FROM_ASCEND]));
 1318     fprintf(fp, "#    %d=%s, %d=%s,\n",
 1319         SORT_ARTICLES_BY_DATE_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_DATE_DESCEND]),
 1320         SORT_ARTICLES_BY_DATE_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_DATE_ASCEND]));
 1321     fprintf(fp, "#    %d=%s, %d=%s,\n",
 1322         SORT_ARTICLES_BY_SCORE_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SCORE_DESCEND]),
 1323         SORT_ARTICLES_BY_SCORE_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SCORE_ASCEND]));
 1324     fprintf(fp, "#    %d=%s, %d=%s\n",
 1325         SORT_ARTICLES_BY_LINES_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_LINES_DESCEND]),
 1326         SORT_ARTICLES_BY_LINES_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_LINES_ASCEND]));
 1327     fprintf(fp, _("#  sort_threads_type=NUM\n"));
 1328     fprintf(fp, "#    %d=%s, %d=%s, %d=%s\n",
 1329         SORT_THREADS_BY_NOTHING, _(txt_sort_t_type[SORT_THREADS_BY_NOTHING]),
 1330         SORT_THREADS_BY_SCORE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_DESCEND]),
 1331         SORT_THREADS_BY_SCORE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_ASCEND]));
 1332     fprintf(fp, "#    %d=%s\n",
 1333         SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND]));
 1334     fprintf(fp, "#    %d=%s\n",
 1335         SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND]));
 1336     fprintf(fp, _("#  tex2iso_conv=ON/OFF\n"));
 1337     fprintf(fp, _("#  thread_catchup_on_exit=ON/OFF\n"));
 1338     fprintf(fp, _("#  thread_articles=NUM"));
 1339     for (i = 0; i <= THREAD_MAX; i++) {
 1340         if (!(i % 2))
 1341             fprintf(fp, "\n#    ");
 1342         fprintf(fp, "%d=%s, ", i, _(txt_threading[i]));
 1343     }
 1344     fprintf(fp, "\n");
 1345     fprintf(fp, _("#  thread_format=STRING (eg. %%n %%m [%%L]  %%T  %%F)\n"));
 1346     fprintf(fp, _("#  thread_perc=NUM\n"));
 1347     fprintf(fp, _("#  trim_article_body=NUM\n"));
 1348     fprintf(fp, _("#    0 = Don't trim article body\n"));
 1349     fprintf(fp, _("#    1 = Skip leading blank lines\n"));
 1350     fprintf(fp, _("#    2 = Skip trailing blank lines\n"));
 1351     fprintf(fp, _("#    3 = Skip leading and trailing blank lines\n"));
 1352     fprintf(fp, _("#    4 = Compact multiple blank lines between text blocks\n"));
 1353     fprintf(fp, _("#    5 = Compact multiple blank lines between text blocks and skip\n#        leading blank lines\n"));
 1354     fprintf(fp, _("#    6 = Compact multiple blank lines between text blocks and skip\n#        trailing blank lines\n"));
 1355     fprintf(fp, _("#    7 = Compact multiple blank lines between text blocks and skip\n#        leading and trailing blank lines\n"));
 1356     fprintf(fp, _("#  verbatim_handling=ON/OFF\n"));
 1357 #ifdef HAVE_COLOR
 1358     fprintf(fp, _("#  extquote_handling=ON/OFF\n"));
 1359 #endif /* HAVE_COLOR */
 1360     fprintf(fp, _("#  wrap_on_next_unread=ON/OFF\n"));
 1361     fprintf(fp, _("#  x_body=STRING (eg. ~/.tin/extra-body-text)\n"));
 1362     fprintf(fp, _("#  x_comment_to=ON/OFF\n"));
 1363     fprintf(fp, _("#  x_headers=STRING (eg. ~/.tin/extra-headers)\n"));
 1364     fprintf(fp, _("#\n# Note that it is best to put general (global scoping)\n"));
 1365     fprintf(fp, _("# entries first followed by group specific entries.\n#\n"));
 1366     fprintf(fp, _("############################################################################\n"));
 1367 
 1368     /*
 1369      * determine the file offset
 1370      * this is necessary because a changed locale setting
 1371      * may lead to an invalid offset
 1372      */
 1373     if ((fpos = ftell(fp)) <= 0) {
 1374         clearerr(fp);
 1375         fclose(fp);
 1376         unlink(new_file);
 1377         free(new_file);
 1378         error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
 1379         return;
 1380     }
 1381     rewind(fp);
 1382     attrib_file_offset = 1;
 1383     while ((i = fgetc(fp)) != EOF) {
 1384         if (i == '\n')
 1385             attrib_file_offset++;
 1386     }
 1387     if (fseek(fp, fpos, SEEK_SET)) {
 1388         clearerr(fp);
 1389         fclose(fp);
 1390         unlink(new_file);
 1391         free(new_file);
 1392         error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
 1393         return;
 1394     }
 1395 
 1396     if ((num_scope > 0) && (scopes != NULL)) {
 1397         struct t_scope *scope;
 1398 
 1399         for (i = 1; i < num_scope; i++) {
 1400             scope = &scopes[i];
 1401             if (!scope->global) {
 1402                 if (skip_scope(scope))
 1403                     continue;
 1404                 fprintf(fp, "\nscope=%s\n", scope->scope);
 1405                 if (scope->state->add_posted_to_filter)
 1406                     fprintf(fp, "add_posted_to_filter=%s\n", print_boolean(scope->attribute->add_posted_to_filter));
 1407                 if (scope->state->advertising)
 1408                     fprintf(fp, "advertising=%s\n", print_boolean(scope->attribute->advertising));
 1409                 if (scope->state->alternative_handling)
 1410                     fprintf(fp, "alternative_handling=%s\n", print_boolean(scope->attribute->alternative_handling));
 1411                 if (scope->state->ask_for_metamail)
 1412                     fprintf(fp, "ask_for_metamail=%s\n", print_boolean(scope->attribute->ask_for_metamail));
 1413                 if (scope->state->auto_cc_bcc)
 1414                     fprintf(fp, "auto_cc_bcc=%u\n", scope->attribute->auto_cc_bcc);
 1415                 if (scope->state->auto_list_thread)
 1416                     fprintf(fp, "auto_list_thread=%s\n", print_boolean(scope->attribute->auto_list_thread));
 1417                 if (scope->state->auto_select)
 1418                     fprintf(fp, "auto_select=%s\n", print_boolean(scope->attribute->auto_select));
 1419                 if (scope->state->batch_save)
 1420                     fprintf(fp, "batch_save=%s\n", print_boolean(scope->attribute->batch_save));
 1421                 if (scope->state->date_format && scope->attribute->date_format)
 1422                     fprintf(fp, "date_format=%s\n", scope->attribute->date_format);
 1423                 if (scope->state->delete_tmp_files)
 1424                     fprintf(fp, "delete_tmp_files=%s\n", print_boolean(scope->attribute->delete_tmp_files));
 1425                 if (scope->state->editor_format && scope->attribute->editor_format)
 1426                     fprintf(fp, "editor_format=%s\n", scope->attribute->editor_format);
 1427 #ifdef HAVE_COLOR
 1428                 if (scope->state->extquote_handling)
 1429                     fprintf(fp, "extquote_handling=%s\n", print_boolean(scope->attribute->extquote_handling));
 1430 #endif /* HAVE_COLOR */
 1431                 if (scope->state->fcc && scope->attribute->fcc)
 1432                     fprintf(fp, "fcc=%s\n", scope->attribute->fcc);
 1433                 if (scope->state->followup_to && scope->attribute->followup_to)
 1434                     fprintf(fp, "followup_to=%s\n", scope->attribute->followup_to);
 1435                 if (scope->state->from && scope->attribute->from)
 1436                     fprintf(fp, "from=%s\n", scope->attribute->from);
 1437                 if (scope->state->group_catchup_on_exit)
 1438                     fprintf(fp, "group_catchup_on_exit=%s\n", print_boolean(scope->attribute->group_catchup_on_exit));
 1439                 if (scope->state->group_format && scope->attribute->group_format)
 1440                     fprintf(fp, "group_format=%s\n", scope->attribute->group_format);
 1441                 if (scope->state->mail_8bit_header)
 1442                     fprintf(fp, "mail_8bit_header=%s\n", print_boolean(scope->attribute->mail_8bit_header));
 1443                 if (scope->state->mail_mime_encoding)
 1444                     fprintf(fp, "mail_mime_encoding=%s\n", txt_mime_encodings[scope->attribute->mail_mime_encoding]);
 1445 #ifdef HAVE_ISPELL
 1446                 if (scope->state->ispell && scope->attribute->ispell)
 1447                     fprintf(fp, "ispell=%s\n", scope->attribute->ispell);
 1448 #endif /* HAVE_ISPELL */
 1449                 if (scope->state->maildir && scope->attribute->maildir)
 1450                     fprintf(fp, "maildir=%s\n", scope->attribute->maildir);
 1451                 if (scope->state->mailing_list && scope->attribute->mailing_list)
 1452                     fprintf(fp, "mailing_list=%s\n", scope->attribute->mailing_list);
 1453                 if (scope->state->mark_ignore_tags)
 1454                     fprintf(fp, "mark_ignore_tags=%s\n", print_boolean(scope->attribute->mark_ignore_tags));
 1455                 if (scope->state->mark_saved_read)
 1456                     fprintf(fp, "mark_saved_read=%s\n", print_boolean(scope->attribute->mark_saved_read));
 1457                 if (scope->state->mime_forward)
 1458                     fprintf(fp, "mime_forward=%s\n", print_boolean(scope->attribute->mime_forward));
 1459                 if (scope->state->mime_types_to_save && scope->attribute->mime_types_to_save)
 1460                     fprintf(fp, "mime_types_to_save=%s\n", scope->attribute->mime_types_to_save);
 1461 #ifdef CHARSET_CONVERSION
 1462                 if (scope->state->mm_network_charset)
 1463                     fprintf(fp, "mm_network_charset=%s\n", txt_mime_charsets[scope->attribute->mm_network_charset]);
 1464                 if (scope->state->undeclared_charset && scope->attribute->undeclared_charset)
 1465                     fprintf(fp, "undeclared_charset=%s\n", scope->attribute->undeclared_charset);
 1466 #endif /* CHARSET_CONVERSION */
 1467                 if (scope->state->news_headers_to_display && scope->attribute->news_headers_to_display)
 1468                     fprintf(fp, "news_headers_to_display=%s\n", scope->attribute->news_headers_to_display);
 1469                 if (scope->state->news_headers_to_not_display && scope->attribute->news_headers_to_not_display)
 1470                     fprintf(fp, "news_headers_to_not_display=%s\n", scope->attribute->news_headers_to_not_display);
 1471                 if (scope->state->news_quote_format && scope->attribute->news_quote_format)
 1472                     fprintf(fp, "news_quote_format=%s\n", scope->attribute->news_quote_format);
 1473                 if (scope->state->organization && scope->attribute->organization)
 1474                     fprintf(fp, "organization=%s\n", scope->attribute->organization);
 1475                 if (scope->state->pos_first_unread)
 1476                     fprintf(fp, "pos_first_unread=%s\n", print_boolean(scope->attribute->pos_first_unread));
 1477                 if (scope->state->post_8bit_header)
 1478                     fprintf(fp, "post_8bit_header=%s\n", print_boolean(scope->attribute->post_8bit_header));
 1479                 if (scope->state->post_mime_encoding)
 1480                     fprintf(fp, "post_mime_encoding=%s\n", txt_mime_encodings[scope->attribute->post_mime_encoding]);
 1481                 if (scope->state->post_process_view)
 1482                     fprintf(fp, "post_process_view=%s\n", print_boolean(scope->attribute->post_process_view));
 1483                 if (scope->state->post_process_type)
 1484                     fprintf(fp, "post_process_type=%u\n", scope->attribute->post_process_type);
 1485 #ifndef DISABLE_PRINTING
 1486                 if (scope->state->print_header)
 1487                     fprintf(fp, "print_header=%s\n", print_boolean(scope->attribute->print_header));
 1488 #endif /* !DISABLE_PRINTING */
 1489                 if (scope->state->process_only_unread)
 1490                     fprintf(fp, "process_only_unread=%s\n", print_boolean(scope->attribute->process_only_unread));
 1491                 if (scope->state->prompt_followupto)
 1492                     fprintf(fp, "prompt_followupto=%s\n", print_boolean(scope->attribute->prompt_followupto));
 1493                 if (scope->state->quick_kill_scope && scope->attribute->quick_kill_scope)
 1494                     fprintf(fp, "quick_kill_scope=%s\n", scope->attribute->quick_kill_scope);
 1495                 if (scope->state->quick_kill_case)
 1496                     fprintf(fp, "quick_kill_case=%s\n", print_boolean(scope->attribute->quick_kill_case));
 1497                 if (scope->state->quick_kill_expire)
 1498                     fprintf(fp, "quick_kill_expire=%s\n", print_boolean(scope->attribute->quick_kill_expire));
 1499                 if (scope->state->quick_kill_header)
 1500                     fprintf(fp, "quick_kill_header=%u\n", scope->attribute->quick_kill_header);
 1501                 if (scope->state->quick_select_scope && scope->attribute->quick_select_scope)
 1502                     fprintf(fp, "quick_select_scope=%s\n", scope->attribute->quick_select_scope);
 1503                 if (scope->state->quick_select_case)
 1504                     fprintf(fp, "quick_select_case=%s\n", print_boolean(scope->attribute->quick_select_case));
 1505                 if (scope->state->quick_select_expire)
 1506                     fprintf(fp, "quick_select_expire=%s\n", print_boolean(scope->attribute->quick_select_expire));
 1507                 if (scope->state->quick_select_header)
 1508                     fprintf(fp, "quick_select_header=%u\n", scope->attribute->quick_select_header);
 1509                 if (scope->state->quote_chars && scope->attribute->quote_chars)
 1510                     fprintf(fp, "quote_chars=%s\n", quote_space_to_dash(scope->attribute->quote_chars));
 1511                 if (scope->state->savedir && scope->attribute->savedir)
 1512                     fprintf(fp, "savedir=%s\n", scope->attribute->savedir);
 1513                 if (scope->state->savefile && scope->attribute->savefile)
 1514                     fprintf(fp, "savefile=%s\n", scope->attribute->savefile);
 1515                 if (scope->state->show_author)
 1516                     fprintf(fp, "show_author=%u\n", scope->attribute->show_author);
 1517                 if (scope->state->show_only_unread_arts)
 1518                     fprintf(fp, "show_only_unread_arts=%s\n", print_boolean(scope->attribute->show_only_unread_arts));
 1519                 if (scope->state->show_signatures)
 1520                     fprintf(fp, "show_signatures=%s\n", print_boolean(scope->attribute->show_signatures));
 1521                 if (scope->state->sigdashes)
 1522                     fprintf(fp, "sigdashes=%s\n", print_boolean(scope->attribute->sigdashes));
 1523                 if (scope->state->sigfile && scope->attribute->sigfile)
 1524                     fprintf(fp, "sigfile=%s\n", scope->attribute->sigfile);
 1525                 if (scope->state->signature_repost)
 1526                     fprintf(fp, "signature_repost=%s\n", print_boolean(scope->attribute->signature_repost));
 1527                 if (scope->state->sort_article_type)
 1528                     fprintf(fp, "sort_article_type=%u\n", scope->attribute->sort_article_type);
 1529                 if (scope->state->sort_threads_type)
 1530                     fprintf(fp, "sort_threads_type=%u\n", scope->attribute->sort_threads_type);
 1531                 if (scope->state->tex2iso_conv)
 1532                     fprintf(fp, "tex2iso_conv=%s\n", print_boolean(scope->attribute->tex2iso_conv));
 1533                 if (scope->state->thread_articles)
 1534                     fprintf(fp, "thread_articles=%u\n", scope->attribute->thread_articles);
 1535                 if (scope->state->thread_catchup_on_exit)
 1536                     fprintf(fp, "thread_catchup_on_exit=%s\n", print_boolean(scope->attribute->thread_catchup_on_exit));
 1537                 if (scope->state->thread_format && scope->attribute->thread_format)
 1538                     fprintf(fp, "thread_format=%s\n", scope->attribute->thread_format);
 1539                 if (scope->state->thread_perc)
 1540                     fprintf(fp, "thread_perc=%u\n", scope->attribute->thread_perc);
 1541                 if (scope->state->trim_article_body)
 1542                     fprintf(fp, "trim_article_body=%u\n", scope->attribute->trim_article_body);
 1543                 if (scope->state->verbatim_handling)
 1544                     fprintf(fp, "verbatim_handling=%s\n", print_boolean(scope->attribute->verbatim_handling));
 1545                 if (scope->state->wrap_on_next_unread)
 1546                     fprintf(fp, "wrap_on_next_unread=%s\n", print_boolean(scope->attribute->wrap_on_next_unread));
 1547                 if (scope->state->x_headers && scope->attribute->x_headers)
 1548                     fprintf(fp, "x_headers=%s\n", scope->attribute->x_headers);
 1549                 if (scope->state->x_body && scope->attribute->x_body)
 1550                     fprintf(fp, "x_body=%s\n", scope->attribute->x_body);
 1551                 if (scope->state->x_comment_to)
 1552                     fprintf(fp, "x_comment_to=%s\n", print_boolean(scope->attribute->x_comment_to));
 1553             }
 1554         }
 1555     }
 1556 
 1557     /* rename_file() preserves mode, so this is safe */
 1558 #ifdef HAVE_FCHMOD
 1559     fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR));
 1560 #else
 1561 #   ifdef HAVE_CHMOD
 1562     chmod(new_file, (mode_t) (S_IRUSR|S_IWUSR));
 1563 #   endif /* HAVE_CHMOD */
 1564 #endif /* HAVE_FCHMOD */
 1565 
 1566     if ((i = ferror(fp)) || fclose(fp)) {
 1567         error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
 1568         unlink(new_file);
 1569         if (i) {
 1570             clearerr(fp);
 1571             fclose(fp);
 1572         }
 1573     } else
 1574         rename_file(new_file, file);
 1575 
 1576     free(new_file);
 1577 }
 1578 
 1579 
 1580 /*
 1581  * Returns true if given scope is empty, i.e. no attribute is set
 1582  */
 1583 static t_bool
 1584 skip_scope(
 1585     struct t_scope *scope)
 1586 {
 1587     return !(scope->state->add_posted_to_filter
 1588         || scope->state->advertising
 1589         || scope->state->alternative_handling
 1590         || scope->state->ask_for_metamail
 1591         || scope->state->auto_cc_bcc
 1592         || scope->state->auto_list_thread
 1593         || scope->state->auto_select
 1594         || scope->state->batch_save
 1595         || (scope->state->date_format && scope->attribute->date_format)
 1596         || scope->state->delete_tmp_files
 1597         || (scope->state->editor_format && scope->attribute->editor_format)
 1598 #ifdef HAVE_COLOR
 1599         || scope->state->extquote_handling
 1600 #endif /* HAVE_COLOR */
 1601         || (scope->state->fcc && scope->attribute->fcc)
 1602         || (scope->state->followup_to && scope->attribute->followup_to)
 1603         || (scope->state->from && scope->attribute->from)
 1604         || scope->state->group_catchup_on_exit
 1605         || (scope->state->group_format && scope->attribute->group_format)
 1606         || scope->state->mail_8bit_header
 1607         || scope->state->mail_mime_encoding
 1608 #ifdef HAVE_ISPELL
 1609         || (scope->state->ispell && scope->attribute->ispell)
 1610 #endif /* HAVE_ISPELL */
 1611         || (scope->state->maildir && scope->attribute->maildir)
 1612         || (scope->state->mailing_list && scope->attribute->mailing_list)
 1613         || scope->state->mark_ignore_tags
 1614         || scope->state->mark_saved_read
 1615         || scope->state->mime_forward
 1616         || (scope->state->mime_types_to_save && scope->attribute->mime_types_to_save)
 1617 #ifdef CHARSET_CONVERSION
 1618         || scope->state->mm_network_charset
 1619         || (scope->state->undeclared_charset && scope->attribute->undeclared_charset)
 1620 #endif /* CHARSET_CONVERSION */
 1621         || (scope->state->news_headers_to_display && scope->attribute->news_headers_to_display)
 1622         || (scope->state->news_headers_to_not_display && scope->attribute->news_headers_to_not_display)
 1623         || (scope->state->news_quote_format && scope->attribute->news_quote_format)
 1624         || (scope->state->organization && scope->attribute->organization)
 1625         || scope->state->pos_first_unread
 1626         || scope->state->post_8bit_header
 1627         || scope->state->post_mime_encoding
 1628         || scope->state->post_process_view
 1629         || scope->state->post_process_type
 1630 #ifndef DISABLE_PRINTING
 1631         || scope->state->print_header
 1632 #endif /* !DISABLE_PRINTING */
 1633         || scope->state->process_only_unread
 1634         || scope->state->prompt_followupto
 1635         || (scope->state->quick_kill_scope && scope->attribute->quick_kill_scope)
 1636         || scope->state->quick_kill_case
 1637         || scope->state->quick_kill_expire
 1638         || scope->state->quick_kill_header
 1639         || (scope->state->quick_select_scope && scope->attribute->quick_select_scope)
 1640         || scope->state->quick_select_case
 1641         || scope->state->quick_select_expire
 1642         || scope->state->quick_select_header
 1643         || (scope->state->quote_chars && scope->attribute->quote_chars)
 1644         || (scope->state->savedir && scope->attribute->savedir)
 1645         || (scope->state->savefile && scope->attribute->savefile)
 1646         || scope->state->show_author
 1647         || scope->state->show_only_unread_arts
 1648         || scope->state->show_signatures
 1649         || scope->state->sigdashes
 1650         || (scope->state->sigfile && scope->attribute->sigfile)
 1651         || scope->state->signature_repost
 1652         || scope->state->sort_article_type
 1653         || scope->state->sort_threads_type
 1654         || scope->state->tex2iso_conv
 1655         || scope->state->thread_articles
 1656         || scope->state->thread_catchup_on_exit
 1657         || (scope->state->thread_format && scope->attribute->thread_format)
 1658         || scope->state->thread_perc
 1659         || scope->state->trim_article_body
 1660         || scope->state->verbatim_handling
 1661         || scope->state->wrap_on_next_unread
 1662         || (scope->state->x_headers && scope->attribute->x_headers)
 1663         || (scope->state->x_body && scope->attribute->x_body)
 1664         || scope->state->x_comment_to);
 1665 }
 1666 
 1667 
 1668 #ifdef DEBUG
 1669 #   if 0
 1670 static void
 1671 debug_print_filter_attributes(
 1672     void)
 1673 {
 1674     if (debug & DEBUG_ATTRIB) {
 1675         int i;
 1676         struct t_group *group;
 1677 
 1678         my_printf("\nBEG ***\n");
 1679 
 1680         for_each_group(i) {
 1681             group = &active[i];
 1682             my_printf("Grp=[%s] KILL   header=[%d] scope=[%s] case=[%s] expire=[%s]\n",
 1683                 group->name, group->attribute->quick_kill_header,
 1684                 BlankIfNull(group->attribute->quick_kill_scope),
 1685                 txt_onoff[group->attribute->quick_kill_case != FALSE ? 1 : 0],
 1686                 txt_onoff[group->attribute->quick_kill_expire != FALSE ? 1 : 0]);
 1687             my_printf("Grp=[%s] SELECT header=[%d] scope=[%s] case=[%s] expire=[%s]\n",
 1688                 group->name, group->attribute->quick_select_header,
 1689                 BlankIfNull(group->attribute->quick_select_scope),
 1690                 txt_onoff[group->attribute->quick_select_case != FALSE ? 1 : 0],
 1691                 txt_onoff[group->attribute->quick_select_expire != FALSE ? 1 : 0]);
 1692         }
 1693         my_printf("END ***\n");
 1694     }
 1695 }
 1696 #   endif /* 0 */
 1697 
 1698 
 1699 static void
 1700 dump_attributes(
 1701     void)
 1702 {
 1703     if (debug & DEBUG_ATTRIB) {
 1704         int i, j;
 1705         struct t_group *group;
 1706 
 1707         for_each_group(i) {
 1708             group = &active[i];
 1709             if (!group->attribute)
 1710                 continue;
 1711             debug_print_file("ATTRIBUTES", "group=%s", BlankIfNull(group->name));
 1712             debug_print_file("ATTRIBUTES", "\tGlobal=%d", group->attribute->global);
 1713             debug_print_file("ATTRIBUTES", "\tmaildir=%s", BlankIfNull(group->attribute->maildir));
 1714             debug_print_file("ATTRIBUTES", "\tsavedir=%s", BlankIfNull(group->attribute->savedir));
 1715             debug_print_file("ATTRIBUTES", "\tsavefile=%s", BlankIfNull(group->attribute->savefile));
 1716             debug_print_file("ATTRIBUTES", "\tsigfile=%s", BlankIfNull(group->attribute->sigfile));
 1717             debug_print_file("ATTRIBUTES", "\torganization=%s", BlankIfNull(group->attribute->organization));
 1718             debug_print_file("ATTRIBUTES", "\tfollowup_to=%s", BlankIfNull(group->attribute->followup_to));
 1719             debug_print_file("ATTRIBUTES", "\tmailing_list=%s", BlankIfNull(group->attribute->mailing_list));
 1720             debug_print_file("ATTRIBUTES", "\tx_headers=%s", BlankIfNull(group->attribute->x_headers));
 1721             debug_print_file("ATTRIBUTES", "\tx_body=%s", BlankIfNull(group->attribute->x_body));
 1722             debug_print_file("ATTRIBUTES", "\tfrom=%s", BlankIfNull(group->attribute->from));
 1723             debug_print_file("ATTRIBUTES", "\tnews_quote_format=%s", BlankIfNull(group->attribute->news_quote_format));
 1724             debug_print_file("ATTRIBUTES", "\tquote_chars=%s", quote_space_to_dash(BlankIfNull(group->attribute->quote_chars)));
 1725             debug_print_file("ATTRIBUTES", "\tmime_types_to_save=%s", BlankIfNull(group->attribute->mime_types_to_save));
 1726 #   ifdef HAVE_ISPELL
 1727             debug_print_file("ATTRIBUTES", "\tispell=%s", BlankIfNull(group->attribute->ispell));
 1728 #   endif /* HAVE_ISPELL */
 1729             debug_print_file("ATTRIBUTES", "\tshow_only_unread_arts=%s", print_boolean(group->attribute->show_only_unread_arts));
 1730             debug_print_file("ATTRIBUTES", "\tthread_articles=%d", group->attribute->thread_articles);
 1731             debug_print_file("ATTRIBUTES", "\tthread_perc=%d", group->attribute->thread_perc);
 1732             debug_print_file("ATTRIBUTES", "\tadd_posted_to_filter=%s", print_boolean(group->attribute->add_posted_to_filter));
 1733             debug_print_file("ATTRIBUTES", "\tadvertising=%s", print_boolean(group->attribute->advertising));
 1734             debug_print_file("ATTRIBUTES", "\talternative_handling=%s", print_boolean(group->attribute->alternative_handling));
 1735             debug_print_file("ATTRIBUTES", "\task_for_metamail=%s", print_boolean(group->attribute->ask_for_metamail));
 1736             debug_print_file("ATTRIBUTES", "\tauto_cc_bcc=%d", group->attribute->auto_cc_bcc);
 1737             debug_print_file("ATTRIBUTES", "\tauto_list_thread=%s", print_boolean(group->attribute->auto_list_thread));
 1738             debug_print_file("ATTRIBUTES", "\tauto_select=%s", print_boolean(group->attribute->auto_select));
 1739             debug_print_file("ATTRIBUTES", "\tbatch_save=%s", print_boolean(group->attribute->batch_save));
 1740             debug_print_file("ATTRIBUTES", "\tdate_format=%s", BlankIfNull(group->attribute->date_format));
 1741             debug_print_file("ATTRIBUTES", "\tdelete_tmp_files=%s", print_boolean(group->attribute->delete_tmp_files));
 1742             debug_print_file("ATTRIBUTES", "\teditor_format=%s", BlankIfNull(group->attribute->editor_format));
 1743 #   ifdef HAVE_COLOR
 1744             debug_print_file("ATTRIBUTES", "\textquote_handling=%s", print_boolean(group->attribute->extquote_handling));
 1745 #   endif /* HAVE_COLOR */
 1746             debug_print_file("ATTRIBUTES", "\tgroup_catchup_on_exit=%s", print_boolean(group->attribute->group_catchup_on_exit));
 1747             debug_print_file("ATTRIBUTES", "\tgroup_format=%s", BlankIfNull(group->attribute->group_format));
 1748             debug_print_file("ATTRIBUTES", "\tmail_8bit_header=%s", print_boolean(group->attribute->mail_8bit_header));
 1749             debug_print_file("ATTRIBUTES", "\tmail_mime_encoding=%s", txt_mime_encodings[group->attribute->mail_mime_encoding]);
 1750             debug_print_file("ATTRIBUTES", "\tmark_ignore_tags=%s", print_boolean(group->attribute->mark_ignore_tags));
 1751             debug_print_file("ATTRIBUTES", "\tmark_saved_read=%s", print_boolean(group->attribute->mark_saved_read));
 1752             debug_print_file("ATTRIBUTES", "\tnews_headers_to_display=%s", BlankIfNull(group->attribute->news_headers_to_display));
 1753             if (group->attribute->headers_to_display) {
 1754                 debug_print_file("ATTRIBUTES", "\theaders_to_display->num=%d", group->attribute->headers_to_display->num);
 1755                 for (j = 0; j < group->attribute->headers_to_display->num; j++)
 1756                     debug_print_file("ATTRIBUTES", "\theaders_to_display->header[%d]=%s", j, group->attribute->headers_to_display->header[j]);
 1757             }
 1758             debug_print_file("ATTRIBUTES", "\tnews_headers_to_not_display=%s", BlankIfNull(group->attribute->news_headers_to_not_display));
 1759             if (group->attribute->headers_to_not_display) {
 1760                 debug_print_file("ATTRIBUTES", "\theaders_to_not_display->num=%d", group->attribute->headers_to_not_display->num);
 1761                 for (j = 0; j < group->attribute->headers_to_not_display->num; j++)
 1762                     debug_print_file("ATTRIBUTES", "\theaders_to_not_display->header[%d]=%s", j, group->attribute->headers_to_not_display->header[j]);
 1763             }
 1764             debug_print_file("ATTRIBUTES", "\tpos_first_unread=%s", print_boolean(group->attribute->pos_first_unread));
 1765             debug_print_file("ATTRIBUTES", "\tpost_8bit_header=%s", print_boolean(group->attribute->post_8bit_header));
 1766             debug_print_file("ATTRIBUTES", "\tpost_mime_encoding=%s", txt_mime_encodings[group->attribute->post_mime_encoding]);
 1767             debug_print_file("ATTRIBUTES", "\tpost_process_view=%s", print_boolean(group->attribute->post_process_view));
 1768 #   ifndef DISABLE_PRINTING
 1769             debug_print_file("ATTRIBUTES", "\tprint_header=%s", print_boolean(group->attribute->print_header));
 1770 #   endif /* !DISABLE_PRINTING */
 1771             debug_print_file("ATTRIBUTES", "\tprocess_only_unread=%s", print_boolean(group->attribute->process_only_unread));
 1772             debug_print_file("ATTRIBUTES", "\tprompt_followupto=%s", print_boolean(group->attribute->prompt_followupto));
 1773             debug_print_file("ATTRIBUTES", "\tsort_article_type=%d", group->attribute->sort_article_type);
 1774             debug_print_file("ATTRIBUTES", "\tsort_threads_type=%d", group->attribute->sort_threads_type);
 1775             debug_print_file("ATTRIBUTES", "\tshow_author=%d", group->attribute->show_author);
 1776             debug_print_file("ATTRIBUTES", "\tshow_signatures=%s", print_boolean(group->attribute->show_signatures));
 1777             debug_print_file("ATTRIBUTES", "\tsigdashes=%s", print_boolean(group->attribute->sigdashes));
 1778             debug_print_file("ATTRIBUTES", "\tsignature_repost=%s", print_boolean(group->attribute->signature_repost));
 1779             debug_print_file("ATTRIBUTES", "\tthread_catchup_on_exit=%s", print_boolean(group->attribute->thread_catchup_on_exit));
 1780             debug_print_file("ATTRIBUTES", "\tthread_format=%s", BlankIfNull(group->attribute->thread_format));
 1781             debug_print_file("ATTRIBUTES", "\ttrim_article_body=%d", group->attribute->trim_article_body);
 1782             debug_print_file("ATTRIBUTES", "\tverbatim_handling=%s", print_boolean(group->attribute->verbatim_handling));
 1783             debug_print_file("ATTRIBUTES", "\twrap_on_next_unread=%s", print_boolean(group->attribute->wrap_on_next_unread));
 1784             debug_print_file("ATTRIBUTES", "\tpost_process_type=%d", group->attribute->post_process_type);
 1785             debug_print_file("ATTRIBUTES", "\tquick_kill_scope=%s", BlankIfNull(group->attribute->quick_kill_scope));
 1786             debug_print_file("ATTRIBUTES", "\tquick_kill_case=%s", print_boolean(group->attribute->quick_kill_case));
 1787             debug_print_file("ATTRIBUTES", "\tquick_kill_expire=%s", print_boolean(group->attribute->quick_kill_expire));
 1788             debug_print_file("ATTRIBUTES", "\tquick_kill_header=%d", group->attribute->quick_kill_header);
 1789             debug_print_file("ATTRIBUTES", "\tquick_select_scope=%s", BlankIfNull(group->attribute->quick_select_scope));
 1790             debug_print_file("ATTRIBUTES", "\tquick_select_case=%s", print_boolean(group->attribute->quick_select_case));
 1791             debug_print_file("ATTRIBUTES", "\tquick_select_expire=%s", print_boolean(group->attribute->quick_select_expire));
 1792             debug_print_file("ATTRIBUTES", "\tquick_select_header=%d", group->attribute->quick_select_header);
 1793             debug_print_file("ATTRIBUTES", "\tx_comment_to=%s", print_boolean(group->attribute->x_comment_to));
 1794             debug_print_file("ATTRIBUTES", "\tfcc=%s", BlankIfNull(group->attribute->fcc));
 1795             debug_print_file("ATTRIBUTES", "\ttex2iso_conv=%s", print_boolean(group->attribute->tex2iso_conv));
 1796             debug_print_file("ATTRIBUTES", "\tmime_forward=%s", print_boolean(group->attribute->mime_forward));
 1797 #   ifdef CHARSET_CONVERSION
 1798             debug_print_file("ATTRIBUTES", "\tmm_network_charset=%s", txt_mime_charsets[group->attribute->mm_network_charset]);
 1799             debug_print_file("ATTRIBUTES", "\tundeclared_charset=%s", BlankIfNull(group->attribute->undeclared_charset));
 1800 #   endif /* CHARSET_CONVERSION */
 1801             debug_print_file("ATTRIBUTES", "");
 1802         }
 1803     }
 1804 }
 1805 
 1806 
 1807 #define DEBUG_PRINT_STATE(attrib) (scope->state->attrib ? "+ " : "  ")
 1808 #define DEBUG_PRINT_STRING(attrib) (scope->attribute->attrib ? scope->attribute->attrib : "NULL")
 1809 
 1810 
 1811 static void
 1812 dump_scopes(
 1813     const char *fname)
 1814 {
 1815     if (!scopes)
 1816         return;
 1817 
 1818     if (debug & DEBUG_ATTRIB) {
 1819         int i, j;
 1820         struct t_scope *scope;
 1821 
 1822         for (i = 0; i < num_scope; i++) {
 1823             scope = &scopes[i];
 1824             debug_print_file(fname, "scopes[%d]", i);
 1825             debug_print_file(fname, "scope=%s", scope->scope ? scope->scope : "NULL");
 1826             debug_print_file(fname, "\t  global=%d", scope->global);
 1827             debug_print_file(fname, "\t%smaildir=%s", DEBUG_PRINT_STATE(maildir), DEBUG_PRINT_STRING(maildir));
 1828             debug_print_file(fname, "\t%ssavedir=%s", DEBUG_PRINT_STATE(savedir), DEBUG_PRINT_STRING(savedir));
 1829             debug_print_file(fname, "\t%ssavefile=%s", DEBUG_PRINT_STATE(savefile), DEBUG_PRINT_STRING(savefile));
 1830             debug_print_file(fname, "\t%ssigfile=%s", DEBUG_PRINT_STATE(sigfile), DEBUG_PRINT_STRING(sigfile));
 1831             debug_print_file(fname, "\t%sorganization=%s", DEBUG_PRINT_STATE(organization), DEBUG_PRINT_STRING(organization));
 1832             debug_print_file(fname, "\t%sfollowup_to=%s", DEBUG_PRINT_STATE(followup_to), DEBUG_PRINT_STRING(followup_to));
 1833             debug_print_file(fname, "\t%smailing_list=%s", DEBUG_PRINT_STATE(mailing_list), DEBUG_PRINT_STRING(mailing_list));
 1834             debug_print_file(fname, "\t%sx_headers=%s", DEBUG_PRINT_STATE(x_headers), DEBUG_PRINT_STRING(x_headers));
 1835             debug_print_file(fname, "\t%sx_body=%s", DEBUG_PRINT_STATE(x_body), DEBUG_PRINT_STRING(x_body));
 1836             debug_print_file(fname, "\t%sfrom=%s", DEBUG_PRINT_STATE(from), DEBUG_PRINT_STRING(from));
 1837             debug_print_file(fname, "\t%snews_quote_format=%s", DEBUG_PRINT_STATE(news_quote_format), DEBUG_PRINT_STRING(news_quote_format));
 1838             debug_print_file(fname, "\t%squote_chars=%s", DEBUG_PRINT_STATE(quote_chars), quote_space_to_dash(DEBUG_PRINT_STRING(quote_chars)));
 1839             debug_print_file(fname, "\t%smime_types_to_save=%s", DEBUG_PRINT_STATE(mime_types_to_save), DEBUG_PRINT_STRING(mime_types_to_save));
 1840 #   ifdef HAVE_ISPELL
 1841             debug_print_file(fname, "\t%sispell=%s", DEBUG_PRINT_STATE(ispell), DEBUG_PRINT_STRING(ispell));
 1842 #   endif /* HAVE_ISPELL */
 1843             debug_print_file(fname, "\t%sshow_only_unread_arts=%s", DEBUG_PRINT_STATE(show_only_unread_arts), print_boolean(scope->attribute->show_only_unread_arts));
 1844             debug_print_file(fname, "\t%sthread_articles=%d", DEBUG_PRINT_STATE(thread_articles), scope->attribute->thread_articles);
 1845             debug_print_file(fname, "\t%sthread_perc=%d", DEBUG_PRINT_STATE(thread_perc), scope->attribute->thread_perc);
 1846             debug_print_file(fname, "\t%sadd_posted_to_filter=%s", DEBUG_PRINT_STATE(add_posted_to_filter), print_boolean(scope->attribute->add_posted_to_filter));
 1847             debug_print_file(fname, "\t%sadvertising=%s", DEBUG_PRINT_STATE(advertising), print_boolean(scope->attribute->advertising));
 1848             debug_print_file(fname, "\t%salternative_handling=%s", DEBUG_PRINT_STATE(alternative_handling), print_boolean(scope->attribute->alternative_handling));
 1849             debug_print_file(fname, "\t%sask_for_metamail=%s", DEBUG_PRINT_STATE(ask_for_metamail), print_boolean(scope->attribute->ask_for_metamail));
 1850             debug_print_file(fname, "\t%sauto_cc_bcc=%d", DEBUG_PRINT_STATE(auto_cc_bcc), scope->attribute->auto_cc_bcc);
 1851             debug_print_file(fname, "\t%sauto_list_thread=%s", DEBUG_PRINT_STATE(auto_list_thread), print_boolean(scope->attribute->auto_list_thread));
 1852             debug_print_file(fname, "\t%sauto_select=%s", DEBUG_PRINT_STATE(auto_select), print_boolean(scope->attribute->auto_select));
 1853             debug_print_file(fname, "\t%sbatch_save=%s", DEBUG_PRINT_STATE(batch_save), print_boolean(scope->attribute->batch_save));
 1854             debug_print_file(fname, "\t%sdate_format=%s", DEBUG_PRINT_STATE(date_format), DEBUG_PRINT_STRING(date_format));
 1855             debug_print_file(fname, "\t%sdelete_tmp_files=%s", DEBUG_PRINT_STATE(delete_tmp_files), print_boolean(scope->attribute->delete_tmp_files));
 1856             debug_print_file(fname, "\t%seditor_format=%s", DEBUG_PRINT_STATE(editor_format), DEBUG_PRINT_STRING(editor_format));
 1857 #   ifdef HAVE_COLOR
 1858             debug_print_file(fname, "\t%sextquote_handling=%s", DEBUG_PRINT_STATE(extquote_handling), print_boolean(scope->attribute->extquote_handling));
 1859 #   endif /* HAVE_COLOR */
 1860             debug_print_file(fname, "\t%sgroup_catchup_on_exit=%s", DEBUG_PRINT_STATE(group_catchup_on_exit), print_boolean(scope->attribute->group_catchup_on_exit));
 1861             debug_print_file(fname, "\t%sgroup_format=%s", DEBUG_PRINT_STATE(group_format), DEBUG_PRINT_STRING(group_format));
 1862             debug_print_file(fname, "\t%smail_8bit_header=%s", DEBUG_PRINT_STATE(mail_8bit_header), print_boolean(scope->attribute->mail_8bit_header));
 1863             debug_print_file(fname, "\t%smail_mime_encoding=%s", DEBUG_PRINT_STATE(mail_mime_encoding), txt_mime_encodings[scope->attribute->mail_mime_encoding]);
 1864             debug_print_file(fname, "\t%smark_ignore_tags=%s", DEBUG_PRINT_STATE(mark_ignore_tags), print_boolean(scope->attribute->mark_ignore_tags));
 1865             debug_print_file(fname, "\t%smark_saved_read=%s", DEBUG_PRINT_STATE(mark_saved_read), print_boolean(scope->attribute->mark_saved_read));
 1866             debug_print_file(fname, "\t%snews_headers_to_display=%s", DEBUG_PRINT_STATE(news_headers_to_display), DEBUG_PRINT_STRING(news_headers_to_display));
 1867             if (scope->attribute->headers_to_display) {
 1868                 debug_print_file(fname, "\t    headers_to_display->num=%d", scope->attribute->headers_to_display->num);
 1869                 for (j = 0; j < scope->attribute->headers_to_display->num; j++)
 1870                     debug_print_file(fname, "\t    headers_to_display->header[%d]=%s", j, scope->attribute->headers_to_display->header[j]);
 1871             }
 1872             debug_print_file(fname, "\t%snews_headers_to_not_display=%s", DEBUG_PRINT_STATE(news_headers_to_not_display), DEBUG_PRINT_STRING(news_headers_to_not_display));
 1873             if (scope->attribute->headers_to_not_display) {
 1874                 debug_print_file(fname, "\t    headers_to_not_display->num=%d", scope->attribute->headers_to_not_display->num);
 1875                 for (j = 0; j < scope->attribute->headers_to_not_display->num; j++)
 1876                     debug_print_file(fname, "\t    headers_to_not_display->header[%d]=%s", j, scope->attribute->headers_to_not_display->header[j]);
 1877             }
 1878             debug_print_file(fname, "\t%spos_first_unread=%s", DEBUG_PRINT_STATE(pos_first_unread), print_boolean(scope->attribute->pos_first_unread));
 1879             debug_print_file(fname, "\t%spost_8bit_header=%s", DEBUG_PRINT_STATE(post_8bit_header), print_boolean(scope->attribute->post_8bit_header));
 1880             debug_print_file(fname, "\t%spost_mime_encoding=%s", DEBUG_PRINT_STATE(post_mime_encoding), txt_mime_encodings[scope->attribute->post_mime_encoding]);
 1881             debug_print_file(fname, "\t%spost_process_view=%s", DEBUG_PRINT_STATE(post_process_view), print_boolean(scope->attribute->post_process_view));
 1882 #   ifndef DISABLE_PRINTING
 1883             debug_print_file(fname, "\t%sprint_header=%s", DEBUG_PRINT_STATE(print_header), print_boolean(scope->attribute->print_header));
 1884 #   endif /* !DISABLE_PRINTING */
 1885             debug_print_file(fname, "\t%sprocess_only_unread=%s", DEBUG_PRINT_STATE(process_only_unread), print_boolean(scope->attribute->process_only_unread));
 1886             debug_print_file(fname, "\t%sprompt_followupto=%s", DEBUG_PRINT_STATE(prompt_followupto), print_boolean(scope->attribute->prompt_followupto));
 1887             debug_print_file(fname, "\t%ssort_article_type=%d", DEBUG_PRINT_STATE(sort_article_type), scope->attribute->sort_article_type);
 1888             debug_print_file(fname, "\t%ssort_threads_type=%d", DEBUG_PRINT_STATE(sort_threads_type), scope->attribute->sort_threads_type);
 1889             debug_print_file(fname, "\t%sshow_author=%d", DEBUG_PRINT_STATE(show_author), scope->attribute->show_author);
 1890             debug_print_file(fname, "\t%sshow_signatures=%s", DEBUG_PRINT_STATE(show_signatures), print_boolean(scope->attribute->show_signatures));
 1891             debug_print_file(fname, "\t%ssigdashes=%s", DEBUG_PRINT_STATE(sigdashes), print_boolean(scope->attribute->sigdashes));
 1892             debug_print_file(fname, "\t%ssignature_repost=%s", DEBUG_PRINT_STATE(signature_repost), print_boolean(scope->attribute->signature_repost));
 1893             debug_print_file(fname, "\t%sthread_catchup_on_exit=%s", DEBUG_PRINT_STATE(thread_catchup_on_exit), print_boolean(scope->attribute->thread_catchup_on_exit));
 1894             debug_print_file(fname, "\t%sthread_format=%s", DEBUG_PRINT_STATE(thread_format), DEBUG_PRINT_STRING(thread_format));
 1895             debug_print_file(fname, "\t%strim_article_body=%d", DEBUG_PRINT_STATE(trim_article_body), scope->attribute->trim_article_body);
 1896             debug_print_file(fname, "\t%sverbatim_handling=%s", DEBUG_PRINT_STATE(verbatim_handling), print_boolean(scope->attribute->verbatim_handling));
 1897             debug_print_file(fname, "\t%swrap_on_next_unread=%s", DEBUG_PRINT_STATE(wrap_on_next_unread), print_boolean(scope->attribute->wrap_on_next_unread));
 1898             debug_print_file(fname, "\t%spost_process_type=%d", DEBUG_PRINT_STATE(post_process_type), scope->attribute->post_process_type);
 1899             debug_print_file(fname, "\t%squick_kill_scope=%s", DEBUG_PRINT_STATE(quick_kill_scope), DEBUG_PRINT_STRING(quick_kill_scope));
 1900             debug_print_file(fname, "\t%squick_kill_case=%s", DEBUG_PRINT_STATE(quick_kill_case), print_boolean(scope->attribute->quick_kill_case));
 1901             debug_print_file(fname, "\t%squick_kill_expire=%s", DEBUG_PRINT_STATE(quick_kill_expire), print_boolean(scope->attribute->quick_kill_expire));
 1902             debug_print_file(fname, "\t%squick_kill_header=%d", DEBUG_PRINT_STATE(quick_kill_header), scope->attribute->quick_kill_header);
 1903             debug_print_file(fname, "\t%squick_select_scope=%s", DEBUG_PRINT_STATE(quick_select_scope), DEBUG_PRINT_STRING(quick_select_scope));
 1904             debug_print_file(fname, "\t%squick_select_case=%s", DEBUG_PRINT_STATE(quick_select_case), print_boolean(scope->attribute->quick_select_case));
 1905             debug_print_file(fname, "\t%squick_select_expire=%s", DEBUG_PRINT_STATE(quick_select_expire), print_boolean(scope->attribute->quick_select_expire));
 1906             debug_print_file(fname, "\t%squick_select_header=%d", DEBUG_PRINT_STATE(quick_select_header), scope->attribute->quick_select_header);
 1907             debug_print_file(fname, "\t%sx_comment_to=%s", DEBUG_PRINT_STATE(x_comment_to), print_boolean(scope->attribute->x_comment_to));
 1908             debug_print_file(fname, "\t%sfcc=%s", DEBUG_PRINT_STATE(fcc), DEBUG_PRINT_STRING(fcc));
 1909             debug_print_file(fname, "\t%stex2iso_conv=%s", DEBUG_PRINT_STATE(tex2iso_conv), print_boolean(scope->attribute->tex2iso_conv));
 1910             debug_print_file(fname, "\t%smime_forward=%s", DEBUG_PRINT_STATE(mime_forward), print_boolean(scope->attribute->mime_forward));
 1911 #   ifdef CHARSET_CONVERSION
 1912             debug_print_file(fname, "\t%smm_network_charset=%s", DEBUG_PRINT_STATE(mm_network_charset), txt_mime_charsets[scope->attribute->mm_network_charset]);
 1913             debug_print_file(fname, "\t%sundeclared_charset=%s", DEBUG_PRINT_STATE(undeclared_charset), DEBUG_PRINT_STRING(undeclared_charset));
 1914 #   endif /* CHARSET_CONVERSION */
 1915             debug_print_file(fname, "");
 1916         }
 1917     }
 1918 }
 1919 #endif /* DEBUG */