"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.1/src/config.c" (12 Oct 2016, 66196 Bytes) of archive /linux/misc/tin-2.4.1.tar.gz:


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

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