"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.3/src/config.c" (23 Nov 2018, 67466 Bytes) of package /linux/misc/tin-2.4.3.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.2_vs_2.4.3.

    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : config.c
    4  *  Author    : I. Lea
    5  *  Created   : 1991-04-01
    6  *  Updated   : 2018-11-22
    7  *  Notes     : Configuration file routines
    8  *
    9  * Copyright (c) 1991-2019 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     size_t patlen = strlen(pat);
 1635 
 1636     if (STRNCMPEQ(line, pat, patlen) && (strlen(line) > patlen)) {
 1637         if (dst != NULL && dstlen >= 1)
 1638             my_strncpy(dst, &line[patlen], dstlen - 1);
 1639         return TRUE;
 1640     }
 1641     return FALSE;
 1642 }
 1643 
 1644 
 1645 /* like mach_string() but looks for 100% exact matches */
 1646 static t_bool
 1647 match_item(
 1648     char *line,
 1649     const char *pat,
 1650     char *dst,
 1651     size_t dstlen)
 1652 {
 1653     char *ptr;
 1654     char *nline = my_strdup(line);
 1655     size_t patlen = strlen(pat);
 1656 
 1657     if ((ptr = strchr(nline, '\n')) != NULL) /* terminate on \n */
 1658         *ptr = '\0';
 1659 
 1660     if (!strcasecmp(nline, pat)) {
 1661         if (dst != NULL) {
 1662             strncpy(dst, &nline[patlen], dstlen);
 1663             dst[dstlen ? (dstlen - 1) : 0] = '\0';
 1664         }
 1665         free(nline);
 1666         return TRUE;
 1667     }
 1668     free(nline);
 1669     return FALSE;
 1670 }
 1671 
 1672 
 1673 const char *
 1674 print_boolean(
 1675     t_bool value)
 1676 {
 1677     return txt_onoff[value != FALSE ? 1 : 0];
 1678 }
 1679 
 1680 
 1681 /*
 1682  * convert underlines to spaces in a string
 1683  */
 1684 void
 1685 quote_dash_to_space(
 1686     char *str)
 1687 {
 1688     char *ptr;
 1689 
 1690     for (ptr = str; *ptr; ptr++) {
 1691         if (*ptr == '_')
 1692             *ptr = ' ';
 1693     }
 1694 }
 1695 
 1696 
 1697 /*
 1698  * convert spaces to underlines in a string
 1699  */
 1700 char *
 1701 quote_space_to_dash(
 1702     char *str)
 1703 {
 1704     char *ptr, *dst;
 1705     static char buf[PATH_LEN];
 1706 
 1707     dst = buf;
 1708     for (ptr = str; *ptr; ptr++) {
 1709         if (*ptr == ' ')
 1710             *dst = '_';
 1711         else
 1712             *dst = *ptr;
 1713         dst++;
 1714     }
 1715     *dst = '\0';
 1716 
 1717     return buf;
 1718 }
 1719 
 1720 
 1721 /*
 1722  * Written by: Brad Viviano and Scott Powers (bcv & swp)
 1723  *
 1724  * Takes a 1d string and turns it into a 2d array of strings.
 1725  *
 1726  * Watch out for the frees! You must free(*argv) and then free(argv)!
 1727  * NOTHING ELSE! Do _NOT_ free the individual args of argv.
 1728  */
 1729 char **
 1730 ulBuildArgv(
 1731     char *cmd,
 1732     int *new_argc)
 1733 {
 1734     char **new_argv = NULL;
 1735     char *buf, *tmp;
 1736     int i = 0;
 1737 
 1738     if (!cmd || !*cmd) {
 1739         *new_argc = 0;
 1740         return NULL;
 1741     }
 1742 
 1743     for (tmp = cmd; isspace((int) *tmp); tmp++)
 1744         ;
 1745 
 1746     buf = my_strdup(tmp);
 1747     tmp = buf;
 1748 
 1749     new_argv = my_calloc(1, sizeof(char *));
 1750 
 1751     while (*tmp) {
 1752         if (!isspace((int) *tmp)) { /* found the beginning of a word */
 1753             new_argv[i] = tmp;
 1754             for (; *tmp && !isspace((int) *tmp); tmp++)
 1755                 ;
 1756             if (*tmp) {
 1757                 *tmp = '\0';
 1758                 tmp++;
 1759             }
 1760             i++;
 1761             new_argv = my_realloc(new_argv, ((i + 1) * sizeof(char *)));
 1762             new_argv[i] = NULL;
 1763         } else
 1764             tmp++;
 1765     }
 1766     *new_argc = i;
 1767     return new_argv;
 1768 }
 1769 
 1770 
 1771 /*
 1772  * auto update tinrc
 1773  * called at the beginning of read_config_file()
 1774  */
 1775 static t_bool
 1776 rc_update(
 1777     FILE *fp)
 1778 {
 1779     char buf[LEN];
 1780     int show_info = 1;
 1781     t_bool auto_bcc = FALSE;
 1782     t_bool auto_cc = FALSE;
 1783     t_bool confirm_to_quit = FALSE;
 1784     t_bool confirm_action = FALSE;
 1785     t_bool compress_quotes = FALSE;
 1786     t_bool set_goto_next_unread = FALSE;
 1787     t_bool hide_uue = FALSE;
 1788     t_bool keep_posted_articles = FALSE;
 1789     t_bool pgdn_goto_next = FALSE;
 1790     t_bool quote_empty_lines = FALSE;
 1791     t_bool quote_signatures = FALSE;
 1792     t_bool save_to_mmdf_mailbox = FALSE;
 1793     t_bool show_last_line_prev_page = FALSE;
 1794     t_bool show_lines = FALSE;
 1795     t_bool show_score = FALSE;
 1796     t_bool show_lines_or_score = FALSE;
 1797     t_bool space_goto_next_unread = FALSE;
 1798     t_bool tab_goto_next_unread = FALSE;
 1799     t_bool use_builtin_inews = FALSE;
 1800     t_bool use_getart_limit = FALSE;
 1801     t_bool use_mailreader_i = FALSE;
 1802     t_bool use_metamail = FALSE;
 1803 
 1804     if (!fp)
 1805         return FALSE;
 1806 
 1807     /* rewind(fp); */
 1808     while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
 1809         if (buf[0] == '#' || buf[0] == '\n')
 1810             continue;
 1811 
 1812         switch (tolower((unsigned char) buf[0])) {
 1813             case 'a':
 1814                 if (match_boolean(buf, "auto_bcc=", &auto_bcc))
 1815                     break;
 1816 
 1817                 if (match_boolean(buf, "auto_cc=", &auto_cc))
 1818                     break;
 1819                 break;
 1820 
 1821             case 'c':
 1822                 if (match_boolean(buf, "confirm_action=", &confirm_action))
 1823                     break;
 1824                 if (match_boolean(buf, "confirm_to_quit=", &confirm_to_quit))
 1825                     break;
 1826                 if (match_boolean(buf, "compress_quotes=", &compress_quotes))
 1827                     break;
 1828                 break;
 1829 
 1830             case 'd':
 1831                 /* simple rename */
 1832                 if (match_string(buf, "default_editor_format=", tinrc.editor_format, sizeof(tinrc.editor_format)))
 1833                     break;
 1834                 /* simple rename */
 1835                 if (match_string(buf, "default_maildir=", tinrc.maildir, sizeof(tinrc.maildir)))
 1836                     break;
 1837                 /* simple rename */
 1838                 if (match_string(buf, "default_mailer_format=", tinrc.mailer_format, sizeof(tinrc.mailer_format)))
 1839                     break;
 1840                 /* simple rename */
 1841 #ifndef DISABLE_PRINTING
 1842                 if (match_string(buf, "default_printer=", tinrc.printer, sizeof(tinrc.printer)))
 1843                     break;
 1844 #endif /* !DISABLE_PRINTING */
 1845                 /* simple rename */
 1846                 if (match_string(buf, "default_regex_pattern=", tinrc.default_pattern, sizeof(tinrc.default_pattern)))
 1847                     break;
 1848                 /* simple rename */
 1849                 if (match_string(buf, "default_savedir=", tinrc.savedir, sizeof(tinrc.savedir))) {
 1850                     if (tinrc.savedir[0] == '.' && strlen(tinrc.savedir) == 1) {
 1851                         char buff[PATH_LEN];
 1852 
 1853                         get_cwd(buff);
 1854                         my_strncpy(tinrc.savedir, buff, sizeof(tinrc.savedir) - 1);
 1855                     }
 1856                     break;
 1857                 }
 1858                 /* 1. simple rename
 1859                  *
 1860                  * 2. previous versions has always passed groupname to external
 1861                  *    commands, now we look for %G
 1862                  */
 1863                 if (match_string(buf, "default_sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
 1864                     if (tinrc.sigfile[0] == '!') {
 1865                         char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
 1866 
 1867                         sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
 1868                         my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
 1869                         free(newbuf);
 1870                     }
 1871                     break;
 1872                 }
 1873                 break;
 1874 
 1875             case 'h':
 1876                 if (match_boolean(buf, "hide_uue=", &hide_uue))
 1877                     break;
 1878                 break;
 1879 
 1880             case 'k':
 1881                 if (match_boolean(buf, "keep_posted_articles=", &keep_posted_articles))
 1882                     break;
 1883                 break;
 1884 
 1885             case 'p':
 1886                 if (match_boolean(buf, "pgdn_goto_next=", &pgdn_goto_next)) {
 1887                     set_goto_next_unread = TRUE;
 1888                     break;
 1889                 }
 1890                 break;
 1891 
 1892             case 'q':
 1893                 if (match_boolean(buf, "quote_signatures=", &quote_signatures))
 1894                     break;
 1895                 if (match_boolean(buf, "quote_empty_lines=", &quote_empty_lines))
 1896                     break;
 1897                 break;
 1898 
 1899             case 's':
 1900                 if (match_boolean(buf, "space_goto_next_unread=", &space_goto_next_unread)) {
 1901                     set_goto_next_unread = TRUE;
 1902                     break;
 1903                 }
 1904                 if (match_boolean(buf, "save_to_mmdf_mailbox=", &save_to_mmdf_mailbox))
 1905                     break;
 1906                 if (match_integer(buf, "show_info=", &show_info, 3))
 1907                     break;
 1908                 if (match_boolean(buf, "show_last_line_prev_page=", &show_last_line_prev_page))
 1909                     break;
 1910                 if (match_boolean(buf, "show_lines=", &show_lines)) {
 1911                     show_lines_or_score = TRUE;
 1912                     break;
 1913                 }
 1914                 /* simple rename */
 1915                 if (match_boolean(buf, "show_only_unread=", &tinrc.show_only_unread_arts))
 1916                     break;
 1917                 if (match_boolean(buf, "show_score=", &show_score)) {
 1918                     show_lines_or_score = TRUE;
 1919                     break;
 1920                 }
 1921                 break;
 1922 
 1923             case 't':
 1924                 if (match_boolean(buf, "tab_goto_next_unread=", &tab_goto_next_unread)) {
 1925                     set_goto_next_unread = TRUE;
 1926                     break;
 1927                 }
 1928                 break;
 1929 
 1930             case 'u':
 1931                 if (match_boolean(buf, "use_builtin_inews=", &use_builtin_inews))
 1932                     break;
 1933                 if (match_boolean(buf, "use_getart_limit=", &use_getart_limit))
 1934                     break;
 1935                 if (match_boolean(buf, "use_mailreader_i=", &use_mailreader_i))
 1936                     break;
 1937                 if (match_boolean(buf, "use_metamail=", &use_metamail))
 1938                     break;
 1939                 break;
 1940 
 1941             default:
 1942                 break;
 1943         }
 1944     }
 1945 
 1946     /* update the values */
 1947     tinrc.auto_cc_bcc = (auto_cc ? 1 : 0) + (auto_bcc ? 2 : 0);
 1948     tinrc.confirm_choice = (confirm_action ? 1 : 0) + (confirm_to_quit ? 3 : 0);
 1949 
 1950     if (!use_getart_limit)
 1951         tinrc.getart_limit = 0;
 1952 
 1953     if (set_goto_next_unread) {
 1954         tinrc.goto_next_unread = 0;
 1955         if (pgdn_goto_next || space_goto_next_unread)
 1956             tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_PGDN;
 1957         if (tab_goto_next_unread)
 1958             tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_TAB;
 1959     }
 1960 
 1961     if (hide_uue)
 1962         tinrc.hide_uue = 1;
 1963 
 1964     if (keep_posted_articles)
 1965         STRCPY(tinrc.posted_articles_file, "posted");
 1966 
 1967     tinrc.quote_style = (compress_quotes ? QUOTE_COMPRESS : 0) + (quote_empty_lines ? QUOTE_EMPTY : 0) + (quote_signatures ? QUOTE_SIGS : 0);
 1968 
 1969     tinrc.mailbox_format = (save_to_mmdf_mailbox ? 2 : 0);
 1970 
 1971     if (show_lines_or_score)
 1972         show_info = (show_lines ? 1 : 0) + (show_score ? 2 : 0);
 1973 
 1974     switch (show_info) {
 1975         case 0:
 1976             STRCPY(tinrc.group_format, "%n %m %R  %s  %F");
 1977             STRCPY(tinrc.thread_format, "%n %m  %T  %F");
 1978             break;
 1979 
 1980         case 2:
 1981             STRCPY(tinrc.group_format, "%n %m %R %S  %s  %F");
 1982             STRCPY(tinrc.thread_format, "%n %m  [%S]  %T  %F");
 1983             break;
 1984 
 1985         case 3:
 1986             STRCPY(tinrc.group_format, "%n %m %R %L %S  %s  %F");
 1987             STRCPY(tinrc.thread_format, "%n %m  [%L,%S]  %T  %F");
 1988             break;
 1989 
 1990         default:
 1991             break;
 1992     }
 1993 
 1994     if (show_last_line_prev_page)
 1995         tinrc.scroll_lines = -1;
 1996 
 1997     if (use_builtin_inews)
 1998         STRCPY(tinrc.inews_prog, INTERNAL_CMD);
 1999 
 2000     if (use_mailreader_i)
 2001         tinrc.interactive_mailer = INTERACTIVE_WITHOUT_HEADERS;
 2002 
 2003     if (!use_metamail || getenv("NOMETAMAIL") != NULL)
 2004         STRCPY(tinrc.metamail_prog, INTERNAL_CMD);
 2005     else
 2006         my_strncpy(tinrc.metamail_prog, METAMAIL_CMD, sizeof(tinrc.metamail_prog) - 1);
 2007 
 2008     rewind(fp);
 2009     return TRUE;
 2010 }
 2011 
 2012 
 2013 /*
 2014  * auto update tinrc
 2015  * called at the end of read_config_file()
 2016  * useful to update variables which are already present in tinrc
 2017  */
 2018 static t_bool
 2019 rc_post_update(
 2020     FILE *fp)
 2021 {
 2022     char buf[LEN];
 2023     int groupname_max_length = 0;
 2024 
 2025     if (!fp)
 2026         return FALSE;
 2027 
 2028     rewind(fp);
 2029     while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
 2030         if (buf[0] == '#' || buf[0] == '\n')
 2031             continue;
 2032 
 2033         switch (tolower((unsigned char) buf[0])) {
 2034             case 'c':
 2035 #ifdef USE_CANLOCK
 2036                 {
 2037                     t_bool cancel_locks = TRUE;
 2038 
 2039                     if (match_boolean(buf, "cancel_locks=", &cancel_locks)) {
 2040                         if (!cancel_locks)
 2041                             tinrc.cancel_lock_algo = 0;
 2042                         break;
 2043                     }
 2044                 }
 2045 #endif /* USE_CANLOCK */
 2046                 break;
 2047 
 2048             case 'g':
 2049                 if (match_integer(buf, "groupname_max_length=", &groupname_max_length, 132))
 2050                     break;
 2051                 break;
 2052 
 2053             case 's':
 2054                 /*
 2055                  * previous versions has always passed groupname to external
 2056                  * commands, now we look for %G
 2057                  */
 2058                 if (match_string(buf, "sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
 2059                     if (tinrc.sigfile[0] == '!') {
 2060                         char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
 2061 
 2062                         sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
 2063                         my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
 2064                         free(newbuf);
 2065                     }
 2066                     break;
 2067                 }
 2068                 break;
 2069 
 2070             default:
 2071                 break;
 2072         }
 2073     }
 2074 
 2075     /* update the values */
 2076     if (groupname_max_length > 0 && groupname_max_length != 32) {
 2077         char length[LEN];
 2078         char *dest, *d, *f, *l;
 2079 
 2080         snprintf(length, sizeof(length), ",%d", groupname_max_length);
 2081 
 2082         d = dest = my_malloc(strlen(tinrc.select_format) + strlen(length) + 1);
 2083         f = tinrc.select_format;
 2084         l = length;
 2085 
 2086         while (*f) {
 2087             if (*f == 'G') {
 2088                 while (*l)
 2089                     *d++ = *l++;
 2090             }
 2091             *d++ = *f++;
 2092         }
 2093         *d = '\0';
 2094         STRCPY(tinrc.select_format, dest);
 2095         free(dest);
 2096     }
 2097 
 2098     return TRUE;
 2099 }
 2100 
 2101 
 2102 void
 2103 read_server_config(
 2104     void)
 2105 {
 2106     FILE *fp;
 2107     char *line;
 2108     char file[PATH_LEN];
 2109     char newnews_info[LEN];
 2110     char serverdir[PATH_LEN];
 2111     enum rc_state upgrade = RC_CHECK;
 2112 
 2113 #ifdef NNTP_ABLE
 2114     if (read_news_via_nntp && !read_saved_news && nntp_tcp_port != IPPORT_NNTP)
 2115         snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
 2116     else
 2117 #endif /* NNTP_ABLE */
 2118     {
 2119         STRCPY(file, quote_space_to_dash(nntp_server));
 2120     }
 2121     joinpath(serverdir, sizeof(serverdir), rcdir, file);
 2122     joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
 2123     joinpath(local_newsgroups_file, sizeof(local_newsgroups_file), serverdir, NEWSGROUPS_FILE);
 2124     if ((fp = fopen(file, "r")) == NULL)
 2125         return;
 2126     while ((line = tin_fgets(fp, FALSE)) != NULL) {
 2127         if ((*line == '#') || (*line == '\0'))
 2128             continue;
 2129 
 2130         if (match_string(line, "last_newnews=", newnews_info, sizeof(newnews_info))) {
 2131             size_t tmp_len = strlen(nntp_server) + strlen(newnews_info) + 2;
 2132             char *tmp_info = my_malloc(tmp_len);
 2133 
 2134             snprintf(tmp_info, tmp_len, "%s %s", nntp_server, newnews_info);
 2135             load_newnews_info(tmp_info);
 2136             free(tmp_info);
 2137             continue;
 2138         }
 2139         if (match_string(line, "version=", NULL, 0)) {
 2140             if (upgrade != RC_CHECK) /* ignore duplicate version lines; last match counts */
 2141                 continue;
 2142             if ((upgrade = check_upgrade(line, "version=", SERVERCONFIG_VERSION)) == RC_IGNORE) /* Expected version number; nothing to do -> continue */
 2143                 continue;
 2144 
 2145             /* Nothing to do yet for RC_UPGRADE and RC_DOWNGRADE */
 2146             continue;
 2147         }
 2148     }
 2149     fclose(fp);
 2150 }
 2151 
 2152 
 2153 static void
 2154 write_server_config(
 2155     void)
 2156 {
 2157     FILE *fp;
 2158     char *file_tmp;
 2159     char file[PATH_LEN];
 2160     char timestring[30];
 2161     char serverdir[PATH_LEN];
 2162     int i;
 2163     struct stat statbuf;
 2164 
 2165     if (read_saved_news)
 2166         /* don't update server files while reading locally stored articles */
 2167         return;
 2168 #ifdef NNTP_ABLE
 2169     if (read_news_via_nntp && nntp_tcp_port != IPPORT_NNTP)
 2170         snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
 2171     else
 2172 #endif /* NNTP_ABLE */
 2173     {
 2174         STRCPY(file, nntp_server);
 2175     }
 2176     joinpath(serverdir, sizeof(serverdir), rcdir, file);
 2177     joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
 2178 
 2179     if ((no_write || post_article_and_exit || post_postponed_and_exit) && file_size(file) != -1L)
 2180         return;
 2181 
 2182     if (stat(serverdir, &statbuf) == -1) {
 2183         if (my_mkdir(serverdir, (mode_t) (S_IRWXU)) == -1)
 2184             /* Can't create directory TODO: Add error handling */
 2185             return;
 2186     }
 2187 
 2188     /* generate tmp-filename */
 2189     file_tmp = get_tmpfilename(file);
 2190 
 2191     if ((fp = fopen(file_tmp, "w")) == NULL) {
 2192         error_message(2, _(txt_filesystem_full_backup), SERVERCONFIG_FILE);
 2193         free(file_tmp);
 2194         return;
 2195     }
 2196 
 2197     fprintf(fp, _(txt_serverconfig_header), PRODUCT, tin_progname, VERSION, RELEASEDATE, RELEASENAME, PRODUCT, PRODUCT);
 2198     fprintf(fp, "version=%s\n", SERVERCONFIG_VERSION);
 2199 
 2200     if ((i = find_newnews_index(nntp_server)) >= 0)
 2201         if (my_strftime(timestring, sizeof(timestring) - 1, "%Y-%m-%d %H:%M:%S UTC", gmtime(&(newnews[i].time))))
 2202             fprintf(fp, "last_newnews=%lu (%s)\n", (unsigned long int) newnews[i].time, timestring);
 2203 
 2204     fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
 2205 
 2206     if ((i = ferror(fp)) || fclose(fp)) {
 2207         error_message(2, _(txt_filesystem_full), SERVERCONFIG_FILE);
 2208         if (i) {
 2209             clearerr(fp);
 2210             fclose(fp);
 2211         }
 2212     } else
 2213         rename_file(file_tmp, file);
 2214 
 2215     free(file_tmp);
 2216 }