"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.6.2/src/config.c" (9 Dec 2022, 69957 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:


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

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