"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.1/src/attrib.c" (12 Oct 2016, 77850 Bytes) of package /linux/misc/tin-2.4.1.tar.gz:


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.0_vs_2.4.1.

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