1 /*
2 * Project : tin - a Usenet reader
3 * Module : attrib.c
4 * Author : I. Lea
5 * Created : 1993-12-01
6 * Updated : 2020-04-23
7 * Notes : Group attribute routines
8 *
9 * Copyright (c) 1993-2021 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
51
52 /*
53 * Global file offset for local_attributes_file
54 */
55 int attrib_file_offset;
56
57
58 /*
59 * Local prototypes
60 */
61 static void set_attrib(int type, const char *scope, const char *line, void *data);
62 static void set_default_attributes(struct t_attribute *attributes, struct t_attribute *scope, t_bool global);
63 static void set_default_state(struct t_attribute_state *state);
64 #ifdef DEBUG
65 static void dump_attributes(void);
66 static void dump_scopes(const char *fname);
67 # if 0 /* unused */
68 static void debug_print_filter_attributes(void);
69 # endif /* 0 */
70 #endif /* DEBUG */
71
72
73 /*
74 * Per group attributes. This fills out a basic template of defaults
75 * before the attributes in the current scope are applied.
76 */
77 static void
set_default_attributes(struct t_attribute * attributes,struct t_attribute * scope,t_bool global)78 set_default_attributes(
79 struct t_attribute *attributes,
80 struct t_attribute *scope,
81 t_bool global)
82 {
83 attributes->global = (global ? TRUE : FALSE); /* global/group specific */
84 attributes->maildir = (scope ? scope->maildir : (global ? tinrc.maildir : NULL));
85 attributes->savedir = (scope ? scope->savedir : (global ? tinrc.savedir : NULL));
86 attributes->savefile = NULL;
87 attributes->sigfile = (scope ? scope->sigfile : (global ? tinrc.sigfile : NULL));
88 attributes->group_format = (scope ? scope->group_format : (global ? tinrc.group_format : NULL));
89 attributes->thread_format = (scope ? scope->thread_format : (global ? tinrc.thread_format : NULL));
90 attributes->date_format = (scope ? scope->date_format : (global ? tinrc.date_format : NULL));
91 attributes->editor_format = (scope ? scope->editor_format : (global ? tinrc.editor_format : NULL));
92 attributes->organization = (scope ? scope->organization : (global ? (*default_organization ? default_organization : NULL) : NULL));
93 attributes->followup_to = NULL;
94 attributes->mailing_list = NULL;
95 attributes->x_headers = NULL;
96 attributes->x_body = NULL;
97 attributes->from = (scope ? scope->from : (global ? tinrc.mail_address : NULL));
98 attributes->news_quote_format = (scope ? scope->news_quote_format : (global ? tinrc.news_quote_format : NULL));
99 attributes->quote_chars = (scope ? scope->quote_chars : (global ? tinrc.quote_chars : NULL));
100 attributes->mime_types_to_save = (scope ? scope->mime_types_to_save : (global ? my_strdup("*/*") : NULL));
101 #ifdef HAVE_ISPELL
102 attributes->ispell = NULL;
103 #endif /* HAVE_ISPELL */
104 attributes->quick_kill_scope = (scope ? scope->quick_kill_scope : (global ? (tinrc.default_filter_kill_global ? my_strdup("*") : NULL) : NULL));
105 attributes->quick_kill_header = tinrc.default_filter_kill_header;
106 attributes->quick_kill_case = tinrc.default_filter_kill_case;
107 attributes->quick_kill_expire = tinrc.default_filter_kill_expire;
108 attributes->quick_select_scope = (scope ? scope->quick_select_scope : (global ? (tinrc.default_filter_select_global ? my_strdup("*") : NULL) : NULL));
109 attributes->quick_select_header = tinrc.default_filter_select_header;
110 attributes->quick_select_case = tinrc.default_filter_select_case;
111 attributes->quick_select_expire = tinrc.default_filter_select_expire;
112 attributes->show_only_unread_arts = tinrc.show_only_unread_arts;
113 attributes->thread_articles = tinrc.thread_articles;
114 attributes->thread_catchup_on_exit = tinrc.thread_catchup_on_exit;
115 attributes->thread_perc = tinrc.thread_perc;
116 attributes->sort_article_type = tinrc.sort_article_type;
117 attributes->sort_threads_type = tinrc.sort_threads_type;
118 attributes->show_author = tinrc.show_author;
119 attributes->show_signatures = tinrc.show_signatures;
120 attributes->trim_article_body = tinrc.trim_article_body;
121 attributes->verbatim_handling = tinrc.verbatim_handling;
122 #ifdef HAVE_COLOR
123 attributes->extquote_handling = tinrc.extquote_handling;
124 #endif /* HAVE_COLOR */
125 attributes->wrap_on_next_unread = tinrc.wrap_on_next_unread;
126 attributes->add_posted_to_filter = tinrc.add_posted_to_filter;
127 attributes->advertising = tinrc.advertising;
128 attributes->alternative_handling = tinrc.alternative_handling;
129 attributes->ask_for_metamail = tinrc.ask_for_metamail;
130 attributes->auto_cc_bcc = tinrc.auto_cc_bcc;
131 attributes->auto_list_thread = tinrc.auto_list_thread;
132 attributes->auto_save = tinrc.auto_save;
133 attributes->auto_select = FALSE;
134 attributes->batch_save = tinrc.batch_save;
135 attributes->delete_tmp_files = FALSE;
136 attributes->group_catchup_on_exit = tinrc.group_catchup_on_exit;
137 attributes->mail_8bit_header = tinrc.mail_8bit_header;
138 attributes->mail_mime_encoding = tinrc.mail_mime_encoding;
139 attributes->mark_ignore_tags = tinrc.mark_ignore_tags;
140 attributes->mark_saved_read = tinrc.mark_saved_read;
141 attributes->news_headers_to_display = (global ? tinrc.news_headers_to_display : NULL);
142 attributes->headers_to_display = (scope ? (scope->headers_to_display ? scope->headers_to_display : NULL) : NULL);
143 attributes->news_headers_to_not_display = (global ? tinrc.news_headers_to_not_display : NULL);
144 attributes->headers_to_not_display = (scope ? (scope->headers_to_not_display ? scope->headers_to_not_display : NULL) : NULL);
145 attributes->pos_first_unread = tinrc.pos_first_unread;
146 attributes->post_8bit_header = tinrc.post_8bit_header;
147 attributes->post_mime_encoding = tinrc.post_mime_encoding;
148 attributes->post_process_view = tinrc.post_process_view;
149 attributes->post_process_type = tinrc.post_process_type;
150 #ifndef DISABLE_PRINTING
151 attributes->print_header = tinrc.print_header;
152 #endif /* !DISABLE_PRINTING */
153 attributes->process_only_unread = tinrc.process_only_unread;
154 attributes->prompt_followupto = tinrc.prompt_followupto;
155 attributes->sigdashes = tinrc.sigdashes;
156 attributes->signature_repost = tinrc.signature_repost;
157 attributes->start_editor_offset = tinrc.start_editor_offset;
158 attributes->x_comment_to = FALSE;
159 attributes->tex2iso_conv = tinrc.tex2iso_conv;
160 attributes->mime_forward = FALSE;
161 attributes->fcc = NULL;
162 #ifdef CHARSET_CONVERSION
163 attributes->mm_network_charset = tinrc.mm_network_charset;
164 attributes->undeclared_charset = NULL;
165 #endif /* CHARSET_CONVERSION */
166 }
167
168
169 static void
set_default_state(struct t_attribute_state * state)170 set_default_state(
171 struct t_attribute_state *state)
172 {
173 state->add_posted_to_filter = FALSE;
174 state->advertising = FALSE;
175 state->alternative_handling = FALSE;
176 state->ask_for_metamail = FALSE;
177 state->auto_cc_bcc = FALSE;
178 state->auto_list_thread = FALSE;
179 state->auto_save = FALSE;
180 state->auto_select = FALSE;
181 state->batch_save = FALSE;
182 state->date_format = FALSE;
183 state->delete_tmp_files = FALSE;
184 state->editor_format = FALSE;
185 state->fcc = FALSE;
186 state->followup_to = FALSE;
187 state->from = FALSE;
188 state->group_catchup_on_exit = FALSE;
189 state->group_format = FALSE;
190 #ifdef HAVE_ISPELL
191 state->ispell = FALSE;
192 #endif /* HAVE_ISPELL */
193 state->mail_8bit_header = FALSE;
194 state->mail_mime_encoding = FALSE;
195 state->maildir = FALSE;
196 state->mailing_list = FALSE;
197 state->mark_ignore_tags = FALSE;
198 state->mark_saved_read = FALSE;
199 state->mime_forward = FALSE;
200 state->mime_types_to_save = FALSE;
201 state->news_headers_to_display = FALSE;
202 state->news_headers_to_not_display = FALSE;
203 state->news_quote_format = FALSE;
204 state->organization = FALSE;
205 state->pos_first_unread = FALSE;
206 state->post_8bit_header = FALSE;
207 state->post_mime_encoding = FALSE;
208 state->post_process_type = FALSE;
209 state->post_process_view = FALSE;
210 #ifndef DISABLE_PRINTING
211 state->print_header = FALSE;
212 #endif /* !DISABLE_PRINTING */
213 state->process_only_unread = FALSE;
214 state->prompt_followupto = FALSE;
215 state->quick_kill_case = FALSE;
216 state->quick_kill_expire = FALSE;
217 state->quick_kill_header = FALSE;
218 state->quick_kill_scope = FALSE;
219 state->quick_select_case = FALSE;
220 state->quick_select_expire = FALSE;
221 state->quick_select_header = FALSE;
222 state->quick_select_scope = FALSE;
223 state->quote_chars = FALSE;
224 state->savedir = FALSE;
225 state->savefile = FALSE;
226 state->show_author = FALSE;
227 state->show_only_unread_arts = FALSE;
228 state->show_signatures = FALSE;
229 state->sigdashes = FALSE;
230 state->sigfile = FALSE;
231 state->signature_repost = FALSE;
232 state->sort_article_type = FALSE;
233 state->sort_threads_type = FALSE;
234 state->start_editor_offset = FALSE;
235 state->tex2iso_conv = FALSE;
236 state->thread_articles = FALSE;
237 state->thread_catchup_on_exit = FALSE;
238 state->thread_format = FALSE;
239 state->thread_perc = FALSE;
240 state->trim_article_body = FALSE;
241 #ifdef CHARSET_CONVERSION
242 state->undeclared_charset = FALSE;
243 state->mm_network_charset = FALSE;
244 #endif /* CHARSET_CONVERSION */
245 state->verbatim_handling = FALSE;
246 #ifdef HAVE_COLOR
247 state->extquote_handling = FALSE;
248 #endif /* HAVE_COLOR */
249 state->wrap_on_next_unread = FALSE;
250 state->x_body = FALSE;
251 state->x_comment_to = FALSE;
252 state->x_headers = FALSE;
253 }
254
255
256 #define MATCH_BOOLEAN(pattern, type) \
257 if (match_boolean(line, pattern, &flag)) { \
258 num = (flag != FALSE); \
259 set_attrib(type, scope, line, &num); \
260 found = TRUE; \
261 break; \
262 }
263 #define MATCH_INTEGER(pattern, type, maxval) \
264 if (match_integer(line, pattern, &num, maxval)) { \
265 set_attrib(type, scope, line, &num); \
266 found = TRUE; \
267 break; \
268 }
269 #define MATCH_STRING(pattern, type) \
270 if (match_string(line, pattern, buf, sizeof(buf) - strlen(pattern))) { \
271 set_attrib(type, scope, line, buf); \
272 found = TRUE; \
273 break; \
274 }
275 #define MATCH_LIST(pattern, type, table) \
276 if (match_list(line, pattern, table, &num)) { \
277 set_attrib(type, scope, line, &num); \
278 found = TRUE; \
279 break; \
280 }
281 #if !defined(CHARSET_CONVERSION) || !defined(HAVE_ISPELL) || defined(DISABLE_PRINTING)
282 # define SKIP_ITEM(pattern) \
283 if (!strncmp(line, pattern, strlen(pattern))) { \
284 found = TRUE; \
285 break; \
286 }
287 #endif /* !CHARSET_CONVERSION || !HAVE_ISPELL || DISABLE_PRINTING */
288
289
290 /*
291 * read global/local attributes file
292 */
293 void
read_attributes_file(t_bool global_file)294 read_attributes_file(
295 t_bool global_file)
296 {
297 FILE *fp;
298 char *file;
299 char buf[LEN];
300 char line[LEN];
301 char scope[LEN];
302 int i, num;
303 struct t_version *upgrade = NULL;
304 static t_bool startup = TRUE;
305 t_bool flag, found = FALSE;
306
307 if (!batch_mode || verbose)
308 wait_message(0, _(txt_reading_attributes_file), (global_file ? _(txt_global) : ""));
309 /*
310 * Initialize global attributes even if there is no global file
311 * These setting are used as the default for all groups unless overridden
312 */
313 if (global_file) {
314 i = add_scope("_default_");
315 scopes[i].global = TRUE;
316 set_default_attributes(scopes[i].attribute, NULL, TRUE);
317 build_news_headers_array(scopes[i].attribute, TRUE);
318 build_news_headers_array(scopes[i].attribute, FALSE);
319 file = global_attributes_file;
320 } else {
321 attrib_file_offset = 1;
322 file = local_attributes_file;
323 }
324
325 if ((fp = fopen(file, "r")) != NULL) {
326 scope[0] = '\0';
327 /*
328 * TODO: use tin_fgets() instead to handle long lines
329 * (e.g. buggy translation)
330 */
331 while (fgets(line, (int) sizeof(line), fp) != NULL) {
332 if (line[0] == '\n')
333 continue;
334 if (line[0] == '#') {
335 if (!global_file) {
336 if (scope[0] == '\0')
337 attrib_file_offset++;
338 if (startup && upgrade == NULL && match_string(line, "# Group attributes file V", NULL, 0)) {
339 upgrade = check_upgrade(line, "# Group attributes file V", ATTRIBUTES_VERSION);
340 if (upgrade->state != RC_IGNORE)
341 upgrade_prompt_quit(upgrade, file); /* TODO: do something (more) useful here */
342 }
343 }
344 continue;
345 }
346
347 switch (my_tolower((unsigned char) line[0])) {
348 case 'a':
349 MATCH_BOOLEAN("add_posted_to_filter=", OPT_ATTRIB_ADD_POSTED_TO_FILTER);
350 MATCH_BOOLEAN("advertising=", OPT_ATTRIB_ADVERTISING);
351 MATCH_BOOLEAN("alternative_handling=", OPT_ATTRIB_ALTERNATIVE_HANDLING);
352 MATCH_BOOLEAN("ask_for_metamail=", OPT_ATTRIB_ASK_FOR_METAMAIL);
353 MATCH_INTEGER("auto_cc_bcc=", OPT_ATTRIB_AUTO_CC_BCC, AUTO_CC_BCC);
354 MATCH_BOOLEAN("auto_list_thread=", OPT_ATTRIB_AUTO_LIST_THREAD);
355 MATCH_BOOLEAN("auto_save=", OPT_ATTRIB_AUTO_SAVE);
356 MATCH_BOOLEAN("auto_select=", OPT_ATTRIB_AUTO_SELECT);
357 break;
358
359 case 'b':
360 MATCH_BOOLEAN("batch_save=", OPT_ATTRIB_BATCH_SAVE);
361 break;
362
363 case 'd':
364 MATCH_STRING("date_format=", OPT_ATTRIB_DATE_FORMAT);
365 MATCH_BOOLEAN("delete_tmp_files=", OPT_ATTRIB_DELETE_TMP_FILES);
366 break;
367
368 case 'e':
369 MATCH_STRING("editor_format=", OPT_ATTRIB_EDITOR_FORMAT);
370 #ifdef HAVE_COLOR
371 MATCH_BOOLEAN("extquote_handling=", OPT_ATTRIB_EXTQUOTE_HANDLING);
372 #endif /* HAVE_COLOR */
373
374 break;
375
376 case 'f':
377 MATCH_STRING("fcc=", OPT_ATTRIB_FCC);
378 MATCH_STRING("followup_to=", OPT_ATTRIB_FOLLOWUP_TO);
379 MATCH_STRING("from=", OPT_ATTRIB_FROM);
380 break;
381
382 case 'g':
383 MATCH_BOOLEAN("group_catchup_on_exit=", OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT);
384 MATCH_STRING("group_format=", OPT_ATTRIB_GROUP_FORMAT);
385 break;
386
387 case 'i':
388 #ifdef HAVE_ISPELL
389 MATCH_STRING("ispell=", OPT_ATTRIB_ISPELL);
390 #else
391 SKIP_ITEM("ispell=");
392 #endif /* HAVE_ISPELL */
393 break;
394
395 case 'm':
396 MATCH_BOOLEAN("mail_8bit_header=", OPT_ATTRIB_MAIL_8BIT_HEADER);
397 MATCH_LIST("mail_mime_encoding=", OPT_ATTRIB_MAIL_MIME_ENCODING, txt_mime_encodings);
398 MATCH_STRING("maildir=", OPT_ATTRIB_MAILDIR);
399 MATCH_STRING("mailing_list=", OPT_ATTRIB_MAILING_LIST);
400 MATCH_BOOLEAN("mark_ignore_tags=", OPT_ATTRIB_MARK_IGNORE_TAGS);
401 MATCH_BOOLEAN("mark_saved_read=", OPT_ATTRIB_MARK_SAVED_READ);
402 MATCH_BOOLEAN("mime_forward=", OPT_ATTRIB_MIME_FORWARD);
403 MATCH_STRING("mime_types_to_save=", OPT_ATTRIB_MIME_TYPES_TO_SAVE);
404 #ifdef CHARSET_CONVERSION
405 MATCH_LIST("mm_network_charset=", OPT_ATTRIB_MM_NETWORK_CHARSET, txt_mime_charsets);
406 #else
407 SKIP_ITEM("mm_network_charset=");
408 #endif /* CHARSET_CONVERSION */
409 break;
410
411 case 'n':
412 MATCH_STRING("news_headers_to_display=", OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY);
413 MATCH_STRING("news_headers_to_not_display=", OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY);
414 MATCH_STRING("news_quote_format=", OPT_ATTRIB_NEWS_QUOTE_FORMAT);
415 break;
416
417 case 'o':
418 MATCH_STRING("organization=", OPT_ATTRIB_ORGANIZATION);
419 break;
420
421 case 'p':
422 MATCH_BOOLEAN("pos_first_unread=", OPT_ATTRIB_POS_FIRST_UNREAD);
423 MATCH_BOOLEAN("post_8bit_header=", OPT_ATTRIB_POST_8BIT_HEADER);
424 MATCH_LIST("post_mime_encoding=", OPT_ATTRIB_POST_MIME_ENCODING, txt_mime_encodings);
425 MATCH_BOOLEAN("post_process_view=", OPT_ATTRIB_POST_PROCESS_VIEW);
426 MATCH_INTEGER("post_process_type=", OPT_ATTRIB_POST_PROCESS_TYPE, POST_PROC_YES);
427 #ifndef DISABLE_PRINTING
428 MATCH_BOOLEAN("print_header=", OPT_ATTRIB_PRINT_HEADER);
429 #else
430 SKIP_ITEM("print_header=");
431 #endif /* !DISABLE_PRINTING */
432 MATCH_BOOLEAN("process_only_unread=", OPT_ATTRIB_PROCESS_ONLY_UNREAD);
433 MATCH_BOOLEAN("prompt_followupto=", OPT_ATTRIB_PROMPT_FOLLOWUPTO);
434 break;
435
436 case 'q':
437 MATCH_BOOLEAN("quick_kill_case=", OPT_ATTRIB_QUICK_KILL_CASE);
438 MATCH_BOOLEAN("quick_kill_expire=", OPT_ATTRIB_QUICK_KILL_EXPIRE);
439 MATCH_INTEGER("quick_kill_header=", OPT_ATTRIB_QUICK_KILL_HEADER, FILTER_LINES);
440 MATCH_STRING("quick_kill_scope=", OPT_ATTRIB_QUICK_KILL_SCOPE);
441 MATCH_BOOLEAN("quick_select_case=", OPT_ATTRIB_QUICK_SELECT_CASE);
442 MATCH_BOOLEAN("quick_select_expire=", OPT_ATTRIB_QUICK_SELECT_EXPIRE);
443 MATCH_INTEGER("quick_select_header=", OPT_ATTRIB_QUICK_SELECT_HEADER, FILTER_LINES);
444 MATCH_STRING("quick_select_scope=", OPT_ATTRIB_QUICK_SELECT_SCOPE);
445 if (match_string(line, "quote_chars=", buf, sizeof(buf))) {
446 if (upgrade && upgrade->file_version < 10010) { /* %s/%S changed to %I */
447 char *q = buf;
448
449 while (*q) {
450 if (*q == '%' && (*(q + 1) == 's' || *(q + 1) == 'S'))
451 *(++q) = 'I';
452
453 q++;
454 }
455 }
456 quote_dash_to_space(buf);
457 set_attrib(OPT_ATTRIB_QUOTE_CHARS, scope, line, buf);
458 found = TRUE;
459 break;
460 }
461 break;
462
463 case 's':
464 MATCH_STRING("savedir=", OPT_ATTRIB_SAVEDIR);
465 MATCH_STRING("savefile=", OPT_ATTRIB_SAVEFILE);
466 if (match_string(line, "scope=", scope, sizeof(scope))) {
467 i = add_scope(scope);
468 scopes[i].global = global_file ? TRUE : FALSE;
469 found = TRUE;
470 break;
471 }
472 MATCH_INTEGER("show_author=", OPT_ATTRIB_SHOW_AUTHOR, SHOW_FROM_BOTH);
473 MATCH_BOOLEAN("show_only_unread_arts=", OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS);
474 MATCH_BOOLEAN("show_signatures=", OPT_ATTRIB_SHOW_SIGNATURES);
475 MATCH_BOOLEAN("sigdashes=", OPT_ATTRIB_SIGDASHES);
476 MATCH_BOOLEAN("signature_repost=", OPT_ATTRIB_SIGNATURE_REPOST);
477 MATCH_BOOLEAN("start_editor_offset=", OPT_ATTRIB_START_EDITOR_OFFSET);
478 MATCH_STRING("sigfile=", OPT_ATTRIB_SIGFILE);
479 MATCH_INTEGER("sort_article_type=", OPT_ATTRIB_SORT_ARTICLE_TYPE, SORT_ARTICLES_BY_LINES_ASCEND);
480 MATCH_INTEGER("sort_threads_type=", OPT_ATTRIB_SORT_THREADS_TYPE, SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND);
481 break;
482
483 case 't':
484 MATCH_BOOLEAN("tex2iso_conv=", OPT_ATTRIB_TEX2ISO_CONV);
485 MATCH_INTEGER("thread_articles=", OPT_ATTRIB_THREAD_ARTICLES, THREAD_MAX);
486 MATCH_BOOLEAN("thread_catchup_on_exit=", OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT);
487 MATCH_STRING("thread_format=", OPT_ATTRIB_THREAD_FORMAT);
488 MATCH_INTEGER("thread_perc=", OPT_ATTRIB_THREAD_PERC, 100);
489 MATCH_INTEGER("trim_article_body=", OPT_ATTRIB_TRIM_ARTICLE_BODY, 7);
490 break;
491
492 case 'u':
493 #ifdef CHARSET_CONVERSION
494 MATCH_STRING("undeclared_charset=", OPT_ATTRIB_UNDECLARED_CHARSET);
495 #else
496 SKIP_ITEM("undeclared_charset=");
497 #endif /* CHARSET_CONVERSION */
498 break;
499
500 case 'v':
501 MATCH_BOOLEAN("verbatim_handling=", OPT_ATTRIB_VERBATIM_HANDLING);
502 break;
503
504 case 'w':
505 MATCH_BOOLEAN("wrap_on_next_unread=", OPT_ATTRIB_WRAP_ON_NEXT_UNREAD);
506 break;
507
508 case 'x':
509 MATCH_STRING("x_body=", OPT_ATTRIB_X_BODY);
510 MATCH_BOOLEAN("x_comment_to=", OPT_ATTRIB_X_COMMENT_TO);
511 MATCH_STRING("x_headers=", OPT_ATTRIB_X_HEADERS);
512 break;
513
514 default:
515 break;
516 }
517
518 if (!global_file && upgrade && upgrade->state == RC_UPGRADE) {
519 int auto_cc_bcc;
520 int show_info;
521 t_bool auto_bcc = FALSE;
522 t_bool auto_cc = FALSE;
523
524 switch (my_tolower((unsigned char) line[0])) {
525 case 'a':
526 if (match_boolean(line, "auto_bcc=", &auto_bcc)) {
527 if (scopes[num_scope - 1].attribute->auto_cc_bcc & AUTO_CC)
528 auto_cc_bcc = (auto_bcc ? AUTO_CC_BCC : AUTO_CC);
529 else
530 auto_cc_bcc = (auto_bcc ? AUTO_BCC : 0);
531 set_attrib(OPT_ATTRIB_AUTO_CC_BCC, scope, line, &auto_cc_bcc);
532 found = TRUE;
533 break;
534 }
535 if (match_boolean(line, "auto_cc=", &auto_cc)) {
536 if (scopes[num_scope - 1].attribute->auto_cc_bcc & AUTO_BCC)
537 auto_cc_bcc = (auto_cc ? AUTO_CC_BCC : AUTO_BCC);
538 else
539 auto_cc_bcc = (auto_cc ? AUTO_CC : 0);
540 set_attrib(OPT_ATTRIB_AUTO_CC_BCC, scope, line, &auto_cc_bcc);
541 found = TRUE;
542 break;
543 }
544 break;
545
546 case 'p':
547 MATCH_INTEGER("post_proc_type=", OPT_ATTRIB_POST_PROCESS_TYPE, POST_PROC_YES);
548 break;
549
550 case 's':
551 if (match_integer(line, "show_info=", &show_info, 3)) {
552 char *gbuf = my_malloc(23);
553 char *tbuf = my_malloc(23);
554
555 switch (show_info) {
556 case 0:
557 strcpy(gbuf, "%n %m %R %s %F");
558 strcpy(tbuf, "%n %m %T %F");
559 break;
560
561 case 2:
562 strcpy(gbuf, "%n %m %R %S %s %F");
563 strcpy(tbuf, "%n %m [%S] %T %F");
564 break;
565
566 case 3:
567 strcpy(gbuf, "%n %m %R %L %S %s %F");
568 strcpy(tbuf, "%n %m [%L,%S] %T %F");
569 break;
570
571 default:
572 strcpy(gbuf, DEFAULT_GROUP_FORMAT);
573 strcpy(tbuf, DEFAULT_THREAD_FORMAT);
574 break;
575 }
576 set_attrib(OPT_ATTRIB_GROUP_FORMAT, scope, line, gbuf);
577 set_attrib(OPT_ATTRIB_THREAD_FORMAT, scope, line, tbuf);
578 free(gbuf);
579 free(tbuf);
580 found = TRUE;
581 break;
582 }
583 /*
584 * previous versions has always passed groupname to external
585 * commands, now we look for %G
586 *
587 * 8 == sizeof("sigfile=")
588 */
589 if (match_string(line, "sigfile=", buf, sizeof(buf) - 8) && buf[0] == '!') {
590 /* just append %G if ATTRIBUTES_VERSION <= 1.0.8 */
591 if (upgrade && upgrade->file_version < 10009) {
592 char *newbuf = my_malloc(sizeof(buf) - 8 + 4);
593
594 sprintf(newbuf, "%s %s", buf, "%G");
595 set_attrib(OPT_ATTRIB_SIGFILE, scope, line, newbuf);
596 free(newbuf);
597 }
598 break;
599 }
600 MATCH_BOOLEAN("show_only_unread=", OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS);
601 MATCH_INTEGER("sort_art_type=", OPT_ATTRIB_SORT_ARTICLE_TYPE, SORT_ARTICLES_BY_LINES_ASCEND);
602 break;
603
604 case 't':
605 MATCH_INTEGER("thread_arts=", OPT_ATTRIB_THREAD_ARTICLES, THREAD_MAX);
606 break;
607
608 default:
609 break;
610 }
611 }
612
613 if (found)
614 found = FALSE;
615 else {
616 /* TODO: even without DEBUG? */
617 error_message(1, _(txt_bad_attrib), line);
618 #ifdef DEBUG
619 if (debug & (DEBUG_ATTRIB))
620 debug_print_file("ATTRIBUTES", txt_bad_attrib, line);
621 #endif /* DEBUG */
622 }
623 }
624 fclose(fp);
625
626 /*
627 * TODO: do something useful for the other cases
628 */
629 if (!global_file && upgrade && upgrade->state == RC_UPGRADE)
630 write_attributes_file(file);
631
632 FreeAndNull(upgrade);
633
634 } else if (!global_file && startup) {
635 /* no local attributes file, add some useful defaults and write file */
636
637 add_scope("*");
638 snprintf(buf, sizeof(buf), "%s", "~/.tin/headers");
639 set_attrib(OPT_ATTRIB_X_HEADERS, "*", "", buf);
640
641 add_scope("*sources*");
642 num = POST_PROC_SHAR;
643 set_attrib(OPT_ATTRIB_POST_PROCESS_TYPE, "*sources*", "", &num);
644
645 add_scope("*binaries*");
646 num = POST_PROC_YES;
647 set_attrib(OPT_ATTRIB_POST_PROCESS_TYPE, "*binaries*", "", &num);
648 num = FALSE;
649 set_attrib(OPT_ATTRIB_TEX2ISO_CONV, "*binaries*", "", &num);
650 num = TRUE;
651 set_attrib(OPT_ATTRIB_DELETE_TMP_FILES, "*binaries*", "", &num);
652 snprintf(buf, sizeof(buf), "%s", "poster");
653 set_attrib(OPT_ATTRIB_FOLLOWUP_TO, "*binaries*", "", buf);
654
655 write_attributes_file(file);
656 }
657 if (!global_file && startup)
658 startup = FALSE;
659 #ifdef DEBUG
660 if (!global_file)
661 dump_scopes("SCOPES-R");
662 #endif /* DEBUG */
663 }
664
665
666 #define SET_STRING(string) \
667 FreeIfNeeded(curr_scope->attribute->string); \
668 curr_scope->attribute->string = my_strdup((char *) data); \
669 curr_scope->state->string = TRUE; \
670 break
671 #define SET_INTEGER(integer) \
672 curr_scope->attribute->integer = *((int *) data); \
673 curr_scope->state->integer = TRUE; \
674 break
675
676
677 static void
set_attrib(int type,const char * scope,const char * line,void * data)678 set_attrib(
679 int type,
680 const char *scope,
681 const char *line,
682 void *data)
683 {
684 struct t_scope *curr_scope;
685
686 if (scope == NULL || *scope == '\0') { /* No active scope set yet */
687 error_message(2, _(txt_attrib_no_scope), line);
688 #ifdef DEBUG
689 if (debug & DEBUG_ATTRIB)
690 debug_print_file("ATTRIBUTES", txt_attrib_no_scope, line);
691 #endif /* DEBUG */
692 return;
693 }
694
695 if (num_scope > 1) {
696 curr_scope = &scopes[num_scope - 1];
697 /*
698 * Now set the required attribute
699 */
700 switch (type) {
701 case OPT_ATTRIB_MAILDIR:
702 SET_STRING(maildir);
703
704 case OPT_ATTRIB_SAVEDIR:
705 SET_STRING(savedir);
706
707 case OPT_ATTRIB_SAVEFILE:
708 SET_STRING(savefile);
709
710 case OPT_ATTRIB_ORGANIZATION:
711 SET_STRING(organization);
712
713 case OPT_ATTRIB_FROM:
714 SET_STRING(from);
715
716 case OPT_ATTRIB_SIGFILE:
717 SET_STRING(sigfile);
718
719 case OPT_ATTRIB_FOLLOWUP_TO:
720 SET_STRING(followup_to);
721
722 case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
723 SET_INTEGER(add_posted_to_filter);
724
725 case OPT_ATTRIB_ADVERTISING:
726 SET_INTEGER(advertising);
727
728 case OPT_ATTRIB_ALTERNATIVE_HANDLING:
729 SET_INTEGER(alternative_handling);
730
731 case OPT_ATTRIB_ASK_FOR_METAMAIL:
732 SET_INTEGER(ask_for_metamail);
733
734 case OPT_ATTRIB_AUTO_CC_BCC:
735 SET_INTEGER(auto_cc_bcc);
736
737 case OPT_ATTRIB_AUTO_LIST_THREAD:
738 SET_INTEGER(auto_list_thread);
739
740 case OPT_ATTRIB_AUTO_SELECT:
741 SET_INTEGER(auto_select);
742
743 case OPT_ATTRIB_AUTO_SAVE:
744 SET_INTEGER(auto_save);
745
746 case OPT_ATTRIB_BATCH_SAVE:
747 SET_INTEGER(batch_save);
748
749 case OPT_ATTRIB_DATE_FORMAT:
750 SET_STRING(date_format);
751
752 case OPT_ATTRIB_DELETE_TMP_FILES:
753 SET_INTEGER(delete_tmp_files);
754
755 case OPT_ATTRIB_EDITOR_FORMAT:
756 SET_STRING(editor_format);
757
758 case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
759 SET_INTEGER(group_catchup_on_exit);
760
761 case OPT_ATTRIB_GROUP_FORMAT:
762 SET_STRING(group_format);
763
764 case OPT_ATTRIB_MAIL_8BIT_HEADER:
765 SET_INTEGER(mail_8bit_header);
766
767 case OPT_ATTRIB_MAIL_MIME_ENCODING:
768 SET_INTEGER(mail_mime_encoding);
769
770 case OPT_ATTRIB_MARK_IGNORE_TAGS:
771 SET_INTEGER(mark_ignore_tags);
772
773 case OPT_ATTRIB_MARK_SAVED_READ:
774 SET_INTEGER(mark_saved_read);
775
776 case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
777 FreeIfNeeded(curr_scope->attribute->news_headers_to_display);
778 curr_scope->attribute->news_headers_to_display = my_strdup((char *) data);
779 build_news_headers_array(curr_scope->attribute, TRUE);
780 curr_scope->state->news_headers_to_display = TRUE;
781 break;
782
783 case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
784 FreeIfNeeded(curr_scope->attribute->news_headers_to_not_display);
785 curr_scope->attribute->news_headers_to_not_display = my_strdup((char *) data);
786 build_news_headers_array(curr_scope->attribute, FALSE);
787 curr_scope->state->news_headers_to_not_display = TRUE;
788 break;
789
790 case OPT_ATTRIB_POS_FIRST_UNREAD:
791 SET_INTEGER(pos_first_unread);
792
793 case OPT_ATTRIB_POST_8BIT_HEADER:
794 SET_INTEGER(post_8bit_header);
795
796 case OPT_ATTRIB_POST_MIME_ENCODING:
797 SET_INTEGER(post_mime_encoding);
798
799 case OPT_ATTRIB_POST_PROCESS_VIEW:
800 SET_INTEGER(post_process_view);
801
802 #ifndef DISABLE_PRINTING
803 case OPT_ATTRIB_PRINT_HEADER:
804 SET_INTEGER(print_header);
805 #endif /* !DISABLE_PRINTING */
806
807 case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
808 SET_INTEGER(process_only_unread);
809
810 case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
811 SET_INTEGER(prompt_followupto);
812
813 #ifdef HAVE_COLOR
814 case OPT_ATTRIB_EXTQUOTE_HANDLING:
815 SET_INTEGER(extquote_handling);
816 #endif /* HAVE_COLOR */
817
818 case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
819 SET_INTEGER(show_only_unread_arts);
820
821 case OPT_ATTRIB_SIGDASHES:
822 SET_INTEGER(sigdashes);
823
824 case OPT_ATTRIB_SIGNATURE_REPOST:
825 SET_INTEGER(signature_repost);
826
827 case OPT_ATTRIB_START_EDITOR_OFFSET:
828 SET_INTEGER(start_editor_offset);
829
830 case OPT_ATTRIB_THREAD_ARTICLES:
831 SET_INTEGER(thread_articles);
832
833 case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
834 SET_INTEGER(thread_catchup_on_exit);
835
836 case OPT_ATTRIB_THREAD_FORMAT:
837 SET_STRING(thread_format);
838
839 case OPT_ATTRIB_THREAD_PERC:
840 SET_INTEGER(thread_perc);
841
842 case OPT_ATTRIB_SHOW_AUTHOR:
843 SET_INTEGER(show_author);
844
845 case OPT_ATTRIB_SHOW_SIGNATURES:
846 SET_INTEGER(show_signatures);
847
848 case OPT_ATTRIB_TRIM_ARTICLE_BODY:
849 SET_INTEGER(trim_article_body);
850
851 case OPT_ATTRIB_VERBATIM_HANDLING:
852 SET_INTEGER(verbatim_handling);
853
854 case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
855 SET_INTEGER(wrap_on_next_unread);
856
857 case OPT_ATTRIB_SORT_ARTICLE_TYPE:
858 SET_INTEGER(sort_article_type);
859
860 case OPT_ATTRIB_SORT_THREADS_TYPE:
861 SET_INTEGER(sort_threads_type);
862
863 case OPT_ATTRIB_POST_PROCESS_TYPE:
864 SET_INTEGER(post_process_type);
865
866 case OPT_ATTRIB_QUICK_KILL_HEADER:
867 SET_INTEGER(quick_kill_header);
868
869 case OPT_ATTRIB_QUICK_KILL_SCOPE:
870 SET_STRING(quick_kill_scope);
871
872 case OPT_ATTRIB_QUICK_KILL_EXPIRE:
873 SET_INTEGER(quick_kill_expire);
874
875 case OPT_ATTRIB_QUICK_KILL_CASE:
876 SET_INTEGER(quick_kill_case);
877
878 case OPT_ATTRIB_QUICK_SELECT_HEADER:
879 SET_INTEGER(quick_select_header);
880
881 case OPT_ATTRIB_QUICK_SELECT_SCOPE:
882 SET_STRING(quick_select_scope);
883
884 case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
885 SET_INTEGER(quick_select_expire);
886
887 case OPT_ATTRIB_QUICK_SELECT_CASE:
888 SET_INTEGER(quick_select_case);
889
890 case OPT_ATTRIB_MAILING_LIST:
891 SET_STRING(mailing_list);
892
893 #ifdef CHARSET_CONVERSION
894 case OPT_ATTRIB_MM_NETWORK_CHARSET:
895 SET_INTEGER(mm_network_charset);
896
897 case OPT_ATTRIB_UNDECLARED_CHARSET:
898 SET_STRING(undeclared_charset);
899 #endif /* CHARSET_CONVERSION */
900
901 case OPT_ATTRIB_X_HEADERS:
902 SET_STRING(x_headers);
903
904 case OPT_ATTRIB_X_BODY:
905 SET_STRING(x_body);
906
907 case OPT_ATTRIB_X_COMMENT_TO:
908 SET_INTEGER(x_comment_to);
909
910 case OPT_ATTRIB_FCC:
911 SET_STRING(fcc);
912
913 case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
914 SET_STRING(news_quote_format);
915
916 case OPT_ATTRIB_QUOTE_CHARS:
917 SET_STRING(quote_chars);
918
919 case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
920 SET_STRING(mime_types_to_save);
921
922 case OPT_ATTRIB_MIME_FORWARD:
923 SET_INTEGER(mime_forward);
924
925 #ifdef HAVE_ISPELL
926 case OPT_ATTRIB_ISPELL:
927 SET_STRING(ispell);
928 #endif /* HAVE_ISPELL */
929
930 case OPT_ATTRIB_TEX2ISO_CONV:
931 SET_INTEGER(tex2iso_conv);
932
933 default:
934 break;
935 }
936 }
937 }
938
939
940 /*
941 * Insert a new scope entry into scopes[] and return the index.
942 */
943 int
add_scope(const char * scope)944 add_scope(
945 const char *scope)
946 {
947 if (!scope || !*scope)
948 return 0;
949
950 if ((num_scope >= max_scope) || (num_scope < 0) || (scopes == NULL))
951 expand_scope();
952
953 scopes[num_scope].scope = my_strdup(scope);
954 scopes[num_scope].attribute = my_malloc(sizeof(struct t_attribute));
955 set_default_attributes(scopes[num_scope].attribute, NULL, FALSE);
956 scopes[num_scope].state = my_malloc(sizeof(struct t_attribute_state));
957 set_default_state(scopes[num_scope].state);
958 scopes[num_scope].global = FALSE;
959 return num_scope++;
960 }
961
962
963 #define SET_ATTRIB(attr) do { \
964 if (curr_scope->state->attr) \
965 group->attribute->attr = curr_scope->attribute->attr; \
966 } while (0)
967
968
969 /*
970 * Set the attributes of all groups
971 */
972 void
assign_attributes_to_groups(void)973 assign_attributes_to_groups(
974 void)
975 {
976 struct t_group *group;
977 struct t_scope *default_scope, *curr_scope;
978 t_bool found;
979 int i, j;
980 long processed = 0L;
981 #ifdef CHARSET_CONVERSION
982 t_bool is_7bit;
983 #endif /* CHARSET_CONVERSION */
984
985 if (!batch_mode || verbose)
986 wait_message(0, _("Processing attributes... ")); /* TODO: -> lang.c */
987
988 default_scope = &scopes[0];
989 for_each_group(i) {
990 if (++processed % (MODULO_COUNT_NUM) == 0)
991 spin_cursor();
992 group = &active[i];
993 found = FALSE;
994 for (j = 1; j < num_scope; j++) {
995 curr_scope = &scopes[j];
996 if (match_group_list(group->name, curr_scope->scope)) {
997 if (group->attribute == NULL || group->attribute == default_scope->attribute) {
998 group->attribute = my_malloc(sizeof(struct t_attribute));
999 set_default_attributes(group->attribute, default_scope->attribute, FALSE);
1000 found = TRUE;
1001 }
1002 if (!found) {
1003 set_default_attributes(group->attribute, default_scope->attribute, FALSE);
1004 found = TRUE;
1005 }
1006 SET_ATTRIB(maildir);
1007 SET_ATTRIB(savedir);
1008 SET_ATTRIB(savefile);
1009 SET_ATTRIB(sigfile);
1010 SET_ATTRIB(group_format);
1011 SET_ATTRIB(thread_format);
1012 SET_ATTRIB(date_format);
1013 SET_ATTRIB(editor_format);
1014 SET_ATTRIB(organization);
1015 SET_ATTRIB(fcc);
1016 SET_ATTRIB(followup_to);
1017 SET_ATTRIB(mailing_list);
1018 SET_ATTRIB(x_headers);
1019 SET_ATTRIB(x_body);
1020 SET_ATTRIB(from);
1021 SET_ATTRIB(news_quote_format);
1022 SET_ATTRIB(quote_chars);
1023 SET_ATTRIB(mime_types_to_save);
1024 #ifdef HAVE_ISPELL
1025 SET_ATTRIB(ispell);
1026 #endif /* HAVE_ISPELL */
1027 #ifdef CHARSET_CONVERSION
1028 SET_ATTRIB(mm_network_charset);
1029 SET_ATTRIB(undeclared_charset);
1030 #endif /* CHARSET_CONVERSION */
1031 SET_ATTRIB(quick_kill_scope);
1032 SET_ATTRIB(quick_kill_header);
1033 SET_ATTRIB(quick_kill_case);
1034 SET_ATTRIB(quick_kill_expire);
1035 SET_ATTRIB(quick_select_scope);
1036 SET_ATTRIB(quick_select_header);
1037 SET_ATTRIB(quick_select_case);
1038 SET_ATTRIB(quick_select_expire);
1039 SET_ATTRIB(show_only_unread_arts);
1040 SET_ATTRIB(thread_articles);
1041 SET_ATTRIB(thread_catchup_on_exit);
1042 SET_ATTRIB(thread_perc);
1043 SET_ATTRIB(sort_article_type);
1044 SET_ATTRIB(sort_threads_type);
1045 SET_ATTRIB(show_author);
1046 SET_ATTRIB(show_signatures);
1047 SET_ATTRIB(trim_article_body);
1048 SET_ATTRIB(verbatim_handling);
1049 #ifdef HAVE_COLOR
1050 SET_ATTRIB(extquote_handling);
1051 #endif /* HAVE_COLOR */
1052 SET_ATTRIB(wrap_on_next_unread);
1053 SET_ATTRIB(add_posted_to_filter);
1054 SET_ATTRIB(advertising);
1055 SET_ATTRIB(alternative_handling);
1056 SET_ATTRIB(ask_for_metamail);
1057 SET_ATTRIB(auto_cc_bcc);
1058 SET_ATTRIB(auto_list_thread);
1059 SET_ATTRIB(auto_save);
1060 SET_ATTRIB(auto_select);
1061 SET_ATTRIB(batch_save);
1062 SET_ATTRIB(delete_tmp_files);
1063 SET_ATTRIB(group_catchup_on_exit);
1064 SET_ATTRIB(mail_8bit_header);
1065 SET_ATTRIB(mail_mime_encoding);
1066 SET_ATTRIB(mark_ignore_tags);
1067 SET_ATTRIB(mark_saved_read);
1068 if (curr_scope->state->news_headers_to_display)
1069 group->attribute->headers_to_display = curr_scope->attribute->headers_to_display;
1070 if (curr_scope->state->news_headers_to_not_display)
1071 group->attribute->headers_to_not_display = curr_scope->attribute->headers_to_not_display;
1072 SET_ATTRIB(pos_first_unread);
1073 SET_ATTRIB(post_8bit_header);
1074 SET_ATTRIB(post_mime_encoding);
1075 SET_ATTRIB(post_process_view);
1076 SET_ATTRIB(post_process_type);
1077 #ifndef DISABLE_PRINTING
1078 SET_ATTRIB(print_header);
1079 #endif /* !DISABLE_PRINTING */
1080 SET_ATTRIB(process_only_unread);
1081 SET_ATTRIB(prompt_followupto);
1082 SET_ATTRIB(sigdashes);
1083 SET_ATTRIB(signature_repost);
1084 SET_ATTRIB(start_editor_offset);
1085 SET_ATTRIB(x_comment_to);
1086 SET_ATTRIB(tex2iso_conv);
1087 SET_ATTRIB(mime_forward);
1088 }
1089 }
1090 if (found) {
1091 /*
1092 * sort out conflicting settings
1093 */
1094 #ifdef CHARSET_CONVERSION
1095 /*
1096 * check if we have a 7bit charset but a !7bit encoding
1097 * or a 8bit charset but a !8bit encoding, update encoding if needed
1098 */
1099 is_7bit = FALSE;
1100 for (j = 0; txt_mime_7bit_charsets[j] != NULL; j++) {
1101 if (!strcasecmp(txt_mime_charsets[group->attribute->mm_network_charset], txt_mime_7bit_charsets[j])) {
1102 is_7bit = TRUE;
1103 break;
1104 }
1105 }
1106 if (is_7bit) {
1107 group->attribute->mail_mime_encoding = group->attribute->post_mime_encoding = MIME_ENCODING_7BIT;
1108 } else {
1109 if (group->attribute->mail_mime_encoding == MIME_ENCODING_7BIT)
1110 group->attribute->mail_mime_encoding = MIME_ENCODING_QP;
1111 if (group->attribute->post_mime_encoding == MIME_ENCODING_7BIT)
1112 group->attribute->post_mime_encoding = MIME_ENCODING_8BIT;
1113 }
1114 #endif /* CHARSET_CONVERSION */
1115 /* do not use 8 bit headers if mime encoding is not 8bit */
1116 if (group->attribute->mail_mime_encoding != MIME_ENCODING_8BIT)
1117 group->attribute->mail_8bit_header = FALSE;
1118 if (group->attribute->post_mime_encoding != MIME_ENCODING_8BIT)
1119 group->attribute->post_8bit_header = FALSE;
1120 } else {
1121 if (group->attribute && !group->attribute->global)
1122 free(group->attribute);
1123 group->attribute = default_scope->attribute;
1124 }
1125 }
1126 #ifdef DEBUG
1127 dump_attributes();
1128 # if 0
1129 debug_print_filter_attributes();
1130 # endif /* 0 */
1131 #endif /* DEBUG */
1132
1133 if (!batch_mode || verbose)
1134 my_fputc('\n', stdout);
1135
1136 if (!cmd_line && !batch_mode)
1137 clear_message();
1138 }
1139
1140
1141 /*
1142 * (re)build scope->headers_to_[not_]display array
1143 */
1144 void
build_news_headers_array(struct t_attribute * scope,t_bool header_to_display)1145 build_news_headers_array(
1146 struct t_attribute *scope,
1147 t_bool header_to_display)
1148 {
1149 if (header_to_display) {
1150 if (scope->headers_to_display == NULL)
1151 scope->headers_to_display = my_malloc(sizeof(struct t_newsheader));
1152 else {
1153 if (scope->headers_to_display->header)
1154 FreeIfNeeded(*scope->headers_to_display->header);
1155 FreeIfNeeded(scope->headers_to_display->header);
1156 }
1157 scope->headers_to_display->header = ulBuildArgv(scope->news_headers_to_display, &scope->headers_to_display->num);
1158 } else {
1159 if (scope->headers_to_not_display == NULL)
1160 scope->headers_to_not_display = my_malloc(sizeof(struct t_newsheader));
1161 else {
1162 if (scope->headers_to_not_display->header)
1163 FreeIfNeeded(*scope->headers_to_not_display->header);
1164 FreeIfNeeded(scope->headers_to_not_display->header);
1165 }
1166 scope->headers_to_not_display->header = ulBuildArgv(scope->news_headers_to_not_display, &scope->headers_to_not_display->num);
1167 }
1168 }
1169
1170
1171 /*
1172 * Save the scope attributes from scopes[] to ~/.tin/attributes
1173 */
1174 void
write_attributes_file(const char * file)1175 write_attributes_file(
1176 const char *file)
1177 {
1178 FILE *fp;
1179 char *new_file;
1180 int i;
1181 long fpos;
1182
1183 if ((batch_mode || no_write || num_scope < 1) && file_size(file) != -1L)
1184 return;
1185
1186 new_file = get_tmpfilename(file);
1187
1188 if ((fp = fopen(new_file, "w+")) == NULL) {
1189 error_message(2, _(txt_filesystem_full_backup), ATTRIBUTES_FILE);
1190 free(new_file);
1191 return;
1192 }
1193
1194 wait_message(0, _(txt_writing_attributes_file));
1195
1196 #ifdef DEBUG
1197 dump_scopes("SCOPES-W");
1198 #endif /* DEBUG */
1199
1200 /*
1201 * TODO: sort in a useful order
1202 * move strings to lang.c
1203 */
1204 fprintf(fp, "# Group attributes file V%s for the TIN newsreader\n", ATTRIBUTES_VERSION);
1205 fprintf(fp, _("# Do not edit this comment block\n#\n"));
1206 fprintf(fp, _("# scope=STRING (eg. alt.*,!alt.bin*) [mandatory]\n"));
1207 fprintf(fp, _("# add_posted_to_filter=ON/OFF\n"));
1208 fprintf(fp, _("# advertising=ON/OFF\n"));
1209 fprintf(fp, _("# alternative_handling=ON/OFF\n"));
1210 fprintf(fp, _("# ask_for_metamail=ON/OFF\n"));
1211 fprintf(fp, _("# auto_cc_bcc=NUM\n"));
1212 fprintf(fp, _("# 0=No, 1=Cc, 2=Bcc, 3=Cc and Bcc\n"));
1213 fprintf(fp, _("# auto_list_thread=ON/OFF\n"));
1214 fprintf(fp, _("# auto_save=ON/OFF\n"));
1215 fprintf(fp, _("# auto_select=ON/OFF\n"));
1216 fprintf(fp, _("# batch_save=ON/OFF\n"));
1217 fprintf(fp, _("# date_format=STRING (eg. %%a, %%d %%b %%Y %%H:%%M:%%S)\n"));
1218 fprintf(fp, _("# delete_tmp_files=ON/OFF\n"));
1219 fprintf(fp, _("# editor_format=STRING (eg. %%E +%%N %%F)\n"));
1220 fprintf(fp, _("# fcc=STRING (eg. =mailbox)\n"));
1221 fprintf(fp, _("# followup_to=STRING\n"));
1222 fprintf(fp, _("# from=STRING (just append wanted From:-line, don't use quotes)\n"));
1223 fprintf(fp, _("# group_catchup_on_exit=ON/OFF\n"));
1224 fprintf(fp, _("# group_format=STRING (eg. %%n %%m %%R %%L %%s %%F)\n"));
1225 fprintf(fp, _("# mail_8bit_header=ON/OFF\n"));
1226 fprintf(fp, _("# mail_mime_encoding=supported_encoding"));
1227 for (i = 0; txt_mime_encodings[i] != NULL; i++) {
1228 if (!(i % 5))
1229 fprintf(fp, "\n# ");
1230 fprintf(fp, "%s, ", txt_mime_encodings[i]);
1231 }
1232 fprintf(fp, "\n");
1233 #ifdef HAVE_ISPELL
1234 fprintf(fp, _("# ispell=STRING\n"));
1235 #endif /* HAVE_ISPELL */
1236 fprintf(fp, _("# maildir=STRING (eg. ~/Mail)\n"));
1237 fprintf(fp, _("# mailing_list=STRING (eg. majordomo@example.org)\n"));
1238 fprintf(fp, _("# mime_types_to_save=STRING (eg. image/*,!image/bmp)\n"));
1239 fprintf(fp, _("# mark_ignore_tags=ON/OFF\n"));
1240 fprintf(fp, _("# mark_saved_read=ON/OFF\n"));
1241 fprintf(fp, _("# mime_forward=ON/OFF\n"));
1242 #ifdef CHARSET_CONVERSION
1243 fprintf(fp, _("# mm_network_charset=supported_charset"));
1244 for (i = 0; txt_mime_charsets[i] != NULL; i++) {
1245 if (!(i % 5)) /* start new line */
1246 fprintf(fp, "\n# ");
1247 fprintf(fp, "%s, ", txt_mime_charsets[i]);
1248 }
1249 fprintf(fp, "\n");
1250 fprintf(fp, _("# undeclared_charset=STRING (default is US-ASCII)\n"));
1251 #endif /* CHARSET_CONVERSION */
1252 fprintf(fp, _("# news_headers_to_display=STRING\n"));
1253 fprintf(fp, _("# news_headers_to_not_display=STRING\n"));
1254 fprintf(fp, _("# news_quote_format=STRING\n"));
1255 fprintf(fp, _("# organization=STRING (if beginning with '/' read from file)\n"));
1256 fprintf(fp, _("# pos_first_unread=ON/OFF\n"));
1257 fprintf(fp, _("# post_8bit_header=ON/OFF\n"));
1258 fprintf(fp, _("# post_mime_encoding=supported_encoding"));
1259 for (i = 0; txt_mime_encodings[i] != NULL; i++) {
1260 if (!(i % 5))
1261 fprintf(fp, "\n# ");
1262 fprintf(fp, "%s, ", txt_mime_encodings[i]);
1263 }
1264 fprintf(fp, "\n");
1265 fprintf(fp, _("# post_process_type=NUM\n"));
1266 fprintf(fp, "# %d=%s, %d=%s, %d=%s\n",
1267 POST_PROC_NO, _(txt_post_process_types[POST_PROC_NO]),
1268 POST_PROC_SHAR, _(txt_post_process_types[POST_PROC_SHAR]),
1269 POST_PROC_YES, _(txt_post_process_types[POST_PROC_YES]));
1270 fprintf(fp, _("# post_process_view=ON/OFF\n"));
1271 fprintf(fp, _("# quick_kill_scope=STRING (ie. talk.*)\n"));
1272 fprintf(fp, _("# quick_kill_expire=ON/OFF\n"));
1273 fprintf(fp, _("# quick_kill_case=ON/OFF\n"));
1274 fprintf(fp, _("# quick_kill_header=NUM\n"));
1275 fprintf(fp, _("# 0=Subject: (case sensitive) 1=Subject: (ignore case)\n"));
1276 fprintf(fp, _("# 2=From: (case sensitive) 3=From: (ignore case)\n"));
1277 fprintf(fp, _("# 4=Message-ID: & full References: line\n"));
1278 fprintf(fp, _("# 5=Message-ID: & last References: entry only\n"));
1279 fprintf(fp, _("# 6=Message-ID: entry only 7=Lines:\n"));
1280 fprintf(fp, _("# quick_select_scope=STRING\n"));
1281 fprintf(fp, _("# quick_select_expire=ON/OFF\n"));
1282 fprintf(fp, _("# quick_select_case=ON/OFF\n"));
1283 fprintf(fp, _("# quick_select_header=NUM\n"));
1284 fprintf(fp, _("# 0=Subject: (case sensitive) 1=Subject: (ignore case)\n"));
1285 fprintf(fp, _("# 2=From: (case sensitive) 3=From: (ignore case)\n"));
1286 fprintf(fp, _("# 4=Message-ID: & full References: line\n"));
1287 fprintf(fp, _("# 5=Message-ID: & last References: entry only\n"));
1288 fprintf(fp, _("# 6=Message-ID: entry only 7=Lines:\n"));
1289 fprintf(fp, _("# quote_chars=STRING (%%I for initials)\n"));
1290 #ifndef DISABLE_PRINTING
1291 fprintf(fp, _("# print_header=ON/OFF\n"));
1292 #endif /* !DISABLE_PRINTING */
1293 fprintf(fp, _("# process_only_unread=ON/OFF\n"));
1294 fprintf(fp, _("# prompt_followupto=ON/OFF\n"));
1295 fprintf(fp, _("# savedir=STRING (eg. ~user/News)\n"));
1296 fprintf(fp, _("# savefile=STRING (eg. =linux)\n"));
1297 fprintf(fp, _("# sigfile=STRING (eg. $var/sig)\n"));
1298 fprintf(fp, _("# show_author=NUM\n"));
1299 fprintf(fp, "# %d=%s, %d=%s, %d=%s, %d=%s\n",
1300 SHOW_FROM_NONE, _(txt_show_from[SHOW_FROM_NONE]),
1301 SHOW_FROM_ADDR, _(txt_show_from[SHOW_FROM_ADDR]),
1302 SHOW_FROM_NAME, _(txt_show_from[SHOW_FROM_NAME]),
1303 SHOW_FROM_BOTH, _(txt_show_from[SHOW_FROM_BOTH]));
1304 fprintf(fp, _("# show_signatures=ON/OFF\n"));
1305 fprintf(fp, _("# show_only_unread_arts=ON/OFF\n"));
1306 fprintf(fp, _("# sigdashes=ON/OFF\n"));
1307 fprintf(fp, _("# signature_repost=ON/OFF\n"));
1308 fprintf(fp, _("# sort_article_type=NUM\n"));
1309 fprintf(fp, "# %d=%s,\n",
1310 SORT_ARTICLES_BY_NOTHING, _(txt_sort_a_type[SORT_ARTICLES_BY_NOTHING]));
1311 fprintf(fp, "# %d=%s, %d=%s,\n",
1312 SORT_ARTICLES_BY_SUBJ_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SUBJ_DESCEND]),
1313 SORT_ARTICLES_BY_SUBJ_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SUBJ_ASCEND]));
1314 fprintf(fp, "# %d=%s, %d=%s,\n",
1315 SORT_ARTICLES_BY_FROM_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_FROM_DESCEND]),
1316 SORT_ARTICLES_BY_FROM_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_FROM_ASCEND]));
1317 fprintf(fp, "# %d=%s, %d=%s,\n",
1318 SORT_ARTICLES_BY_DATE_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_DATE_DESCEND]),
1319 SORT_ARTICLES_BY_DATE_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_DATE_ASCEND]));
1320 fprintf(fp, "# %d=%s, %d=%s,\n",
1321 SORT_ARTICLES_BY_SCORE_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SCORE_DESCEND]),
1322 SORT_ARTICLES_BY_SCORE_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SCORE_ASCEND]));
1323 fprintf(fp, "# %d=%s, %d=%s\n",
1324 SORT_ARTICLES_BY_LINES_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_LINES_DESCEND]),
1325 SORT_ARTICLES_BY_LINES_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_LINES_ASCEND]));
1326 fprintf(fp, _("# sort_threads_type=NUM\n"));
1327 fprintf(fp, "# %d=%s, %d=%s, %d=%s\n",
1328 SORT_THREADS_BY_NOTHING, _(txt_sort_t_type[SORT_THREADS_BY_NOTHING]),
1329 SORT_THREADS_BY_SCORE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_DESCEND]),
1330 SORT_THREADS_BY_SCORE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_ASCEND]));
1331 fprintf(fp, "# %d=%s\n",
1332 SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND]));
1333 fprintf(fp, "# %d=%s\n",
1334 SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND]));
1335 fprintf(fp, _("# start_editor_offset=ON/OFF\n"));
1336 fprintf(fp, _("# tex2iso_conv=ON/OFF\n"));
1337 fprintf(fp, _("# thread_catchup_on_exit=ON/OFF\n"));
1338 fprintf(fp, _("# thread_articles=NUM"));
1339 for (i = 0; i <= THREAD_MAX; i++) {
1340 if (!(i % 2))
1341 fprintf(fp, "\n# ");
1342 fprintf(fp, "%d=%s, ", i, _(txt_threading[i]));
1343 }
1344 fprintf(fp, "\n");
1345 fprintf(fp, _("# thread_format=STRING (eg. %%n %%m [%%L] %%T %%F)\n"));
1346 fprintf(fp, _("# thread_perc=NUM\n"));
1347 fprintf(fp, _("# trim_article_body=NUM\n"));
1348 fprintf(fp, _("# 0 = Don't trim article body\n"));
1349 fprintf(fp, _("# 1 = Skip leading blank lines\n"));
1350 fprintf(fp, _("# 2 = Skip trailing blank lines\n"));
1351 fprintf(fp, _("# 3 = Skip leading and trailing blank lines\n"));
1352 fprintf(fp, _("# 4 = Compact multiple blank lines between text blocks\n"));
1353 fprintf(fp, _("# 5 = Compact multiple blank lines between text blocks and skip\n# leading blank lines\n"));
1354 fprintf(fp, _("# 6 = Compact multiple blank lines between text blocks and skip\n# trailing blank lines\n"));
1355 fprintf(fp, _("# 7 = Compact multiple blank lines between text blocks and skip\n# leading and trailing blank lines\n"));
1356 fprintf(fp, _("# verbatim_handling=ON/OFF\n"));
1357 #ifdef HAVE_COLOR
1358 fprintf(fp, _("# extquote_handling=ON/OFF\n"));
1359 #endif /* HAVE_COLOR */
1360 fprintf(fp, _("# wrap_on_next_unread=ON/OFF\n"));
1361 fprintf(fp, _("# x_body=STRING (eg. ~/.tin/extra-body-text)\n"));
1362 fprintf(fp, _("# x_comment_to=ON/OFF\n"));
1363 fprintf(fp, _("# x_headers=STRING (eg. ~/.tin/extra-headers)\n"));
1364 fprintf(fp, _("#\n# Note that it is best to put general (global scoping)\n"));
1365 fprintf(fp, _("# entries first followed by group specific entries.\n#\n"));
1366 fprintf(fp, _("############################################################################\n"));
1367
1368 /*
1369 * determine the file offset
1370 * this is necessary because a changed locale setting
1371 * may lead to an invalid offset
1372 */
1373 if ((fpos = ftell(fp)) <= 0) {
1374 clearerr(fp);
1375 fclose(fp);
1376 unlink(new_file);
1377 free(new_file);
1378 error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
1379 return;
1380 }
1381 rewind(fp);
1382 attrib_file_offset = 1;
1383 while ((i = fgetc(fp)) != EOF) {
1384 if (i == '\n')
1385 attrib_file_offset++;
1386 }
1387 if (fseek(fp, fpos, SEEK_SET)) {
1388 clearerr(fp);
1389 fclose(fp);
1390 unlink(new_file);
1391 free(new_file);
1392 error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
1393 return;
1394 }
1395
1396 if ((num_scope > 0) && (scopes != NULL)) {
1397 struct t_scope *scope;
1398
1399 for (i = 1; i < num_scope; i++) {
1400 scope = &scopes[i];
1401 if (!scope->global) {
1402 fprintf(fp, "\nscope=%s\n", scope->scope);
1403 if (scope->state->add_posted_to_filter)
1404 fprintf(fp, "add_posted_to_filter=%s\n", print_boolean(scope->attribute->add_posted_to_filter));
1405 if (scope->state->advertising)
1406 fprintf(fp, "advertising=%s\n", print_boolean(scope->attribute->advertising));
1407 if (scope->state->alternative_handling)
1408 fprintf(fp, "alternative_handling=%s\n", print_boolean(scope->attribute->alternative_handling));
1409 if (scope->state->ask_for_metamail)
1410 fprintf(fp, "ask_for_metamail=%s\n", print_boolean(scope->attribute->ask_for_metamail));
1411 if (scope->state->auto_cc_bcc)
1412 fprintf(fp, "auto_cc_bcc=%u\n", scope->attribute->auto_cc_bcc);
1413 if (scope->state->auto_list_thread)
1414 fprintf(fp, "auto_list_thread=%s\n", print_boolean(scope->attribute->auto_list_thread));
1415 if (scope->state->auto_select)
1416 fprintf(fp, "auto_select=%s\n", print_boolean(scope->attribute->auto_select));
1417 if (scope->state->auto_save)
1418 fprintf(fp, "auto_save=%s\n", print_boolean(scope->attribute->auto_save));
1419 if (scope->state->batch_save)
1420 fprintf(fp, "batch_save=%s\n", print_boolean(scope->attribute->batch_save));
1421 if (scope->state->date_format && scope->attribute->date_format)
1422 fprintf(fp, "date_format=%s\n", scope->attribute->date_format);
1423 if (scope->state->delete_tmp_files)
1424 fprintf(fp, "delete_tmp_files=%s\n", print_boolean(scope->attribute->delete_tmp_files));
1425 if (scope->state->editor_format && scope->attribute->editor_format)
1426 fprintf(fp, "editor_format=%s\n", scope->attribute->editor_format);
1427 #ifdef HAVE_COLOR
1428 if (scope->state->extquote_handling)
1429 fprintf(fp, "extquote_handling=%s\n", print_boolean(scope->attribute->extquote_handling));
1430 #endif /* HAVE_COLOR */
1431 if (scope->state->fcc && scope->attribute->fcc)
1432 fprintf(fp, "fcc=%s\n", scope->attribute->fcc);
1433 if (scope->state->followup_to && scope->attribute->followup_to)
1434 fprintf(fp, "followup_to=%s\n", scope->attribute->followup_to);
1435 if (scope->state->from && scope->attribute->from)
1436 fprintf(fp, "from=%s\n", scope->attribute->from);
1437 if (scope->state->group_catchup_on_exit)
1438 fprintf(fp, "group_catchup_on_exit=%s\n", print_boolean(scope->attribute->group_catchup_on_exit));
1439 if (scope->state->group_format && scope->attribute->group_format)
1440 fprintf(fp, "group_format=%s\n", scope->attribute->group_format);
1441 if (scope->state->mail_8bit_header)
1442 fprintf(fp, "mail_8bit_header=%s\n", print_boolean(scope->attribute->mail_8bit_header));
1443 if (scope->state->mail_mime_encoding)
1444 fprintf(fp, "mail_mime_encoding=%s\n", txt_mime_encodings[scope->attribute->mail_mime_encoding]);
1445 #ifdef HAVE_ISPELL
1446 if (scope->state->ispell && scope->attribute->ispell)
1447 fprintf(fp, "ispell=%s\n", scope->attribute->ispell);
1448 #endif /* HAVE_ISPELL */
1449 if (scope->state->maildir && scope->attribute->maildir)
1450 fprintf(fp, "maildir=%s\n", scope->attribute->maildir);
1451 if (scope->state->mailing_list && scope->attribute->mailing_list)
1452 fprintf(fp, "mailing_list=%s\n", scope->attribute->mailing_list);
1453 if (scope->state->mark_ignore_tags)
1454 fprintf(fp, "mark_ignore_tags=%s\n", print_boolean(scope->attribute->mark_ignore_tags));
1455 if (scope->state->mark_saved_read)
1456 fprintf(fp, "mark_saved_read=%s\n", print_boolean(scope->attribute->mark_saved_read));
1457 if (scope->state->mime_forward)
1458 fprintf(fp, "mime_forward=%s\n", print_boolean(scope->attribute->mime_forward));
1459 if (scope->state->mime_types_to_save && scope->attribute->mime_types_to_save)
1460 fprintf(fp, "mime_types_to_save=%s\n", scope->attribute->mime_types_to_save);
1461 #ifdef CHARSET_CONVERSION
1462 if (scope->state->mm_network_charset)
1463 fprintf(fp, "mm_network_charset=%s\n", txt_mime_charsets[scope->attribute->mm_network_charset]);
1464 if (scope->state->undeclared_charset && scope->attribute->undeclared_charset)
1465 fprintf(fp, "undeclared_charset=%s\n", scope->attribute->undeclared_charset);
1466 #endif /* CHARSET_CONVERSION */
1467 if (scope->state->news_headers_to_display && scope->attribute->news_headers_to_display)
1468 fprintf(fp, "news_headers_to_display=%s\n", scope->attribute->news_headers_to_display);
1469 if (scope->state->news_headers_to_not_display && scope->attribute->news_headers_to_not_display)
1470 fprintf(fp, "news_headers_to_not_display=%s\n", scope->attribute->news_headers_to_not_display);
1471 if (scope->state->news_quote_format && scope->attribute->news_quote_format)
1472 fprintf(fp, "news_quote_format=%s\n", scope->attribute->news_quote_format);
1473 if (scope->state->organization && scope->attribute->organization)
1474 fprintf(fp, "organization=%s\n", scope->attribute->organization);
1475 if (scope->state->pos_first_unread)
1476 fprintf(fp, "pos_first_unread=%s\n", print_boolean(scope->attribute->pos_first_unread));
1477 if (scope->state->post_8bit_header)
1478 fprintf(fp, "post_8bit_header=%s\n", print_boolean(scope->attribute->post_8bit_header));
1479 if (scope->state->post_mime_encoding)
1480 fprintf(fp, "post_mime_encoding=%s\n", txt_mime_encodings[scope->attribute->post_mime_encoding]);
1481 if (scope->state->post_process_view)
1482 fprintf(fp, "post_process_view=%s\n", print_boolean(scope->attribute->post_process_view));
1483 if (scope->state->post_process_type)
1484 fprintf(fp, "post_process_type=%u\n", scope->attribute->post_process_type);
1485 #ifndef DISABLE_PRINTING
1486 if (scope->state->print_header)
1487 fprintf(fp, "print_header=%s\n", print_boolean(scope->attribute->print_header));
1488 #endif /* !DISABLE_PRINTING */
1489 if (scope->state->process_only_unread)
1490 fprintf(fp, "process_only_unread=%s\n", print_boolean(scope->attribute->process_only_unread));
1491 if (scope->state->prompt_followupto)
1492 fprintf(fp, "prompt_followupto=%s\n", print_boolean(scope->attribute->prompt_followupto));
1493 if (scope->state->quick_kill_scope && scope->attribute->quick_kill_scope)
1494 fprintf(fp, "quick_kill_scope=%s\n", scope->attribute->quick_kill_scope);
1495 if (scope->state->quick_kill_case)
1496 fprintf(fp, "quick_kill_case=%s\n", print_boolean(scope->attribute->quick_kill_case));
1497 if (scope->state->quick_kill_expire)
1498 fprintf(fp, "quick_kill_expire=%s\n", print_boolean(scope->attribute->quick_kill_expire));
1499 if (scope->state->quick_kill_header)
1500 fprintf(fp, "quick_kill_header=%u\n", scope->attribute->quick_kill_header);
1501 if (scope->state->quick_select_scope && scope->attribute->quick_select_scope)
1502 fprintf(fp, "quick_select_scope=%s\n", scope->attribute->quick_select_scope);
1503 if (scope->state->quick_select_case)
1504 fprintf(fp, "quick_select_case=%s\n", print_boolean(scope->attribute->quick_select_case));
1505 if (scope->state->quick_select_expire)
1506 fprintf(fp, "quick_select_expire=%s\n", print_boolean(scope->attribute->quick_select_expire));
1507 if (scope->state->quick_select_header)
1508 fprintf(fp, "quick_select_header=%u\n", scope->attribute->quick_select_header);
1509 if (scope->state->quote_chars && scope->attribute->quote_chars)
1510 fprintf(fp, "quote_chars=%s\n", quote_space_to_dash(scope->attribute->quote_chars));
1511 if (scope->state->savedir && scope->attribute->savedir)
1512 fprintf(fp, "savedir=%s\n", scope->attribute->savedir);
1513 if (scope->state->savefile && scope->attribute->savefile)
1514 fprintf(fp, "savefile=%s\n", scope->attribute->savefile);
1515 if (scope->state->show_author)
1516 fprintf(fp, "show_author=%u\n", scope->attribute->show_author);
1517 if (scope->state->show_only_unread_arts)
1518 fprintf(fp, "show_only_unread_arts=%s\n", print_boolean(scope->attribute->show_only_unread_arts));
1519 if (scope->state->show_signatures)
1520 fprintf(fp, "show_signatures=%s\n", print_boolean(scope->attribute->show_signatures));
1521 if (scope->state->sigdashes)
1522 fprintf(fp, "sigdashes=%s\n", print_boolean(scope->attribute->sigdashes));
1523 if (scope->state->sigfile && scope->attribute->sigfile)
1524 fprintf(fp, "sigfile=%s\n", scope->attribute->sigfile);
1525 if (scope->state->signature_repost)
1526 fprintf(fp, "signature_repost=%s\n", print_boolean(scope->attribute->signature_repost));
1527 if (scope->state->sort_article_type)
1528 fprintf(fp, "sort_article_type=%u\n", scope->attribute->sort_article_type);
1529 if (scope->state->sort_threads_type)
1530 fprintf(fp, "sort_threads_type=%u\n", scope->attribute->sort_threads_type);
1531 if (scope->state->start_editor_offset)
1532 fprintf(fp, "start_editor_offset=%s\n", print_boolean(scope->attribute->start_editor_offset));
1533 if (scope->state->tex2iso_conv)
1534 fprintf(fp, "tex2iso_conv=%s\n", print_boolean(scope->attribute->tex2iso_conv));
1535 if (scope->state->thread_articles)
1536 fprintf(fp, "thread_articles=%u\n", scope->attribute->thread_articles);
1537 if (scope->state->thread_catchup_on_exit)
1538 fprintf(fp, "thread_catchup_on_exit=%s\n", print_boolean(scope->attribute->thread_catchup_on_exit));
1539 if (scope->state->thread_format && scope->attribute->thread_format)
1540 fprintf(fp, "thread_format=%s\n", scope->attribute->thread_format);
1541 if (scope->state->thread_perc)
1542 fprintf(fp, "thread_perc=%u\n", scope->attribute->thread_perc);
1543 if (scope->state->trim_article_body)
1544 fprintf(fp, "trim_article_body=%u\n", scope->attribute->trim_article_body);
1545 if (scope->state->verbatim_handling)
1546 fprintf(fp, "verbatim_handling=%s\n", print_boolean(scope->attribute->verbatim_handling));
1547 if (scope->state->wrap_on_next_unread)
1548 fprintf(fp, "wrap_on_next_unread=%s\n", print_boolean(scope->attribute->wrap_on_next_unread));
1549 if (scope->state->x_headers && scope->attribute->x_headers)
1550 fprintf(fp, "x_headers=%s\n", scope->attribute->x_headers);
1551 if (scope->state->x_body && scope->attribute->x_body)
1552 fprintf(fp, "x_body=%s\n", scope->attribute->x_body);
1553 if (scope->state->x_comment_to)
1554 fprintf(fp, "x_comment_to=%s\n", print_boolean(scope->attribute->x_comment_to));
1555 }
1556 }
1557 }
1558
1559 /* rename_file() preserves mode, so this is safe */
1560 #ifdef HAVE_FCHMOD
1561 fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR));
1562 #else
1563 # ifdef HAVE_CHMOD
1564 chmod(new_file, (mode_t) (S_IRUSR|S_IWUSR));
1565 # endif /* HAVE_CHMOD */
1566 #endif /* HAVE_FCHMOD */
1567
1568 if ((i = ferror(fp)) || fclose(fp)) {
1569 error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
1570 unlink(new_file);
1571 if (i) {
1572 clearerr(fp);
1573 fclose(fp);
1574 }
1575 } else
1576 rename_file(new_file, file);
1577
1578 free(new_file);
1579 }
1580
1581
1582 #ifdef DEBUG
1583 # if 0
1584 static void
1585 debug_print_filter_attributes(
1586 void)
1587 {
1588 if (debug & DEBUG_ATTRIB) {
1589 int i;
1590 struct t_group *group;
1591
1592 my_printf("\nBEG ***\n");
1593
1594 for_each_group(i) {
1595 group = &active[i];
1596 my_printf("Grp=[%s] KILL header=[%d] scope=[%s] case=[%s] expire=[%s]\n",
1597 group->name, group->attribute->quick_kill_header,
1598 BlankIfNull(group->attribute->quick_kill_scope),
1599 txt_onoff[group->attribute->quick_kill_case != FALSE ? 1 : 0],
1600 txt_onoff[group->attribute->quick_kill_expire != FALSE ? 1 : 0]);
1601 my_printf("Grp=[%s] SELECT header=[%d] scope=[%s] case=[%s] expire=[%s]\n",
1602 group->name, group->attribute->quick_select_header,
1603 BlankIfNull(group->attribute->quick_select_scope),
1604 txt_onoff[group->attribute->quick_select_case != FALSE ? 1 : 0],
1605 txt_onoff[group->attribute->quick_select_expire != FALSE ? 1 : 0]);
1606 }
1607 my_printf("END ***\n");
1608 }
1609 }
1610 # endif /* 0 */
1611
1612
1613 static void
dump_attributes(void)1614 dump_attributes(
1615 void)
1616 {
1617 if (debug & DEBUG_ATTRIB) {
1618 int i, j;
1619 struct t_group *group;
1620
1621 for_each_group(i) {
1622 group = &active[i];
1623 if (!group->attribute)
1624 continue;
1625 debug_print_file("ATTRIBUTES", "group=%s", BlankIfNull(group->name));
1626 debug_print_file("ATTRIBUTES", "\tGlobal=%d", group->attribute->global);
1627 debug_print_file("ATTRIBUTES", "\tmaildir=%s", BlankIfNull(group->attribute->maildir));
1628 debug_print_file("ATTRIBUTES", "\tsavedir=%s", BlankIfNull(group->attribute->savedir));
1629 debug_print_file("ATTRIBUTES", "\tsavefile=%s", BlankIfNull(group->attribute->savefile));
1630 debug_print_file("ATTRIBUTES", "\tsigfile=%s", BlankIfNull(group->attribute->sigfile));
1631 debug_print_file("ATTRIBUTES", "\torganization=%s", BlankIfNull(group->attribute->organization));
1632 debug_print_file("ATTRIBUTES", "\tfollowup_to=%s", BlankIfNull(group->attribute->followup_to));
1633 debug_print_file("ATTRIBUTES", "\tmailing_list=%s", BlankIfNull(group->attribute->mailing_list));
1634 debug_print_file("ATTRIBUTES", "\tx_headers=%s", BlankIfNull(group->attribute->x_headers));
1635 debug_print_file("ATTRIBUTES", "\tx_body=%s", BlankIfNull(group->attribute->x_body));
1636 debug_print_file("ATTRIBUTES", "\tfrom=%s", BlankIfNull(group->attribute->from));
1637 debug_print_file("ATTRIBUTES", "\tnews_quote_format=%s", BlankIfNull(group->attribute->news_quote_format));
1638 debug_print_file("ATTRIBUTES", "\tquote_chars=%s", quote_space_to_dash(BlankIfNull(group->attribute->quote_chars)));
1639 debug_print_file("ATTRIBUTES", "\tmime_types_to_save=%s", BlankIfNull(group->attribute->mime_types_to_save));
1640 # ifdef HAVE_ISPELL
1641 debug_print_file("ATTRIBUTES", "\tispell=%s", BlankIfNull(group->attribute->ispell));
1642 # endif /* HAVE_ISPELL */
1643 debug_print_file("ATTRIBUTES", "\tshow_only_unread_arts=%s", print_boolean(group->attribute->show_only_unread_arts));
1644 debug_print_file("ATTRIBUTES", "\tthread_articles=%d", group->attribute->thread_articles);
1645 debug_print_file("ATTRIBUTES", "\tthread_perc=%d", group->attribute->thread_perc);
1646 debug_print_file("ATTRIBUTES", "\tadd_posted_to_filter=%s", print_boolean(group->attribute->add_posted_to_filter));
1647 debug_print_file("ATTRIBUTES", "\tadvertising=%s", print_boolean(group->attribute->advertising));
1648 debug_print_file("ATTRIBUTES", "\talternative_handling=%s", print_boolean(group->attribute->alternative_handling));
1649 debug_print_file("ATTRIBUTES", "\task_for_metamail=%s", print_boolean(group->attribute->ask_for_metamail));
1650 debug_print_file("ATTRIBUTES", "\tauto_cc_bcc=%d", group->attribute->auto_cc_bcc);
1651 debug_print_file("ATTRIBUTES", "\tauto_list_thread=%s", print_boolean(group->attribute->auto_list_thread));
1652 debug_print_file("ATTRIBUTES", "\tauto_select=%s", print_boolean(group->attribute->auto_select));
1653 debug_print_file("ATTRIBUTES", "\tauto_save=%s", print_boolean(group->attribute->auto_save));
1654 debug_print_file("ATTRIBUTES", "\tbatch_save=%s", print_boolean(group->attribute->batch_save));
1655 debug_print_file("ATTRIBUTES", "\tdate_format=%s", BlankIfNull(group->attribute->date_format));
1656 debug_print_file("ATTRIBUTES", "\tdelete_tmp_files=%s", print_boolean(group->attribute->delete_tmp_files));
1657 debug_print_file("ATTRIBUTES", "\teditor_format=%s", BlankIfNull(group->attribute->editor_format));
1658 # ifdef HAVE_COLOR
1659 debug_print_file("ATTRIBUTES", "\textquote_handling=%s", print_boolean(group->attribute->extquote_handling));
1660 # endif /* HAVE_COLOR */
1661 debug_print_file("ATTRIBUTES", "\tgroup_catchup_on_exit=%s", print_boolean(group->attribute->group_catchup_on_exit));
1662 debug_print_file("ATTRIBUTES", "\tgroup_format=%s", BlankIfNull(group->attribute->group_format));
1663 debug_print_file("ATTRIBUTES", "\tmail_8bit_header=%s", print_boolean(group->attribute->mail_8bit_header));
1664 debug_print_file("ATTRIBUTES", "\tmail_mime_encoding=%s", txt_mime_encodings[group->attribute->mail_mime_encoding]);
1665 debug_print_file("ATTRIBUTES", "\tmark_ignore_tags=%s", print_boolean(group->attribute->mark_ignore_tags));
1666 debug_print_file("ATTRIBUTES", "\tmark_saved_read=%s", print_boolean(group->attribute->mark_saved_read));
1667 debug_print_file("ATTRIBUTES", "\tnews_headers_to_display=%s", BlankIfNull(group->attribute->news_headers_to_display));
1668 if (group->attribute->headers_to_display) {
1669 debug_print_file("ATTRIBUTES", "\theaders_to_display->num=%d", group->attribute->headers_to_display->num);
1670 for (j = 0; j < group->attribute->headers_to_display->num; j++)
1671 debug_print_file("ATTRIBUTES", "\theaders_to_display->header[%d]=%s", j, group->attribute->headers_to_display->header[j]);
1672 }
1673 debug_print_file("ATTRIBUTES", "\tnews_headers_to_not_display=%s", BlankIfNull(group->attribute->news_headers_to_not_display));
1674 if (group->attribute->headers_to_not_display) {
1675 debug_print_file("ATTRIBUTES", "\theaders_to_not_display->num=%d", group->attribute->headers_to_not_display->num);
1676 for (j = 0; j < group->attribute->headers_to_not_display->num; j++)
1677 debug_print_file("ATTRIBUTES", "\theaders_to_not_display->header[%d]=%s", j, group->attribute->headers_to_not_display->header[j]);
1678 }
1679 debug_print_file("ATTRIBUTES", "\tpos_first_unread=%s", print_boolean(group->attribute->pos_first_unread));
1680 debug_print_file("ATTRIBUTES", "\tpost_8bit_header=%s", print_boolean(group->attribute->post_8bit_header));
1681 debug_print_file("ATTRIBUTES", "\tpost_mime_encoding=%s", txt_mime_encodings[group->attribute->post_mime_encoding]);
1682 debug_print_file("ATTRIBUTES", "\tpost_process_view=%s", print_boolean(group->attribute->post_process_view));
1683 # ifndef DISABLE_PRINTING
1684 debug_print_file("ATTRIBUTES", "\tprint_header=%s", print_boolean(group->attribute->print_header));
1685 # endif /* !DISABLE_PRINTING */
1686 debug_print_file("ATTRIBUTES", "\tprocess_only_unread=%s", print_boolean(group->attribute->process_only_unread));
1687 debug_print_file("ATTRIBUTES", "\tprompt_followupto=%s", print_boolean(group->attribute->prompt_followupto));
1688 debug_print_file("ATTRIBUTES", "\tsort_article_type=%d", group->attribute->sort_article_type);
1689 debug_print_file("ATTRIBUTES", "\tsort_threads_type=%d", group->attribute->sort_threads_type);
1690 debug_print_file("ATTRIBUTES", "\tshow_author=%d", group->attribute->show_author);
1691 debug_print_file("ATTRIBUTES", "\tshow_signatures=%s", print_boolean(group->attribute->show_signatures));
1692 debug_print_file("ATTRIBUTES", "\tsigdashes=%s", print_boolean(group->attribute->sigdashes));
1693 debug_print_file("ATTRIBUTES", "\tsignature_repost=%s", print_boolean(group->attribute->signature_repost));
1694 debug_print_file("ATTRIBUTES", "\tstart_editor_offset=%s", print_boolean(group->attribute->start_editor_offset));
1695 debug_print_file("ATTRIBUTES", "\tthread_catchup_on_exit=%s", print_boolean(group->attribute->thread_catchup_on_exit));
1696 debug_print_file("ATTRIBUTES", "\tthread_format=%s", BlankIfNull(group->attribute->thread_format));
1697 debug_print_file("ATTRIBUTES", "\ttrim_article_body=%d", group->attribute->trim_article_body);
1698 debug_print_file("ATTRIBUTES", "\tverbatim_handling=%s", print_boolean(group->attribute->verbatim_handling));
1699 debug_print_file("ATTRIBUTES", "\twrap_on_next_unread=%s", print_boolean(group->attribute->wrap_on_next_unread));
1700 debug_print_file("ATTRIBUTES", "\tpost_process_type=%d", group->attribute->post_process_type);
1701 debug_print_file("ATTRIBUTES", "\tquick_kill_scope=%s", BlankIfNull(group->attribute->quick_kill_scope));
1702 debug_print_file("ATTRIBUTES", "\tquick_kill_case=%s", print_boolean(group->attribute->quick_kill_case));
1703 debug_print_file("ATTRIBUTES", "\tquick_kill_expire=%s", print_boolean(group->attribute->quick_kill_expire));
1704 debug_print_file("ATTRIBUTES", "\tquick_kill_header=%d", group->attribute->quick_kill_header);
1705 debug_print_file("ATTRIBUTES", "\tquick_select_scope=%s", BlankIfNull(group->attribute->quick_select_scope));
1706 debug_print_file("ATTRIBUTES", "\tquick_select_case=%s", print_boolean(group->attribute->quick_select_case));
1707 debug_print_file("ATTRIBUTES", "\tquick_select_expire=%s", print_boolean(group->attribute->quick_select_expire));
1708 debug_print_file("ATTRIBUTES", "\tquick_select_header=%d", group->attribute->quick_select_header);
1709 debug_print_file("ATTRIBUTES", "\tx_comment_to=%s", print_boolean(group->attribute->x_comment_to));
1710 debug_print_file("ATTRIBUTES", "\tfcc=%s", BlankIfNull(group->attribute->fcc));
1711 debug_print_file("ATTRIBUTES", "\ttex2iso_conv=%s", print_boolean(group->attribute->tex2iso_conv));
1712 debug_print_file("ATTRIBUTES", "\tmime_forward=%s", print_boolean(group->attribute->mime_forward));
1713 # ifdef CHARSET_CONVERSION
1714 debug_print_file("ATTRIBUTES", "\tmm_network_charset=%s", txt_mime_charsets[group->attribute->mm_network_charset]);
1715 debug_print_file("ATTRIBUTES", "\tundeclared_charset=%s", BlankIfNull(group->attribute->undeclared_charset));
1716 # endif /* CHARSET_CONVERSION */
1717 debug_print_file("ATTRIBUTES", "");
1718 }
1719 }
1720 }
1721
1722
1723 #define DEBUG_PRINT_STATE(attrib) (scope->state->attrib ? "+ " : " ")
1724 #define DEBUG_PRINT_STRING(attrib) (scope->attribute->attrib ? scope->attribute->attrib : "NULL")
1725
1726
1727 static void
dump_scopes(const char * fname)1728 dump_scopes(
1729 const char *fname)
1730 {
1731 if (!scopes)
1732 return;
1733
1734 if (debug & DEBUG_ATTRIB) {
1735 int i, j;
1736 struct t_scope *scope;
1737
1738 for (i = 0; i < num_scope; i++) {
1739 scope = &scopes[i];
1740 debug_print_file(fname, "scopes[%d]", i);
1741 debug_print_file(fname, "scope=%s", scope->scope ? scope->scope : "NULL");
1742 debug_print_file(fname, "\t global=%d", scope->global);
1743 debug_print_file(fname, "\t%smaildir=%s", DEBUG_PRINT_STATE(maildir), DEBUG_PRINT_STRING(maildir));
1744 debug_print_file(fname, "\t%ssavedir=%s", DEBUG_PRINT_STATE(savedir), DEBUG_PRINT_STRING(savedir));
1745 debug_print_file(fname, "\t%ssavefile=%s", DEBUG_PRINT_STATE(savefile), DEBUG_PRINT_STRING(savefile));
1746 debug_print_file(fname, "\t%ssigfile=%s", DEBUG_PRINT_STATE(sigfile), DEBUG_PRINT_STRING(sigfile));
1747 debug_print_file(fname, "\t%sorganization=%s", DEBUG_PRINT_STATE(organization), DEBUG_PRINT_STRING(organization));
1748 debug_print_file(fname, "\t%sfollowup_to=%s", DEBUG_PRINT_STATE(followup_to), DEBUG_PRINT_STRING(followup_to));
1749 debug_print_file(fname, "\t%smailing_list=%s", DEBUG_PRINT_STATE(mailing_list), DEBUG_PRINT_STRING(mailing_list));
1750 debug_print_file(fname, "\t%sx_headers=%s", DEBUG_PRINT_STATE(x_headers), DEBUG_PRINT_STRING(x_headers));
1751 debug_print_file(fname, "\t%sx_body=%s", DEBUG_PRINT_STATE(x_body), DEBUG_PRINT_STRING(x_body));
1752 debug_print_file(fname, "\t%sfrom=%s", DEBUG_PRINT_STATE(from), DEBUG_PRINT_STRING(from));
1753 debug_print_file(fname, "\t%snews_quote_format=%s", DEBUG_PRINT_STATE(news_quote_format), DEBUG_PRINT_STRING(news_quote_format));
1754 debug_print_file(fname, "\t%squote_chars=%s", DEBUG_PRINT_STATE(quote_chars), quote_space_to_dash(DEBUG_PRINT_STRING(quote_chars)));
1755 debug_print_file(fname, "\t%smime_types_to_save=%s", DEBUG_PRINT_STATE(mime_types_to_save), DEBUG_PRINT_STRING(mime_types_to_save));
1756 # ifdef HAVE_ISPELL
1757 debug_print_file(fname, "\t%sispell=%s", DEBUG_PRINT_STATE(ispell), DEBUG_PRINT_STRING(ispell));
1758 # endif /* HAVE_ISPELL */
1759 debug_print_file(fname, "\t%sshow_only_unread_arts=%s", DEBUG_PRINT_STATE(show_only_unread_arts), print_boolean(scope->attribute->show_only_unread_arts));
1760 debug_print_file(fname, "\t%sthread_articles=%d", DEBUG_PRINT_STATE(thread_articles), scope->attribute->thread_articles);
1761 debug_print_file(fname, "\t%sthread_perc=%d", DEBUG_PRINT_STATE(thread_perc), scope->attribute->thread_perc);
1762 debug_print_file(fname, "\t%sadd_posted_to_filter=%s", DEBUG_PRINT_STATE(add_posted_to_filter), print_boolean(scope->attribute->add_posted_to_filter));
1763 debug_print_file(fname, "\t%sadvertising=%s", DEBUG_PRINT_STATE(advertising), print_boolean(scope->attribute->advertising));
1764 debug_print_file(fname, "\t%salternative_handling=%s", DEBUG_PRINT_STATE(alternative_handling), print_boolean(scope->attribute->alternative_handling));
1765 debug_print_file(fname, "\t%sask_for_metamail=%s", DEBUG_PRINT_STATE(ask_for_metamail), print_boolean(scope->attribute->ask_for_metamail));
1766 debug_print_file(fname, "\t%sauto_cc_bcc=%d", DEBUG_PRINT_STATE(auto_cc_bcc), scope->attribute->auto_cc_bcc);
1767 debug_print_file(fname, "\t%sauto_list_thread=%s", DEBUG_PRINT_STATE(auto_list_thread), print_boolean(scope->attribute->auto_list_thread));
1768 debug_print_file(fname, "\t%sauto_select=%s", DEBUG_PRINT_STATE(auto_select), print_boolean(scope->attribute->auto_select));
1769 debug_print_file(fname, "\t%sauto_save=%s", DEBUG_PRINT_STATE(auto_save), print_boolean(scope->attribute->auto_save));
1770 debug_print_file(fname, "\t%sbatch_save=%s", DEBUG_PRINT_STATE(batch_save), print_boolean(scope->attribute->batch_save));
1771 debug_print_file(fname, "\t%sdate_format=%s", DEBUG_PRINT_STATE(date_format), DEBUG_PRINT_STRING(date_format));
1772 debug_print_file(fname, "\t%sdelete_tmp_files=%s", DEBUG_PRINT_STATE(delete_tmp_files), print_boolean(scope->attribute->delete_tmp_files));
1773 debug_print_file(fname, "\t%seditor_format=%s", DEBUG_PRINT_STATE(editor_format), DEBUG_PRINT_STRING(editor_format));
1774 # ifdef HAVE_COLOR
1775 debug_print_file(fname, "\t%sextquote_handling=%s", DEBUG_PRINT_STATE(extquote_handling), print_boolean(scope->attribute->extquote_handling));
1776 # endif /* HAVE_COLOR */
1777 debug_print_file(fname, "\t%sgroup_catchup_on_exit=%s", DEBUG_PRINT_STATE(group_catchup_on_exit), print_boolean(scope->attribute->group_catchup_on_exit));
1778 debug_print_file(fname, "\t%sgroup_format=%s", DEBUG_PRINT_STATE(group_format), DEBUG_PRINT_STRING(group_format));
1779 debug_print_file(fname, "\t%smail_8bit_header=%s", DEBUG_PRINT_STATE(mail_8bit_header), print_boolean(scope->attribute->mail_8bit_header));
1780 debug_print_file(fname, "\t%smail_mime_encoding=%s", DEBUG_PRINT_STATE(mail_mime_encoding), txt_mime_encodings[scope->attribute->mail_mime_encoding]);
1781 debug_print_file(fname, "\t%smark_ignore_tags=%s", DEBUG_PRINT_STATE(mark_ignore_tags), print_boolean(scope->attribute->mark_ignore_tags));
1782 debug_print_file(fname, "\t%smark_saved_read=%s", DEBUG_PRINT_STATE(mark_saved_read), print_boolean(scope->attribute->mark_saved_read));
1783 debug_print_file(fname, "\t%snews_headers_to_display=%s", DEBUG_PRINT_STATE(news_headers_to_display), DEBUG_PRINT_STRING(news_headers_to_display));
1784 if (scope->attribute->headers_to_display) {
1785 debug_print_file(fname, "\t headers_to_display->num=%d", scope->attribute->headers_to_display->num);
1786 for (j = 0; j < scope->attribute->headers_to_display->num; j++)
1787 debug_print_file(fname, "\t headers_to_display->header[%d]=%s", j, scope->attribute->headers_to_display->header[j]);
1788 }
1789 debug_print_file(fname, "\t%snews_headers_to_not_display=%s", DEBUG_PRINT_STATE(news_headers_to_not_display), DEBUG_PRINT_STRING(news_headers_to_not_display));
1790 if (scope->attribute->headers_to_not_display) {
1791 debug_print_file(fname, "\t headers_to_not_display->num=%d", scope->attribute->headers_to_not_display->num);
1792 for (j = 0; j < scope->attribute->headers_to_not_display->num; j++)
1793 debug_print_file(fname, "\t headers_to_not_display->header[%d]=%s", j, scope->attribute->headers_to_not_display->header[j]);
1794 }
1795 debug_print_file(fname, "\t%spos_first_unread=%s", DEBUG_PRINT_STATE(pos_first_unread), print_boolean(scope->attribute->pos_first_unread));
1796 debug_print_file(fname, "\t%spost_8bit_header=%s", DEBUG_PRINT_STATE(post_8bit_header), print_boolean(scope->attribute->post_8bit_header));
1797 debug_print_file(fname, "\t%spost_mime_encoding=%s", DEBUG_PRINT_STATE(post_mime_encoding), txt_mime_encodings[scope->attribute->post_mime_encoding]);
1798 debug_print_file(fname, "\t%spost_process_view=%s", DEBUG_PRINT_STATE(post_process_view), print_boolean(scope->attribute->post_process_view));
1799 # ifndef DISABLE_PRINTING
1800 debug_print_file(fname, "\t%sprint_header=%s", DEBUG_PRINT_STATE(print_header), print_boolean(scope->attribute->print_header));
1801 # endif /* !DISABLE_PRINTING */
1802 debug_print_file(fname, "\t%sprocess_only_unread=%s", DEBUG_PRINT_STATE(process_only_unread), print_boolean(scope->attribute->process_only_unread));
1803 debug_print_file(fname, "\t%sprompt_followupto=%s", DEBUG_PRINT_STATE(prompt_followupto), print_boolean(scope->attribute->prompt_followupto));
1804 debug_print_file(fname, "\t%ssort_article_type=%d", DEBUG_PRINT_STATE(sort_article_type), scope->attribute->sort_article_type);
1805 debug_print_file(fname, "\t%ssort_threads_type=%d", DEBUG_PRINT_STATE(sort_threads_type), scope->attribute->sort_threads_type);
1806 debug_print_file(fname, "\t%sshow_author=%d", DEBUG_PRINT_STATE(show_author), scope->attribute->show_author);
1807 debug_print_file(fname, "\t%sshow_signatures=%s", DEBUG_PRINT_STATE(show_signatures), print_boolean(scope->attribute->show_signatures));
1808 debug_print_file(fname, "\t%ssigdashes=%s", DEBUG_PRINT_STATE(sigdashes), print_boolean(scope->attribute->sigdashes));
1809 debug_print_file(fname, "\t%ssignature_repost=%s", DEBUG_PRINT_STATE(signature_repost), print_boolean(scope->attribute->signature_repost));
1810 debug_print_file(fname, "\t%sstart_editor_offset=%s", DEBUG_PRINT_STATE(start_editor_offset), print_boolean(scope->attribute->start_editor_offset));
1811 debug_print_file(fname, "\t%sthread_catchup_on_exit=%s", DEBUG_PRINT_STATE(thread_catchup_on_exit), print_boolean(scope->attribute->thread_catchup_on_exit));
1812 debug_print_file(fname, "\t%sthread_format=%s", DEBUG_PRINT_STATE(thread_format), DEBUG_PRINT_STRING(thread_format));
1813 debug_print_file(fname, "\t%strim_article_body=%d", DEBUG_PRINT_STATE(trim_article_body), scope->attribute->trim_article_body);
1814 debug_print_file(fname, "\t%sverbatim_handling=%s", DEBUG_PRINT_STATE(verbatim_handling), print_boolean(scope->attribute->verbatim_handling));
1815 debug_print_file(fname, "\t%swrap_on_next_unread=%s", DEBUG_PRINT_STATE(wrap_on_next_unread), print_boolean(scope->attribute->wrap_on_next_unread));
1816 debug_print_file(fname, "\t%spost_process_type=%d", DEBUG_PRINT_STATE(post_process_type), scope->attribute->post_process_type);
1817 debug_print_file(fname, "\t%squick_kill_scope=%s", DEBUG_PRINT_STATE(quick_kill_scope), DEBUG_PRINT_STRING(quick_kill_scope));
1818 debug_print_file(fname, "\t%squick_kill_case=%s", DEBUG_PRINT_STATE(quick_kill_case), print_boolean(scope->attribute->quick_kill_case));
1819 debug_print_file(fname, "\t%squick_kill_expire=%s", DEBUG_PRINT_STATE(quick_kill_expire), print_boolean(scope->attribute->quick_kill_expire));
1820 debug_print_file(fname, "\t%squick_kill_header=%d", DEBUG_PRINT_STATE(quick_kill_header), scope->attribute->quick_kill_header);
1821 debug_print_file(fname, "\t%squick_select_scope=%s", DEBUG_PRINT_STATE(quick_select_scope), DEBUG_PRINT_STRING(quick_select_scope));
1822 debug_print_file(fname, "\t%squick_select_case=%s", DEBUG_PRINT_STATE(quick_select_case), print_boolean(scope->attribute->quick_select_case));
1823 debug_print_file(fname, "\t%squick_select_expire=%s", DEBUG_PRINT_STATE(quick_select_expire), print_boolean(scope->attribute->quick_select_expire));
1824 debug_print_file(fname, "\t%squick_select_header=%d", DEBUG_PRINT_STATE(quick_select_header), scope->attribute->quick_select_header);
1825 debug_print_file(fname, "\t%sx_comment_to=%s", DEBUG_PRINT_STATE(x_comment_to), print_boolean(scope->attribute->x_comment_to));
1826 debug_print_file(fname, "\t%sfcc=%s", DEBUG_PRINT_STATE(fcc), DEBUG_PRINT_STRING(fcc));
1827 debug_print_file(fname, "\t%stex2iso_conv=%s", DEBUG_PRINT_STATE(tex2iso_conv), print_boolean(scope->attribute->tex2iso_conv));
1828 debug_print_file(fname, "\t%smime_forward=%s", DEBUG_PRINT_STATE(mime_forward), print_boolean(scope->attribute->mime_forward));
1829 # ifdef CHARSET_CONVERSION
1830 debug_print_file(fname, "\t%smm_network_charset=%s", DEBUG_PRINT_STATE(mm_network_charset), txt_mime_charsets[scope->attribute->mm_network_charset]);
1831 debug_print_file(fname, "\t%sundeclared_charset=%s", DEBUG_PRINT_STATE(undeclared_charset), DEBUG_PRINT_STRING(undeclared_charset));
1832 # endif /* CHARSET_CONVERSION */
1833 debug_print_file(fname, "");
1834 }
1835 }
1836 }
1837 #endif /* DEBUG */
1838