"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.5/src/config.c" (1 Dec 2020, 68426 Bytes) of package /linux/misc/tin-2.4.5.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.4_vs_2.4.5.

    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : config.c
    4  *  Author    : I. Lea
    5  *  Created   : 1991-04-01
    6  *  Updated   : 2020-04-23
    7  *  Notes     : Configuration file routines
    8  *
    9  * Copyright (c) 1991-2021 Iain Lea <iain@bricbrac.de>
   10  * All rights reserved.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  *
   16  * 1. Redistributions of source code must retain the above copyright notice,
   17  *    this list of conditions and the following disclaimer.
   18  *
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  *
   23  * 3. Neither the name of the copyright holder nor the names of its
   24  *    contributors may be used to endorse or promote products derived from
   25  *    this software without specific prior written permission.
   26  *
   27  * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 
   41 #ifndef TIN_H
   42 #   include "tin.h"
   43 #endif /* !TIN_H */
   44 #ifndef VERSION_H
   45 #   include "version.h"
   46 #endif /* !VERSION_H */
   47 #ifndef TCURSES_H
   48 #   include "tcurses.h"
   49 #endif /* !TCURSES_H */
   50 #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 #ifdef HAVE_FCHMOD
 1490     fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
 1491 #else
 1492 #   ifdef HAVE_CHMOD
 1493     chmod(file_tmp, (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
 1494 #   endif /* HAVE_CHMOD */
 1495 #endif /* HAVE_FCHMOD */
 1496 
 1497     if ((i = ferror(fp)) || fclose(fp)) {
 1498         error_message(2, _(txt_filesystem_full), CONFIG_FILE);
 1499         if (i) {
 1500             clearerr(fp);
 1501             fclose(fp);
 1502         }
 1503     } else
 1504         rename_file(file_tmp, file);
 1505 
 1506     free(file_tmp);
 1507     write_server_config();
 1508 }
 1509 
 1510 
 1511 t_bool
 1512 match_boolean(
 1513     char *line,
 1514     const char *pat,
 1515     t_bool *dst)
 1516 {
 1517     size_t patlen = strlen(pat);
 1518 
 1519     if (STRNCASECMPEQ(line, pat, patlen)) {
 1520         *dst = (t_bool) (STRNCASECMPEQ(&line[patlen], "ON", 2) ? TRUE : FALSE);
 1521         return TRUE;
 1522     }
 1523     return FALSE;
 1524 }
 1525 
 1526 
 1527 #ifdef HAVE_COLOR
 1528 static t_bool
 1529 match_color(
 1530     char *line,
 1531     const char *pat,
 1532     int *dst,
 1533     int max)
 1534 {
 1535     size_t patlen = strlen(pat);
 1536 
 1537     if (STRNCMPEQ(line, pat, patlen)) {
 1538         int n;
 1539         t_bool found = FALSE;
 1540 
 1541         for (n = 0; n < MAX_COLOR + 1; n++) {
 1542             if (!strcasecmp(&line[patlen], txt_colors[n])) {
 1543                 found = TRUE;
 1544                 *dst = n;
 1545             }
 1546         }
 1547 
 1548         if (!found)
 1549             *dst = atoi(&line[patlen]);
 1550 
 1551         if (max) {
 1552             if (max == MAX_BACKCOLOR && *dst > max && *dst <= MAX_COLOR)
 1553                 *dst %= MAX_BACKCOLOR + 1;
 1554             else if ((*dst < -1) || (*dst > max)) {
 1555                 my_fprintf(stderr, _(txt_value_out_of_range), pat, *dst, max);
 1556                 *dst = 0;
 1557             }
 1558         } else
 1559             *dst = -1;
 1560         return TRUE;
 1561     }
 1562     return FALSE;
 1563 }
 1564 #endif /* HAVE_COLOR */
 1565 
 1566 
 1567 /*
 1568  * If pat matches the start of line, convert rest of line to an integer, dst
 1569  * If maxval is set, constrain value to 0 <= dst <= maxlen and return TRUE.
 1570  * If no match is made, return FALSE.
 1571  */
 1572 t_bool
 1573 match_integer(
 1574     char *line,
 1575     const char *pat,
 1576     int *dst,
 1577     int maxval)
 1578 {
 1579     size_t patlen = strlen(pat);
 1580 
 1581     if (STRNCMPEQ(line, pat, patlen)) {
 1582         *dst = atoi(&line[patlen]);
 1583 
 1584         if (maxval) {
 1585             if ((*dst < 0) || (*dst > maxval)) {
 1586                 my_fprintf(stderr, _(txt_value_out_of_range), pat, *dst, maxval);
 1587                 *dst = 0;
 1588             }
 1589         }
 1590         return TRUE;
 1591     }
 1592     return FALSE;
 1593 }
 1594 
 1595 
 1596 t_bool
 1597 match_long(
 1598     char *line,
 1599     const char *pat,
 1600     long *dst)
 1601 {
 1602     size_t patlen = strlen(pat);
 1603 
 1604     if (STRNCMPEQ(line, pat, patlen)) {
 1605         *dst = atol(&line[patlen]);
 1606         return TRUE;
 1607     }
 1608     return FALSE;
 1609 }
 1610 
 1611 
 1612 /*
 1613  * If the 'pat' keyword matches, lookup & return an index into the table
 1614  */
 1615 t_bool
 1616 match_list(
 1617     char *line,
 1618     constext *pat,
 1619     constext *const *table,
 1620     int *dst)
 1621 {
 1622     size_t patlen = strlen(pat);
 1623 
 1624     if (STRNCMPEQ(line, pat, patlen)) {
 1625         char temp[LEN];
 1626         size_t n;
 1627 
 1628         line += patlen;
 1629         *dst = 0;   /* default, if no match */
 1630         for (n = 0; table[n] != NULL; n++) {
 1631             if (match_item(line, table[n], temp, sizeof(temp))) {
 1632                 *dst = (int) n;
 1633                 break;
 1634             }
 1635         }
 1636         return TRUE;
 1637     }
 1638     return FALSE;
 1639 }
 1640 
 1641 
 1642 t_bool
 1643 match_string(
 1644     char *line,
 1645     const char *pat,
 1646     char *dst,
 1647     size_t dstlen)
 1648 {
 1649     size_t patlen = strlen(pat);
 1650 
 1651     if (STRNCMPEQ(line, pat, patlen) && (strlen(line) > patlen)) {
 1652         if (dst != NULL && dstlen >= 1)
 1653             my_strncpy(dst, &line[patlen], dstlen - 1);
 1654         return TRUE;
 1655     }
 1656     return FALSE;
 1657 }
 1658 
 1659 
 1660 /* like mach_string() but looks for 100% exact matches */
 1661 static t_bool
 1662 match_item(
 1663     char *line,
 1664     const char *pat,
 1665     char *dst,
 1666     size_t dstlen)
 1667 {
 1668     char *ptr;
 1669     char *nline = my_strdup(line);
 1670     size_t patlen = strlen(pat);
 1671 
 1672     if ((ptr = strchr(nline, '\n')) != NULL) /* terminate on \n */
 1673         *ptr = '\0';
 1674 
 1675     if (!strcasecmp(nline, pat)) {
 1676         if (dst != NULL) {
 1677             strncpy(dst, &nline[patlen], dstlen);
 1678             dst[dstlen ? (dstlen - 1) : 0] = '\0';
 1679         }
 1680         free(nline);
 1681         return TRUE;
 1682     }
 1683     free(nline);
 1684     return FALSE;
 1685 }
 1686 
 1687 
 1688 const char *
 1689 print_boolean(
 1690     t_bool value)
 1691 {
 1692     return txt_onoff[value != FALSE ? 1 : 0];
 1693 }
 1694 
 1695 
 1696 /*
 1697  * convert underlines to spaces in a string
 1698  */
 1699 void
 1700 quote_dash_to_space(
 1701     char *str)
 1702 {
 1703     char *ptr;
 1704 
 1705     for (ptr = str; *ptr; ptr++) {
 1706         if (*ptr == '_')
 1707             *ptr = ' ';
 1708     }
 1709 }
 1710 
 1711 
 1712 /*
 1713  * convert spaces to underlines in a string
 1714  */
 1715 char *
 1716 quote_space_to_dash(
 1717     char *str)
 1718 {
 1719     char *ptr, *dst;
 1720     static char buf[PATH_LEN];
 1721 
 1722     dst = buf;
 1723     for (ptr = str; *ptr; ptr++) {
 1724         if (*ptr == ' ')
 1725             *dst = '_';
 1726         else
 1727             *dst = *ptr;
 1728         dst++;
 1729     }
 1730     *dst = '\0';
 1731 
 1732     return buf;
 1733 }
 1734 
 1735 
 1736 /*
 1737  * Written by: Brad Viviano and Scott Powers (bcv & swp)
 1738  *
 1739  * Takes a 1d string and turns it into a 2d array of strings.
 1740  *
 1741  * Watch out for the frees! You must free(*argv) and then free(argv)!
 1742  * NOTHING ELSE! Do _NOT_ free the individual args of argv.
 1743  */
 1744 char **
 1745 ulBuildArgv(
 1746     char *cmd,
 1747     int *new_argc)
 1748 {
 1749     char **new_argv = NULL;
 1750     char *buf, *tmp;
 1751     int i = 0;
 1752 
 1753     if (!cmd || !*cmd) {
 1754         *new_argc = 0;
 1755         return NULL;
 1756     }
 1757 
 1758     for (tmp = cmd; isspace((int) *tmp); tmp++)
 1759         ;
 1760 
 1761     buf = my_strdup(tmp);
 1762     tmp = buf;
 1763 
 1764     new_argv = my_calloc(1, sizeof(char *));
 1765 
 1766     while (*tmp) {
 1767         if (!isspace((int) *tmp)) { /* found the beginning of a word */
 1768             new_argv[i] = tmp;
 1769             for (; *tmp && !isspace((int) *tmp); tmp++)
 1770                 ;
 1771             if (*tmp) {
 1772                 *tmp = '\0';
 1773                 tmp++;
 1774             }
 1775             i++;
 1776             new_argv = my_realloc(new_argv, ((i + 1) * sizeof(char *)));
 1777             new_argv[i] = NULL;
 1778         } else
 1779             tmp++;
 1780     }
 1781     *new_argc = i;
 1782     return new_argv;
 1783 }
 1784 
 1785 
 1786 /*
 1787  * auto update tinrc
 1788  * called at the beginning of read_config_file()
 1789  */
 1790 static t_bool
 1791 rc_update(
 1792     FILE *fp)
 1793 {
 1794     char buf[LEN];
 1795     int show_info = 1;
 1796     t_bool auto_bcc = FALSE;
 1797     t_bool auto_cc = FALSE;
 1798     t_bool confirm_to_quit = FALSE;
 1799     t_bool confirm_action = FALSE;
 1800     t_bool compress_quotes = FALSE;
 1801     t_bool set_goto_next_unread = FALSE;
 1802     t_bool hide_uue = FALSE;
 1803     t_bool keep_posted_articles = FALSE;
 1804     t_bool pgdn_goto_next = FALSE;
 1805     t_bool quote_empty_lines = FALSE;
 1806     t_bool quote_signatures = FALSE;
 1807     t_bool save_to_mmdf_mailbox = FALSE;
 1808     t_bool show_last_line_prev_page = FALSE;
 1809     t_bool show_lines = FALSE;
 1810     t_bool show_score = FALSE;
 1811     t_bool show_lines_or_score = FALSE;
 1812     t_bool space_goto_next_unread = FALSE;
 1813     t_bool tab_goto_next_unread = FALSE;
 1814     t_bool use_builtin_inews = FALSE;
 1815     t_bool use_getart_limit = FALSE;
 1816     t_bool use_mailreader_i = FALSE;
 1817     t_bool use_metamail = FALSE;
 1818 
 1819     if (!fp)
 1820         return FALSE;
 1821 
 1822     /* rewind(fp); */
 1823     while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
 1824         if (buf[0] == '#' || buf[0] == '\n')
 1825             continue;
 1826 
 1827         switch (my_tolower((unsigned char) buf[0])) {
 1828             case 'a':
 1829                 if (match_boolean(buf, "auto_bcc=", &auto_bcc))
 1830                     break;
 1831 
 1832                 if (match_boolean(buf, "auto_cc=", &auto_cc))
 1833                     break;
 1834                 break;
 1835 
 1836             case 'c':
 1837                 if (match_boolean(buf, "confirm_action=", &confirm_action))
 1838                     break;
 1839                 if (match_boolean(buf, "confirm_to_quit=", &confirm_to_quit))
 1840                     break;
 1841                 if (match_boolean(buf, "compress_quotes=", &compress_quotes))
 1842                     break;
 1843                 break;
 1844 
 1845             case 'd':
 1846                 /* simple rename */
 1847                 if (match_string(buf, "default_editor_format=", tinrc.editor_format, sizeof(tinrc.editor_format)))
 1848                     break;
 1849                 /* simple rename */
 1850                 if (match_string(buf, "default_maildir=", tinrc.maildir, sizeof(tinrc.maildir)))
 1851                     break;
 1852                 /* simple rename */
 1853                 if (match_string(buf, "default_mailer_format=", tinrc.mailer_format, sizeof(tinrc.mailer_format)))
 1854                     break;
 1855                 /* simple rename */
 1856 #ifndef DISABLE_PRINTING
 1857                 if (match_string(buf, "default_printer=", tinrc.printer, sizeof(tinrc.printer)))
 1858                     break;
 1859 #endif /* !DISABLE_PRINTING */
 1860                 /* simple rename */
 1861                 if (match_string(buf, "default_regex_pattern=", tinrc.default_pattern, sizeof(tinrc.default_pattern)))
 1862                     break;
 1863                 /* simple rename */
 1864                 if (match_string(buf, "default_savedir=", tinrc.savedir, sizeof(tinrc.savedir))) {
 1865                     if (tinrc.savedir[0] == '.' && strlen(tinrc.savedir) == 1) {
 1866                         char buff[PATH_LEN];
 1867 
 1868                         get_cwd(buff);
 1869                         my_strncpy(tinrc.savedir, buff, sizeof(tinrc.savedir) - 1);
 1870                     }
 1871                     break;
 1872                 }
 1873                 /* 1. simple rename
 1874                  *
 1875                  * 2. previous versions has always passed groupname to external
 1876                  *    commands, now we look for %G
 1877                  */
 1878                 if (match_string(buf, "default_sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
 1879                     size_t l = strlen(tinrc.sigfile);
 1880 
 1881                     if (tinrc.sigfile[0] == '!' && (tinrc.sigfile[l - 2] != '%' || tinrc.sigfile[l - 1] != 'G')) {
 1882                         char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
 1883 
 1884                         sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
 1885                         my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
 1886                         free(newbuf);
 1887                     }
 1888                     break;
 1889                 }
 1890                 break;
 1891 
 1892             case 'h':
 1893                 if (match_boolean(buf, "hide_uue=", &hide_uue))
 1894                     break;
 1895                 break;
 1896 
 1897             case 'k':
 1898                 if (match_boolean(buf, "keep_posted_articles=", &keep_posted_articles))
 1899                     break;
 1900                 break;
 1901 
 1902             case 'p':
 1903                 if (match_boolean(buf, "pgdn_goto_next=", &pgdn_goto_next)) {
 1904                     set_goto_next_unread = TRUE;
 1905                     break;
 1906                 }
 1907                 break;
 1908 
 1909             case 'q':
 1910                 if (match_boolean(buf, "quote_signatures=", &quote_signatures))
 1911                     break;
 1912                 if (match_boolean(buf, "quote_empty_lines=", &quote_empty_lines))
 1913                     break;
 1914                 break;
 1915 
 1916             case 's':
 1917                 if (match_boolean(buf, "space_goto_next_unread=", &space_goto_next_unread)) {
 1918                     set_goto_next_unread = TRUE;
 1919                     break;
 1920                 }
 1921                 if (match_boolean(buf, "save_to_mmdf_mailbox=", &save_to_mmdf_mailbox))
 1922                     break;
 1923                 if (match_integer(buf, "show_info=", &show_info, 3))
 1924                     break;
 1925                 if (match_boolean(buf, "show_last_line_prev_page=", &show_last_line_prev_page))
 1926                     break;
 1927                 if (match_boolean(buf, "show_lines=", &show_lines)) {
 1928                     show_lines_or_score = TRUE;
 1929                     break;
 1930                 }
 1931                 /* simple rename */
 1932                 if (match_boolean(buf, "show_only_unread=", &tinrc.show_only_unread_arts))
 1933                     break;
 1934                 if (match_boolean(buf, "show_score=", &show_score)) {
 1935                     show_lines_or_score = TRUE;
 1936                     break;
 1937                 }
 1938                 break;
 1939 
 1940             case 't':
 1941                 if (match_boolean(buf, "tab_goto_next_unread=", &tab_goto_next_unread)) {
 1942                     set_goto_next_unread = TRUE;
 1943                     break;
 1944                 }
 1945                 break;
 1946 
 1947             case 'u':
 1948                 if (match_boolean(buf, "use_builtin_inews=", &use_builtin_inews))
 1949                     break;
 1950                 if (match_boolean(buf, "use_getart_limit=", &use_getart_limit))
 1951                     break;
 1952                 if (match_boolean(buf, "use_mailreader_i=", &use_mailreader_i))
 1953                     break;
 1954                 if (match_boolean(buf, "use_metamail=", &use_metamail))
 1955                     break;
 1956                 break;
 1957 
 1958             default:
 1959                 break;
 1960         }
 1961     }
 1962 
 1963     /* update the values */
 1964     tinrc.auto_cc_bcc = (auto_cc ? 1 : 0) + (auto_bcc ? 2 : 0);
 1965     tinrc.confirm_choice = (confirm_action ? 1 : 0) + (confirm_to_quit ? 3 : 0);
 1966 
 1967     if (!use_getart_limit)
 1968         tinrc.getart_limit = 0;
 1969 
 1970     if (set_goto_next_unread) {
 1971         tinrc.goto_next_unread = 0;
 1972         if (pgdn_goto_next || space_goto_next_unread)
 1973             tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_PGDN;
 1974         if (tab_goto_next_unread)
 1975             tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_TAB;
 1976     }
 1977 
 1978     if (hide_uue)
 1979         tinrc.hide_uue = 1;
 1980 
 1981     if (keep_posted_articles)
 1982         STRCPY(tinrc.posted_articles_file, "posted");
 1983 
 1984     tinrc.quote_style = (compress_quotes ? QUOTE_COMPRESS : 0) + (quote_empty_lines ? QUOTE_EMPTY : 0) + (quote_signatures ? QUOTE_SIGS : 0);
 1985 
 1986     tinrc.mailbox_format = (save_to_mmdf_mailbox ? 2 : 0);
 1987 
 1988     if (show_lines_or_score)
 1989         show_info = (show_lines ? 1 : 0) + (show_score ? 2 : 0);
 1990 
 1991     switch (show_info) {
 1992         case 0:
 1993             STRCPY(tinrc.group_format, "%n %m %R  %s  %F");
 1994             STRCPY(tinrc.thread_format, "%n %m  %T  %F");
 1995             break;
 1996 
 1997         case 2:
 1998             STRCPY(tinrc.group_format, "%n %m %R %S  %s  %F");
 1999             STRCPY(tinrc.thread_format, "%n %m  [%S]  %T  %F");
 2000             break;
 2001 
 2002         case 3:
 2003             STRCPY(tinrc.group_format, "%n %m %R %L %S  %s  %F");
 2004             STRCPY(tinrc.thread_format, "%n %m  [%L,%S]  %T  %F");
 2005             break;
 2006 
 2007         default:
 2008             break;
 2009     }
 2010 
 2011     if (show_last_line_prev_page)
 2012         tinrc.scroll_lines = -1;
 2013 
 2014     if (use_builtin_inews)
 2015         STRCPY(tinrc.inews_prog, INTERNAL_CMD);
 2016 
 2017     if (use_mailreader_i)
 2018         tinrc.interactive_mailer = INTERACTIVE_WITHOUT_HEADERS;
 2019 
 2020     if (!use_metamail || getenv("NOMETAMAIL") != NULL)
 2021         STRCPY(tinrc.metamail_prog, INTERNAL_CMD);
 2022     else
 2023         my_strncpy(tinrc.metamail_prog, METAMAIL_CMD, sizeof(tinrc.metamail_prog) - 1);
 2024 
 2025     rewind(fp);
 2026     return TRUE;
 2027 }
 2028 
 2029 
 2030 /*
 2031  * auto update tinrc
 2032  * called at the end of read_config_file()
 2033  * useful to update variables which are already present in tinrc
 2034  *
 2035  * pass upgrade to this function once we need to exactly check
 2036  * upgrade->file_version, upgrade->current_version
 2037  */
 2038 static t_bool
 2039 rc_post_update(
 2040     FILE *fp
 2041     /* , struct t_version *upgrade */)
 2042 {
 2043     char buf[LEN];
 2044     int groupname_max_length = 0;
 2045 
 2046     if (!fp)
 2047         return FALSE;
 2048 
 2049     rewind(fp);
 2050     while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
 2051         if (buf[0] == '#' || buf[0] == '\n')
 2052             continue;
 2053 
 2054         switch (my_tolower((unsigned char) buf[0])) {
 2055             case 'c':
 2056 #ifdef USE_CANLOCK
 2057                 {
 2058                     t_bool cancel_locks = TRUE;
 2059 
 2060                     if (match_boolean(buf, "cancel_locks=", &cancel_locks)) {
 2061                         if (!cancel_locks)
 2062                             tinrc.cancel_lock_algo = 0;
 2063                         break;
 2064                     }
 2065                 }
 2066 #endif /* USE_CANLOCK */
 2067                 break;
 2068 
 2069             case 'g':
 2070                 if (match_integer(buf, "groupname_max_length=", &groupname_max_length, 132))
 2071                     break;
 2072                 break;
 2073 
 2074             case 's':
 2075                 /*
 2076                  * previous versions has always passed groupname to external
 2077                  * commands, now we look for %G
 2078                  */
 2079                 if (match_string(buf, "sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
 2080                     size_t l = strlen(tinrc.sigfile);
 2081 
 2082                     if (tinrc.sigfile[0] == '!' && (tinrc.sigfile[l - 2] != '%' || tinrc.sigfile[l - 1] != 'G')) {
 2083                         char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
 2084 
 2085                         sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
 2086                         my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
 2087                         free(newbuf);
 2088                     }
 2089                     break;
 2090                 }
 2091                 break;
 2092 
 2093             default:
 2094                 break;
 2095         }
 2096     }
 2097 
 2098     /* update the values */
 2099     if (groupname_max_length > 0 && groupname_max_length != 32) {
 2100         char length[LEN];
 2101         char *dest, *d, *f, *l;
 2102 
 2103         snprintf(length, sizeof(length), ",%d", groupname_max_length);
 2104 
 2105         d = dest = my_malloc(strlen(tinrc.select_format) + strlen(length) + 1);
 2106         f = tinrc.select_format;
 2107         l = length;
 2108 
 2109         while (*f) {
 2110             if (*f == 'G') {
 2111                 while (*l)
 2112                     *d++ = *l++;
 2113             }
 2114             *d++ = *f++;
 2115         }
 2116         *d = '\0';
 2117         STRCPY(tinrc.select_format, dest);
 2118         free(dest);
 2119     }
 2120 
 2121     return TRUE;
 2122 }
 2123 
 2124 
 2125 void
 2126 read_server_config(
 2127     void)
 2128 {
 2129     FILE *fp;
 2130     char *line;
 2131     char file[PATH_LEN];
 2132     char newnews_info[LEN];
 2133     char serverdir[PATH_LEN];
 2134     struct t_version *upgrade = NULL;
 2135 
 2136 #ifdef NNTP_ABLE
 2137     if (read_news_via_nntp && !read_saved_news && nntp_tcp_port != IPPORT_NNTP)
 2138         snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
 2139     else
 2140 #endif /* NNTP_ABLE */
 2141     {
 2142         STRCPY(file, quote_space_to_dash(nntp_server));
 2143     }
 2144     joinpath(serverdir, sizeof(serverdir), rcdir, file);
 2145     joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
 2146     joinpath(local_newsgroups_file, sizeof(local_newsgroups_file), serverdir, NEWSGROUPS_FILE);
 2147 
 2148     if ((fp = fopen(file, "r")) == NULL)
 2149         return;
 2150 
 2151     while ((line = tin_fgets(fp, FALSE)) != NULL) {
 2152         if ((*line == '#') || (*line == '\0'))
 2153             continue;
 2154 
 2155         if (match_string(line, "last_newnews=", newnews_info, sizeof(newnews_info))) {
 2156             size_t tmp_len = strlen(nntp_server) + strlen(newnews_info) + 2;
 2157             char *tmp_info = my_malloc(tmp_len);
 2158 
 2159             snprintf(tmp_info, tmp_len, "%s %s", nntp_server, newnews_info);
 2160             load_newnews_info(tmp_info);
 2161             free(tmp_info);
 2162             continue;
 2163         }
 2164 
 2165         if (match_string(line, "version=", NULL, 0)) {
 2166             if (upgrade != NULL) /* ignore duplicate version lines; first match counts */
 2167                 continue;
 2168 
 2169             upgrade = check_upgrade(line, "version=", SERVERCONFIG_VERSION);
 2170             if (upgrade->state == RC_IGNORE) /* Expected version number; nothing to do -> continue */
 2171                 continue;
 2172 
 2173             /* Nothing to do yet for RC_UPGRADE and RC_DOWNGRADE */
 2174             continue;
 2175         }
 2176     }
 2177     fclose(fp);
 2178     FreeAndNull(upgrade);
 2179 }
 2180 
 2181 
 2182 static void
 2183 write_server_config(
 2184     void)
 2185 {
 2186     FILE *fp;
 2187     char *file_tmp;
 2188     char file[PATH_LEN];
 2189     char timestring[30];
 2190     char serverdir[PATH_LEN];
 2191     int i;
 2192     struct stat statbuf;
 2193 
 2194     if (read_saved_news)
 2195         /* don't update server files while reading locally stored articles */
 2196         return;
 2197 #ifdef NNTP_ABLE
 2198     if (read_news_via_nntp && nntp_tcp_port != IPPORT_NNTP)
 2199         snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
 2200     else
 2201 #endif /* NNTP_ABLE */
 2202     {
 2203         STRCPY(file, nntp_server);
 2204     }
 2205     joinpath(serverdir, sizeof(serverdir), rcdir, file);
 2206     joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
 2207 
 2208     if ((no_write || post_article_and_exit || post_postponed_and_exit) && file_size(file) != -1L)
 2209         return;
 2210 
 2211     if (stat(serverdir, &statbuf) == -1) {
 2212         if (my_mkdir(serverdir, (mode_t) (S_IRWXU)) == -1)
 2213             /* Can't create directory TODO: Add error handling */
 2214             return;
 2215     }
 2216 
 2217     /* generate tmp-filename */
 2218     file_tmp = get_tmpfilename(file);
 2219 
 2220     if ((fp = fopen(file_tmp, "w")) == NULL) {
 2221         error_message(2, _(txt_filesystem_full_backup), SERVERCONFIG_FILE);
 2222         free(file_tmp);
 2223         return;
 2224     }
 2225 
 2226     fprintf(fp, _(txt_serverconfig_header), PRODUCT, tin_progname, VERSION, RELEASEDATE, RELEASENAME, PRODUCT, PRODUCT);
 2227     fprintf(fp, "version=%s\n", SERVERCONFIG_VERSION);
 2228 
 2229     if ((i = find_newnews_index(nntp_server)) >= 0) {
 2230         if (my_strftime(timestring, sizeof(timestring) - 1, "%Y-%m-%d %H:%M:%S UTC", gmtime(&(newnews[i].time))))
 2231             fprintf(fp, "last_newnews=%lu (%s)\n", (unsigned long int) newnews[i].time, timestring);
 2232     }
 2233 
 2234 #ifdef HAVE_FCHMOD
 2235     fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
 2236 #else
 2237 #   ifdef HAVE_CHMOD
 2238     chmod(file_tmp, (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
 2239 #   endif /* HAVE_CHMOD */
 2240 #endif /* HAVE_FCHMOD */
 2241 
 2242     if ((i = ferror(fp)) || fclose(fp)) {
 2243         error_message(2, _(txt_filesystem_full), SERVERCONFIG_FILE);
 2244         if (i) {
 2245             clearerr(fp);
 2246             fclose(fp);
 2247         }
 2248     } else
 2249         rename_file(file_tmp, file);
 2250 
 2251     free(file_tmp);
 2252 }