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