"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.3/src/attrib.c" (23 Nov 2018, 78541 Bytes) of package /linux/misc/tin-2.4.3.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.2_vs_2.4.3.

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