"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.4/src/config.c" (20 Nov 2019, 68075 Bytes) of package /linux/misc/tin-2.4.4.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 "config.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.3_vs_2.4.4.

    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : config.c
    4  *  Author    : I. Lea
    5  *  Created   : 1991-04-01
    6  *  Updated   : 2019-07-03
    7  *  Notes     : Configuration file routines
    8  *
    9  * Copyright (c) 1991-2020 Iain Lea <iain@bricbrac.de>
   10  * All rights reserved.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  *
   16  * 1. Redistributions of source code must retain the above copyright notice,
   17  *    this list of conditions and the following disclaimer.
   18  *
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  *
   23  * 3. Neither the name of the copyright holder nor the names of its
   24  *    contributors may be used to endorse or promote products derived from
   25  *    this software without specific prior written permission.
   26  *
   27  * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 
   41 #ifndef TIN_H
   42 #   include "tin.h"
   43 #endif /* !TIN_H */
   44 #ifndef VERSION_H
   45 #   include "version.h"
   46 #endif /* !VERSION_H */
   47 #ifndef TCURSES_H
   48 #   include "tcurses.h"
   49 #endif /* !TCURSES_H */
   50 #ifndef TNNTP_H
   51 #   include "tnntp.h"
   52 #endif /* TNNTP_H */
   53 
   54 /*
   55  * local prototypes
   56  */
   57 static t_bool match_item(char *line, const char *pat, char *dst, size_t dstlen);
   58 static t_bool rc_update(FILE *fp);
   59 static t_bool rc_post_update(FILE *fp/* , struct t_version *upgrade */);
   60 static void write_server_config(void);
   61 #ifdef HAVE_COLOR
   62     static t_bool match_color(char *line, const char *pat, int *dst, int max);
   63 #endif /* HAVE_COLOR */
   64 
   65 
   66 #define DASH_TO_SPACE(mark) ((char) (mark == '_' ? ' ' : mark))
   67 #define SPACE_TO_DASH(mark) ((char) (mark == ' ' ? '_' : mark))
   68 
   69 
   70 /*
   71  * read local & global configuration defaults
   72  */
   73 t_bool
   74 read_config_file(
   75     char *file,
   76     t_bool global_file) /* return value is always ignored */
   77 {
   78     FILE *fp;
   79     char buf[LEN], tmp[LEN];
   80     struct t_version *upgrade = NULL;
   81 #ifdef CHARSET_CONVERSION
   82     int i;
   83     t_bool is_7bit;
   84 #endif /* CHARSET_CONVERSION */
   85 
   86     if ((fp = fopen(file, "r")) == NULL)
   87         return FALSE;
   88 
   89     if (!batch_mode || verbose)
   90         wait_message(0, _(txt_reading_config_file), (global_file) ? _(txt_global) : "");
   91 
   92     while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
   93         if (buf[0] == '\n')
   94             continue;
   95         if (buf[0] == '#') {
   96             if (upgrade == NULL && !global_file && match_string(buf, "# tin configuration file V", NULL, 0)) {
   97                 upgrade = check_upgrade(buf, "# tin configuration file V", TINRC_VERSION);
   98                 if (upgrade->state != RC_IGNORE)
   99                     upgrade_prompt_quit(upgrade, CONFIG_FILE);
  100                 if (upgrade->state == RC_UPGRADE)
  101                     rc_update(fp);
  102             }
  103             continue;
  104         }
  105 
  106         switch (my_tolower((unsigned char) buf[0])) {
  107         case 'a':
  108             if (match_boolean(buf, "abbreviate_groupname=", &tinrc.abbreviate_groupname))
  109                 break;
  110 
  111             if (match_boolean(buf, "add_posted_to_filter=", &tinrc.add_posted_to_filter))
  112                 break;
  113 
  114             if (match_boolean(buf, "advertising=", &tinrc.advertising))
  115                 break;
  116 
  117             if (match_boolean(buf, "alternative_handling=", &tinrc.alternative_handling))
  118                 break;
  119 
  120             if (match_string(buf, "art_marked_deleted=", tmp, sizeof(tmp))) {
  121                 tinrc.art_marked_deleted = !tmp[0] ? ART_MARK_DELETED : DASH_TO_SPACE(tmp[0]);
  122                 break;
  123             }
  124 
  125             if (match_string(buf, "art_marked_inrange=", tmp, sizeof(tmp))) {
  126                 tinrc.art_marked_inrange = !tmp[0] ? MARK_INRANGE : DASH_TO_SPACE(tmp[0]);
  127                 break;
  128             }
  129 
  130             if (match_string(buf, "art_marked_killed=", tmp, sizeof(tmp))) {
  131                 tinrc.art_marked_killed = !tmp[0] ? ART_MARK_KILLED : DASH_TO_SPACE(tmp[0]);
  132                 break;
  133             }
  134 
  135             if (match_string(buf, "art_marked_read=", tmp, sizeof(tmp))) {
  136                 tinrc.art_marked_read = !tmp[0] ? ART_MARK_READ : DASH_TO_SPACE(tmp[0]);
  137                 break;
  138             }
  139 
  140             if (match_string(buf, "art_marked_read_selected=", tmp, sizeof(tmp))) {
  141                 tinrc.art_marked_read_selected = !tmp[0] ? ART_MARK_READ_SELECTED : DASH_TO_SPACE(tmp[0]);
  142                 break;
  143             }
  144 
  145             if (match_string(buf, "art_marked_recent=", tmp, sizeof(tmp))) {
  146                 tinrc.art_marked_recent = !tmp[0] ? ART_MARK_RECENT : DASH_TO_SPACE(tmp[0]);
  147                 break;
  148             }
  149 
  150             if (match_string(buf, "art_marked_return=", tmp, sizeof(tmp))) {
  151                 tinrc.art_marked_return = !tmp[0] ? ART_MARK_RETURN : DASH_TO_SPACE(tmp[0]);
  152                 break;
  153             }
  154 
  155             if (match_string(buf, "art_marked_selected=", tmp, sizeof(tmp))) {
  156                 tinrc.art_marked_selected = !tmp[0] ? ART_MARK_SELECTED : DASH_TO_SPACE(tmp[0]);
  157                 break;
  158             }
  159 
  160             if (match_string(buf, "art_marked_unread=", tmp, sizeof(tmp))) {
  161                 tinrc.art_marked_unread = !tmp[0] ? ART_MARK_UNREAD : DASH_TO_SPACE(tmp[0]);
  162                 break;
  163             }
  164 
  165             if (match_boolean(buf, "ask_for_metamail=", &tinrc.ask_for_metamail))
  166                 break;
  167 
  168             if (match_integer(buf, "auto_cc_bcc=", &tinrc.auto_cc_bcc, AUTO_CC_BCC))
  169                 break;
  170 
  171             if (match_boolean(buf, "auto_list_thread=", &tinrc.auto_list_thread))
  172                 break;
  173 
  174             if (match_boolean(buf, "auto_reconnect=", &tinrc.auto_reconnect))
  175                 break;
  176 
  177             if (match_boolean(buf, "auto_save=", &tinrc.auto_save))
  178                 break;
  179 
  180             break;
  181 
  182         case 'b':
  183             if (match_boolean(buf, "batch_save=", &tinrc.batch_save))
  184                 break;
  185 
  186             if (match_boolean(buf, "beginner_level=", &tinrc.beginner_level))
  187                 break;
  188 
  189             break;
  190 
  191         case 'c':
  192             if (match_boolean(buf, "cache_overview_files=", &tinrc.cache_overview_files))
  193                 break;
  194 
  195 #ifdef USE_CANLOCK
  196             if (match_list(buf, "cancel_lock_algo=", txt_cancel_lock_algos, &tinrc.cancel_lock_algo))
  197                 break;
  198 #endif /* USE_CANLOCK */
  199 
  200             if (match_boolean(buf, "catchup_read_groups=", &tinrc.catchup_read_groups))
  201                 break;
  202 
  203 #ifdef HAVE_COLOR
  204             if (match_color(buf, "col_back=", &tinrc.col_back, MAX_BACKCOLOR))
  205                 break;
  206 
  207             if (match_color(buf, "col_invers_bg=", &tinrc.col_invers_bg, MAX_BACKCOLOR))
  208                 break;
  209 
  210             if (match_color(buf, "col_invers_fg=", &tinrc.col_invers_fg, MAX_COLOR))
  211                 break;
  212 
  213             if (match_color(buf, "col_text=", &tinrc.col_text, MAX_COLOR))
  214                 break;
  215 
  216             if (match_color(buf, "col_minihelp=", &tinrc.col_minihelp, MAX_COLOR))
  217                 break;
  218 
  219             if (match_color(buf, "col_help=", &tinrc.col_help, MAX_COLOR))
  220                 break;
  221 
  222             if (match_color(buf, "col_message=", &tinrc.col_message, MAX_COLOR))
  223                 break;
  224 
  225             if (match_color(buf, "col_quote=", &tinrc.col_quote, MAX_COLOR))
  226                 break;
  227 
  228             if (match_color(buf, "col_quote2=", &tinrc.col_quote2, MAX_COLOR))
  229                 break;
  230 
  231             if (match_color(buf, "col_quote3=", &tinrc.col_quote3, MAX_COLOR))
  232                 break;
  233 
  234             if (match_color(buf, "col_extquote=", &tinrc.col_extquote, MAX_COLOR))
  235                 break;
  236 
  237             if (match_color(buf, "col_head=", &tinrc.col_head, MAX_COLOR))
  238                 break;
  239 
  240             if (match_color(buf, "col_newsheaders=", &tinrc.col_newsheaders, MAX_COLOR))
  241                 break;
  242 
  243             if (match_color(buf, "col_subject=", &tinrc.col_subject, MAX_COLOR))
  244                 break;
  245 
  246             if (match_color(buf, "col_response=", &tinrc.col_response, MAX_COLOR))
  247                 break;
  248 
  249             if (match_color(buf, "col_from=", &tinrc.col_from, MAX_COLOR))
  250                 break;
  251 
  252             if (match_color(buf, "col_normal=", &tinrc.col_normal, MAX_COLOR))
  253                 break;
  254 
  255             if (match_color(buf, "col_title=", &tinrc.col_title, MAX_COLOR))
  256                 break;
  257 
  258             if (match_color(buf, "col_signature=", &tinrc.col_signature, MAX_COLOR))
  259                 break;
  260 
  261             if (match_color(buf, "col_urls=", &tinrc.col_urls, MAX_COLOR))
  262                 break;
  263 
  264             if (match_color(buf, "col_verbatim=", &tinrc.col_verbatim, MAX_COLOR))
  265                 break;
  266 
  267             if (match_color(buf, "col_markstar=", &tinrc.col_markstar, MAX_COLOR))
  268                 break;
  269 
  270             if (match_color(buf, "col_markdash=", &tinrc.col_markdash, MAX_COLOR))
  271                 break;
  272 
  273             if (match_color(buf, "col_markslash=", &tinrc.col_markslash, MAX_COLOR))
  274                 break;
  275 
  276             if (match_color(buf, "col_markstroke=", &tinrc.col_markstroke, MAX_COLOR))
  277                 break;
  278 #endif /* HAVE_COLOR */
  279 
  280             if (upgrade && upgrade->file_version < 10316) {
  281                 if (match_list(buf, "confirm_choice=", txt_confirm_choices, &tinrc.confirm_choice))
  282                     break;
  283             } else {
  284                 if (match_integer(buf, "confirm_choice=", &tinrc.confirm_choice, TINRC_CONFIRM_MAX))
  285                     break;
  286             }
  287 
  288             break;
  289 
  290         case 'd':
  291             if (match_string(buf, "date_format=", tinrc.date_format, sizeof(tinrc.date_format)))
  292                 break;
  293 
  294             if (match_integer(buf, "default_filter_days=", &tinrc.filter_days, 0)) {
  295                 if (tinrc.filter_days <= 0)
  296                     tinrc.filter_days = 1;
  297                 break;
  298             }
  299 
  300             if (match_integer(buf, "default_filter_kill_header=", &tinrc.default_filter_kill_header, FILTER_LINES))
  301                 break;
  302 
  303             if (match_boolean(buf, "default_filter_kill_global=", &tinrc.default_filter_kill_global))
  304                 break;
  305 
  306             if (match_boolean(buf, "default_filter_kill_case=", &tinrc.default_filter_kill_case))
  307                 break;
  308 
  309             if (match_boolean(buf, "default_filter_kill_expire=", &tinrc.default_filter_kill_expire))
  310                 break;
  311 
  312             if (match_integer(buf, "default_filter_select_header=", &tinrc.default_filter_select_header, FILTER_LINES))
  313                 break;
  314 
  315             if (match_boolean(buf, "default_filter_select_global=", &tinrc.default_filter_select_global))
  316                 break;
  317 
  318             if (match_boolean(buf, "default_filter_select_case=", &tinrc.default_filter_select_case))
  319                 break;
  320 
  321             if (match_boolean(buf, "default_filter_select_expire=", &tinrc.default_filter_select_expire))
  322                 break;
  323 
  324             if (match_string(buf, "default_save_mode=", tmp, sizeof(tmp))) {
  325                 tinrc.default_save_mode = tmp[0];
  326                 break;
  327             }
  328 
  329             if (match_string(buf, "default_author_search=", tinrc.default_search_author, sizeof(tinrc.default_search_author)))
  330                 break;
  331 
  332             if (match_string(buf, "default_goto_group=", tinrc.default_goto_group, sizeof(tinrc.default_goto_group)))
  333                 break;
  334 
  335             if (match_string(buf, "default_config_search=", tinrc.default_search_config, sizeof(tinrc.default_search_config)))
  336                 break;
  337 
  338             if (match_string(buf, "default_group_search=", tinrc.default_search_group, sizeof(tinrc.default_search_group)))
  339                 break;
  340 
  341             if (match_string(buf, "default_subject_search=", tinrc.default_search_subject, sizeof(tinrc.default_search_subject)))
  342                 break;
  343 
  344             if (match_string(buf, "default_art_search=", tinrc.default_search_art, sizeof(tinrc.default_search_art)))
  345                 break;
  346 
  347             if (match_string(buf, "default_repost_group=", tinrc.default_repost_group, sizeof(tinrc.default_repost_group)))
  348                 break;
  349 
  350             if (match_string(buf, "default_mail_address=", tinrc.default_mail_address, sizeof(tinrc.default_mail_address)))
  351                 break;
  352 
  353             if (match_integer(buf, "default_move_group=", &tinrc.default_move_group, 0))
  354                 break;
  355 
  356 #ifndef DONT_HAVE_PIPING
  357             if (match_string(buf, "default_pipe_command=", tinrc.default_pipe_command, sizeof(tinrc.default_pipe_command)))
  358                 break;
  359 #endif /* !DONT_HAVE_PIPING */
  360 
  361             if (match_string(buf, "default_post_newsgroups=", tinrc.default_post_newsgroups, sizeof(tinrc.default_post_newsgroups)))
  362                 break;
  363 
  364             if (match_string(buf, "default_post_subject=", tinrc.default_post_subject, sizeof(tinrc.default_post_subject)))
  365                 break;
  366 
  367             if (match_string(buf, "default_pattern=", tinrc.default_pattern, sizeof(tinrc.default_pattern)))
  368                 break;
  369 
  370             if (match_string(buf, "default_range_group=", tinrc.default_range_group, sizeof(tinrc.default_range_group)))
  371                 break;
  372 
  373             if (match_string(buf, "default_range_select=", tinrc.default_range_select, sizeof(tinrc.default_range_select)))
  374                 break;
  375 
  376             if (match_string(buf, "default_range_thread=", tinrc.default_range_thread, sizeof(tinrc.default_range_thread)))
  377                 break;
  378 
  379             if (match_string(buf, "default_save_file=", tinrc.default_save_file, sizeof(tinrc.default_save_file)))
  380                 break;
  381 
  382             if (match_string(buf, "default_select_pattern=", tinrc.default_select_pattern, sizeof(tinrc.default_select_pattern)))
  383                 break;
  384 
  385             if (match_string(buf, "default_shell_command=", tinrc.default_shell_command, sizeof(tinrc.default_shell_command)))
  386                 break;
  387 
  388             if (match_boolean(buf, "draw_arrow=", &tinrc.draw_arrow))
  389                 break;
  390 
  391             break;
  392 
  393         case 'e':
  394             if (match_string(buf, "editor_format=", tinrc.editor_format, sizeof(tinrc.editor_format)))
  395                 break;
  396 
  397 #ifdef HAVE_COLOR
  398             if (match_boolean(buf, "extquote_handling=", &tinrc.extquote_handling))
  399                 break;
  400 
  401             if (match_string(buf, "extquote_regex=", tinrc.extquote_regex, sizeof(tinrc.extquote_regex)))
  402                 break;
  403 #endif /* HAVE_COLOR */
  404 
  405             break;
  406 
  407         case 'f':
  408             if (match_boolean(buf, "force_screen_redraw=", &tinrc.force_screen_redraw))
  409                 break;
  410 
  411             break;
  412 
  413         case 'g':
  414             if (match_integer(buf, "getart_limit=", &tinrc.getart_limit, 0))
  415                 break;
  416 
  417             if (match_integer(buf, "goto_next_unread=", &tinrc.goto_next_unread, NUM_GOTO_NEXT_UNREAD))
  418                 break;
  419 
  420             if (match_string(buf, "group_format=", tinrc.group_format, sizeof(tinrc.group_format)))
  421                 break;
  422 
  423             if (match_boolean(buf, "group_catchup_on_exit=", &tinrc.group_catchup_on_exit))
  424                 break;
  425 
  426             break;
  427 
  428         case 'h':
  429             if (match_integer(buf, "hide_uue=", &tinrc.hide_uue, UUE_ALL))
  430                 break;
  431 
  432             break;
  433 
  434         case 'i':
  435             if (match_boolean(buf, "info_in_last_line=", &tinrc.info_in_last_line))
  436                 break;
  437 
  438             if (match_boolean(buf, "inverse_okay=", &tinrc.inverse_okay))
  439                 break;
  440 
  441             if (match_string(buf, "inews_prog=", tinrc.inews_prog, sizeof(tinrc.inews_prog)))
  442                 break;
  443 
  444             if (match_integer(buf, "interactive_mailer=", &tinrc.interactive_mailer, INTERACTIVE_NONE))
  445                 break;
  446 
  447             break;
  448 
  449         case 'k':
  450             if (match_boolean(buf, "keep_dead_articles=", &tinrc.keep_dead_articles))
  451                 break;
  452 
  453             if (match_integer(buf, "kill_level=", &tinrc.kill_level, KILL_NOTHREAD))
  454                 break;
  455 
  456             break;
  457 
  458         case 'm':
  459             if (match_string(buf, "maildir=", tinrc.maildir, sizeof(tinrc.maildir)))
  460                 break;
  461 
  462             if (match_string(buf, "mailer_format=", tinrc.mailer_format, sizeof(tinrc.mailer_format)))
  463                 break;
  464 
  465             if (match_list(buf, "mail_mime_encoding=", txt_mime_encodings, &tinrc.mail_mime_encoding))
  466                 break;
  467 
  468             if (match_boolean(buf, "mail_8bit_header=", &tinrc.mail_8bit_header))
  469                 break;
  470 
  471 #ifndef CHARSET_CONVERSION
  472             if (match_string(buf, "mm_charset=", tinrc.mm_charset, sizeof(tinrc.mm_charset)))
  473                 break;
  474 #else
  475             if (match_list(buf, "mm_charset=", txt_mime_charsets, &tinrc.mm_network_charset))
  476                 break;
  477             if (match_list(buf, "mm_network_charset=", txt_mime_charsets, &tinrc.mm_network_charset))
  478                 break;
  479 #   ifdef NO_LOCALE
  480             if (match_string(buf, "mm_local_charset=", tinrc.mm_local_charset, sizeof(tinrc.mm_local_charset)))
  481                 break;
  482 #   endif /* NO_LOCALE */
  483 #endif /* !CHARSET_CONVERSION */
  484 
  485             if (match_boolean(buf, "mark_ignore_tags=", &tinrc.mark_ignore_tags))
  486                 break;
  487 
  488             if (match_boolean(buf, "mark_saved_read=", &tinrc.mark_saved_read))
  489                 break;
  490 
  491             if (match_string(buf, "mail_address=", tinrc.mail_address, sizeof(tinrc.mail_address)))
  492                 break;
  493 
  494             if (match_string(buf, "mail_quote_format=", tinrc.mail_quote_format, sizeof(tinrc.mail_quote_format)))
  495                 break;
  496 
  497             if (match_list(buf, "mailbox_format=", txt_mailbox_formats, &tinrc.mailbox_format))
  498                 break;
  499 
  500             if (match_string(buf, "metamail_prog=", tinrc.metamail_prog, sizeof(tinrc.metamail_prog)))
  501                 break;
  502 
  503             if (match_integer(buf, "mono_markdash=", &tinrc.mono_markdash, MAX_ATTR))
  504                 break;
  505 
  506             if (match_integer(buf, "mono_markstar=", &tinrc.mono_markstar, MAX_ATTR))
  507                 break;
  508 
  509             if (match_integer(buf, "mono_markslash=", &tinrc.mono_markslash, MAX_ATTR))
  510                 break;
  511 
  512             if (match_integer(buf, "mono_markstroke=", &tinrc.mono_markstroke, MAX_ATTR))
  513                 break;
  514 
  515             break;
  516 
  517         case 'n':
  518             if (match_string(buf, "newnews=", tmp, sizeof(tmp))) {
  519                 load_newnews_info(tmp);
  520                 break;
  521             }
  522 
  523             /* pick which news headers to display */
  524             if (match_string(buf, "news_headers_to_display=", tinrc.news_headers_to_display, sizeof(tinrc.news_headers_to_display)))
  525                 break;
  526 
  527             /* pick which news headers to NOT display */
  528             if (match_string(buf, "news_headers_to_not_display=", tinrc.news_headers_to_not_display, sizeof(tinrc.news_headers_to_not_display)))
  529                 break;
  530 
  531             if (match_string(buf, "news_quote_format=", tinrc.news_quote_format, sizeof(tinrc.news_quote_format)))
  532                 break;
  533 
  534 #if defined(HAVE_ALARM) && defined(SIGALRM)
  535             /* the number of seconds is limited on some systems (e.g. Free/OpenBSD: 100000000) */
  536             if (match_integer(buf, "nntp_read_timeout_secs=", &tinrc.nntp_read_timeout_secs, 16383))
  537                 break;
  538 #endif /* HAVE_ALARM && SIGALRM */
  539 
  540 #ifdef HAVE_UNICODE_NORMALIZATION
  541             if (match_integer(buf, "normalization_form=", &tinrc.normalization_form, NORMALIZE_MAX))
  542                 break;
  543 #endif /* HAVE_UNICODE_NORMALIZATION */
  544 
  545             break;
  546 
  547         case 'p':
  548             if (match_list(buf, "post_mime_encoding=", txt_mime_encodings, &tinrc.post_mime_encoding))
  549                 break;
  550 
  551             if (match_boolean(buf, "post_8bit_header=", &tinrc.post_8bit_header))
  552                 break;
  553 
  554 #ifndef DISABLE_PRINTING
  555             if (match_string(buf, "printer=", tinrc.printer, sizeof(tinrc.printer)))
  556                 break;
  557 
  558             if (match_boolean(buf, "print_header=", &tinrc.print_header))
  559                 break;
  560 #endif /* !DISABLE_PRINTING */
  561 
  562             if (match_boolean(buf, "pos_first_unread=", &tinrc.pos_first_unread))
  563                 break;
  564 
  565             if (match_integer(buf, "post_process_type=", &tinrc.post_process_type, POST_PROC_YES))
  566                 break;
  567 
  568             if (match_boolean(buf, "post_process_view=", &tinrc.post_process_view))
  569                 break;
  570 
  571             if (match_string(buf, "posted_articles_file=", tinrc.posted_articles_file, sizeof(tinrc.posted_articles_file)))
  572                 break;
  573 
  574             if (match_boolean(buf, "process_only_unread=", &tinrc.process_only_unread))
  575                 break;
  576 
  577             if (match_boolean(buf, "prompt_followupto=", &tinrc.prompt_followupto))
  578                 break;
  579 
  580             break;
  581 
  582         case 'q':
  583             if (match_string(buf, "quote_chars=", tinrc.quote_chars, sizeof(tinrc.quote_chars))) {
  584                 if (upgrade && upgrade->file_version < 10317) { /* %s/%S changed to %I */
  585                     char *q = tinrc.quote_chars;
  586 
  587                     while (*q) {
  588                         if (*q == '%' && (*(q + 1) == 's' || *(q + 1) == 'S'))
  589                             *(++q) = 'I';
  590 
  591                         q++;
  592                     }
  593                 }
  594                 quote_dash_to_space(tinrc.quote_chars);
  595                 break;
  596             }
  597 
  598             if (match_integer(buf, "quote_style=", &tinrc.quote_style, (QUOTE_COMPRESS|QUOTE_SIGS|QUOTE_EMPTY)))
  599                 break;
  600 
  601 #ifdef HAVE_COLOR
  602             if (match_string(buf, "quote_regex=", tinrc.quote_regex, sizeof(tinrc.quote_regex)))
  603                 break;
  604 
  605             if (match_string(buf, "quote_regex2=", tinrc.quote_regex2, sizeof(tinrc.quote_regex2)))
  606                 break;
  607 
  608             if (match_string(buf, "quote_regex3=", tinrc.quote_regex3, sizeof(tinrc.quote_regex3)))
  609                 break;
  610 #endif /* HAVE_COLOR */
  611 
  612             break;
  613 
  614         case 'r':
  615             if (match_integer(buf, "recent_time=", &tinrc.recent_time, 16383)) /* use INT_MAX? */
  616                 break;
  617 
  618 #if defined(HAVE_LIBICUUC) && defined(MULTIBYTE_ABLE) && defined(HAVE_UNICODE_UBIDI_H) && !defined(NO_LOCALE)
  619             if (match_boolean(buf, "render_bidi=", &tinrc.render_bidi))
  620                 break;
  621 #endif /* HAVE_LIBICUUC && MULTIBYTE_ABLE && HAVE_UNICODE_UBIDI_H && !NO_LOCALE */
  622 
  623             if (match_integer(buf, "reread_active_file_secs=", &tinrc.reread_active_file_secs, 16383)) /* use INT_MAX? */
  624                 break;
  625 
  626             break;
  627 
  628         case 's':
  629             if (match_string(buf, "savedir=", tinrc.savedir, sizeof(tinrc.savedir))) {
  630                 if (tinrc.savedir[0] == '.' && strlen(tinrc.savedir) == 1) {
  631                     char buff[PATH_LEN];
  632 
  633                     get_cwd(buff);
  634                     my_strncpy(tinrc.savedir, buff, sizeof(tinrc.savedir) - 1);
  635                 }
  636                 break;
  637             }
  638 
  639             if (match_integer(buf, "score_limit_kill=", &tinrc.score_limit_kill, 0))
  640                 break;
  641 
  642             if (match_integer(buf, "score_limit_select=", &tinrc.score_limit_select, 0))
  643                 break;
  644 
  645             if (match_integer(buf, "score_kill=", &tinrc.score_kill, 0)) {
  646                 check_score_defaults();
  647                 break;
  648             }
  649 
  650             if (match_integer(buf, "score_select=", &tinrc.score_select, 0)) {
  651                 check_score_defaults();
  652                 break;
  653             }
  654 
  655             if (match_string(buf, "select_format=", tinrc.select_format, sizeof(tinrc.select_format)))
  656                 break;
  657 
  658             if (match_integer(buf, "show_author=", &tinrc.show_author, SHOW_FROM_BOTH))
  659                 break;
  660 
  661             if (match_boolean(buf, "show_description=", &tinrc.show_description)) {
  662                 if (show_description)
  663                     show_description = tinrc.show_description;
  664                 break;
  665             }
  666 
  667             if (match_boolean(buf, "show_only_unread_arts=", &tinrc.show_only_unread_arts))
  668                 break;
  669 
  670             if (match_boolean(buf, "show_only_unread_groups=", &tinrc.show_only_unread_groups))
  671                 break;
  672 
  673             if (match_boolean(buf, "sigdashes=", &tinrc.sigdashes))
  674                 break;
  675 
  676             if (match_string(buf, "sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile)))
  677                 break;
  678 
  679             if (match_boolean(buf, "signature_repost=", &tinrc.signature_repost))
  680                 break;
  681 
  682             if (match_string(buf, "spamtrap_warning_addresses=", tinrc.spamtrap_warning_addresses, sizeof(tinrc.spamtrap_warning_addresses)))
  683                 break;
  684 
  685             if (match_boolean(buf, "start_editor_offset=", &tinrc.start_editor_offset))
  686                 break;
  687 
  688             if (match_integer(buf, "sort_article_type=", &tinrc.sort_article_type, SORT_ARTICLES_BY_LINES_ASCEND))
  689                 break;
  690 
  691             if (match_integer(buf, "sort_threads_type=", &tinrc.sort_threads_type, SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND))
  692                 break;
  693 
  694 #ifdef USE_HEAPSORT
  695             if (match_integer(buf, "sort_function=", &tinrc.sort_function, MAX_SORT_FUNCS))
  696                 break;
  697 #endif /* USE_HEAPSORT */
  698 
  699             if (match_integer(buf, "scroll_lines=", &tinrc.scroll_lines, 0))
  700                 break;
  701 
  702             if (match_boolean(buf, "show_signatures=", &tinrc.show_signatures))
  703                 break;
  704 
  705             if (match_string(buf, "slashes_regex=", tinrc.slashes_regex, sizeof(tinrc.slashes_regex)))
  706                 break;
  707 
  708             if (match_string(buf, "stars_regex=", tinrc.stars_regex, sizeof(tinrc.stars_regex)))
  709                 break;
  710 
  711             if (match_string(buf, "strokes_regex=", tinrc.strokes_regex, sizeof(tinrc.strokes_regex)))
  712                 break;
  713 
  714 #ifndef USE_CURSES
  715             if (match_boolean(buf, "strip_blanks=", &tinrc.strip_blanks))
  716                 break;
  717 #endif /* !USE_CURSES */
  718 
  719             if (match_integer(buf, "strip_bogus=", &tinrc.strip_bogus, BOGUS_SHOW))
  720                 break;
  721 
  722             if (match_boolean(buf, "strip_newsrc=", &tinrc.strip_newsrc))
  723                 break;
  724 
  725             /* Regexp used to strip "Re: "s and similar */
  726             if (match_string(buf, "strip_re_regex=", tinrc.strip_re_regex, sizeof(tinrc.strip_re_regex)))
  727                 break;
  728 
  729             if (match_string(buf, "strip_was_regex=", tinrc.strip_was_regex, sizeof(tinrc.strip_was_regex)))
  730                 break;
  731 
  732             break;
  733 
  734         case 't':
  735             if (match_integer(buf, "thread_articles=", &tinrc.thread_articles, THREAD_MAX))
  736                 break;
  737 
  738             if (match_integer(buf, "thread_perc=", &tinrc.thread_perc, 100))
  739                 break;
  740 
  741             if (match_string(buf, "thread_format=", tinrc.thread_format, sizeof(tinrc.thread_format)))
  742                 break;
  743 
  744             if (match_integer(buf, "thread_score=", &tinrc.thread_score, THREAD_SCORE_WEIGHT))
  745                 break;
  746 
  747             if (match_boolean(buf, "tex2iso_conv=", &tinrc.tex2iso_conv))
  748                 break;
  749 
  750             if (match_boolean(buf, "thread_catchup_on_exit=", &tinrc.thread_catchup_on_exit))
  751                 break;
  752 
  753 #if defined(HAVE_ICONV_OPEN_TRANSLIT) && defined(CHARSET_CONVERSION)
  754             if (match_boolean(buf, "translit=", &tinrc.translit))
  755                 break;
  756 #endif /* HAVE_ICONV_OPEN_TRANSLIT && CHARSET_CONVERSION */
  757 
  758             if (match_integer(buf, "trim_article_body=", &tinrc.trim_article_body, NUM_TRIM_ARTICLE_BODY))
  759                 break;
  760 
  761             break;
  762 
  763         case 'u':
  764             if (match_string(buf, "underscores_regex=", tinrc.underscores_regex, sizeof(tinrc.underscores_regex)))
  765                 break;
  766 
  767             if (match_boolean(buf, "unlink_article=", &tinrc.unlink_article))
  768                 break;
  769 
  770             if (match_string(buf, "url_handler=", tinrc.url_handler, sizeof(tinrc.url_handler)))
  771                 break;
  772 
  773             if (match_boolean(buf, "url_highlight=", &tinrc.url_highlight))
  774                 break;
  775 
  776             if (match_boolean(buf, "use_mouse=", &tinrc.use_mouse))
  777                 break;
  778 
  779 #ifdef HAVE_KEYPAD
  780             if (match_boolean(buf, "use_keypad=", &tinrc.use_keypad))
  781                 break;
  782 #endif /* HAVE_KEYPAD */
  783 
  784 #ifdef HAVE_COLOR
  785             if (match_boolean(buf, "use_color=", &tinrc.use_color)) {
  786                 use_color = (cmdline.args & CMDLINE_USE_COLOR) ? bool_not(tinrc.use_color) : tinrc.use_color;
  787                 break;
  788             }
  789 #endif /* HAVE_COLOR */
  790 
  791 #ifdef XFACE_ABLE
  792             if (match_boolean(buf, "use_slrnface=", &tinrc.use_slrnface))
  793                 break;
  794 #endif /* XFACE_ABLE */
  795 
  796 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
  797             if (match_boolean(buf, "utf8_graphics=", &tinrc.utf8_graphics)) {
  798                 /* only enable this when local charset is UTF-8 */
  799                 tinrc.utf8_graphics = tinrc.utf8_graphics ? IS_LOCAL_CHARSET("UTF-8") : FALSE;
  800                 break;
  801             }
  802 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
  803 
  804             break;
  805 
  806         case 'v':
  807             if (match_string(buf, "verbatim_begin_regex=", tinrc.verbatim_begin_regex, sizeof(tinrc.verbatim_begin_regex)))
  808                 break;
  809 
  810             if (match_string(buf, "verbatim_end_regex=", tinrc.verbatim_end_regex, sizeof(tinrc.verbatim_end_regex)))
  811                 break;
  812 
  813             if (match_boolean(buf, "verbatim_handling=", &tinrc.verbatim_handling))
  814                 break;
  815 
  816             break;
  817 
  818         case 'w':
  819             if (match_integer(buf, "wildcard=", &tinrc.wildcard, 2))
  820                 break;
  821 
  822             if (match_boolean(buf, "word_highlight=", &tinrc.word_highlight)) {
  823                 word_highlight = tinrc.word_highlight;
  824                 break;
  825             }
  826 
  827             if (match_integer(buf, "wrap_column=", &tinrc.wrap_column, 0))
  828                 break;
  829 
  830             if (match_boolean(buf, "wrap_on_next_unread=", &tinrc.wrap_on_next_unread))
  831                 break;
  832 
  833             if (match_integer(buf, "word_h_display_marks=", &tinrc.word_h_display_marks, MAX_MARK))
  834                 break;
  835 
  836             break;
  837 
  838         case 'x':
  839             if (match_string(buf, "xpost_quote_format=", tinrc.xpost_quote_format, sizeof(tinrc.xpost_quote_format)))
  840                 break;
  841 
  842             break;
  843 
  844         default:
  845             break;
  846         }
  847     }
  848     if (!global_file && upgrade && upgrade->state == RC_UPGRADE)
  849         rc_post_update(fp/* , upgrade */);
  850 
  851     FreeAndNull(upgrade);
  852     fclose(fp);
  853 
  854     /*
  855      * sort out conflicting settings
  856      */
  857 
  858     /* nobody likes to navigate blind */
  859     if (!(tinrc.draw_arrow || tinrc.inverse_okay))
  860         tinrc.draw_arrow = TRUE;
  861 
  862 #ifdef CHARSET_CONVERSION
  863     /*
  864      * check if we have a 7bit charset but a !7bit encoding
  865      * or a 8bit charset but a !8bit encoding, update encoding if needed
  866      */
  867     is_7bit = FALSE;
  868     for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
  869         if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
  870             is_7bit = TRUE;
  871             break;
  872         }
  873     }
  874     if (is_7bit) {
  875         tinrc.mail_mime_encoding = tinrc.post_mime_encoding = MIME_ENCODING_7BIT;
  876     } else {
  877         if (tinrc.mail_mime_encoding == MIME_ENCODING_7BIT)
  878             tinrc.mail_mime_encoding = MIME_ENCODING_QP;
  879         if (tinrc.post_mime_encoding == MIME_ENCODING_7BIT)
  880             tinrc.post_mime_encoding = MIME_ENCODING_8BIT;
  881     }
  882 #endif /* CHARSET_CONVERSION */
  883 
  884     /* do not use 8 bit headers if mime encoding is not 8bit */
  885     if (tinrc.mail_mime_encoding != MIME_ENCODING_8BIT)
  886         tinrc.mail_8bit_header = FALSE;
  887     if (tinrc.post_mime_encoding != MIME_ENCODING_8BIT)
  888         tinrc.post_8bit_header = FALSE;
  889 
  890     /* set defaults if blank */
  891     if (!*tinrc.editor_format)
  892         STRCPY(tinrc.editor_format, TIN_EDITOR_FMT_ON);
  893     if (!*tinrc.select_format)
  894         STRCPY(tinrc.select_format, DEFAULT_SELECT_FORMAT);
  895     if (!*tinrc.group_format)
  896         STRCPY(tinrc.group_format, DEFAULT_GROUP_FORMAT);
  897     if (!*tinrc.thread_format)
  898         STRCPY(tinrc.thread_format, DEFAULT_THREAD_FORMAT);
  899     if (!*tinrc.date_format)
  900         STRCPY(tinrc.date_format, DEFAULT_DATE_FORMAT);
  901     /* determine local charset */
  902 #if defined(NO_LOCALE) && !defined(CHARSET_CONVERSION)
  903     strcpy(tinrc.mm_local_charset, tinrc.mm_charset);
  904 #endif /* NO_LOCALE && !CHARSET_CONVERSION */
  905     return TRUE;
  906 }
  907 
  908 
  909 /*
  910  * write config defaults to file
  911  */
  912 void
  913 write_config_file(
  914     char *file)
  915 {
  916     FILE *fp;
  917     char *file_tmp;
  918     int i;
  919 
  920     if ((no_write || post_article_and_exit || post_postponed_and_exit) && file_size(file) != -1L)
  921         return;
  922 
  923     /* generate tmp-filename */
  924     file_tmp = get_tmpfilename(file);
  925 
  926     if ((fp = fopen(file_tmp, "w")) == NULL) {
  927         error_message(2, _(txt_filesystem_full_backup), CONFIG_FILE);
  928         free(file_tmp);
  929         return;
  930     }
  931 
  932     wait_message(0, _(txt_saving));
  933 
  934     fprintf(fp, txt_tinrc_header, PRODUCT, TINRC_VERSION, tin_progname, VERSION, RELEASEDATE, RELEASENAME);
  935 
  936     fprintf(fp, "%s", _(txt_savedir.tinrc));
  937     fprintf(fp, "savedir=%s\n\n", tinrc.savedir);
  938 
  939     fprintf(fp, "%s", _(txt_auto_save.tinrc));
  940     fprintf(fp, "auto_save=%s\n\n", print_boolean(tinrc.auto_save));
  941 
  942     fprintf(fp, "%s", _(txt_mark_saved_read.tinrc));
  943     fprintf(fp, "mark_saved_read=%s\n\n", print_boolean(tinrc.mark_saved_read));
  944 
  945     fprintf(fp, "%s", _(txt_post_process_type.tinrc));
  946     fprintf(fp, "post_process_type=%d\n\n", tinrc.post_process_type);
  947 
  948     fprintf(fp, "%s", _(txt_post_process_view.tinrc));
  949     fprintf(fp, "post_process_view=%s\n\n", print_boolean(tinrc.post_process_view));
  950 
  951     fprintf(fp, "%s", _(txt_process_only_unread.tinrc));
  952     fprintf(fp, "process_only_unread=%s\n\n", print_boolean(tinrc.process_only_unread));
  953 
  954     fprintf(fp, "%s", _(txt_prompt_followupto.tinrc));
  955     fprintf(fp, "prompt_followupto=%s\n\n", print_boolean(tinrc.prompt_followupto));
  956 
  957     fprintf(fp, "%s", _(txt_confirm_choice.tinrc));
  958     fprintf(fp, "confirm_choice=%d\n\n", tinrc.confirm_choice);
  959 
  960     fprintf(fp, "%s", _(txt_mark_ignore_tags.tinrc));
  961     fprintf(fp, "mark_ignore_tags=%s\n\n", print_boolean(tinrc.mark_ignore_tags));
  962 
  963     fprintf(fp, "%s", _(txt_auto_reconnect.tinrc));
  964     fprintf(fp, "auto_reconnect=%s\n\n", print_boolean(tinrc.auto_reconnect));
  965 
  966     fprintf(fp, "%s", _(txt_draw_arrow.tinrc));
  967     fprintf(fp, "draw_arrow=%s\n\n", print_boolean(tinrc.draw_arrow));
  968 
  969     fprintf(fp, "%s", _(txt_inverse_okay.tinrc));
  970     fprintf(fp, "inverse_okay=%s\n\n", print_boolean(tinrc.inverse_okay));
  971 
  972     fprintf(fp, "%s", _(txt_pos_first_unread.tinrc));
  973     fprintf(fp, "pos_first_unread=%s\n\n", print_boolean(tinrc.pos_first_unread));
  974 
  975     fprintf(fp, "%s", _(txt_show_only_unread_arts.tinrc));
  976     fprintf(fp, "show_only_unread_arts=%s\n\n", print_boolean(tinrc.show_only_unread_arts));
  977 
  978     fprintf(fp, "%s", _(txt_show_only_unread_groups.tinrc));
  979     fprintf(fp, "show_only_unread_groups=%s\n\n", print_boolean(tinrc.show_only_unread_groups));
  980 
  981     fprintf(fp, "%s", _(txt_kill_level.tinrc));
  982     fprintf(fp, "kill_level=%d\n\n", tinrc.kill_level);
  983 
  984     fprintf(fp, "%s", _(txt_goto_next_unread.tinrc));
  985     fprintf(fp, "goto_next_unread=%d\n\n", tinrc.goto_next_unread);
  986 
  987     fprintf(fp, "%s", _(txt_scroll_lines.tinrc));
  988     fprintf(fp, "scroll_lines=%d\n\n", tinrc.scroll_lines);
  989 
  990     fprintf(fp, "%s", _(txt_catchup_read_groups.tinrc));
  991     fprintf(fp, "catchup_read_groups=%s\n\n", print_boolean(tinrc.catchup_read_groups));
  992 
  993     fprintf(fp, "%s", _(txt_group_catchup_on_exit.tinrc));
  994     fprintf(fp, "group_catchup_on_exit=%s\n", print_boolean(tinrc.group_catchup_on_exit));
  995     fprintf(fp, "thread_catchup_on_exit=%s\n\n", print_boolean(tinrc.thread_catchup_on_exit));
  996 
  997     fprintf(fp, "%s", _(txt_thread_articles.tinrc));
  998     fprintf(fp, "thread_articles=%d\n\n", tinrc.thread_articles);
  999 
 1000     fprintf(fp, "%s", _(txt_thread_perc.tinrc));
 1001     fprintf(fp, "thread_perc=%d\n\n", tinrc.thread_perc);
 1002 
 1003     fprintf(fp, "%s", _(txt_show_description.tinrc));
 1004     fprintf(fp, "show_description=%s\n\n", print_boolean(tinrc.show_description));
 1005 
 1006     fprintf(fp, "%s", _(txt_show_author.tinrc));
 1007     fprintf(fp, "show_author=%d\n\n", tinrc.show_author);
 1008 
 1009     fprintf(fp, "%s", _(txt_news_headers_to_display.tinrc));
 1010     fprintf(fp, "news_headers_to_display=%s\n\n", tinrc.news_headers_to_display);
 1011 
 1012     fprintf(fp, "%s", _(txt_news_headers_to_not_display.tinrc));
 1013     fprintf(fp, "news_headers_to_not_display=%s\n\n", tinrc.news_headers_to_not_display);
 1014 
 1015     fprintf(fp, "%s", _(txt_tinrc_info_in_last_line));
 1016     fprintf(fp, "info_in_last_line=%s\n\n", print_boolean(tinrc.info_in_last_line));
 1017 
 1018     fprintf(fp, "%s", _(txt_sort_article_type.tinrc));
 1019     fprintf(fp, "sort_article_type=%d\n\n", tinrc.sort_article_type);
 1020 
 1021     fprintf(fp, "%s", _(txt_sort_threads_type.tinrc));
 1022     fprintf(fp, "sort_threads_type=%d\n\n", tinrc.sort_threads_type);
 1023 
 1024 #ifdef USE_HEAPSORT
 1025     fprintf(fp, "%s", _(txt_sort_function.tinrc));
 1026     fprintf(fp, "sort_function=%d\n\n", tinrc.sort_function);
 1027 #endif /* USE_HEAPSORT */
 1028 
 1029     fprintf(fp, "%s", _(txt_maildir.tinrc));
 1030     fprintf(fp, "maildir=%s\n\n", tinrc.maildir);
 1031 
 1032     fprintf(fp, "%s", _(txt_mailbox_format.tinrc));
 1033     fprintf(fp, "mailbox_format=%s\n\n", txt_mailbox_formats[tinrc.mailbox_format]);
 1034 
 1035 #ifndef DISABLE_PRINTING
 1036     fprintf(fp, "%s", _(txt_print_header.tinrc));
 1037     fprintf(fp, "print_header=%s\n\n", print_boolean(tinrc.print_header));
 1038 
 1039     fprintf(fp, "%s", _(txt_printer.tinrc));
 1040     fprintf(fp, "printer=%s\n\n", tinrc.printer);
 1041 #endif /* !DISABLE_PRINTING */
 1042 
 1043     fprintf(fp, "%s", _(txt_batch_save.tinrc));
 1044     fprintf(fp, "batch_save=%s\n\n", print_boolean(tinrc.batch_save));
 1045 
 1046     fprintf(fp, "%s", _(txt_start_editor_offset.tinrc));
 1047     fprintf(fp, "start_editor_offset=%s\n\n", print_boolean(tinrc.start_editor_offset));
 1048 
 1049     fprintf(fp, "%s", _(txt_editor_format.tinrc));
 1050     fprintf(fp, "editor_format=%s\n\n", tinrc.editor_format);
 1051 
 1052     fprintf(fp, "%s", _(txt_mailer_format.tinrc));
 1053     fprintf(fp, "mailer_format=%s\n\n", tinrc.mailer_format);
 1054 
 1055     fprintf(fp, "%s", _(txt_interactive_mailer.tinrc));
 1056     fprintf(fp, "interactive_mailer=%d\n\n", tinrc.interactive_mailer);
 1057 
 1058     fprintf(fp, "%s", _(txt_thread_score.tinrc));
 1059     fprintf(fp, "thread_score=%d\n\n", tinrc.thread_score);
 1060 
 1061     fprintf(fp, "%s", _(txt_unlink_article.tinrc));
 1062     fprintf(fp, "unlink_article=%s\n\n", print_boolean(tinrc.unlink_article));
 1063 
 1064     fprintf(fp, "%s", _(txt_keep_dead_articles.tinrc));
 1065     fprintf(fp, "keep_dead_articles=%s\n\n", print_boolean(tinrc.keep_dead_articles));
 1066 
 1067     fprintf(fp, "%s", _(txt_posted_articles_file.tinrc));
 1068     fprintf(fp, "posted_articles_file=%s\n\n", tinrc.posted_articles_file);
 1069 
 1070     fprintf(fp, "%s", _(txt_add_posted_to_filter.tinrc));
 1071     fprintf(fp, "add_posted_to_filter=%s\n\n", print_boolean(tinrc.add_posted_to_filter));
 1072 
 1073     fprintf(fp, "%s", _(txt_sigfile.tinrc));
 1074     fprintf(fp, "sigfile=%s\n\n", tinrc.sigfile);
 1075 
 1076     fprintf(fp, "%s", _(txt_sigdashes.tinrc));
 1077     fprintf(fp, "sigdashes=%s\n\n", print_boolean(tinrc.sigdashes));
 1078 
 1079     fprintf(fp, "%s", _(txt_signature_repost.tinrc));
 1080     fprintf(fp, "signature_repost=%s\n\n", print_boolean(tinrc.signature_repost));
 1081 
 1082     fprintf(fp, "%s", _(txt_spamtrap_warning_addresses.tinrc));
 1083     fprintf(fp, "spamtrap_warning_addresses=%s\n\n", tinrc.spamtrap_warning_addresses);
 1084 
 1085     fprintf(fp, "%s", _(txt_url_handler.tinrc));
 1086     fprintf(fp, "url_handler=%s\n\n", tinrc.url_handler);
 1087 
 1088     fprintf(fp, "%s", _(txt_advertising.tinrc));
 1089     fprintf(fp, "advertising=%s\n\n", print_boolean(tinrc.advertising));
 1090 
 1091     fprintf(fp, "%s", _(txt_reread_active_file_secs.tinrc));
 1092     fprintf(fp, "reread_active_file_secs=%d\n\n", tinrc.reread_active_file_secs);
 1093 
 1094 #if defined(HAVE_ALARM) && defined(SIGALRM)
 1095     fprintf(fp, "%s", _(txt_nntp_read_timeout_secs.tinrc));
 1096     fprintf(fp, "nntp_read_timeout_secs=%d\n\n", tinrc.nntp_read_timeout_secs);
 1097 #endif /* HAVE_ALARM && SIGALRM */
 1098 
 1099     fprintf(fp, "%s", _(txt_quote_chars.tinrc));
 1100     fprintf(fp, "quote_chars=%s\n\n", quote_space_to_dash(tinrc.quote_chars));
 1101 
 1102     fprintf(fp, "%s", _(txt_quote_style.tinrc));
 1103     fprintf(fp, "quote_style=%d\n\n", tinrc.quote_style);
 1104 
 1105 #ifdef HAVE_COLOR
 1106     fprintf(fp, "%s", _(txt_quote_regex.tinrc));
 1107     fprintf(fp, "quote_regex=%s\n\n", tinrc.quote_regex);
 1108     fprintf(fp, "%s", _(txt_quote_regex2.tinrc));
 1109     fprintf(fp, "quote_regex2=%s\n\n", tinrc.quote_regex2);
 1110     fprintf(fp, "%s", _(txt_quote_regex3.tinrc));
 1111     fprintf(fp, "quote_regex3=%s\n\n", tinrc.quote_regex3);
 1112 #endif /* HAVE_COLOR */
 1113 
 1114     fprintf(fp, "%s", _(txt_slashes_regex.tinrc));
 1115     fprintf(fp, "slashes_regex=%s\n\n", tinrc.slashes_regex);
 1116     fprintf(fp, "%s", _(txt_stars_regex.tinrc));
 1117     fprintf(fp, "stars_regex=%s\n\n", tinrc.stars_regex);
 1118     fprintf(fp, "%s", _(txt_strokes_regex.tinrc));
 1119     fprintf(fp, "strokes_regex=%s\n\n", tinrc.strokes_regex);
 1120     fprintf(fp, "%s", _(txt_underscores_regex.tinrc));
 1121     fprintf(fp, "underscores_regex=%s\n\n", tinrc.underscores_regex);
 1122 
 1123     fprintf(fp, "%s", _(txt_strip_re_regex.tinrc));
 1124     fprintf(fp, "strip_re_regex=%s\n\n", tinrc.strip_re_regex);
 1125     fprintf(fp, "%s", _(txt_strip_was_regex.tinrc));
 1126     fprintf(fp, "strip_was_regex=%s\n\n", tinrc.strip_was_regex);
 1127 
 1128     fprintf(fp, "%s", _(txt_verbatim_begin_regex.tinrc));
 1129     fprintf(fp, "verbatim_begin_regex=%s\n\n", tinrc.verbatim_begin_regex);
 1130     fprintf(fp, "%s", _(txt_verbatim_end_regex.tinrc));
 1131     fprintf(fp, "verbatim_end_regex=%s\n\n", tinrc.verbatim_end_regex);
 1132 
 1133 #ifdef HAVE_COLOR
 1134     fprintf(fp, "%s", _(txt_extquote_regex.tinrc));
 1135     fprintf(fp, "extquote_regex=%s\n\n", tinrc.extquote_regex);
 1136 #endif /* HAVE_COLOR */
 1137 
 1138     fprintf(fp, "%s", _(txt_show_signatures.tinrc));
 1139     fprintf(fp, "show_signatures=%s\n\n", print_boolean(tinrc.show_signatures));
 1140 
 1141     fprintf(fp, "%s", _(txt_tex2iso_conv.tinrc));
 1142     fprintf(fp, "tex2iso_conv=%s\n\n", print_boolean(tinrc.tex2iso_conv));
 1143 
 1144     fprintf(fp, "%s", _(txt_hide_uue.tinrc));
 1145     fprintf(fp, "hide_uue=%d\n\n", tinrc.hide_uue);
 1146 
 1147     fprintf(fp, "%s", _(txt_news_quote_format.tinrc));
 1148     fprintf(fp, "news_quote_format=%s\n", tinrc.news_quote_format);
 1149     fprintf(fp, "mail_quote_format=%s\n", tinrc.mail_quote_format);
 1150     fprintf(fp, "xpost_quote_format=%s\n\n", tinrc.xpost_quote_format);
 1151 
 1152     fprintf(fp, "%s", _(txt_auto_cc_bcc.tinrc));
 1153     fprintf(fp, "auto_cc_bcc=%d\n\n", tinrc.auto_cc_bcc);
 1154 
 1155 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
 1156     fprintf(fp, "%s", _(txt_utf8_graphics.tinrc));
 1157     fprintf(fp, "utf8_graphics=%s\n\n", print_boolean(tinrc.utf8_graphics));
 1158 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
 1159 
 1160     fprintf(fp, "%s", _(txt_art_marked_deleted.tinrc));
 1161     fprintf(fp, "art_marked_deleted=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_deleted));
 1162 
 1163     fprintf(fp, "%s", _(txt_art_marked_inrange.tinrc));
 1164     fprintf(fp, "art_marked_inrange=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_inrange));
 1165 
 1166     fprintf(fp, "%s", _(txt_art_marked_return.tinrc));
 1167     fprintf(fp, "art_marked_return=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_return));
 1168 
 1169     fprintf(fp, "%s", _(txt_art_marked_selected.tinrc));
 1170     fprintf(fp, "art_marked_selected=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_selected));
 1171 
 1172     fprintf(fp, "%s", _(txt_art_marked_recent.tinrc));
 1173     fprintf(fp, "art_marked_recent=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_recent));
 1174 
 1175     fprintf(fp, "%s", _(txt_art_marked_unread.tinrc));
 1176     fprintf(fp, "art_marked_unread=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_unread));
 1177 
 1178     fprintf(fp, "%s", _(txt_art_marked_read.tinrc));
 1179     fprintf(fp, "art_marked_read=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_read));
 1180 
 1181     fprintf(fp, "%s", _(txt_art_marked_killed.tinrc));
 1182     fprintf(fp, "art_marked_killed=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_killed));
 1183 
 1184     fprintf(fp, "%s", _(txt_art_marked_read_selected.tinrc));
 1185     fprintf(fp, "art_marked_read_selected=%c\n\n", SPACE_TO_DASH(tinrc.art_marked_read_selected));
 1186 
 1187     fprintf(fp, "%s", _(txt_force_screen_redraw.tinrc));
 1188     fprintf(fp, "force_screen_redraw=%s\n\n", print_boolean(tinrc.force_screen_redraw));
 1189 
 1190     fprintf(fp, "%s", _(txt_inews_prog.tinrc));
 1191     fprintf(fp, "inews_prog=%s\n\n", tinrc.inews_prog);
 1192 
 1193 #ifdef USE_CANLOCK
 1194     fprintf(fp, "%s", _(txt_cancel_lock_algo.tinrc));
 1195     fprintf(fp, "cancel_lock_algo=%s\n\n", txt_cancel_lock_algos[tinrc.cancel_lock_algo]);
 1196 #endif /* USE_CANLOCK */
 1197 
 1198     fprintf(fp, "%s", _(txt_auto_list_thread.tinrc));
 1199     fprintf(fp, "auto_list_thread=%s\n\n", print_boolean(tinrc.auto_list_thread));
 1200 
 1201     fprintf(fp, "%s", _(txt_wrap_on_next_unread.tinrc));
 1202     fprintf(fp, "wrap_on_next_unread=%s\n\n", print_boolean(tinrc.wrap_on_next_unread));
 1203 
 1204     fprintf(fp, "%s", _(txt_use_mouse.tinrc));
 1205     fprintf(fp, "use_mouse=%s\n\n", print_boolean(tinrc.use_mouse));
 1206 
 1207 #ifndef USE_CURSES
 1208     fprintf(fp, "%s", _(txt_strip_blanks.tinrc));
 1209     fprintf(fp, "strip_blanks=%s\n\n", print_boolean(tinrc.strip_blanks));
 1210 #endif /* !USE_CURSES */
 1211 
 1212     fprintf(fp, "%s", _(txt_abbreviate_groupname.tinrc));
 1213     fprintf(fp, "abbreviate_groupname=%s\n\n", print_boolean(tinrc.abbreviate_groupname));
 1214 
 1215     fprintf(fp, "%s", _(txt_beginner_level.tinrc));
 1216     fprintf(fp, "beginner_level=%s\n\n", print_boolean(tinrc.beginner_level));
 1217 
 1218     fprintf(fp, "%s", _(txt_filter_days.tinrc));
 1219     fprintf(fp, "default_filter_days=%d\n\n", tinrc.filter_days);
 1220 
 1221     fprintf(fp, "%s", _(txt_cache_overview_files.tinrc));
 1222     fprintf(fp, "cache_overview_files=%s\n\n", print_boolean(tinrc.cache_overview_files));
 1223 
 1224     fprintf(fp, "%s", _(txt_getart_limit.tinrc));
 1225     fprintf(fp, "getart_limit=%d\n\n", tinrc.getart_limit);
 1226 
 1227     fprintf(fp, "%s", _(txt_recent_time.tinrc));
 1228     fprintf(fp, "recent_time=%d\n\n", tinrc.recent_time);
 1229 
 1230     fprintf(fp, "%s", _(txt_score_limit_kill.tinrc));
 1231     fprintf(fp, "score_limit_kill=%d\n\n", tinrc.score_limit_kill);
 1232 
 1233     fprintf(fp, "%s", _(txt_score_kill.tinrc));
 1234     fprintf(fp, "score_kill=%d\n\n", tinrc.score_kill);
 1235 
 1236     fprintf(fp, "%s", _(txt_score_limit_select.tinrc));
 1237     fprintf(fp, "score_limit_select=%d\n\n", tinrc.score_limit_select);
 1238 
 1239     fprintf(fp, "%s", _(txt_score_select.tinrc));
 1240     fprintf(fp, "score_select=%d\n\n", tinrc.score_select);
 1241 
 1242 #ifdef HAVE_COLOR
 1243     fprintf(fp, "%s", _(txt_use_color.tinrc));
 1244     fprintf(fp, "use_color=%s\n\n", print_boolean(tinrc.use_color));
 1245 
 1246     fprintf(fp, "%s", _(txt_tinrc_colors));
 1247 
 1248     fprintf(fp, "%s", _(txt_col_normal.tinrc));
 1249     fprintf(fp, "col_normal=%d\n\n", tinrc.col_normal);
 1250 
 1251     fprintf(fp, "%s", _(txt_col_back.tinrc));
 1252     fprintf(fp, "col_back=%d\n\n", tinrc.col_back);
 1253 
 1254     fprintf(fp, "%s", _(txt_col_invers_bg.tinrc));
 1255     fprintf(fp, "col_invers_bg=%d\n\n", tinrc.col_invers_bg);
 1256 
 1257     fprintf(fp, "%s", _(txt_col_invers_fg.tinrc));
 1258     fprintf(fp, "col_invers_fg=%d\n\n", tinrc.col_invers_fg);
 1259 
 1260     fprintf(fp, "%s", _(txt_col_text.tinrc));
 1261     fprintf(fp, "col_text=%d\n\n", tinrc.col_text);
 1262 
 1263     fprintf(fp, "%s", _(txt_col_minihelp.tinrc));
 1264     fprintf(fp, "col_minihelp=%d\n\n", tinrc.col_minihelp);
 1265 
 1266     fprintf(fp, "%s", _(txt_col_help.tinrc));
 1267     fprintf(fp, "col_help=%d\n\n", tinrc.col_help);
 1268 
 1269     fprintf(fp, "%s", _(txt_col_message.tinrc));
 1270     fprintf(fp, "col_message=%d\n\n", tinrc.col_message);
 1271 
 1272     fprintf(fp, "%s", _(txt_col_quote.tinrc));
 1273     fprintf(fp, "col_quote=%d\n\n", tinrc.col_quote);
 1274 
 1275     fprintf(fp, "%s", _(txt_col_quote2.tinrc));
 1276     fprintf(fp, "col_quote2=%d\n\n", tinrc.col_quote2);
 1277 
 1278     fprintf(fp, "%s", _(txt_col_quote3.tinrc));
 1279     fprintf(fp, "col_quote3=%d\n\n", tinrc.col_quote3);
 1280 
 1281     fprintf(fp, "%s", _(txt_col_head.tinrc));
 1282     fprintf(fp, "col_head=%d\n\n", tinrc.col_head);
 1283 
 1284     fprintf(fp, "%s", _(txt_col_newsheaders.tinrc));
 1285     fprintf(fp, "col_newsheaders=%d\n\n", tinrc.col_newsheaders);
 1286 
 1287     fprintf(fp, "%s", _(txt_col_subject.tinrc));
 1288     fprintf(fp, "col_subject=%d\n\n", tinrc.col_subject);
 1289 
 1290     fprintf(fp, "%s", _(txt_col_extquote.tinrc));
 1291     fprintf(fp, "col_extquote=%d\n\n", tinrc.col_extquote);
 1292 
 1293     fprintf(fp, "%s", _(txt_col_response.tinrc));
 1294     fprintf(fp, "col_response=%d\n\n", tinrc.col_response);
 1295 
 1296     fprintf(fp, "%s", _(txt_col_from.tinrc));
 1297     fprintf(fp, "col_from=%d\n\n", tinrc.col_from);
 1298 
 1299     fprintf(fp, "%s", _(txt_col_title.tinrc));
 1300     fprintf(fp, "col_title=%d\n\n", tinrc.col_title);
 1301 
 1302     fprintf(fp, "%s", _(txt_col_signature.tinrc));
 1303     fprintf(fp, "col_signature=%d\n\n", tinrc.col_signature);
 1304 
 1305     fprintf(fp, "%s", _(txt_col_urls.tinrc));
 1306     fprintf(fp, "col_urls=%d\n\n", tinrc.col_urls);
 1307 
 1308     fprintf(fp, "%s", _(txt_col_verbatim.tinrc));
 1309     fprintf(fp, "col_verbatim=%d\n\n", tinrc.col_verbatim);
 1310 #endif /* HAVE_COLOR */
 1311 
 1312     fprintf(fp, "%s", _(txt_url_highlight.tinrc));
 1313     fprintf(fp, "url_highlight=%s\n\n", print_boolean(tinrc.url_highlight));
 1314 
 1315     fprintf(fp, "%s", _(txt_word_highlight.tinrc));
 1316     fprintf(fp, "word_highlight=%s\n\n", print_boolean(tinrc.word_highlight));
 1317 
 1318     fprintf(fp, "%s", _(txt_word_h_display_marks.tinrc));
 1319     fprintf(fp, "word_h_display_marks=%d\n\n", tinrc.word_h_display_marks);
 1320 
 1321 #ifdef HAVE_COLOR
 1322     fprintf(fp, "%s", _(txt_col_markstar.tinrc));
 1323     fprintf(fp, "col_markstar=%d\n\n", tinrc.col_markstar);
 1324     fprintf(fp, "%s", _(txt_col_markdash.tinrc));
 1325     fprintf(fp, "col_markdash=%d\n\n", tinrc.col_markdash);
 1326     fprintf(fp, "%s", _(txt_col_markslash.tinrc));
 1327     fprintf(fp, "col_markslash=%d\n\n", tinrc.col_markslash);
 1328     fprintf(fp, "%s", _(txt_col_markstroke.tinrc));
 1329     fprintf(fp, "col_markstroke=%d\n\n", tinrc.col_markstroke);
 1330 #endif /* HAVE_COLOR */
 1331 
 1332     fprintf(fp, "%s", _(txt_mono_markstar.tinrc));
 1333     fprintf(fp, "mono_markstar=%d\n\n", tinrc.mono_markstar);
 1334     fprintf(fp, "%s", _(txt_mono_markdash.tinrc));
 1335     fprintf(fp, "mono_markdash=%d\n\n", tinrc.mono_markdash);
 1336     fprintf(fp, "%s", _(txt_mono_markslash.tinrc));
 1337     fprintf(fp, "mono_markslash=%d\n\n", tinrc.mono_markslash);
 1338     fprintf(fp, "%s", _(txt_mono_markstroke.tinrc));
 1339     fprintf(fp, "mono_markstroke=%d\n\n", tinrc.mono_markstroke);
 1340 
 1341     fprintf(fp, "%s", _(txt_mail_address.tinrc));
 1342     fprintf(fp, "mail_address=%s\n\n", tinrc.mail_address);
 1343 
 1344 #ifdef XFACE_ABLE
 1345     fprintf(fp, "%s", _(txt_use_slrnface.tinrc));
 1346     fprintf(fp, "use_slrnface=%s\n\n", print_boolean(tinrc.use_slrnface));
 1347 #endif /* XFACE_ABLE */
 1348 
 1349     fprintf(fp, "%s", _(txt_wrap_column.tinrc));
 1350     fprintf(fp, "wrap_column=%d\n\n", tinrc.wrap_column);
 1351 
 1352     fprintf(fp, "%s", _(txt_trim_article_body.tinrc));
 1353     fprintf(fp, "trim_article_body=%d\n\n", tinrc.trim_article_body);
 1354 
 1355 #ifndef CHARSET_CONVERSION
 1356     fprintf(fp, "%s", _(txt_mm_charset.tinrc));
 1357     fprintf(fp, "mm_charset=%s\n\n", tinrc.mm_charset);
 1358 #else
 1359     fprintf(fp, "%s", _(txt_mm_network_charset.tinrc));
 1360     fprintf(fp, "mm_network_charset=%s\n\n", txt_mime_charsets[tinrc.mm_network_charset]);
 1361 
 1362 #   ifdef NO_LOCALE
 1363     fprintf(fp, "%s", _(txt_mm_local_charset.tinrc));
 1364     fprintf(fp, "mm_local_charset=%s\n\n", tinrc.mm_local_charset);
 1365 #   endif /* NO_LOCALE */
 1366 #   ifdef HAVE_ICONV_OPEN_TRANSLIT
 1367     fprintf(fp, "%s", _(txt_translit.tinrc));
 1368     fprintf(fp, "translit=%s\n\n", print_boolean(tinrc.translit));
 1369 #   endif /* HAVE_ICONV_OPEN_TRANSLIT */
 1370 #endif /* !CHARSET_CONVERSION */
 1371 
 1372     fprintf(fp, "%s", _(txt_post_mime_encoding.tinrc));
 1373     fprintf(fp, "post_mime_encoding=%s\n", txt_mime_encodings[tinrc.post_mime_encoding]);
 1374     fprintf(fp, "mail_mime_encoding=%s\n\n", txt_mime_encodings[tinrc.mail_mime_encoding]);
 1375 
 1376     fprintf(fp, "%s", _(txt_post_8bit_header.tinrc));
 1377     fprintf(fp, "post_8bit_header=%s\n\n", print_boolean(tinrc.post_8bit_header));
 1378 
 1379     fprintf(fp, "%s", _(txt_mail_8bit_header.tinrc));
 1380     fprintf(fp, "mail_8bit_header=%s\n\n", print_boolean(tinrc.mail_8bit_header));
 1381 
 1382     fprintf(fp, "%s", _(txt_metamail_prog.tinrc));
 1383     fprintf(fp, "metamail_prog=%s\n\n", tinrc.metamail_prog);
 1384 
 1385     fprintf(fp, "%s", _(txt_ask_for_metamail.tinrc));
 1386     fprintf(fp, "ask_for_metamail=%s\n\n", print_boolean(tinrc.ask_for_metamail));
 1387 
 1388 #ifdef HAVE_KEYPAD
 1389     fprintf(fp, "%s", _(txt_use_keypad.tinrc));
 1390     fprintf(fp, "use_keypad=%s\n\n", print_boolean(tinrc.use_keypad));
 1391 #endif /* HAVE_KEYPAD */
 1392 
 1393     fprintf(fp, "%s", _(txt_alternative_handling.tinrc));
 1394     fprintf(fp, "alternative_handling=%s\n\n", print_boolean(tinrc.alternative_handling));
 1395 
 1396     fprintf(fp, "%s", _(txt_verbatim_handling.tinrc));
 1397     fprintf(fp, "verbatim_handling=%s\n\n", print_boolean(tinrc.verbatim_handling));
 1398 
 1399 #ifdef HAVE_COLOR
 1400     fprintf(fp, "%s", _(txt_extquote_handling.tinrc));
 1401     fprintf(fp, "extquote_handling=%s\n\n", print_boolean(tinrc.extquote_handling));
 1402 #endif /* HAVE_COLOR */
 1403 
 1404     fprintf(fp, "%s", _(txt_strip_newsrc.tinrc));
 1405     fprintf(fp, "strip_newsrc=%s\n\n", print_boolean(tinrc.strip_newsrc));
 1406 
 1407     fprintf(fp, "%s", _(txt_strip_bogus.tinrc));
 1408     fprintf(fp, "strip_bogus=%d\n\n", tinrc.strip_bogus);
 1409 
 1410     fprintf(fp, "%s", _(txt_select_format.tinrc));
 1411     fprintf(fp, "select_format=%s\n\n", tinrc.select_format);
 1412 
 1413     fprintf(fp, "%s", _(txt_group_format.tinrc));
 1414     fprintf(fp, "group_format=%s\n\n", tinrc.group_format);
 1415 
 1416     fprintf(fp, "%s", _(txt_thread_format.tinrc));
 1417     fprintf(fp, "thread_format=%s\n\n", tinrc.thread_format);
 1418 
 1419     fprintf(fp, "%s", _(txt_date_format.tinrc));
 1420     fprintf(fp, "date_format=%s\n\n", tinrc.date_format);
 1421 
 1422     fprintf(fp, "%s", _(txt_wildcard.tinrc));
 1423     fprintf(fp, "wildcard=%d\n\n", tinrc.wildcard);
 1424 
 1425 #ifdef HAVE_UNICODE_NORMALIZATION
 1426     fprintf(fp, "%s", _(txt_normalization_form.tinrc));
 1427     fprintf(fp, "normalization_form=%d\n\n", tinrc.normalization_form);
 1428 #endif /* HAVE_UNICODE_NORMALIZATION */
 1429 
 1430 #if defined(HAVE_LIBICUUC) && defined(MULTIBYTE_ABLE) && defined(HAVE_UNICODE_UBIDI_H) && !defined(NO_LOCALE)
 1431     fprintf(fp, "%s", _(txt_render_bidi.tinrc));
 1432     fprintf(fp, "render_bidi=%s\n\n", print_boolean(tinrc.render_bidi));
 1433 #endif /* HAVE_LIBICUUC && MULTIBYTE_ABLE && HAVE_UNICODE_UBIDI_H && !NO_LOCALE */
 1434 
 1435     fprintf(fp, "%s", _(txt_tinrc_filter));
 1436     fprintf(fp, "default_filter_kill_header=%d\n", tinrc.default_filter_kill_header);
 1437     fprintf(fp, "default_filter_kill_global=%s\n", print_boolean(tinrc.default_filter_kill_global));
 1438     fprintf(fp, "default_filter_kill_case=%s\n", print_boolean(tinrc.default_filter_kill_case));
 1439     fprintf(fp, "default_filter_kill_expire=%s\n", print_boolean(tinrc.default_filter_kill_expire));
 1440     fprintf(fp, "default_filter_select_header=%d\n", tinrc.default_filter_select_header);
 1441     fprintf(fp, "default_filter_select_global=%s\n", print_boolean(tinrc.default_filter_select_global));
 1442     fprintf(fp, "default_filter_select_case=%s\n", print_boolean(tinrc.default_filter_select_case));
 1443     fprintf(fp, "default_filter_select_expire=%s\n\n", print_boolean(tinrc.default_filter_select_expire));
 1444 
 1445     fprintf(fp, "%s", _(txt_tinrc_defaults));
 1446     fprintf(fp, "default_save_mode=%c\n", tinrc.default_save_mode);
 1447     fprintf(fp, "default_author_search=%s\n", tinrc.default_search_author);
 1448     fprintf(fp, "default_goto_group=%s\n", tinrc.default_goto_group);
 1449     fprintf(fp, "default_config_search=%s\n", tinrc.default_search_config);
 1450     fprintf(fp, "default_group_search=%s\n", tinrc.default_search_group);
 1451     fprintf(fp, "default_subject_search=%s\n", tinrc.default_search_subject);
 1452     fprintf(fp, "default_art_search=%s\n", tinrc.default_search_art);
 1453     fprintf(fp, "default_repost_group=%s\n", tinrc.default_repost_group);
 1454     fprintf(fp, "default_mail_address=%s\n", tinrc.default_mail_address);
 1455     fprintf(fp, "default_move_group=%d\n", tinrc.default_move_group);
 1456 #ifndef DONT_HAVE_PIPING
 1457     fprintf(fp, "default_pipe_command=%s\n", tinrc.default_pipe_command);
 1458 #endif /* !DONT_HAVE_PIPING */
 1459     fprintf(fp, "default_post_newsgroups=%s\n", tinrc.default_post_newsgroups);
 1460     fprintf(fp, "default_post_subject=%s\n", tinrc.default_post_subject);
 1461     fprintf(fp, "default_range_group=%s\n", tinrc.default_range_group);
 1462     fprintf(fp, "default_range_select=%s\n", tinrc.default_range_select);
 1463     fprintf(fp, "default_range_thread=%s\n", tinrc.default_range_thread);
 1464     fprintf(fp, "default_pattern=%s\n", tinrc.default_pattern);
 1465     fprintf(fp, "default_save_file=%s\n", tinrc.default_save_file);
 1466     fprintf(fp, "default_select_pattern=%s\n", tinrc.default_select_pattern);
 1467     fprintf(fp, "default_shell_command=%s\n\n", tinrc.default_shell_command);
 1468 
 1469     fprintf(fp, "%s", _(txt_tinrc_newnews));
 1470     {
 1471         char timestring[30];
 1472         int j = find_newnews_index(nntp_server);
 1473 
 1474         /*
 1475          * Newnews timestamps in tinrc are bogus as of tin 1.5.19 because they
 1476          * are now stored in a separate file to prevent overwriting them from
 1477          * another instance running concurrently. Except for the current server,
 1478          * however, we must remember them because otherwise we would lose them
 1479          * after the first start of a tin 1.5.19 (or later) version.
 1480          */
 1481         for (i = 0; i < num_newnews; i++) {
 1482             if (i == j)
 1483                 continue;
 1484             if (my_strftime(timestring, sizeof(timestring) - 1, "%Y-%m-%d %H:%M:%S UTC", gmtime(&(newnews[i].time))))
 1485                 fprintf(fp, "newnews=%s %lu (%s)\n", newnews[i].host, (unsigned long int) newnews[i].time, timestring);
 1486         }
 1487     }
 1488 
 1489     fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
 1490 
 1491     if ((i = ferror(fp)) || fclose(fp)) {
 1492         error_message(2, _(txt_filesystem_full), CONFIG_FILE);
 1493         if (i) {
 1494             clearerr(fp);
 1495             fclose(fp);
 1496         }
 1497     } else
 1498         rename_file(file_tmp, file);
 1499 
 1500     free(file_tmp);
 1501     write_server_config();
 1502 }
 1503 
 1504 
 1505 t_bool
 1506 match_boolean(
 1507     char *line,
 1508     const char *pat,
 1509     t_bool *dst)
 1510 {
 1511     size_t patlen = strlen(pat);
 1512 
 1513     if (STRNCASECMPEQ(line, pat, patlen)) {
 1514         *dst = (t_bool) (STRNCASECMPEQ(&line[patlen], "ON", 2) ? TRUE : FALSE);
 1515         return TRUE;
 1516     }
 1517     return FALSE;
 1518 }
 1519 
 1520 
 1521 #ifdef HAVE_COLOR
 1522 static t_bool
 1523 match_color(
 1524     char *line,
 1525     const char *pat,
 1526     int *dst,
 1527     int max)
 1528 {
 1529     size_t patlen = strlen(pat);
 1530 
 1531     if (STRNCMPEQ(line, pat, patlen)) {
 1532         int n;
 1533         t_bool found = FALSE;
 1534 
 1535         for (n = 0; n < MAX_COLOR + 1; n++) {
 1536             if (!strcasecmp(&line[patlen], txt_colors[n])) {
 1537                 found = TRUE;
 1538                 *dst = n;
 1539             }
 1540         }
 1541 
 1542         if (!found)
 1543             *dst = atoi(&line[patlen]);
 1544 
 1545         if (max) {
 1546             if (max == MAX_BACKCOLOR && *dst > max && *dst <= MAX_COLOR)
 1547                 *dst %= MAX_BACKCOLOR + 1;
 1548             else if ((*dst < -1) || (*dst > max)) {
 1549                 my_fprintf(stderr, _(txt_value_out_of_range), pat, *dst, max);
 1550                 *dst = 0;
 1551             }
 1552         } else
 1553             *dst = -1;
 1554         return TRUE;
 1555     }
 1556     return FALSE;
 1557 }
 1558 #endif /* HAVE_COLOR */
 1559 
 1560 
 1561 /*
 1562  * If pat matches the start of line, convert rest of line to an integer, dst
 1563  * If maxval is set, constrain value to 0 <= dst <= maxlen and return TRUE.
 1564  * If no match is made, return FALSE.
 1565  */
 1566 t_bool
 1567 match_integer(
 1568     char *line,
 1569     const char *pat,
 1570     int *dst,
 1571     int maxval)
 1572 {
 1573     size_t patlen = strlen(pat);
 1574 
 1575     if (STRNCMPEQ(line, pat, patlen)) {
 1576         *dst = atoi(&line[patlen]);
 1577 
 1578         if (maxval) {
 1579             if ((*dst < 0) || (*dst > maxval)) {
 1580                 my_fprintf(stderr, _(txt_value_out_of_range), pat, *dst, maxval);
 1581                 *dst = 0;
 1582             }
 1583         }
 1584         return TRUE;
 1585     }
 1586     return FALSE;
 1587 }
 1588 
 1589 
 1590 t_bool
 1591 match_long(
 1592     char *line,
 1593     const char *pat,
 1594     long *dst)
 1595 {
 1596     size_t patlen = strlen(pat);
 1597 
 1598     if (STRNCMPEQ(line, pat, patlen)) {
 1599         *dst = atol(&line[patlen]);
 1600         return TRUE;
 1601     }
 1602     return FALSE;
 1603 }
 1604 
 1605 
 1606 /*
 1607  * If the 'pat' keyword matches, lookup & return an index into the table
 1608  */
 1609 t_bool
 1610 match_list(
 1611     char *line,
 1612     constext *pat,
 1613     constext *const *table,
 1614     int *dst)
 1615 {
 1616     size_t patlen = strlen(pat);
 1617 
 1618     if (STRNCMPEQ(line, pat, patlen)) {
 1619         char temp[LEN];
 1620         size_t n;
 1621 
 1622         line += patlen;
 1623         *dst = 0;   /* default, if no match */
 1624         for (n = 0; table[n] != NULL; n++) {
 1625             if (match_item(line, table[n], temp, sizeof(temp))) {
 1626                 *dst = (int) n;
 1627                 break;
 1628             }
 1629         }
 1630         return TRUE;
 1631     }
 1632     return FALSE;
 1633 }
 1634 
 1635 
 1636 t_bool
 1637 match_string(
 1638     char *line,
 1639     const char *pat,
 1640     char *dst,
 1641     size_t dstlen)
 1642 {
 1643     size_t patlen = strlen(pat);
 1644 
 1645     if (STRNCMPEQ(line, pat, patlen) && (strlen(line) > patlen)) {
 1646         if (dst != NULL && dstlen >= 1)
 1647             my_strncpy(dst, &line[patlen], dstlen - 1);
 1648         return TRUE;
 1649     }
 1650     return FALSE;
 1651 }
 1652 
 1653 
 1654 /* like mach_string() but looks for 100% exact matches */
 1655 static t_bool
 1656 match_item(
 1657     char *line,
 1658     const char *pat,
 1659     char *dst,
 1660     size_t dstlen)
 1661 {
 1662     char *ptr;
 1663     char *nline = my_strdup(line);
 1664     size_t patlen = strlen(pat);
 1665 
 1666     if ((ptr = strchr(nline, '\n')) != NULL) /* terminate on \n */
 1667         *ptr = '\0';
 1668 
 1669     if (!strcasecmp(nline, pat)) {
 1670         if (dst != NULL) {
 1671             strncpy(dst, &nline[patlen], dstlen);
 1672             dst[dstlen ? (dstlen - 1) : 0] = '\0';
 1673         }
 1674         free(nline);
 1675         return TRUE;
 1676     }
 1677     free(nline);
 1678     return FALSE;
 1679 }
 1680 
 1681 
 1682 const char *
 1683 print_boolean(
 1684     t_bool value)
 1685 {
 1686     return txt_onoff[value != FALSE ? 1 : 0];
 1687 }
 1688 
 1689 
 1690 /*
 1691  * convert underlines to spaces in a string
 1692  */
 1693 void
 1694 quote_dash_to_space(
 1695     char *str)
 1696 {
 1697     char *ptr;
 1698 
 1699     for (ptr = str; *ptr; ptr++) {
 1700         if (*ptr == '_')
 1701             *ptr = ' ';
 1702     }
 1703 }
 1704 
 1705 
 1706 /*
 1707  * convert spaces to underlines in a string
 1708  */
 1709 char *
 1710 quote_space_to_dash(
 1711     char *str)
 1712 {
 1713     char *ptr, *dst;
 1714     static char buf[PATH_LEN];
 1715 
 1716     dst = buf;
 1717     for (ptr = str; *ptr; ptr++) {
 1718         if (*ptr == ' ')
 1719             *dst = '_';
 1720         else
 1721             *dst = *ptr;
 1722         dst++;
 1723     }
 1724     *dst = '\0';
 1725 
 1726     return buf;
 1727 }
 1728 
 1729 
 1730 /*
 1731  * Written by: Brad Viviano and Scott Powers (bcv & swp)
 1732  *
 1733  * Takes a 1d string and turns it into a 2d array of strings.
 1734  *
 1735  * Watch out for the frees! You must free(*argv) and then free(argv)!
 1736  * NOTHING ELSE! Do _NOT_ free the individual args of argv.
 1737  */
 1738 char **
 1739 ulBuildArgv(
 1740     char *cmd,
 1741     int *new_argc)
 1742 {
 1743     char **new_argv = NULL;
 1744     char *buf, *tmp;
 1745     int i = 0;
 1746 
 1747     if (!cmd || !*cmd) {
 1748         *new_argc = 0;
 1749         return NULL;
 1750     }
 1751 
 1752     for (tmp = cmd; isspace((int) *tmp); tmp++)
 1753         ;
 1754 
 1755     buf = my_strdup(tmp);
 1756     tmp = buf;
 1757 
 1758     new_argv = my_calloc(1, sizeof(char *));
 1759 
 1760     while (*tmp) {
 1761         if (!isspace((int) *tmp)) { /* found the beginning of a word */
 1762             new_argv[i] = tmp;
 1763             for (; *tmp && !isspace((int) *tmp); tmp++)
 1764                 ;
 1765             if (*tmp) {
 1766                 *tmp = '\0';
 1767                 tmp++;
 1768             }
 1769             i++;
 1770             new_argv = my_realloc(new_argv, ((i + 1) * sizeof(char *)));
 1771             new_argv[i] = NULL;
 1772         } else
 1773             tmp++;
 1774     }
 1775     *new_argc = i;
 1776     return new_argv;
 1777 }
 1778 
 1779 
 1780 /*
 1781  * auto update tinrc
 1782  * called at the beginning of read_config_file()
 1783  */
 1784 static t_bool
 1785 rc_update(
 1786     FILE *fp)
 1787 {
 1788     char buf[LEN];
 1789     int show_info = 1;
 1790     t_bool auto_bcc = FALSE;
 1791     t_bool auto_cc = FALSE;
 1792     t_bool confirm_to_quit = FALSE;
 1793     t_bool confirm_action = FALSE;
 1794     t_bool compress_quotes = FALSE;
 1795     t_bool set_goto_next_unread = FALSE;
 1796     t_bool hide_uue = FALSE;
 1797     t_bool keep_posted_articles = FALSE;
 1798     t_bool pgdn_goto_next = FALSE;
 1799     t_bool quote_empty_lines = FALSE;
 1800     t_bool quote_signatures = FALSE;
 1801     t_bool save_to_mmdf_mailbox = FALSE;
 1802     t_bool show_last_line_prev_page = FALSE;
 1803     t_bool show_lines = FALSE;
 1804     t_bool show_score = FALSE;
 1805     t_bool show_lines_or_score = FALSE;
 1806     t_bool space_goto_next_unread = FALSE;
 1807     t_bool tab_goto_next_unread = FALSE;
 1808     t_bool use_builtin_inews = FALSE;
 1809     t_bool use_getart_limit = FALSE;
 1810     t_bool use_mailreader_i = FALSE;
 1811     t_bool use_metamail = FALSE;
 1812 
 1813     if (!fp)
 1814         return FALSE;
 1815 
 1816     /* rewind(fp); */
 1817     while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
 1818         if (buf[0] == '#' || buf[0] == '\n')
 1819             continue;
 1820 
 1821         switch (my_tolower((unsigned char) buf[0])) {
 1822             case 'a':
 1823                 if (match_boolean(buf, "auto_bcc=", &auto_bcc))
 1824                     break;
 1825 
 1826                 if (match_boolean(buf, "auto_cc=", &auto_cc))
 1827                     break;
 1828                 break;
 1829 
 1830             case 'c':
 1831                 if (match_boolean(buf, "confirm_action=", &confirm_action))
 1832                     break;
 1833                 if (match_boolean(buf, "confirm_to_quit=", &confirm_to_quit))
 1834                     break;
 1835                 if (match_boolean(buf, "compress_quotes=", &compress_quotes))
 1836                     break;
 1837                 break;
 1838 
 1839             case 'd':
 1840                 /* simple rename */
 1841                 if (match_string(buf, "default_editor_format=", tinrc.editor_format, sizeof(tinrc.editor_format)))
 1842                     break;
 1843                 /* simple rename */
 1844                 if (match_string(buf, "default_maildir=", tinrc.maildir, sizeof(tinrc.maildir)))
 1845                     break;
 1846                 /* simple rename */
 1847                 if (match_string(buf, "default_mailer_format=", tinrc.mailer_format, sizeof(tinrc.mailer_format)))
 1848                     break;
 1849                 /* simple rename */
 1850 #ifndef DISABLE_PRINTING
 1851                 if (match_string(buf, "default_printer=", tinrc.printer, sizeof(tinrc.printer)))
 1852                     break;
 1853 #endif /* !DISABLE_PRINTING */
 1854                 /* simple rename */
 1855                 if (match_string(buf, "default_regex_pattern=", tinrc.default_pattern, sizeof(tinrc.default_pattern)))
 1856                     break;
 1857                 /* simple rename */
 1858                 if (match_string(buf, "default_savedir=", tinrc.savedir, sizeof(tinrc.savedir))) {
 1859                     if (tinrc.savedir[0] == '.' && strlen(tinrc.savedir) == 1) {
 1860                         char buff[PATH_LEN];
 1861 
 1862                         get_cwd(buff);
 1863                         my_strncpy(tinrc.savedir, buff, sizeof(tinrc.savedir) - 1);
 1864                     }
 1865                     break;
 1866                 }
 1867                 /* 1. simple rename
 1868                  *
 1869                  * 2. previous versions has always passed groupname to external
 1870                  *    commands, now we look for %G
 1871                  */
 1872                 if (match_string(buf, "default_sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
 1873                     size_t l = strlen(tinrc.sigfile);
 1874 
 1875                     if (tinrc.sigfile[0] == '!' && (tinrc.sigfile[l - 2] != '%' || tinrc.sigfile[l - 1] != 'G')) {
 1876                         char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
 1877 
 1878                         sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
 1879                         my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
 1880                         free(newbuf);
 1881                     }
 1882                     break;
 1883                 }
 1884                 break;
 1885 
 1886             case 'h':
 1887                 if (match_boolean(buf, "hide_uue=", &hide_uue))
 1888                     break;
 1889                 break;
 1890 
 1891             case 'k':
 1892                 if (match_boolean(buf, "keep_posted_articles=", &keep_posted_articles))
 1893                     break;
 1894                 break;
 1895 
 1896             case 'p':
 1897                 if (match_boolean(buf, "pgdn_goto_next=", &pgdn_goto_next)) {
 1898                     set_goto_next_unread = TRUE;
 1899                     break;
 1900                 }
 1901                 break;
 1902 
 1903             case 'q':
 1904                 if (match_boolean(buf, "quote_signatures=", &quote_signatures))
 1905                     break;
 1906                 if (match_boolean(buf, "quote_empty_lines=", &quote_empty_lines))
 1907                     break;
 1908                 break;
 1909 
 1910             case 's':
 1911                 if (match_boolean(buf, "space_goto_next_unread=", &space_goto_next_unread)) {
 1912                     set_goto_next_unread = TRUE;
 1913                     break;
 1914                 }
 1915                 if (match_boolean(buf, "save_to_mmdf_mailbox=", &save_to_mmdf_mailbox))
 1916                     break;
 1917                 if (match_integer(buf, "show_info=", &show_info, 3))
 1918                     break;
 1919                 if (match_boolean(buf, "show_last_line_prev_page=", &show_last_line_prev_page))
 1920                     break;
 1921                 if (match_boolean(buf, "show_lines=", &show_lines)) {
 1922                     show_lines_or_score = TRUE;
 1923                     break;
 1924                 }
 1925                 /* simple rename */
 1926                 if (match_boolean(buf, "show_only_unread=", &tinrc.show_only_unread_arts))
 1927                     break;
 1928                 if (match_boolean(buf, "show_score=", &show_score)) {
 1929                     show_lines_or_score = TRUE;
 1930                     break;
 1931                 }
 1932                 break;
 1933 
 1934             case 't':
 1935                 if (match_boolean(buf, "tab_goto_next_unread=", &tab_goto_next_unread)) {
 1936                     set_goto_next_unread = TRUE;
 1937                     break;
 1938                 }
 1939                 break;
 1940 
 1941             case 'u':
 1942                 if (match_boolean(buf, "use_builtin_inews=", &use_builtin_inews))
 1943                     break;
 1944                 if (match_boolean(buf, "use_getart_limit=", &use_getart_limit))
 1945                     break;
 1946                 if (match_boolean(buf, "use_mailreader_i=", &use_mailreader_i))
 1947                     break;
 1948                 if (match_boolean(buf, "use_metamail=", &use_metamail))
 1949                     break;
 1950                 break;
 1951 
 1952             default:
 1953                 break;
 1954         }
 1955     }
 1956 
 1957     /* update the values */
 1958     tinrc.auto_cc_bcc = (auto_cc ? 1 : 0) + (auto_bcc ? 2 : 0);
 1959     tinrc.confirm_choice = (confirm_action ? 1 : 0) + (confirm_to_quit ? 3 : 0);
 1960 
 1961     if (!use_getart_limit)
 1962         tinrc.getart_limit = 0;
 1963 
 1964     if (set_goto_next_unread) {
 1965         tinrc.goto_next_unread = 0;
 1966         if (pgdn_goto_next || space_goto_next_unread)
 1967             tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_PGDN;
 1968         if (tab_goto_next_unread)
 1969             tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_TAB;
 1970     }
 1971 
 1972     if (hide_uue)
 1973         tinrc.hide_uue = 1;
 1974 
 1975     if (keep_posted_articles)
 1976         STRCPY(tinrc.posted_articles_file, "posted");
 1977 
 1978     tinrc.quote_style = (compress_quotes ? QUOTE_COMPRESS : 0) + (quote_empty_lines ? QUOTE_EMPTY : 0) + (quote_signatures ? QUOTE_SIGS : 0);
 1979 
 1980     tinrc.mailbox_format = (save_to_mmdf_mailbox ? 2 : 0);
 1981 
 1982     if (show_lines_or_score)
 1983         show_info = (show_lines ? 1 : 0) + (show_score ? 2 : 0);
 1984 
 1985     switch (show_info) {
 1986         case 0:
 1987             STRCPY(tinrc.group_format, "%n %m %R  %s  %F");
 1988             STRCPY(tinrc.thread_format, "%n %m  %T  %F");
 1989             break;
 1990 
 1991         case 2:
 1992             STRCPY(tinrc.group_format, "%n %m %R %S  %s  %F");
 1993             STRCPY(tinrc.thread_format, "%n %m  [%S]  %T  %F");
 1994             break;
 1995 
 1996         case 3:
 1997             STRCPY(tinrc.group_format, "%n %m %R %L %S  %s  %F");
 1998             STRCPY(tinrc.thread_format, "%n %m  [%L,%S]  %T  %F");
 1999             break;
 2000 
 2001         default:
 2002             break;
 2003     }
 2004 
 2005     if (show_last_line_prev_page)
 2006         tinrc.scroll_lines = -1;
 2007 
 2008     if (use_builtin_inews)
 2009         STRCPY(tinrc.inews_prog, INTERNAL_CMD);
 2010 
 2011     if (use_mailreader_i)
 2012         tinrc.interactive_mailer = INTERACTIVE_WITHOUT_HEADERS;
 2013 
 2014     if (!use_metamail || getenv("NOMETAMAIL") != NULL)
 2015         STRCPY(tinrc.metamail_prog, INTERNAL_CMD);
 2016     else
 2017         my_strncpy(tinrc.metamail_prog, METAMAIL_CMD, sizeof(tinrc.metamail_prog) - 1);
 2018 
 2019     rewind(fp);
 2020     return TRUE;
 2021 }
 2022 
 2023 
 2024 /*
 2025  * auto update tinrc
 2026  * called at the end of read_config_file()
 2027  * useful to update variables which are already present in tinrc
 2028  *
 2029  * pass upgrade to this function once we need to exactly check
 2030  * upgrade->file_version, upgrade->current_version
 2031  */
 2032 static t_bool
 2033 rc_post_update(
 2034     FILE *fp
 2035     /* , struct t_version *upgrade */)
 2036 {
 2037     char buf[LEN];
 2038     int groupname_max_length = 0;
 2039 
 2040     if (!fp)
 2041         return FALSE;
 2042 
 2043     rewind(fp);
 2044     while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
 2045         if (buf[0] == '#' || buf[0] == '\n')
 2046             continue;
 2047 
 2048         switch (my_tolower((unsigned char) buf[0])) {
 2049             case 'c':
 2050 #ifdef USE_CANLOCK
 2051                 {
 2052                     t_bool cancel_locks = TRUE;
 2053 
 2054                     if (match_boolean(buf, "cancel_locks=", &cancel_locks)) {
 2055                         if (!cancel_locks)
 2056                             tinrc.cancel_lock_algo = 0;
 2057                         break;
 2058                     }
 2059                 }
 2060 #endif /* USE_CANLOCK */
 2061                 break;
 2062 
 2063             case 'g':
 2064                 if (match_integer(buf, "groupname_max_length=", &groupname_max_length, 132))
 2065                     break;
 2066                 break;
 2067 
 2068             case 's':
 2069                 /*
 2070                  * previous versions has always passed groupname to external
 2071                  * commands, now we look for %G
 2072                  */
 2073                 if (match_string(buf, "sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
 2074                     size_t l = strlen(tinrc.sigfile);
 2075 
 2076                     if (tinrc.sigfile[0] == '!'&& (tinrc.sigfile[l - 2] != '%' || tinrc.sigfile[l - 1] != 'G')) {
 2077                         char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
 2078 
 2079                         sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
 2080                         my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
 2081                         free(newbuf);
 2082                     }
 2083                     break;
 2084                 }
 2085                 break;
 2086 
 2087             default:
 2088                 break;
 2089         }
 2090     }
 2091 
 2092     /* update the values */
 2093     if (groupname_max_length > 0 && groupname_max_length != 32) {
 2094         char length[LEN];
 2095         char *dest, *d, *f, *l;
 2096 
 2097         snprintf(length, sizeof(length), ",%d", groupname_max_length);
 2098 
 2099         d = dest = my_malloc(strlen(tinrc.select_format) + strlen(length) + 1);
 2100         f = tinrc.select_format;
 2101         l = length;
 2102 
 2103         while (*f) {
 2104             if (*f == 'G') {
 2105                 while (*l)
 2106                     *d++ = *l++;
 2107             }
 2108             *d++ = *f++;
 2109         }
 2110         *d = '\0';
 2111         STRCPY(tinrc.select_format, dest);
 2112         free(dest);
 2113     }
 2114 
 2115     return TRUE;
 2116 }
 2117 
 2118 
 2119 void
 2120 read_server_config(
 2121     void)
 2122 {
 2123     FILE *fp;
 2124     char *line;
 2125     char file[PATH_LEN];
 2126     char newnews_info[LEN];
 2127     char serverdir[PATH_LEN];
 2128     struct t_version *upgrade = NULL;
 2129 
 2130 #ifdef NNTP_ABLE
 2131     if (read_news_via_nntp && !read_saved_news && nntp_tcp_port != IPPORT_NNTP)
 2132         snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
 2133     else
 2134 #endif /* NNTP_ABLE */
 2135     {
 2136         STRCPY(file, quote_space_to_dash(nntp_server));
 2137     }
 2138     joinpath(serverdir, sizeof(serverdir), rcdir, file);
 2139     joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
 2140     joinpath(local_newsgroups_file, sizeof(local_newsgroups_file), serverdir, NEWSGROUPS_FILE);
 2141 
 2142     if ((fp = fopen(file, "r")) == NULL)
 2143         return;
 2144 
 2145     while ((line = tin_fgets(fp, FALSE)) != NULL) {
 2146         if ((*line == '#') || (*line == '\0'))
 2147             continue;
 2148 
 2149         if (match_string(line, "last_newnews=", newnews_info, sizeof(newnews_info))) {
 2150             size_t tmp_len = strlen(nntp_server) + strlen(newnews_info) + 2;
 2151             char *tmp_info = my_malloc(tmp_len);
 2152 
 2153             snprintf(tmp_info, tmp_len, "%s %s", nntp_server, newnews_info);
 2154             load_newnews_info(tmp_info);
 2155             free(tmp_info);
 2156             continue;
 2157         }
 2158 
 2159         if (match_string(line, "version=", NULL, 0)) {
 2160             if (upgrade != NULL) /* ignore duplicate version lines; first match counts */
 2161                 continue;
 2162 
 2163             upgrade = check_upgrade(line, "version=", SERVERCONFIG_VERSION);
 2164             if (upgrade->state == RC_IGNORE) /* Expected version number; nothing to do -> continue */
 2165                 continue;
 2166 
 2167             /* Nothing to do yet for RC_UPGRADE and RC_DOWNGRADE */
 2168             continue;
 2169         }
 2170     }
 2171     fclose(fp);
 2172     FreeAndNull(upgrade);
 2173 }
 2174 
 2175 
 2176 static void
 2177 write_server_config(
 2178     void)
 2179 {
 2180     FILE *fp;
 2181     char *file_tmp;
 2182     char file[PATH_LEN];
 2183     char timestring[30];
 2184     char serverdir[PATH_LEN];
 2185     int i;
 2186     struct stat statbuf;
 2187 
 2188     if (read_saved_news)
 2189         /* don't update server files while reading locally stored articles */
 2190         return;
 2191 #ifdef NNTP_ABLE
 2192     if (read_news_via_nntp && nntp_tcp_port != IPPORT_NNTP)
 2193         snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
 2194     else
 2195 #endif /* NNTP_ABLE */
 2196     {
 2197         STRCPY(file, nntp_server);
 2198     }
 2199     joinpath(serverdir, sizeof(serverdir), rcdir, file);
 2200     joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
 2201 
 2202     if ((no_write || post_article_and_exit || post_postponed_and_exit) && file_size(file) != -1L)
 2203         return;
 2204 
 2205     if (stat(serverdir, &statbuf) == -1) {
 2206         if (my_mkdir(serverdir, (mode_t) (S_IRWXU)) == -1)
 2207             /* Can't create directory TODO: Add error handling */
 2208             return;
 2209     }
 2210 
 2211     /* generate tmp-filename */
 2212     file_tmp = get_tmpfilename(file);
 2213 
 2214     if ((fp = fopen(file_tmp, "w")) == NULL) {
 2215         error_message(2, _(txt_filesystem_full_backup), SERVERCONFIG_FILE);
 2216         free(file_tmp);
 2217         return;
 2218     }
 2219 
 2220     fprintf(fp, _(txt_serverconfig_header), PRODUCT, tin_progname, VERSION, RELEASEDATE, RELEASENAME, PRODUCT, PRODUCT);
 2221     fprintf(fp, "version=%s\n", SERVERCONFIG_VERSION);
 2222 
 2223     if ((i = find_newnews_index(nntp_server)) >= 0) {
 2224         if (my_strftime(timestring, sizeof(timestring) - 1, "%Y-%m-%d %H:%M:%S UTC", gmtime(&(newnews[i].time))))
 2225             fprintf(fp, "last_newnews=%lu (%s)\n", (unsigned long int) newnews[i].time, timestring);
 2226     }
 2227 
 2228     fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
 2229 
 2230     if ((i = ferror(fp)) || fclose(fp)) {
 2231         error_message(2, _(txt_filesystem_full), SERVERCONFIG_FILE);
 2232         if (i) {
 2233             clearerr(fp);
 2234             fclose(fp);
 2235         }
 2236     } else
 2237         rename_file(file_tmp, file);
 2238 
 2239     free(file_tmp);
 2240 }