"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.2/src/attrib.c" (8 Dec 2017, 78278 Bytes) of package /linux/misc/tin-2.4.2.tar.xz:


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

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