"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.1/src/config.c" (22 Dec 2021, 68822 Bytes) of package /linux/misc/tin-2.6.1.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.0_vs_2.6.1.
1 /*
2 * Project : tin - a Usenet reader
3 * Module : config.c
4 * Author : I. Lea
5 * Created : 1991-04-01
6 * Updated : 2021-08-05
7 * Notes : Configuration file routines
8 *
9 * Copyright (c) 1991-2022 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_boolean(buf, "show_only_unread_arts=", &tinrc.show_only_unread_arts))
690 break;
691
692 if (match_boolean(buf, "show_only_unread_groups=", &tinrc.show_only_unread_groups))
693 break;
694
695 if (match_boolean(buf, "sigdashes=", &tinrc.sigdashes))
696 break;
697
698 if (match_string(buf, "sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile)))
699 break;
700
701 if (match_boolean(buf, "signature_repost=", &tinrc.signature_repost))
702 break;
703
704 if (match_string(buf, "spamtrap_warning_addresses=", tinrc.spamtrap_warning_addresses, sizeof(tinrc.spamtrap_warning_addresses)))
705 break;
706
707 if (match_integer(buf, "sort_article_type=", &tinrc.sort_article_type, SORT_ARTICLES_BY_LINES_ASCEND))
708 break;
709
710 if (match_integer(buf, "sort_threads_type=", &tinrc.sort_threads_type, SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND))
711 break;
712
713 #ifdef USE_HEAPSORT
714 if (match_integer(buf, "sort_function=", &tinrc.sort_function, MAX_SORT_FUNCS))
715 break;
716 #endif /* USE_HEAPSORT */
717
718 if (match_integer(buf, "scroll_lines=", &tinrc.scroll_lines, 0))
719 break;
720
721 if (match_boolean(buf, "show_signatures=", &tinrc.show_signatures))
722 break;
723
724 if (match_string(buf, "slashes_regex=", tinrc.slashes_regex, sizeof(tinrc.slashes_regex)))
725 break;
726
727 if (match_string(buf, "stars_regex=", tinrc.stars_regex, sizeof(tinrc.stars_regex)))
728 break;
729
730 if (match_string(buf, "strokes_regex=", tinrc.strokes_regex, sizeof(tinrc.strokes_regex)))
731 break;
732
733 #ifndef USE_CURSES
734 if (match_boolean(buf, "strip_blanks=", &tinrc.strip_blanks))
735 break;
736 #endif /* !USE_CURSES */
737
738 if (match_integer(buf, "strip_bogus=", &tinrc.strip_bogus, BOGUS_SHOW))
739 break;
740
741 if (match_boolean(buf, "strip_newsrc=", &tinrc.strip_newsrc))
742 break;
743
744 /* Regexp used to strip "Re: "s and similar */
745 if (match_string(buf, "strip_re_regex=", tinrc.strip_re_regex, sizeof(tinrc.strip_re_regex)))
746 break;
747
748 if (match_string(buf, "strip_was_regex=", tinrc.strip_was_regex, sizeof(tinrc.strip_was_regex)))
749 break;
750
751 break;
752
753 case 't':
754 if (match_integer(buf, "thread_articles=", &tinrc.thread_articles, THREAD_MAX))
755 break;
756
757 if (match_integer(buf, "thread_perc=", &tinrc.thread_perc, 100))
758 break;
759
760 if (match_string(buf, "thread_format=", tinrc.thread_format, sizeof(tinrc.thread_format)))
761 break;
762
763 if (match_integer(buf, "thread_score=", &tinrc.thread_score, THREAD_SCORE_WEIGHT))
764 break;
765
766 if (match_boolean(buf, "tex2iso_conv=", &tinrc.tex2iso_conv))
767 break;
768
769 if (match_boolean(buf, "thread_catchup_on_exit=", &tinrc.thread_catchup_on_exit))
770 break;
771
772 #if defined(HAVE_ICONV_OPEN_TRANSLIT) && defined(CHARSET_CONVERSION)
773 if (match_boolean(buf, "translit=", &tinrc.translit))
774 break;
775 #endif /* HAVE_ICONV_OPEN_TRANSLIT && CHARSET_CONVERSION */
776
777 if (match_integer(buf, "trim_article_body=", &tinrc.trim_article_body, NUM_TRIM_ARTICLE_BODY))
778 break;
779
780 break;
781
782 case 'u':
783 if (match_string(buf, "underscores_regex=", tinrc.underscores_regex, sizeof(tinrc.underscores_regex)))
784 break;
785
786 if (match_boolean(buf, "unlink_article=", &tinrc.unlink_article))
787 break;
788
789 if (match_string(buf, "url_handler=", tinrc.url_handler, sizeof(tinrc.url_handler)))
790 break;
791
792 if (match_boolean(buf, "url_highlight=", &tinrc.url_highlight))
793 break;
794
795 if (match_boolean(buf, "use_mouse=", &tinrc.use_mouse))
796 break;
797
798 #ifdef HAVE_KEYPAD
799 if (match_boolean(buf, "use_keypad=", &tinrc.use_keypad))
800 break;
801 #endif /* HAVE_KEYPAD */
802
803 #ifdef HAVE_COLOR
804 if (match_boolean(buf, "use_color=", &tinrc.use_color)) {
805 use_color = (cmdline.args & CMDLINE_USE_COLOR) ? bool_not(tinrc.use_color) : tinrc.use_color;
806 break;
807 }
808 #endif /* HAVE_COLOR */
809
810 #ifdef XFACE_ABLE
811 if (match_boolean(buf, "use_slrnface=", &tinrc.use_slrnface))
812 break;
813 #endif /* XFACE_ABLE */
814
815 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
816 if (match_boolean(buf, "utf8_graphics=", &tinrc.utf8_graphics)) {
817 /* only enable this when local charset is UTF-8 */
818 tinrc.utf8_graphics = tinrc.utf8_graphics ? IS_LOCAL_CHARSET("UTF-8") : FALSE;
819 break;
820 }
821 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
822
823 break;
824
825 case 'v':
826 if (match_string(buf, "verbatim_begin_regex=", tinrc.verbatim_begin_regex, sizeof(tinrc.verbatim_begin_regex)))
827 break;
828
829 if (match_string(buf, "verbatim_end_regex=", tinrc.verbatim_end_regex, sizeof(tinrc.verbatim_end_regex)))
830 break;
831
832 if (match_boolean(buf, "verbatim_handling=", &tinrc.verbatim_handling))
833 break;
834
835 break;
836
837 case 'w':
838 if (match_integer(buf, "wildcard=", &tinrc.wildcard, 2))
839 break;
840
841 if (match_boolean(buf, "word_highlight=", &tinrc.word_highlight)) {
842 word_highlight = tinrc.word_highlight;
843 break;
844 }
845
846 if (match_integer(buf, "wrap_column=", &tinrc.wrap_column, 0))
847 break;
848
849 if (match_boolean(buf, "wrap_on_next_unread=", &tinrc.wrap_on_next_unread))
850 break;
851
852 if (match_integer(buf, "word_h_display_marks=", &tinrc.word_h_display_marks, MAX_MARK))
853 break;
854
855 break;
856
857 case 'x':
858 if (match_string(buf, "xpost_quote_format=", tinrc.xpost_quote_format, sizeof(tinrc.xpost_quote_format)))
859 break;
860
861 break;
862
863 default:
864 break;
865 }
866 }
867 if (!global_file && upgrade && upgrade->state == RC_UPGRADE)
868 rc_post_update(fp/* , upgrade */);
869
870 FreeAndNull(upgrade);
871 fclose(fp);
872
873 /*
874 * sort out conflicting settings
875 */
876
877 /* nobody likes to navigate blind */
878 if (!(tinrc.draw_arrow || tinrc.inverse_okay))
879 tinrc.draw_arrow = TRUE;
880
881 #ifdef CHARSET_CONVERSION
882 /*
883 * check if we have a 7bit charset but a !7bit encoding
884 * or a 8bit charset but a !8bit encoding, update encoding if needed
885 */
886 is_7bit = FALSE;
887 for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
888 if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
889 is_7bit = TRUE;
890 break;
891 }
892 }
893 if (is_7bit) {
894 tinrc.mail_mime_encoding = tinrc.post_mime_encoding = MIME_ENCODING_7BIT;
895 } else {
896 if (tinrc.mail_mime_encoding == MIME_ENCODING_7BIT)
897 tinrc.mail_mime_encoding = MIME_ENCODING_QP;
898 if (tinrc.post_mime_encoding == MIME_ENCODING_7BIT)
899 tinrc.post_mime_encoding = MIME_ENCODING_8BIT;
900 }
901 #endif /* CHARSET_CONVERSION */
902
903 /* do not use 8 bit headers if mime encoding is not 8bit */
904 if (tinrc.mail_mime_encoding != MIME_ENCODING_8BIT)
905 tinrc.mail_8bit_header = FALSE;
906 if (tinrc.post_mime_encoding != MIME_ENCODING_8BIT)
907 tinrc.post_8bit_header = FALSE;
908
909 /* set defaults if blank */
910 if (!*tinrc.editor_format)
911 STRCPY(tinrc.editor_format, TIN_EDITOR_FMT);
912 if (!*tinrc.select_format)
913 STRCPY(tinrc.select_format, DEFAULT_SELECT_FORMAT);
914 if (!*tinrc.group_format)
915 STRCPY(tinrc.group_format, DEFAULT_GROUP_FORMAT);
916 if (!*tinrc.thread_format)
917 STRCPY(tinrc.thread_format, DEFAULT_THREAD_FORMAT);
918 if (!*tinrc.date_format)
919 STRCPY(tinrc.date_format, DEFAULT_DATE_FORMAT);
920 /* determine local charset */
921 #if defined(NO_LOCALE) && !defined(CHARSET_CONVERSION)
922 strcpy(tinrc.mm_local_charset, tinrc.mm_charset);
923 #endif /* NO_LOCALE && !CHARSET_CONVERSION */
924 return TRUE;
925 }
926
927
928 /*
929 * write config defaults to file
930 */
931 void
932 write_config_file(
933 char *file)
934 {
935 FILE *fp;
936 char *file_tmp;
937 int i;
938
939 if ((no_write || post_article_and_exit || post_postponed_and_exit) && file_size(file) != -1L)
940 return;
941
942 /* generate tmp-filename */
943 file_tmp = get_tmpfilename(file);
944
945 if ((fp = fopen(file_tmp, "w")) == NULL) {
946 error_message(2, _(txt_filesystem_full_backup), CONFIG_FILE);
947 free(file_tmp);
948 return;
949 }
950
951 wait_message(0, _(txt_saving));
952
953 fprintf(fp, txt_tinrc_header, PRODUCT, TINRC_VERSION, tin_progname, VERSION, RELEASEDATE, RELEASENAME);
954
955 fprintf(fp, "%s", _(txt_savedir.tinrc));
956 fprintf(fp, "savedir=%s\n\n", tinrc.savedir);
957
958 fprintf(fp, "%s", _(txt_mark_saved_read.tinrc));
959 fprintf(fp, "mark_saved_read=%s\n\n", print_boolean(tinrc.mark_saved_read));
960
961 fprintf(fp, "%s", _(txt_post_process_type.tinrc));
962 fprintf(fp, "post_process_type=%d\n\n", tinrc.post_process_type);
963
964 fprintf(fp, "%s", _(txt_post_process_view.tinrc));
965 fprintf(fp, "post_process_view=%s\n\n", print_boolean(tinrc.post_process_view));
966
967 fprintf(fp, "%s", _(txt_process_only_unread.tinrc));
968 fprintf(fp, "process_only_unread=%s\n\n", print_boolean(tinrc.process_only_unread));
969
970 fprintf(fp, "%s", _(txt_prompt_followupto.tinrc));
971 fprintf(fp, "prompt_followupto=%s\n\n", print_boolean(tinrc.prompt_followupto));
972
973 fprintf(fp, "%s", _(txt_confirm_choice.tinrc));
974 fprintf(fp, "confirm_choice=%d\n\n", tinrc.confirm_choice);
975
976 fprintf(fp, "%s", _(txt_mark_ignore_tags.tinrc));
977 fprintf(fp, "mark_ignore_tags=%s\n\n", print_boolean(tinrc.mark_ignore_tags));
978
979 fprintf(fp, "%s", _(txt_auto_reconnect.tinrc));
980 fprintf(fp, "auto_reconnect=%s\n\n", print_boolean(tinrc.auto_reconnect));
981
982 fprintf(fp, "%s", _(txt_draw_arrow.tinrc));
983 fprintf(fp, "draw_arrow=%s\n\n", print_boolean(tinrc.draw_arrow));
984
985 fprintf(fp, "%s", _(txt_inverse_okay.tinrc));
986 fprintf(fp, "inverse_okay=%s\n\n", print_boolean(tinrc.inverse_okay));
987
988 fprintf(fp, "%s", _(txt_pos_first_unread.tinrc));
989 fprintf(fp, "pos_first_unread=%s\n\n", print_boolean(tinrc.pos_first_unread));
990
991 fprintf(fp, "%s", _(txt_show_only_unread_arts.tinrc));
992 fprintf(fp, "show_only_unread_arts=%s\n\n", print_boolean(tinrc.show_only_unread_arts));
993
994 fprintf(fp, "%s", _(txt_show_only_unread_groups.tinrc));
995 fprintf(fp, "show_only_unread_groups=%s\n\n", print_boolean(tinrc.show_only_unread_groups));
996
997 fprintf(fp, "%s", _(txt_kill_level.tinrc));
998 fprintf(fp, "kill_level=%d\n\n", tinrc.kill_level);
999
1000 fprintf(fp, "%s", _(txt_goto_next_unread.tinrc));
1001 fprintf(fp, "goto_next_unread=%d\n\n", tinrc.goto_next_unread);
1002
1003 fprintf(fp, "%s", _(txt_scroll_lines.tinrc));
1004 fprintf(fp, "scroll_lines=%d\n\n", tinrc.scroll_lines);
1005
1006 fprintf(fp, "%s", _(txt_catchup_read_groups.tinrc));
1007 fprintf(fp, "catchup_read_groups=%s\n\n", print_boolean(tinrc.catchup_read_groups));
1008
1009 fprintf(fp, "%s", _(txt_group_catchup_on_exit.tinrc));
1010 fprintf(fp, "group_catchup_on_exit=%s\n", print_boolean(tinrc.group_catchup_on_exit));
1011 fprintf(fp, "thread_catchup_on_exit=%s\n\n", print_boolean(tinrc.thread_catchup_on_exit));
1012
1013 fprintf(fp, "%s", _(txt_thread_articles.tinrc));
1014 fprintf(fp, "thread_articles=%d\n\n", tinrc.thread_articles);
1015
1016 fprintf(fp, "%s", _(txt_thread_perc.tinrc));
1017 fprintf(fp, "thread_perc=%d\n\n", tinrc.thread_perc);
1018
1019 fprintf(fp, "%s", _(txt_show_description.tinrc));
1020 fprintf(fp, "show_description=%s\n\n", print_boolean(tinrc.show_description));
1021
1022 fprintf(fp, "%s", _(txt_show_author.tinrc));
1023 fprintf(fp, "show_author=%d\n\n", tinrc.show_author);
1024
1025 fprintf(fp, "%s", _(txt_news_headers_to_display.tinrc));
1026 fprintf(fp, "news_headers_to_display=%s\n\n", tinrc.news_headers_to_display);
1027
1028 fprintf(fp, "%s", _(txt_news_headers_to_not_display.tinrc));
1029 fprintf(fp, "news_headers_to_not_display=%s\n\n", tinrc.news_headers_to_not_display);
1030
1031 fprintf(fp, "%s", _(txt_tinrc_info_in_last_line));
1032 fprintf(fp, "info_in_last_line=%s\n\n", print_boolean(tinrc.info_in_last_line));
1033
1034 fprintf(fp, "%s", _(txt_sort_article_type.tinrc));
1035 fprintf(fp, "sort_article_type=%d\n\n", tinrc.sort_article_type);
1036
1037 fprintf(fp, "%s", _(txt_sort_threads_type.tinrc));
1038 fprintf(fp, "sort_threads_type=%d\n\n", tinrc.sort_threads_type);
1039
1040 #ifdef USE_HEAPSORT
1041 fprintf(fp, "%s", _(txt_sort_function.tinrc));
1042 fprintf(fp, "sort_function=%d\n\n", tinrc.sort_function);
1043 #endif /* USE_HEAPSORT */
1044
1045 fprintf(fp, "%s", _(txt_maildir.tinrc));
1046 fprintf(fp, "maildir=%s\n\n", tinrc.maildir);
1047
1048 fprintf(fp, "%s", _(txt_mailbox_format.tinrc));
1049 fprintf(fp, "mailbox_format=%s\n\n", txt_mailbox_formats[tinrc.mailbox_format]);
1050
1051 #ifndef DISABLE_PRINTING
1052 fprintf(fp, "%s", _(txt_print_header.tinrc));
1053 fprintf(fp, "print_header=%s\n\n", print_boolean(tinrc.print_header));
1054
1055 fprintf(fp, "%s", _(txt_printer.tinrc));
1056 fprintf(fp, "printer=%s\n\n", tinrc.printer);
1057 #endif /* !DISABLE_PRINTING */
1058
1059 fprintf(fp, "%s", _(txt_batch_save.tinrc));
1060 fprintf(fp, "batch_save=%s\n\n", print_boolean(tinrc.batch_save));
1061
1062 fprintf(fp, "%s", _(txt_editor_format.tinrc));
1063 fprintf(fp, "editor_format=%s\n\n", tinrc.editor_format);
1064
1065 fprintf(fp, "%s", _(txt_mailer_format.tinrc));
1066 fprintf(fp, "mailer_format=%s\n\n", tinrc.mailer_format);
1067
1068 fprintf(fp, "%s", _(txt_interactive_mailer.tinrc));
1069 fprintf(fp, "interactive_mailer=%d\n\n", tinrc.interactive_mailer);
1070
1071 fprintf(fp, "%s", _(txt_thread_score.tinrc));
1072 fprintf(fp, "thread_score=%d\n\n", tinrc.thread_score);
1073
1074 fprintf(fp, "%s", _(txt_unlink_article.tinrc));
1075 fprintf(fp, "unlink_article=%s\n\n", print_boolean(tinrc.unlink_article));
1076
1077 fprintf(fp, "%s", _(txt_keep_dead_articles.tinrc));
1078 fprintf(fp, "keep_dead_articles=%s\n\n", print_boolean(tinrc.keep_dead_articles));
1079
1080 fprintf(fp, "%s", _(txt_posted_articles_file.tinrc));
1081 fprintf(fp, "posted_articles_file=%s\n\n", tinrc.posted_articles_file);
1082
1083 fprintf(fp, "%s", _(txt_add_posted_to_filter.tinrc));
1084 fprintf(fp, "add_posted_to_filter=%s\n\n", print_boolean(tinrc.add_posted_to_filter));
1085
1086 fprintf(fp, "%s", _(txt_sigfile.tinrc));
1087 fprintf(fp, "sigfile=%s\n\n", tinrc.sigfile);
1088
1089 fprintf(fp, "%s", _(txt_sigdashes.tinrc));
1090 fprintf(fp, "sigdashes=%s\n\n", print_boolean(tinrc.sigdashes));
1091
1092 fprintf(fp, "%s", _(txt_signature_repost.tinrc));
1093 fprintf(fp, "signature_repost=%s\n\n", print_boolean(tinrc.signature_repost));
1094
1095 fprintf(fp, "%s", _(txt_spamtrap_warning_addresses.tinrc));
1096 fprintf(fp, "spamtrap_warning_addresses=%s\n\n", tinrc.spamtrap_warning_addresses);
1097
1098 fprintf(fp, "%s", _(txt_url_handler.tinrc));
1099 fprintf(fp, "url_handler=%s\n\n", tinrc.url_handler);
1100
1101 fprintf(fp, "%s", _(txt_advertising.tinrc));
1102 fprintf(fp, "advertising=%s\n\n", print_boolean(tinrc.advertising));
1103
1104 fprintf(fp, "%s", _(txt_reread_active_file_secs.tinrc));
1105 fprintf(fp, "reread_active_file_secs=%d\n\n", tinrc.reread_active_file_secs);
1106
1107 #if defined(HAVE_ALARM) && defined(SIGALRM)
1108 fprintf(fp, "%s", _(txt_nntp_read_timeout_secs.tinrc));
1109 fprintf(fp, "nntp_read_timeout_secs=%d\n\n", tinrc.nntp_read_timeout_secs);
1110 #endif /* HAVE_ALARM && SIGALRM */
1111
1112 fprintf(fp, "%s", _(txt_quote_chars.tinrc));
1113 fprintf(fp, "quote_chars=%s\n\n", quote_space_to_dash(tinrc.quote_chars));
1114
1115 fprintf(fp, "%s", _(txt_quote_style.tinrc));
1116 fprintf(fp, "quote_style=%d\n\n", tinrc.quote_style);
1117
1118 #ifdef HAVE_COLOR
1119 fprintf(fp, "%s", _(txt_quote_regex.tinrc));
1120 fprintf(fp, "quote_regex=%s\n\n", tinrc.quote_regex);
1121 fprintf(fp, "%s", _(txt_quote_regex2.tinrc));
1122 fprintf(fp, "quote_regex2=%s\n\n", tinrc.quote_regex2);
1123 fprintf(fp, "%s", _(txt_quote_regex3.tinrc));
1124 fprintf(fp, "quote_regex3=%s\n\n", tinrc.quote_regex3);
1125 #endif /* HAVE_COLOR */
1126
1127 fprintf(fp, "%s", _(txt_slashes_regex.tinrc));
1128 fprintf(fp, "slashes_regex=%s\n\n", tinrc.slashes_regex);
1129 fprintf(fp, "%s", _(txt_stars_regex.tinrc));
1130 fprintf(fp, "stars_regex=%s\n\n", tinrc.stars_regex);
1131 fprintf(fp, "%s", _(txt_strokes_regex.tinrc));
1132 fprintf(fp, "strokes_regex=%s\n\n", tinrc.strokes_regex);
1133 fprintf(fp, "%s", _(txt_underscores_regex.tinrc));
1134 fprintf(fp, "underscores_regex=%s\n\n", tinrc.underscores_regex);
1135
1136 fprintf(fp, "%s", _(txt_strip_re_regex.tinrc));
1137 fprintf(fp, "strip_re_regex=%s\n\n", tinrc.strip_re_regex);
1138 fprintf(fp, "%s", _(txt_strip_was_regex.tinrc));
1139 fprintf(fp, "strip_was_regex=%s\n\n", tinrc.strip_was_regex);
1140
1141 fprintf(fp, "%s", _(txt_verbatim_begin_regex.tinrc));
1142 fprintf(fp, "verbatim_begin_regex=%s\n\n", tinrc.verbatim_begin_regex);
1143 fprintf(fp, "%s", _(txt_verbatim_end_regex.tinrc));
1144 fprintf(fp, "verbatim_end_regex=%s\n\n", tinrc.verbatim_end_regex);
1145
1146 #ifdef HAVE_COLOR
1147 fprintf(fp, "%s", _(txt_extquote_regex.tinrc));
1148 fprintf(fp, "extquote_regex=%s\n\n", tinrc.extquote_regex);
1149 #endif /* HAVE_COLOR */
1150
1151 fprintf(fp, "%s", _(txt_show_signatures.tinrc));
1152 fprintf(fp, "show_signatures=%s\n\n", print_boolean(tinrc.show_signatures));
1153
1154 fprintf(fp, "%s", _(txt_tex2iso_conv.tinrc));
1155 fprintf(fp, "tex2iso_conv=%s\n\n", print_boolean(tinrc.tex2iso_conv));
1156
1157 fprintf(fp, "%s", _(txt_hide_uue.tinrc));
1158 fprintf(fp, "hide_uue=%d\n\n", tinrc.hide_uue);
1159
1160 fprintf(fp, "%s", _(txt_news_quote_format.tinrc));
1161 fprintf(fp, "news_quote_format=%s\n", tinrc.news_quote_format);
1162 fprintf(fp, "mail_quote_format=%s\n", tinrc.mail_quote_format);
1163 fprintf(fp, "xpost_quote_format=%s\n\n", tinrc.xpost_quote_format);
1164
1165 fprintf(fp, "%s", _(txt_auto_cc_bcc.tinrc));
1166 fprintf(fp, "auto_cc_bcc=%d\n\n", tinrc.auto_cc_bcc);
1167
1168 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
1169 fprintf(fp, "%s", _(txt_utf8_graphics.tinrc));
1170 fprintf(fp, "utf8_graphics=%s\n\n", print_boolean(tinrc.utf8_graphics));
1171 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
1172
1173 fprintf(fp, "%s", _(txt_art_marked_deleted.tinrc));
1174 fprintf(fp, "art_marked_deleted=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_deleted));
1175
1176 fprintf(fp, "%s", _(txt_art_marked_inrange.tinrc));
1177 fprintf(fp, "art_marked_inrange=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_inrange));
1178
1179 fprintf(fp, "%s", _(txt_art_marked_return.tinrc));
1180 fprintf(fp, "art_marked_return=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_return));
1181
1182 fprintf(fp, "%s", _(txt_art_marked_selected.tinrc));
1183 fprintf(fp, "art_marked_selected=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_selected));
1184
1185 fprintf(fp, "%s", _(txt_art_marked_recent.tinrc));
1186 fprintf(fp, "art_marked_recent=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_recent));
1187
1188 fprintf(fp, "%s", _(txt_art_marked_unread.tinrc));
1189 fprintf(fp, "art_marked_unread=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_unread));
1190
1191 fprintf(fp, "%s", _(txt_art_marked_read.tinrc));
1192 fprintf(fp, "art_marked_read=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_read));
1193
1194 fprintf(fp, "%s", _(txt_art_marked_killed.tinrc));
1195 fprintf(fp, "art_marked_killed=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_killed));
1196
1197 fprintf(fp, "%s", _(txt_art_marked_read_selected.tinrc));
1198 fprintf(fp, "art_marked_read_selected=%"T_CHAR_FMT"\n\n", SPACE_TO_DASH(tinrc.art_marked_read_selected));
1199
1200 fprintf(fp, "%s", _(txt_force_screen_redraw.tinrc));
1201 fprintf(fp, "force_screen_redraw=%s\n\n", print_boolean(tinrc.force_screen_redraw));
1202
1203 fprintf(fp, "%s", _(txt_inews_prog.tinrc));
1204 fprintf(fp, "inews_prog=%s\n\n", tinrc.inews_prog);
1205
1206 #ifdef USE_CANLOCK
1207 fprintf(fp, "%s", _(txt_cancel_lock_algo.tinrc));
1208 fprintf(fp, "cancel_lock_algo=%s\n\n", txt_cancel_lock_algos[tinrc.cancel_lock_algo]);
1209 #endif /* USE_CANLOCK */
1210
1211 fprintf(fp, "%s", _(txt_auto_list_thread.tinrc));
1212 fprintf(fp, "auto_list_thread=%s\n\n", print_boolean(tinrc.auto_list_thread));
1213
1214 fprintf(fp, "%s", _(txt_wrap_on_next_unread.tinrc));
1215 fprintf(fp, "wrap_on_next_unread=%s\n\n", print_boolean(tinrc.wrap_on_next_unread));
1216
1217 fprintf(fp, "%s", _(txt_use_mouse.tinrc));
1218 fprintf(fp, "use_mouse=%s\n\n", print_boolean(tinrc.use_mouse));
1219
1220 #ifndef USE_CURSES
1221 fprintf(fp, "%s", _(txt_strip_blanks.tinrc));
1222 fprintf(fp, "strip_blanks=%s\n\n", print_boolean(tinrc.strip_blanks));
1223 #endif /* !USE_CURSES */
1224
1225 fprintf(fp, "%s", _(txt_abbreviate_groupname.tinrc));
1226 fprintf(fp, "abbreviate_groupname=%s\n\n", print_boolean(tinrc.abbreviate_groupname));
1227
1228 fprintf(fp, "%s", _(txt_beginner_level.tinrc));
1229 fprintf(fp, "beginner_level=%s\n\n", print_boolean(tinrc.beginner_level));
1230
1231 fprintf(fp, "%s", _(txt_filter_days.tinrc));
1232 fprintf(fp, "default_filter_days=%d\n\n", tinrc.filter_days);
1233
1234 fprintf(fp, "%s", _(txt_cache_overview_files.tinrc));
1235 fprintf(fp, "cache_overview_files=%s\n\n", print_boolean(tinrc.cache_overview_files));
1236
1237 fprintf(fp, "%s", _(txt_getart_limit.tinrc));
1238 fprintf(fp, "getart_limit=%d\n\n", tinrc.getart_limit);
1239
1240 fprintf(fp, "%s", _(txt_recent_time.tinrc));
1241 fprintf(fp, "recent_time=%d\n\n", tinrc.recent_time);
1242
1243 fprintf(fp, "%s", _(txt_score_limit_kill.tinrc));
1244 fprintf(fp, "score_limit_kill=%d\n\n", tinrc.score_limit_kill);
1245
1246 fprintf(fp, "%s", _(txt_score_kill.tinrc));
1247 fprintf(fp, "score_kill=%d\n\n", tinrc.score_kill);
1248
1249 fprintf(fp, "%s", _(txt_score_limit_select.tinrc));
1250 fprintf(fp, "score_limit_select=%d\n\n", tinrc.score_limit_select);
1251
1252 fprintf(fp, "%s", _(txt_score_select.tinrc));
1253 fprintf(fp, "score_select=%d\n\n", tinrc.score_select);
1254
1255 #ifdef HAVE_COLOR
1256 fprintf(fp, "%s", _(txt_use_color.tinrc));
1257 fprintf(fp, "use_color=%s\n\n", print_boolean(tinrc.use_color));
1258
1259 fprintf(fp, "%s", _(txt_tinrc_colors));
1260
1261 fprintf(fp, "%s", _(txt_col_normal.tinrc));
1262 fprintf(fp, "col_normal=%d\n\n", tinrc.col_normal);
1263
1264 fprintf(fp, "%s", _(txt_col_back.tinrc));
1265 fprintf(fp, "col_back=%d\n\n", tinrc.col_back);
1266
1267 fprintf(fp, "%s", _(txt_col_invers_bg.tinrc));
1268 fprintf(fp, "col_invers_bg=%d\n\n", tinrc.col_invers_bg);
1269
1270 fprintf(fp, "%s", _(txt_col_invers_fg.tinrc));
1271 fprintf(fp, "col_invers_fg=%d\n\n", tinrc.col_invers_fg);
1272
1273 fprintf(fp, "%s", _(txt_col_text.tinrc));
1274 fprintf(fp, "col_text=%d\n\n", tinrc.col_text);
1275
1276 fprintf(fp, "%s", _(txt_col_minihelp.tinrc));
1277 fprintf(fp, "col_minihelp=%d\n\n", tinrc.col_minihelp);
1278
1279 fprintf(fp, "%s", _(txt_col_help.tinrc));
1280 fprintf(fp, "col_help=%d\n\n", tinrc.col_help);
1281
1282 fprintf(fp, "%s", _(txt_col_message.tinrc));
1283 fprintf(fp, "col_message=%d\n\n", tinrc.col_message);
1284
1285 fprintf(fp, "%s", _(txt_col_quote.tinrc));
1286 fprintf(fp, "col_quote=%d\n\n", tinrc.col_quote);
1287
1288 fprintf(fp, "%s", _(txt_col_quote2.tinrc));
1289 fprintf(fp, "col_quote2=%d\n\n", tinrc.col_quote2);
1290
1291 fprintf(fp, "%s", _(txt_col_quote3.tinrc));
1292 fprintf(fp, "col_quote3=%d\n\n", tinrc.col_quote3);
1293
1294 fprintf(fp, "%s", _(txt_col_head.tinrc));
1295 fprintf(fp, "col_head=%d\n\n", tinrc.col_head);
1296
1297 fprintf(fp, "%s", _(txt_col_newsheaders.tinrc));
1298 fprintf(fp, "col_newsheaders=%d\n\n", tinrc.col_newsheaders);
1299
1300 fprintf(fp, "%s", _(txt_col_subject.tinrc));
1301 fprintf(fp, "col_subject=%d\n\n", tinrc.col_subject);
1302
1303 fprintf(fp, "%s", _(txt_col_extquote.tinrc));
1304 fprintf(fp, "col_extquote=%d\n\n", tinrc.col_extquote);
1305
1306 fprintf(fp, "%s", _(txt_col_response.tinrc));
1307 fprintf(fp, "col_response=%d\n\n", tinrc.col_response);
1308
1309 fprintf(fp, "%s", _(txt_col_from.tinrc));
1310 fprintf(fp, "col_from=%d\n\n", tinrc.col_from);
1311
1312 fprintf(fp, "%s", _(txt_col_title.tinrc));
1313 fprintf(fp, "col_title=%d\n\n", tinrc.col_title);
1314
1315 fprintf(fp, "%s", _(txt_col_signature.tinrc));
1316 fprintf(fp, "col_signature=%d\n\n", tinrc.col_signature);
1317
1318 fprintf(fp, "%s", _(txt_col_urls.tinrc));
1319 fprintf(fp, "col_urls=%d\n\n", tinrc.col_urls);
1320
1321 fprintf(fp, "%s", _(txt_col_verbatim.tinrc));
1322 fprintf(fp, "col_verbatim=%d\n\n", tinrc.col_verbatim);
1323 #endif /* HAVE_COLOR */
1324
1325 fprintf(fp, "%s", _(txt_url_highlight.tinrc));
1326 fprintf(fp, "url_highlight=%s\n\n", print_boolean(tinrc.url_highlight));
1327
1328 fprintf(fp, "%s", _(txt_word_highlight.tinrc));
1329 fprintf(fp, "word_highlight=%s\n\n", print_boolean(tinrc.word_highlight));
1330
1331 fprintf(fp, "%s", _(txt_word_h_display_marks.tinrc));
1332 fprintf(fp, "word_h_display_marks=%d\n\n", tinrc.word_h_display_marks);
1333
1334 #ifdef HAVE_COLOR
1335 fprintf(fp, "%s", _(txt_col_markstar.tinrc));
1336 fprintf(fp, "col_markstar=%d\n\n", tinrc.col_markstar);
1337 fprintf(fp, "%s", _(txt_col_markdash.tinrc));
1338 fprintf(fp, "col_markdash=%d\n\n", tinrc.col_markdash);
1339 fprintf(fp, "%s", _(txt_col_markslash.tinrc));
1340 fprintf(fp, "col_markslash=%d\n\n", tinrc.col_markslash);
1341 fprintf(fp, "%s", _(txt_col_markstroke.tinrc));
1342 fprintf(fp, "col_markstroke=%d\n\n", tinrc.col_markstroke);
1343 #endif /* HAVE_COLOR */
1344
1345 fprintf(fp, "%s", _(txt_mono_markstar.tinrc));
1346 fprintf(fp, "mono_markstar=%d\n\n", tinrc.mono_markstar);
1347 fprintf(fp, "%s", _(txt_mono_markdash.tinrc));
1348 fprintf(fp, "mono_markdash=%d\n\n", tinrc.mono_markdash);
1349 fprintf(fp, "%s", _(txt_mono_markslash.tinrc));
1350 fprintf(fp, "mono_markslash=%d\n\n", tinrc.mono_markslash);
1351 fprintf(fp, "%s", _(txt_mono_markstroke.tinrc));
1352 fprintf(fp, "mono_markstroke=%d\n\n", tinrc.mono_markstroke);
1353
1354 fprintf(fp, "%s", _(txt_mail_address.tinrc));
1355 fprintf(fp, "mail_address=%s\n\n", tinrc.mail_address);
1356
1357 #ifdef XFACE_ABLE
1358 fprintf(fp, "%s", _(txt_use_slrnface.tinrc));
1359 fprintf(fp, "use_slrnface=%s\n\n", print_boolean(tinrc.use_slrnface));
1360 #endif /* XFACE_ABLE */
1361
1362 fprintf(fp, "%s", _(txt_wrap_column.tinrc));
1363 fprintf(fp, "wrap_column=%d\n\n", tinrc.wrap_column);
1364
1365 fprintf(fp, "%s", _(txt_trim_article_body.tinrc));
1366 fprintf(fp, "trim_article_body=%d\n\n", tinrc.trim_article_body);
1367
1368 #ifndef CHARSET_CONVERSION
1369 fprintf(fp, "%s", _(txt_mm_charset.tinrc));
1370 fprintf(fp, "mm_charset=%s\n\n", tinrc.mm_charset);
1371 #else
1372 fprintf(fp, "%s", _(txt_mm_network_charset.tinrc));
1373 fprintf(fp, "mm_network_charset=%s\n\n", txt_mime_charsets[tinrc.mm_network_charset]);
1374
1375 # ifdef NO_LOCALE
1376 fprintf(fp, "%s", _(txt_mm_local_charset.tinrc));
1377 fprintf(fp, "mm_local_charset=%s\n\n", tinrc.mm_local_charset);
1378 # endif /* NO_LOCALE */
1379 # ifdef HAVE_ICONV_OPEN_TRANSLIT
1380 fprintf(fp, "%s", _(txt_translit.tinrc));
1381 fprintf(fp, "translit=%s\n\n", print_boolean(tinrc.translit));
1382 # endif /* HAVE_ICONV_OPEN_TRANSLIT */
1383 #endif /* !CHARSET_CONVERSION */
1384
1385 fprintf(fp, "%s", _(txt_post_mime_encoding.tinrc));
1386 fprintf(fp, "post_mime_encoding=%s\n", txt_mime_encodings[tinrc.post_mime_encoding]);
1387 fprintf(fp, "mail_mime_encoding=%s\n\n", txt_mime_encodings[tinrc.mail_mime_encoding]);
1388
1389 fprintf(fp, "%s", _(txt_post_8bit_header.tinrc));
1390 fprintf(fp, "post_8bit_header=%s\n\n", print_boolean(tinrc.post_8bit_header));
1391
1392 fprintf(fp, "%s", _(txt_mail_8bit_header.tinrc));
1393 fprintf(fp, "mail_8bit_header=%s\n\n", print_boolean(tinrc.mail_8bit_header));
1394
1395 fprintf(fp, "%s", _(txt_metamail_prog.tinrc));
1396 fprintf(fp, "metamail_prog=%s\n\n", tinrc.metamail_prog);
1397
1398 fprintf(fp, "%s", _(txt_ask_for_metamail.tinrc));
1399 fprintf(fp, "ask_for_metamail=%s\n\n", print_boolean(tinrc.ask_for_metamail));
1400
1401 #ifdef HAVE_KEYPAD
1402 fprintf(fp, "%s", _(txt_use_keypad.tinrc));
1403 fprintf(fp, "use_keypad=%s\n\n", print_boolean(tinrc.use_keypad));
1404 #endif /* HAVE_KEYPAD */
1405
1406 fprintf(fp, "%s", _(txt_alternative_handling.tinrc));
1407 fprintf(fp, "alternative_handling=%s\n\n", print_boolean(tinrc.alternative_handling));
1408
1409 fprintf(fp, "%s", _(txt_verbatim_handling.tinrc));
1410 fprintf(fp, "verbatim_handling=%s\n\n", print_boolean(tinrc.verbatim_handling));
1411
1412 #ifdef HAVE_COLOR
1413 fprintf(fp, "%s", _(txt_extquote_handling.tinrc));
1414 fprintf(fp, "extquote_handling=%s\n\n", print_boolean(tinrc.extquote_handling));
1415 #endif /* HAVE_COLOR */
1416
1417 fprintf(fp, "%s", _(txt_strip_newsrc.tinrc));
1418 fprintf(fp, "strip_newsrc=%s\n\n", print_boolean(tinrc.strip_newsrc));
1419
1420 fprintf(fp, "%s", _(txt_strip_bogus.tinrc));
1421 fprintf(fp, "strip_bogus=%d\n\n", tinrc.strip_bogus);
1422
1423 fprintf(fp, "%s", _(txt_select_format.tinrc));
1424 fprintf(fp, "select_format=%s\n\n", tinrc.select_format);
1425
1426 fprintf(fp, "%s", _(txt_group_format.tinrc));
1427 fprintf(fp, "group_format=%s\n\n", tinrc.group_format);
1428
1429 fprintf(fp, "%s", _(txt_thread_format.tinrc));
1430 fprintf(fp, "thread_format=%s\n\n", tinrc.thread_format);
1431
1432 fprintf(fp, "%s", _(txt_date_format.tinrc));
1433 fprintf(fp, "date_format=%s\n\n", tinrc.date_format);
1434
1435 fprintf(fp, "%s", _(txt_wildcard.tinrc));
1436 fprintf(fp, "wildcard=%d\n\n", tinrc.wildcard);
1437
1438 #ifdef HAVE_UNICODE_NORMALIZATION
1439 fprintf(fp, "%s", _(txt_normalization_form.tinrc));
1440 fprintf(fp, "normalization_form=%d\n\n", tinrc.normalization_form);
1441 #endif /* HAVE_UNICODE_NORMALIZATION */
1442
1443 #if defined(HAVE_LIBICUUC) && defined(MULTIBYTE_ABLE) && defined(HAVE_UNICODE_UBIDI_H) && !defined(NO_LOCALE)
1444 fprintf(fp, "%s", _(txt_render_bidi.tinrc));
1445 fprintf(fp, "render_bidi=%s\n\n", print_boolean(tinrc.render_bidi));
1446 #endif /* HAVE_LIBICUUC && MULTIBYTE_ABLE && HAVE_UNICODE_UBIDI_H && !NO_LOCALE */
1447
1448 fprintf(fp, "%s", _(txt_tinrc_filter));
1449 fprintf(fp, "default_filter_kill_header=%d\n", tinrc.default_filter_kill_header);
1450 fprintf(fp, "default_filter_kill_global=%s\n", print_boolean(tinrc.default_filter_kill_global));
1451 fprintf(fp, "default_filter_kill_case=%s\n", print_boolean(tinrc.default_filter_kill_case));
1452 fprintf(fp, "default_filter_kill_expire=%s\n", print_boolean(tinrc.default_filter_kill_expire));
1453 fprintf(fp, "default_filter_select_header=%d\n", tinrc.default_filter_select_header);
1454 fprintf(fp, "default_filter_select_global=%s\n", print_boolean(tinrc.default_filter_select_global));
1455 fprintf(fp, "default_filter_select_case=%s\n", print_boolean(tinrc.default_filter_select_case));
1456 fprintf(fp, "default_filter_select_expire=%s\n\n", print_boolean(tinrc.default_filter_select_expire));
1457
1458 fprintf(fp, "%s", _(txt_tinrc_defaults));
1459 fprintf(fp, "default_save_mode=%c\n", tinrc.default_save_mode);
1460 fprintf(fp, "default_author_search=%s\n", tinrc.default_search_author);
1461 fprintf(fp, "default_goto_group=%s\n", tinrc.default_goto_group);
1462 fprintf(fp, "default_config_search=%s\n", tinrc.default_search_config);
1463 fprintf(fp, "default_group_search=%s\n", tinrc.default_search_group);
1464 fprintf(fp, "default_subject_search=%s\n", tinrc.default_search_subject);
1465 fprintf(fp, "default_art_search=%s\n", tinrc.default_search_art);
1466 fprintf(fp, "default_repost_group=%s\n", tinrc.default_repost_group);
1467 fprintf(fp, "default_mail_address=%s\n", tinrc.default_mail_address);
1468 fprintf(fp, "default_move_group=%d\n", tinrc.default_move_group);
1469 #ifndef DONT_HAVE_PIPING
1470 fprintf(fp, "default_pipe_command=%s\n", tinrc.default_pipe_command);
1471 #endif /* !DONT_HAVE_PIPING */
1472 fprintf(fp, "default_post_newsgroups=%s\n", tinrc.default_post_newsgroups);
1473 fprintf(fp, "default_post_subject=%s\n", tinrc.default_post_subject);
1474 fprintf(fp, "default_range_group=%s\n", tinrc.default_range_group);
1475 fprintf(fp, "default_range_select=%s\n", tinrc.default_range_select);
1476 fprintf(fp, "default_range_thread=%s\n", tinrc.default_range_thread);
1477 fprintf(fp, "default_pattern=%s\n", tinrc.default_pattern);
1478 fprintf(fp, "default_save_file=%s\n", tinrc.default_save_file);
1479 fprintf(fp, "default_select_pattern=%s\n", tinrc.default_select_pattern);
1480 fprintf(fp, "default_shell_command=%s\n\n", tinrc.default_shell_command);
1481
1482 fprintf(fp, "%s", _(txt_tinrc_newnews));
1483 {
1484 char timestring[30];
1485 int j = find_newnews_index(nntp_server);
1486
1487 /*
1488 * Newnews timestamps in tinrc are bogus as of tin 1.5.19 because they
1489 * are now stored in a separate file to prevent overwriting them from
1490 * another instance running concurrently. Except for the current server,
1491 * however, we must remember them because otherwise we would lose them
1492 * after the first start of a tin 1.5.19 (or later) version.
1493 */
1494 for (i = 0; i < num_newnews; i++) {
1495 if (i == j)
1496 continue;
1497 if (my_strftime(timestring, sizeof(timestring) - 1, "%Y-%m-%d %H:%M:%S UTC", gmtime(&(newnews[i].time))))
1498 fprintf(fp, "newnews=%s %lu (%s)\n", newnews[i].host, (unsigned long int) newnews[i].time, timestring);
1499 }
1500 }
1501
1502 #ifdef HAVE_FCHMOD
1503 fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
1504 #else
1505 # ifdef HAVE_CHMOD
1506 chmod(file_tmp, (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
1507 # endif /* HAVE_CHMOD */
1508 #endif /* HAVE_FCHMOD */
1509
1510 if ((i = ferror(fp)) || fclose(fp)) {
1511 error_message(2, _(txt_filesystem_full), CONFIG_FILE);
1512 if (i) {
1513 clearerr(fp);
1514 fclose(fp);
1515 }
1516 } else
1517 rename_file(file_tmp, file);
1518
1519 free(file_tmp);
1520 write_server_config();
1521 }
1522
1523
1524 t_bool
1525 match_boolean(
1526 char *line,
1527 const char *pat,
1528 t_bool *dst)
1529 {
1530 size_t patlen = strlen(pat);
1531
1532 if (STRNCASECMPEQ(line, pat, patlen)) {
1533 *dst = (t_bool) (STRNCASECMPEQ(&line[patlen], "ON", 2) ? TRUE : FALSE);
1534 return TRUE;
1535 }
1536 return FALSE;
1537 }
1538
1539
1540 #ifdef HAVE_COLOR
1541 static t_bool
1542 match_color(
1543 char *line,
1544 const char *pat,
1545 int *dst,
1546 int max)
1547 {
1548 size_t patlen = strlen(pat);
1549
1550 if (STRNCMPEQ(line, pat, patlen)) {
1551 int n;
1552 t_bool found = FALSE;
1553
1554 for (n = 0; n < MAX_COLOR + 1; n++) {
1555 if (!strcasecmp(&line[patlen], txt_colors[n])) {
1556 found = TRUE;
1557 *dst = n;
1558 }
1559 }
1560
1561 if (!found)
1562 *dst = atoi(&line[patlen]);
1563
1564 if (max) {
1565 if (max == MAX_BACKCOLOR && *dst > max && *dst <= MAX_COLOR)
1566 *dst %= MAX_BACKCOLOR + 1;
1567 else if ((*dst < -1) || (*dst > max)) {
1568 my_fprintf(stderr, _(txt_value_out_of_range), pat, *dst, max);
1569 *dst = 0;
1570 }
1571 } else
1572 *dst = -1;
1573 return TRUE;
1574 }
1575 return FALSE;
1576 }
1577 #endif /* HAVE_COLOR */
1578
1579
1580 /*
1581 * If pat matches the start of line, convert rest of line to an integer, dst
1582 * If maxval is set, constrain value to 0 <= dst <= maxlen and return TRUE.
1583 * If no match is made, return FALSE.
1584 */
1585 t_bool
1586 match_integer(
1587 char *line,
1588 const char *pat,
1589 int *dst,
1590 int maxval)
1591 {
1592 size_t patlen = strlen(pat);
1593
1594 if (STRNCMPEQ(line, pat, patlen)) {
1595 *dst = atoi(&line[patlen]);
1596
1597 if (maxval) {
1598 if ((*dst < 0) || (*dst > maxval)) {
1599 my_fprintf(stderr, _(txt_value_out_of_range), pat, *dst, maxval);
1600 *dst = 0;
1601 }
1602 }
1603 return TRUE;
1604 }
1605 return FALSE;
1606 }
1607
1608
1609 t_bool
1610 match_long(
1611 char *line,
1612 const char *pat,
1613 long *dst)
1614 {
1615 size_t patlen = strlen(pat);
1616
1617 if (STRNCMPEQ(line, pat, patlen)) {
1618 *dst = atol(&line[patlen]);
1619 return TRUE;
1620 }
1621 return FALSE;
1622 }
1623
1624
1625 /*
1626 * If the 'pat' keyword matches, lookup & return an index into the table
1627 */
1628 t_bool
1629 match_list(
1630 char *line,
1631 constext *pat,
1632 constext *const *table,
1633 int *dst)
1634 {
1635 size_t patlen = strlen(pat);
1636
1637 if (STRNCMPEQ(line, pat, patlen)) {
1638 char temp[LEN];
1639 size_t n;
1640
1641 line += patlen;
1642 *dst = 0; /* default, if no match */
1643 for (n = 0; table[n] != NULL; n++) {
1644 if (match_item(line, table[n], temp, sizeof(temp))) {
1645 *dst = (int) n;
1646 break;
1647 }
1648 }
1649 return TRUE;
1650 }
1651 return FALSE;
1652 }
1653
1654
1655 t_bool
1656 match_string(
1657 char *line,
1658 const char *pat,
1659 char *dst,
1660 size_t dstlen)
1661 {
1662 size_t patlen = strlen(pat);
1663
1664 if (STRNCMPEQ(line, pat, patlen) && (strlen(line) > patlen)) {
1665 if (dst != NULL && dstlen >= 1)
1666 my_strncpy(dst, &line[patlen], dstlen - 1);
1667 return TRUE;
1668 }
1669 return FALSE;
1670 }
1671
1672
1673 /* like mach_string() but looks for 100% exact matches */
1674 static t_bool
1675 match_item(
1676 char *line,
1677 const char *pat,
1678 char *dst,
1679 size_t dstlen)
1680 {
1681 char *ptr;
1682 char *nline = my_strdup(line);
1683 size_t patlen = strlen(pat);
1684
1685 if ((ptr = strchr(nline, '\n')) != NULL) /* terminate on \n */
1686 *ptr = '\0';
1687
1688 if (!strcasecmp(nline, pat)) {
1689 if (dst != NULL) {
1690 strncpy(dst, &nline[patlen], dstlen);
1691 dst[dstlen ? (dstlen - 1) : 0] = '\0';
1692 }
1693 free(nline);
1694 return TRUE;
1695 }
1696 free(nline);
1697 return FALSE;
1698 }
1699
1700
1701 const char *
1702 print_boolean(
1703 t_bool value)
1704 {
1705 return txt_onoff[value != FALSE ? 1 : 0];
1706 }
1707
1708
1709 /*
1710 * convert underlines to spaces in a string
1711 */
1712 void
1713 quote_dash_to_space(
1714 char *str)
1715 {
1716 char *ptr;
1717
1718 for (ptr = str; *ptr; ptr++) {
1719 if (*ptr == '_')
1720 *ptr = ' ';
1721 }
1722 }
1723
1724
1725 /*
1726 * convert spaces to underlines in a string
1727 */
1728 char *
1729 quote_space_to_dash(
1730 char *str)
1731 {
1732 char *ptr, *dst;
1733 static char buf[PATH_LEN];
1734
1735 dst = buf;
1736 for (ptr = str; *ptr; ptr++) {
1737 if (*ptr == ' ')
1738 *dst = '_';
1739 else
1740 *dst = *ptr;
1741 dst++;
1742 }
1743 *dst = '\0';
1744
1745 return buf;
1746 }
1747
1748
1749 /*
1750 * Written by: Brad Viviano and Scott Powers (bcv & swp)
1751 *
1752 * Takes a 1d string and turns it into a 2d array of strings.
1753 *
1754 * Watch out for the frees! You must free(*argv) and then free(argv)!
1755 * NOTHING ELSE! Do _NOT_ free the individual args of argv.
1756 */
1757 char **
1758 ulBuildArgv(
1759 char *cmd,
1760 int *new_argc)
1761 {
1762 char **new_argv = NULL;
1763 char *buf, *tmp;
1764 int i = 0;
1765
1766 if (!cmd || !*cmd) {
1767 *new_argc = 0;
1768 return NULL;
1769 }
1770
1771 for (tmp = cmd; isspace((int) *tmp); tmp++)
1772 ;
1773
1774 buf = my_strdup(tmp);
1775 tmp = buf;
1776
1777 new_argv = my_calloc(1, sizeof(char *));
1778
1779 while (*tmp) {
1780 if (!isspace((int) *tmp)) { /* found the beginning of a word */
1781 new_argv[i] = tmp;
1782 for (; *tmp && !isspace((int) *tmp); tmp++)
1783 ;
1784 if (*tmp) {
1785 *tmp = '\0';
1786 tmp++;
1787 }
1788 i++;
1789 new_argv = my_realloc(new_argv, ((size_t) (i + 1) * sizeof(char *)));
1790 new_argv[i] = NULL;
1791 } else
1792 tmp++;
1793 }
1794 *new_argc = i;
1795 return new_argv;
1796 }
1797
1798
1799 /*
1800 * auto update tinrc
1801 * called at the beginning of read_config_file()
1802 */
1803 static t_bool
1804 rc_update(
1805 FILE *fp)
1806 {
1807 char buf[LEN];
1808 int show_info = 1;
1809 t_bool auto_bcc = FALSE;
1810 t_bool auto_cc = FALSE;
1811 t_bool confirm_to_quit = FALSE;
1812 t_bool confirm_action = FALSE;
1813 t_bool compress_quotes = FALSE;
1814 t_bool set_goto_next_unread = FALSE;
1815 t_bool hide_uue = FALSE;
1816 t_bool keep_posted_articles = FALSE;
1817 t_bool pgdn_goto_next = FALSE;
1818 t_bool quote_empty_lines = FALSE;
1819 t_bool quote_signatures = FALSE;
1820 t_bool save_to_mmdf_mailbox = FALSE;
1821 t_bool show_last_line_prev_page = FALSE;
1822 t_bool show_lines = FALSE;
1823 t_bool show_score = FALSE;
1824 t_bool show_lines_or_score = FALSE;
1825 t_bool space_goto_next_unread = FALSE;
1826 t_bool tab_goto_next_unread = FALSE;
1827 t_bool use_builtin_inews = FALSE;
1828 t_bool use_getart_limit = FALSE;
1829 t_bool use_mailreader_i = FALSE;
1830 t_bool use_metamail = FALSE;
1831
1832 if (!fp)
1833 return FALSE;
1834
1835 /* rewind(fp); */
1836 while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
1837 if (buf[0] == '#' || buf[0] == '\n')
1838 continue;
1839
1840 switch (my_tolower((unsigned char) buf[0])) {
1841 case 'a':
1842 if (match_boolean(buf, "auto_bcc=", &auto_bcc))
1843 break;
1844
1845 if (match_boolean(buf, "auto_cc=", &auto_cc))
1846 break;
1847 break;
1848
1849 case 'c':
1850 if (match_boolean(buf, "confirm_action=", &confirm_action))
1851 break;
1852 if (match_boolean(buf, "confirm_to_quit=", &confirm_to_quit))
1853 break;
1854 if (match_boolean(buf, "compress_quotes=", &compress_quotes))
1855 break;
1856 break;
1857
1858 case 'd':
1859 /* simple rename */
1860 if (match_string(buf, "default_editor_format=", tinrc.editor_format, sizeof(tinrc.editor_format)))
1861 break;
1862 /* simple rename */
1863 if (match_string(buf, "default_maildir=", tinrc.maildir, sizeof(tinrc.maildir)))
1864 break;
1865 /* simple rename */
1866 if (match_string(buf, "default_mailer_format=", tinrc.mailer_format, sizeof(tinrc.mailer_format)))
1867 break;
1868 /* simple rename */
1869 #ifndef DISABLE_PRINTING
1870 if (match_string(buf, "default_printer=", tinrc.printer, sizeof(tinrc.printer)))
1871 break;
1872 #endif /* !DISABLE_PRINTING */
1873 /* simple rename */
1874 if (match_string(buf, "default_regex_pattern=", tinrc.default_pattern, sizeof(tinrc.default_pattern)))
1875 break;
1876 /* simple rename */
1877 if (match_string(buf, "default_savedir=", tinrc.savedir, sizeof(tinrc.savedir))) {
1878 if (tinrc.savedir[0] == '.' && strlen(tinrc.savedir) == 1) {
1879 char buff[PATH_LEN];
1880
1881 get_cwd(buff);
1882 my_strncpy(tinrc.savedir, buff, sizeof(tinrc.savedir) - 1);
1883 }
1884 break;
1885 }
1886 /* 1. simple rename
1887 *
1888 * 2. previous versions has always passed groupname to external
1889 * commands, now we look for %G
1890 */
1891 if (match_string(buf, "default_sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
1892 size_t l = strlen(tinrc.sigfile);
1893
1894 if (tinrc.sigfile[0] == '!' && (tinrc.sigfile[l - 2] != '%' || tinrc.sigfile[l - 1] != 'G')) {
1895 char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
1896
1897 sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
1898 my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
1899 free(newbuf);
1900 }
1901 break;
1902 }
1903 break;
1904
1905 case 'h':
1906 if (match_boolean(buf, "hide_uue=", &hide_uue))
1907 break;
1908 break;
1909
1910 case 'k':
1911 if (match_boolean(buf, "keep_posted_articles=", &keep_posted_articles))
1912 break;
1913 break;
1914
1915 case 'p':
1916 if (match_boolean(buf, "pgdn_goto_next=", &pgdn_goto_next)) {
1917 set_goto_next_unread = TRUE;
1918 break;
1919 }
1920 break;
1921
1922 case 'q':
1923 if (match_boolean(buf, "quote_signatures=", "e_signatures))
1924 break;
1925 if (match_boolean(buf, "quote_empty_lines=", "e_empty_lines))
1926 break;
1927 break;
1928
1929 case 's':
1930 if (match_boolean(buf, "space_goto_next_unread=", &space_goto_next_unread)) {
1931 set_goto_next_unread = TRUE;
1932 break;
1933 }
1934 if (match_boolean(buf, "save_to_mmdf_mailbox=", &save_to_mmdf_mailbox))
1935 break;
1936 if (match_integer(buf, "show_info=", &show_info, 3))
1937 break;
1938 if (match_boolean(buf, "show_last_line_prev_page=", &show_last_line_prev_page))
1939 break;
1940 if (match_boolean(buf, "show_lines=", &show_lines)) {
1941 show_lines_or_score = TRUE;
1942 break;
1943 }
1944 /* simple rename */
1945 if (match_boolean(buf, "show_only_unread=", &tinrc.show_only_unread_arts))
1946 break;
1947 if (match_boolean(buf, "show_score=", &show_score)) {
1948 show_lines_or_score = TRUE;
1949 break;
1950 }
1951 break;
1952
1953 case 't':
1954 if (match_boolean(buf, "tab_goto_next_unread=", &tab_goto_next_unread)) {
1955 set_goto_next_unread = TRUE;
1956 break;
1957 }
1958 break;
1959
1960 case 'u':
1961 if (match_boolean(buf, "use_builtin_inews=", &use_builtin_inews))
1962 break;
1963 if (match_boolean(buf, "use_getart_limit=", &use_getart_limit))
1964 break;
1965 if (match_boolean(buf, "use_mailreader_i=", &use_mailreader_i))
1966 break;
1967 if (match_boolean(buf, "use_metamail=", &use_metamail))
1968 break;
1969 break;
1970
1971 default:
1972 break;
1973 }
1974 }
1975
1976 /* update the values */
1977 tinrc.auto_cc_bcc = (auto_cc ? 1 : 0) + (auto_bcc ? 2 : 0);
1978 tinrc.confirm_choice = (confirm_action ? 1 : 0) + (confirm_to_quit ? 3 : 0);
1979
1980 if (!use_getart_limit)
1981 tinrc.getart_limit = 0;
1982
1983 if (set_goto_next_unread) {
1984 tinrc.goto_next_unread = 0;
1985 if (pgdn_goto_next || space_goto_next_unread)
1986 tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_PGDN;
1987 if (tab_goto_next_unread)
1988 tinrc.goto_next_unread |= GOTO_NEXT_UNREAD_TAB;
1989 }
1990
1991 if (hide_uue)
1992 tinrc.hide_uue = 1;
1993
1994 if (keep_posted_articles)
1995 STRCPY(tinrc.posted_articles_file, "posted");
1996
1997 tinrc.quote_style = (compress_quotes ? QUOTE_COMPRESS : 0) + (quote_empty_lines ? QUOTE_EMPTY : 0) + (quote_signatures ? QUOTE_SIGS : 0);
1998
1999 tinrc.mailbox_format = (save_to_mmdf_mailbox ? 2 : 0);
2000
2001 if (show_lines_or_score)
2002 show_info = (show_lines ? 1 : 0) + (show_score ? 2 : 0);
2003
2004 switch (show_info) {
2005 case 0:
2006 STRCPY(tinrc.group_format, "%n %m %R %s %F");
2007 STRCPY(tinrc.thread_format, "%n %m %T %F");
2008 break;
2009
2010 case 2:
2011 STRCPY(tinrc.group_format, "%n %m %R %S %s %F");
2012 STRCPY(tinrc.thread_format, "%n %m [%S] %T %F");
2013 break;
2014
2015 case 3:
2016 STRCPY(tinrc.group_format, "%n %m %R %L %S %s %F");
2017 STRCPY(tinrc.thread_format, "%n %m [%L,%S] %T %F");
2018 break;
2019
2020 default:
2021 break;
2022 }
2023
2024 if (show_last_line_prev_page)
2025 tinrc.scroll_lines = -1;
2026
2027 if (use_builtin_inews)
2028 STRCPY(tinrc.inews_prog, INTERNAL_CMD);
2029
2030 if (use_mailreader_i)
2031 tinrc.interactive_mailer = INTERACTIVE_WITHOUT_HEADERS;
2032
2033 if (!use_metamail || getenv("NOMETAMAIL") != NULL)
2034 STRCPY(tinrc.metamail_prog, INTERNAL_CMD);
2035 else
2036 my_strncpy(tinrc.metamail_prog, METAMAIL_CMD, sizeof(tinrc.metamail_prog) - 1);
2037
2038 rewind(fp);
2039 return TRUE;
2040 }
2041
2042
2043 /*
2044 * auto update tinrc
2045 * called at the end of read_config_file()
2046 * useful to update variables which are already present in tinrc
2047 *
2048 * pass upgrade to this function once we need to exactly check
2049 * upgrade->file_version, upgrade->current_version
2050 */
2051 static t_bool
2052 rc_post_update(
2053 FILE *fp
2054 /* , struct t_version *upgrade */)
2055 {
2056 char buf[LEN];
2057 int groupname_max_length = 0;
2058
2059 if (!fp)
2060 return FALSE;
2061
2062 rewind(fp);
2063 while (fgets(buf, (int) sizeof(buf), fp) != NULL) {
2064 if (buf[0] == '#' || buf[0] == '\n')
2065 continue;
2066
2067 switch (my_tolower((unsigned char) buf[0])) {
2068 case 'c':
2069 #ifdef USE_CANLOCK
2070 {
2071 t_bool cancel_locks = TRUE;
2072
2073 if (match_boolean(buf, "cancel_locks=", &cancel_locks)) {
2074 if (!cancel_locks)
2075 tinrc.cancel_lock_algo = 0;
2076 break;
2077 }
2078 }
2079 #endif /* USE_CANLOCK */
2080 break;
2081
2082 case 'g':
2083 if (match_integer(buf, "groupname_max_length=", &groupname_max_length, 132))
2084 break;
2085 break;
2086
2087 case 's':
2088 /*
2089 * previous versions has always passed groupname to external
2090 * commands, now we look for %G
2091 */
2092 if (match_string(buf, "sigfile=", tinrc.sigfile, sizeof(tinrc.sigfile))) {
2093 size_t l = strlen(tinrc.sigfile);
2094
2095 if (tinrc.sigfile[0] == '!' && (tinrc.sigfile[l - 2] != '%' || tinrc.sigfile[l - 1] != 'G')) {
2096 char *newbuf = my_malloc(sizeof(tinrc.sigfile) + 4);
2097
2098 sprintf(newbuf, "%s %s", tinrc.sigfile, "%G");
2099 my_strncpy(tinrc.sigfile, newbuf, sizeof(tinrc.sigfile) - 1);
2100 free(newbuf);
2101 }
2102 break;
2103 }
2104 break;
2105
2106 default:
2107 break;
2108 }
2109 }
2110
2111 /* update the values */
2112 if (groupname_max_length > 0 && groupname_max_length != 32) {
2113 char length[LEN];
2114 char *dest, *d, *f, *l;
2115
2116 snprintf(length, sizeof(length), ",%d", groupname_max_length);
2117
2118 d = dest = my_malloc(strlen(tinrc.select_format) + strlen(length) + 1);
2119 f = tinrc.select_format;
2120 l = length;
2121
2122 while (*f) {
2123 if (*f == 'G') {
2124 while (*l)
2125 *d++ = *l++;
2126 }
2127 *d++ = *f++;
2128 }
2129 *d = '\0';
2130 STRCPY(tinrc.select_format, dest);
2131 free(dest);
2132 }
2133
2134 return TRUE;
2135 }
2136
2137
2138 void
2139 read_server_config(
2140 void)
2141 {
2142 FILE *fp;
2143 char *line;
2144 char file[PATH_LEN];
2145 char newnews_info[LEN];
2146 char serverdir[PATH_LEN];
2147 struct t_version *upgrade = NULL;
2148
2149 #ifdef NNTP_ABLE
2150 if (read_news_via_nntp && !read_saved_news && nntp_tcp_port != IPPORT_NNTP)
2151 snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
2152 else
2153 #endif /* NNTP_ABLE */
2154 {
2155 STRCPY(file, quote_space_to_dash(nntp_server));
2156 }
2157 joinpath(serverdir, sizeof(serverdir), rcdir, file);
2158 joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
2159 joinpath(local_newsgroups_file, sizeof(local_newsgroups_file), serverdir, NEWSGROUPS_FILE);
2160
2161 if ((fp = fopen(file, "r")) == NULL)
2162 return;
2163
2164 while ((line = tin_fgets(fp, FALSE)) != NULL) {
2165 if ((*line == '#') || (*line == '\0'))
2166 continue;
2167
2168 if (match_string(line, "last_newnews=", newnews_info, sizeof(newnews_info))) {
2169 size_t tmp_len = strlen(nntp_server) + strlen(newnews_info) + 2;
2170 char *tmp_info = my_malloc(tmp_len);
2171
2172 snprintf(tmp_info, tmp_len, "%s %s", nntp_server, newnews_info);
2173 load_newnews_info(tmp_info);
2174 free(tmp_info);
2175 continue;
2176 }
2177
2178 if (match_string(line, "version=", NULL, 0)) {
2179 if (upgrade != NULL) /* ignore duplicate version lines; first match counts */
2180 continue;
2181
2182 upgrade = check_upgrade(line, "version=", SERVERCONFIG_VERSION);
2183 if (upgrade->state == RC_IGNORE) /* Expected version number; nothing to do -> continue */
2184 continue;
2185
2186 /* Nothing to do yet for RC_UPGRADE and RC_DOWNGRADE */
2187 continue;
2188 }
2189 }
2190 fclose(fp);
2191 FreeAndNull(upgrade);
2192 }
2193
2194
2195 static void
2196 write_server_config(
2197 void)
2198 {
2199 FILE *fp;
2200 char *file_tmp;
2201 char file[PATH_LEN];
2202 char timestring[30];
2203 char serverdir[PATH_LEN];
2204 int i;
2205 struct stat statbuf;
2206
2207 if (read_saved_news)
2208 /* don't update server files while reading locally stored articles */
2209 return;
2210 #ifdef NNTP_ABLE
2211 if (read_news_via_nntp && nntp_tcp_port != IPPORT_NNTP)
2212 snprintf(file, sizeof(file), "%s:%u", nntp_server, nntp_tcp_port);
2213 else
2214 #endif /* NNTP_ABLE */
2215 {
2216 STRCPY(file, nntp_server);
2217 }
2218 joinpath(serverdir, sizeof(serverdir), rcdir, file);
2219 joinpath(file, sizeof(file), serverdir, SERVERCONFIG_FILE);
2220
2221 if ((no_write || post_article_and_exit || post_postponed_and_exit) && file_size(file) != -1L)
2222 return;
2223
2224 if (stat(serverdir, &statbuf) == -1) {
2225 if (my_mkdir(serverdir, (mode_t) (S_IRWXU)) == -1)
2226 /* Can't create directory TODO: Add error handling */
2227 return;
2228 }
2229
2230 /* generate tmp-filename */
2231 file_tmp = get_tmpfilename(file);
2232
2233 if ((fp = fopen(file_tmp, "w")) == NULL) {
2234 error_message(2, _(txt_filesystem_full_backup), SERVERCONFIG_FILE);
2235 free(file_tmp);
2236 return;
2237 }
2238
2239 fprintf(fp, _(txt_serverconfig_header), PRODUCT, tin_progname, VERSION, RELEASEDATE, RELEASENAME, PRODUCT, PRODUCT);
2240 fprintf(fp, "version=%s\n", SERVERCONFIG_VERSION);
2241
2242 if ((i = find_newnews_index(nntp_server)) >= 0) {
2243 if (my_strftime(timestring, sizeof(timestring) - 1, "%Y-%m-%d %H:%M:%S UTC", gmtime(&(newnews[i].time))))
2244 fprintf(fp, "last_newnews=%lu (%s)\n", (unsigned long int) newnews[i].time, timestring);
2245 }
2246
2247 #ifdef HAVE_FCHMOD
2248 fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
2249 #else
2250 # ifdef HAVE_CHMOD
2251 chmod(file_tmp, (mode_t) (S_IRUSR|S_IWUSR)); /* rename_file() preserves mode */
2252 # endif /* HAVE_CHMOD */
2253 #endif /* HAVE_FCHMOD */
2254
2255 if ((i = ferror(fp)) || fclose(fp)) {
2256 error_message(2, _(txt_filesystem_full), SERVERCONFIG_FILE);
2257 if (i) {
2258 clearerr(fp);
2259 fclose(fp);
2260 }
2261 } else
2262 rename_file(file_tmp, file);
2263
2264 free(file_tmp);
2265 }