"Fossies" - the Fresh Open Source Software Archive

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


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

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