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 num = 25;
641 set_attrib(OPT_ATTRIB_MM_NETWORK_CHARSET, "*", "", (char *) &num);
642 set_attrib(OPT_ATTRIB_UNDECLARED_CHARSET, "*", "", "Big5");
643
644 add_scope("*sources*");
645 num = POST_PROC_SHAR;
646 set_attrib(OPT_ATTRIB_POST_PROCESS_TYPE, "*sources*", "", &num);
647
648 add_scope("*binaries*");
649 num = POST_PROC_YES;
650 set_attrib(OPT_ATTRIB_POST_PROCESS_TYPE, "*binaries*", "", &num);
651 num = FALSE;
652 set_attrib(OPT_ATTRIB_TEX2ISO_CONV, "*binaries*", "", &num);
653 num = TRUE;
654 set_attrib(OPT_ATTRIB_DELETE_TMP_FILES, "*binaries*", "", &num);
655 snprintf(buf, sizeof(buf), "%s", "poster");
656 set_attrib(OPT_ATTRIB_FOLLOWUP_TO, "*binaries*", "", buf);
657
658 write_attributes_file(file);
659 }
660 if (!global_file && startup)
661 startup = FALSE;
662 #ifdef DEBUG
663 if (!global_file)
664 dump_scopes("SCOPES-R");
665 #endif /* DEBUG */
666 }
667
668
669 #define SET_STRING(string) \
670 FreeIfNeeded(curr_scope->attribute->string); \
671 curr_scope->attribute->string = my_strdup((char *) data); \
672 curr_scope->state->string = TRUE; \
673 break
674 #define SET_INTEGER(integer) \
675 curr_scope->attribute->integer = *((int *) data); \
676 curr_scope->state->integer = TRUE; \
677 break
678
679
680 static void
set_attrib(int type,const char * scope,const char * line,void * data)681 set_attrib(
682 int type,
683 const char *scope,
684 const char *line,
685 void *data)
686 {
687 struct t_scope *curr_scope;
688
689 if (scope == NULL || *scope == '\0') { /* No active scope set yet */
690 error_message(2, _(txt_attrib_no_scope), line);
691 #ifdef DEBUG
692 if (debug & DEBUG_ATTRIB)
693 debug_print_file("ATTRIBUTES", txt_attrib_no_scope, line);
694 #endif /* DEBUG */
695 return;
696 }
697
698 if (num_scope > 1) {
699 curr_scope = &scopes[num_scope - 1];
700 /*
701 * Now set the required attribute
702 */
703 switch (type) {
704 case OPT_ATTRIB_MAILDIR:
705 SET_STRING(maildir);
706
707 case OPT_ATTRIB_SAVEDIR:
708 SET_STRING(savedir);
709
710 case OPT_ATTRIB_SAVEFILE:
711 SET_STRING(savefile);
712
713 case OPT_ATTRIB_ORGANIZATION:
714 SET_STRING(organization);
715
716 case OPT_ATTRIB_FROM:
717 SET_STRING(from);
718
719 case OPT_ATTRIB_SIGFILE:
720 SET_STRING(sigfile);
721
722 case OPT_ATTRIB_FOLLOWUP_TO:
723 SET_STRING(followup_to);
724
725 case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
726 SET_INTEGER(add_posted_to_filter);
727
728 case OPT_ATTRIB_ADVERTISING:
729 SET_INTEGER(advertising);
730
731 case OPT_ATTRIB_ALTERNATIVE_HANDLING:
732 SET_INTEGER(alternative_handling);
733
734 case OPT_ATTRIB_ASK_FOR_METAMAIL:
735 SET_INTEGER(ask_for_metamail);
736
737 case OPT_ATTRIB_AUTO_CC_BCC:
738 SET_INTEGER(auto_cc_bcc);
739
740 case OPT_ATTRIB_AUTO_LIST_THREAD:
741 SET_INTEGER(auto_list_thread);
742
743 case OPT_ATTRIB_AUTO_SELECT:
744 SET_INTEGER(auto_select);
745
746 case OPT_ATTRIB_AUTO_SAVE:
747 SET_INTEGER(auto_save);
748
749 case OPT_ATTRIB_BATCH_SAVE:
750 SET_INTEGER(batch_save);
751
752 case OPT_ATTRIB_DATE_FORMAT:
753 SET_STRING(date_format);
754
755 case OPT_ATTRIB_DELETE_TMP_FILES:
756 SET_INTEGER(delete_tmp_files);
757
758 case OPT_ATTRIB_EDITOR_FORMAT:
759 SET_STRING(editor_format);
760
761 case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
762 SET_INTEGER(group_catchup_on_exit);
763
764 case OPT_ATTRIB_GROUP_FORMAT:
765 SET_STRING(group_format);
766
767 case OPT_ATTRIB_MAIL_8BIT_HEADER:
768 SET_INTEGER(mail_8bit_header);
769
770 case OPT_ATTRIB_MAIL_MIME_ENCODING:
771 SET_INTEGER(mail_mime_encoding);
772
773 case OPT_ATTRIB_MARK_IGNORE_TAGS:
774 SET_INTEGER(mark_ignore_tags);
775
776 case OPT_ATTRIB_MARK_SAVED_READ:
777 SET_INTEGER(mark_saved_read);
778
779 case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
780 FreeIfNeeded(curr_scope->attribute->news_headers_to_display);
781 curr_scope->attribute->news_headers_to_display = my_strdup((char *) data);
782 build_news_headers_array(curr_scope->attribute, TRUE);
783 curr_scope->state->news_headers_to_display = TRUE;
784 break;
785
786 case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
787 FreeIfNeeded(curr_scope->attribute->news_headers_to_not_display);
788 curr_scope->attribute->news_headers_to_not_display = my_strdup((char *) data);
789 build_news_headers_array(curr_scope->attribute, FALSE);
790 curr_scope->state->news_headers_to_not_display = TRUE;
791 break;
792
793 case OPT_ATTRIB_POS_FIRST_UNREAD:
794 SET_INTEGER(pos_first_unread);
795
796 case OPT_ATTRIB_POST_8BIT_HEADER:
797 SET_INTEGER(post_8bit_header);
798
799 case OPT_ATTRIB_POST_MIME_ENCODING:
800 SET_INTEGER(post_mime_encoding);
801
802 case OPT_ATTRIB_POST_PROCESS_VIEW:
803 SET_INTEGER(post_process_view);
804
805 #ifndef DISABLE_PRINTING
806 case OPT_ATTRIB_PRINT_HEADER:
807 SET_INTEGER(print_header);
808 #endif /* !DISABLE_PRINTING */
809
810 case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
811 SET_INTEGER(process_only_unread);
812
813 case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
814 SET_INTEGER(prompt_followupto);
815
816 #ifdef HAVE_COLOR
817 case OPT_ATTRIB_EXTQUOTE_HANDLING:
818 SET_INTEGER(extquote_handling);
819 #endif /* HAVE_COLOR */
820
821 case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
822 SET_INTEGER(show_only_unread_arts);
823
824 case OPT_ATTRIB_SIGDASHES:
825 SET_INTEGER(sigdashes);
826
827 case OPT_ATTRIB_SIGNATURE_REPOST:
828 SET_INTEGER(signature_repost);
829
830 case OPT_ATTRIB_START_EDITOR_OFFSET:
831 SET_INTEGER(start_editor_offset);
832
833 case OPT_ATTRIB_THREAD_ARTICLES:
834 SET_INTEGER(thread_articles);
835
836 case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
837 SET_INTEGER(thread_catchup_on_exit);
838
839 case OPT_ATTRIB_THREAD_FORMAT:
840 SET_STRING(thread_format);
841
842 case OPT_ATTRIB_THREAD_PERC:
843 SET_INTEGER(thread_perc);
844
845 case OPT_ATTRIB_SHOW_AUTHOR:
846 SET_INTEGER(show_author);
847
848 case OPT_ATTRIB_SHOW_SIGNATURES:
849 SET_INTEGER(show_signatures);
850
851 case OPT_ATTRIB_TRIM_ARTICLE_BODY:
852 SET_INTEGER(trim_article_body);
853
854 case OPT_ATTRIB_VERBATIM_HANDLING:
855 SET_INTEGER(verbatim_handling);
856
857 case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
858 SET_INTEGER(wrap_on_next_unread);
859
860 case OPT_ATTRIB_SORT_ARTICLE_TYPE:
861 SET_INTEGER(sort_article_type);
862
863 case OPT_ATTRIB_SORT_THREADS_TYPE:
864 SET_INTEGER(sort_threads_type);
865
866 case OPT_ATTRIB_POST_PROCESS_TYPE:
867 SET_INTEGER(post_process_type);
868
869 case OPT_ATTRIB_QUICK_KILL_HEADER:
870 SET_INTEGER(quick_kill_header);
871
872 case OPT_ATTRIB_QUICK_KILL_SCOPE:
873 SET_STRING(quick_kill_scope);
874
875 case OPT_ATTRIB_QUICK_KILL_EXPIRE:
876 SET_INTEGER(quick_kill_expire);
877
878 case OPT_ATTRIB_QUICK_KILL_CASE:
879 SET_INTEGER(quick_kill_case);
880
881 case OPT_ATTRIB_QUICK_SELECT_HEADER:
882 SET_INTEGER(quick_select_header);
883
884 case OPT_ATTRIB_QUICK_SELECT_SCOPE:
885 SET_STRING(quick_select_scope);
886
887 case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
888 SET_INTEGER(quick_select_expire);
889
890 case OPT_ATTRIB_QUICK_SELECT_CASE:
891 SET_INTEGER(quick_select_case);
892
893 case OPT_ATTRIB_MAILING_LIST:
894 SET_STRING(mailing_list);
895
896 #ifdef CHARSET_CONVERSION
897 case OPT_ATTRIB_MM_NETWORK_CHARSET:
898 SET_INTEGER(mm_network_charset);
899
900 case OPT_ATTRIB_UNDECLARED_CHARSET:
901 SET_STRING(undeclared_charset);
902 #endif /* CHARSET_CONVERSION */
903
904 case OPT_ATTRIB_X_HEADERS:
905 SET_STRING(x_headers);
906
907 case OPT_ATTRIB_X_BODY:
908 SET_STRING(x_body);
909
910 case OPT_ATTRIB_X_COMMENT_TO:
911 SET_INTEGER(x_comment_to);
912
913 case OPT_ATTRIB_FCC:
914 SET_STRING(fcc);
915
916 case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
917 SET_STRING(news_quote_format);
918
919 case OPT_ATTRIB_QUOTE_CHARS:
920 SET_STRING(quote_chars);
921
922 case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
923 SET_STRING(mime_types_to_save);
924
925 case OPT_ATTRIB_MIME_FORWARD:
926 SET_INTEGER(mime_forward);
927
928 #ifdef HAVE_ISPELL
929 case OPT_ATTRIB_ISPELL:
930 SET_STRING(ispell);
931 #endif /* HAVE_ISPELL */
932
933 case OPT_ATTRIB_TEX2ISO_CONV:
934 SET_INTEGER(tex2iso_conv);
935
936 default:
937 break;
938 }
939 }
940 }
941
942
943 /*
944 * Insert a new scope entry into scopes[] and return the index.
945 */
946 int
add_scope(const char * scope)947 add_scope(
948 const char *scope)
949 {
950 if (!scope || !*scope)
951 return 0;
952
953 if ((num_scope >= max_scope) || (num_scope < 0) || (scopes == NULL))
954 expand_scope();
955
956 scopes[num_scope].scope = my_strdup(scope);
957 scopes[num_scope].attribute = my_malloc(sizeof(struct t_attribute));
958 set_default_attributes(scopes[num_scope].attribute, NULL, FALSE);
959 scopes[num_scope].state = my_malloc(sizeof(struct t_attribute_state));
960 set_default_state(scopes[num_scope].state);
961 scopes[num_scope].global = FALSE;
962 return num_scope++;
963 }
964
965
966 #define SET_ATTRIB(attr) do { \
967 if (curr_scope->state->attr) \
968 group->attribute->attr = curr_scope->attribute->attr; \
969 } while (0)
970
971
972 /*
973 * Set the attributes of all groups
974 */
975 void
assign_attributes_to_groups(void)976 assign_attributes_to_groups(
977 void)
978 {
979 struct t_group *group;
980 struct t_scope *default_scope, *curr_scope;
981 t_bool found;
982 int i, j;
983 long processed = 0L;
984 #ifdef CHARSET_CONVERSION
985 t_bool is_7bit;
986 #endif /* CHARSET_CONVERSION */
987
988 if (!batch_mode || verbose)
989 wait_message(0, _("Processing attributes... ")); /* TODO: -> lang.c */
990
991 default_scope = &scopes[0];
992 for_each_group(i) {
993 if (++processed % (MODULO_COUNT_NUM) == 0)
994 spin_cursor();
995 group = &active[i];
996 found = FALSE;
997 for (j = 1; j < num_scope; j++) {
998 curr_scope = &scopes[j];
999 if (match_group_list(group->name, curr_scope->scope)) {
1000 if (group->attribute == NULL || group->attribute == default_scope->attribute) {
1001 group->attribute = my_malloc(sizeof(struct t_attribute));
1002 set_default_attributes(group->attribute, default_scope->attribute, FALSE);
1003 found = TRUE;
1004 }
1005 if (!found) {
1006 set_default_attributes(group->attribute, default_scope->attribute, FALSE);
1007 found = TRUE;
1008 }
1009 SET_ATTRIB(maildir);
1010 SET_ATTRIB(savedir);
1011 SET_ATTRIB(savefile);
1012 SET_ATTRIB(sigfile);
1013 SET_ATTRIB(group_format);
1014 SET_ATTRIB(thread_format);
1015 SET_ATTRIB(date_format);
1016 SET_ATTRIB(editor_format);
1017 SET_ATTRIB(organization);
1018 SET_ATTRIB(fcc);
1019 SET_ATTRIB(followup_to);
1020 SET_ATTRIB(mailing_list);
1021 SET_ATTRIB(x_headers);
1022 SET_ATTRIB(x_body);
1023 SET_ATTRIB(from);
1024 SET_ATTRIB(news_quote_format);
1025 SET_ATTRIB(quote_chars);
1026 SET_ATTRIB(mime_types_to_save);
1027 #ifdef HAVE_ISPELL
1028 SET_ATTRIB(ispell);
1029 #endif /* HAVE_ISPELL */
1030 #ifdef CHARSET_CONVERSION
1031 SET_ATTRIB(mm_network_charset);
1032 SET_ATTRIB(undeclared_charset);
1033 #endif /* CHARSET_CONVERSION */
1034 SET_ATTRIB(quick_kill_scope);
1035 SET_ATTRIB(quick_kill_header);
1036 SET_ATTRIB(quick_kill_case);
1037 SET_ATTRIB(quick_kill_expire);
1038 SET_ATTRIB(quick_select_scope);
1039 SET_ATTRIB(quick_select_header);
1040 SET_ATTRIB(quick_select_case);
1041 SET_ATTRIB(quick_select_expire);
1042 SET_ATTRIB(show_only_unread_arts);
1043 SET_ATTRIB(thread_articles);
1044 SET_ATTRIB(thread_catchup_on_exit);
1045 SET_ATTRIB(thread_perc);
1046 SET_ATTRIB(sort_article_type);
1047 SET_ATTRIB(sort_threads_type);
1048 SET_ATTRIB(show_author);
1049 SET_ATTRIB(show_signatures);
1050 SET_ATTRIB(trim_article_body);
1051 SET_ATTRIB(verbatim_handling);
1052 #ifdef HAVE_COLOR
1053 SET_ATTRIB(extquote_handling);
1054 #endif /* HAVE_COLOR */
1055 SET_ATTRIB(wrap_on_next_unread);
1056 SET_ATTRIB(add_posted_to_filter);
1057 SET_ATTRIB(advertising);
1058 SET_ATTRIB(alternative_handling);
1059 SET_ATTRIB(ask_for_metamail);
1060 SET_ATTRIB(auto_cc_bcc);
1061 SET_ATTRIB(auto_list_thread);
1062 SET_ATTRIB(auto_save);
1063 SET_ATTRIB(auto_select);
1064 SET_ATTRIB(batch_save);
1065 SET_ATTRIB(delete_tmp_files);
1066 SET_ATTRIB(group_catchup_on_exit);
1067 SET_ATTRIB(mail_8bit_header);
1068 SET_ATTRIB(mail_mime_encoding);
1069 SET_ATTRIB(mark_ignore_tags);
1070 SET_ATTRIB(mark_saved_read);
1071 if (curr_scope->state->news_headers_to_display)
1072 group->attribute->headers_to_display = curr_scope->attribute->headers_to_display;
1073 if (curr_scope->state->news_headers_to_not_display)
1074 group->attribute->headers_to_not_display = curr_scope->attribute->headers_to_not_display;
1075 SET_ATTRIB(pos_first_unread);
1076 SET_ATTRIB(post_8bit_header);
1077 SET_ATTRIB(post_mime_encoding);
1078 SET_ATTRIB(post_process_view);
1079 SET_ATTRIB(post_process_type);
1080 #ifndef DISABLE_PRINTING
1081 SET_ATTRIB(print_header);
1082 #endif /* !DISABLE_PRINTING */
1083 SET_ATTRIB(process_only_unread);
1084 SET_ATTRIB(prompt_followupto);
1085 SET_ATTRIB(sigdashes);
1086 SET_ATTRIB(signature_repost);
1087 SET_ATTRIB(start_editor_offset);
1088 SET_ATTRIB(x_comment_to);
1089 SET_ATTRIB(tex2iso_conv);
1090 SET_ATTRIB(mime_forward);
1091 }
1092 }
1093 if (found) {
1094 /*
1095 * sort out conflicting settings
1096 */
1097 #ifdef CHARSET_CONVERSION
1098 /*
1099 * check if we have a 7bit charset but a !7bit encoding
1100 * or a 8bit charset but a !8bit encoding, update encoding if needed
1101 */
1102 is_7bit = FALSE;
1103 for (j = 0; txt_mime_7bit_charsets[j] != NULL; j++) {
1104 if (!strcasecmp(txt_mime_charsets[group->attribute->mm_network_charset], txt_mime_7bit_charsets[j])) {
1105 is_7bit = TRUE;
1106 break;
1107 }
1108 }
1109 if (is_7bit) {
1110 group->attribute->mail_mime_encoding = group->attribute->post_mime_encoding = MIME_ENCODING_7BIT;
1111 } else {
1112 if (group->attribute->mail_mime_encoding == MIME_ENCODING_7BIT)
1113 group->attribute->mail_mime_encoding = MIME_ENCODING_QP;
1114 if (group->attribute->post_mime_encoding == MIME_ENCODING_7BIT)
1115 group->attribute->post_mime_encoding = MIME_ENCODING_8BIT;
1116 }
1117 #endif /* CHARSET_CONVERSION */
1118 /* do not use 8 bit headers if mime encoding is not 8bit */
1119 if (group->attribute->mail_mime_encoding != MIME_ENCODING_8BIT)
1120 group->attribute->mail_8bit_header = FALSE;
1121 if (group->attribute->post_mime_encoding != MIME_ENCODING_8BIT)
1122 group->attribute->post_8bit_header = FALSE;
1123 } else {
1124 if (group->attribute && !group->attribute->global)
1125 free(group->attribute);
1126 group->attribute = default_scope->attribute;
1127 }
1128 }
1129 #ifdef DEBUG
1130 dump_attributes();
1131 # if 0
1132 debug_print_filter_attributes();
1133 # endif /* 0 */
1134 #endif /* DEBUG */
1135
1136 if (!batch_mode || verbose)
1137 my_fputc('\n', stdout);
1138
1139 if (!cmd_line && !batch_mode)
1140 clear_message();
1141 }
1142
1143
1144 /*
1145 * (re)build scope->headers_to_[not_]display array
1146 */
1147 void
build_news_headers_array(struct t_attribute * scope,t_bool header_to_display)1148 build_news_headers_array(
1149 struct t_attribute *scope,
1150 t_bool header_to_display)
1151 {
1152 if (header_to_display) {
1153 if (scope->headers_to_display == NULL)
1154 scope->headers_to_display = my_malloc(sizeof(struct t_newsheader));
1155 else {
1156 if (scope->headers_to_display->header)
1157 FreeIfNeeded(*scope->headers_to_display->header);
1158 FreeIfNeeded(scope->headers_to_display->header);
1159 }
1160 scope->headers_to_display->header = ulBuildArgv(scope->news_headers_to_display, &scope->headers_to_display->num);
1161 } else {
1162 if (scope->headers_to_not_display == NULL)
1163 scope->headers_to_not_display = my_malloc(sizeof(struct t_newsheader));
1164 else {
1165 if (scope->headers_to_not_display->header)
1166 FreeIfNeeded(*scope->headers_to_not_display->header);
1167 FreeIfNeeded(scope->headers_to_not_display->header);
1168 }
1169 scope->headers_to_not_display->header = ulBuildArgv(scope->news_headers_to_not_display, &scope->headers_to_not_display->num);
1170 }
1171 }
1172
1173
1174 /*
1175 * Save the scope attributes from scopes[] to ~/.tin/attributes
1176 */
1177 void
write_attributes_file(const char * file)1178 write_attributes_file(
1179 const char *file)
1180 {
1181 FILE *fp;
1182 char *new_file;
1183 int i;
1184 long fpos;
1185
1186 if ((batch_mode || no_write || num_scope < 1) && file_size(file) != -1L)
1187 return;
1188
1189 new_file = get_tmpfilename(file);
1190
1191 if ((fp = fopen(new_file, "w+")) == NULL) {
1192 error_message(2, _(txt_filesystem_full_backup), ATTRIBUTES_FILE);
1193 free(new_file);
1194 return;
1195 }
1196
1197 wait_message(0, _(txt_writing_attributes_file));
1198
1199 #ifdef DEBUG
1200 dump_scopes("SCOPES-W");
1201 #endif /* DEBUG */
1202
1203 /*
1204 * TODO: sort in a useful order
1205 * move strings to lang.c
1206 */
1207 fprintf(fp, "# Group attributes file V%s for the TIN newsreader\n", ATTRIBUTES_VERSION);
1208 fprintf(fp, _("# Do not edit this comment block\n#\n"));
1209 fprintf(fp, _("# scope=STRING (eg. alt.*,!alt.bin*) [mandatory]\n"));
1210 fprintf(fp, _("# add_posted_to_filter=ON/OFF\n"));
1211 fprintf(fp, _("# advertising=ON/OFF\n"));
1212 fprintf(fp, _("# alternative_handling=ON/OFF\n"));
1213 fprintf(fp, _("# ask_for_metamail=ON/OFF\n"));
1214 fprintf(fp, _("# auto_cc_bcc=NUM\n"));
1215 fprintf(fp, _("# 0=No, 1=Cc, 2=Bcc, 3=Cc and Bcc\n"));
1216 fprintf(fp, _("# auto_list_thread=ON/OFF\n"));
1217 fprintf(fp, _("# auto_save=ON/OFF\n"));
1218 fprintf(fp, _("# auto_select=ON/OFF\n"));
1219 fprintf(fp, _("# batch_save=ON/OFF\n"));
1220 fprintf(fp, _("# date_format=STRING (eg. %%a, %%d %%b %%Y %%H:%%M:%%S)\n"));
1221 fprintf(fp, _("# delete_tmp_files=ON/OFF\n"));
1222 fprintf(fp, _("# editor_format=STRING (eg. %%E +%%N %%F)\n"));
1223 fprintf(fp, _("# fcc=STRING (eg. =mailbox)\n"));
1224 fprintf(fp, _("# followup_to=STRING\n"));
1225 fprintf(fp, _("# from=STRING (just append wanted From:-line, don't use quotes)\n"));
1226 fprintf(fp, _("# group_catchup_on_exit=ON/OFF\n"));
1227 fprintf(fp, _("# group_format=STRING (eg. %%n %%m %%R %%L %%s %%F)\n"));
1228 fprintf(fp, _("# mail_8bit_header=ON/OFF\n"));
1229 fprintf(fp, _("# mail_mime_encoding=supported_encoding"));
1230 for (i = 0; txt_mime_encodings[i] != NULL; i++) {
1231 if (!(i % 5))
1232 fprintf(fp, "\n# ");
1233 fprintf(fp, "%s, ", txt_mime_encodings[i]);
1234 }
1235 fprintf(fp, "\n");
1236 #ifdef HAVE_ISPELL
1237 fprintf(fp, _("# ispell=STRING\n"));
1238 #endif /* HAVE_ISPELL */
1239 fprintf(fp, _("# maildir=STRING (eg. ~/Mail)\n"));
1240 fprintf(fp, _("# mailing_list=STRING (eg. majordomo@example.org)\n"));
1241 fprintf(fp, _("# mime_types_to_save=STRING (eg. image/*,!image/bmp)\n"));
1242 fprintf(fp, _("# mark_ignore_tags=ON/OFF\n"));
1243 fprintf(fp, _("# mark_saved_read=ON/OFF\n"));
1244 fprintf(fp, _("# mime_forward=ON/OFF\n"));
1245 #ifdef CHARSET_CONVERSION
1246 fprintf(fp, _("# mm_network_charset=supported_charset"));
1247 for (i = 0; txt_mime_charsets[i] != NULL; i++) {
1248 if (!(i % 5)) /* start new line */
1249 fprintf(fp, "\n# ");
1250 fprintf(fp, "%s, ", txt_mime_charsets[i]);
1251 }
1252 fprintf(fp, "\n");
1253 fprintf(fp, _("# undeclared_charset=STRING (default is US-ASCII)\n"));
1254 #endif /* CHARSET_CONVERSION */
1255 fprintf(fp, _("# news_headers_to_display=STRING\n"));
1256 fprintf(fp, _("# news_headers_to_not_display=STRING\n"));
1257 fprintf(fp, _("# news_quote_format=STRING\n"));
1258 fprintf(fp, _("# organization=STRING (if beginning with '/' read from file)\n"));
1259 fprintf(fp, _("# pos_first_unread=ON/OFF\n"));
1260 fprintf(fp, _("# post_8bit_header=ON/OFF\n"));
1261 fprintf(fp, _("# post_mime_encoding=supported_encoding"));
1262 for (i = 0; txt_mime_encodings[i] != NULL; i++) {
1263 if (!(i % 5))
1264 fprintf(fp, "\n# ");
1265 fprintf(fp, "%s, ", txt_mime_encodings[i]);
1266 }
1267 fprintf(fp, "\n");
1268 fprintf(fp, _("# post_process_type=NUM\n"));
1269 fprintf(fp, "# %d=%s, %d=%s, %d=%s\n",
1270 POST_PROC_NO, _(txt_post_process_types[POST_PROC_NO]),
1271 POST_PROC_SHAR, _(txt_post_process_types[POST_PROC_SHAR]),
1272 POST_PROC_YES, _(txt_post_process_types[POST_PROC_YES]));
1273 fprintf(fp, _("# post_process_view=ON/OFF\n"));
1274 fprintf(fp, _("# quick_kill_scope=STRING (ie. talk.*)\n"));
1275 fprintf(fp, _("# quick_kill_expire=ON/OFF\n"));
1276 fprintf(fp, _("# quick_kill_case=ON/OFF\n"));
1277 fprintf(fp, _("# quick_kill_header=NUM\n"));
1278 fprintf(fp, _("# 0=Subject: (case sensitive) 1=Subject: (ignore case)\n"));
1279 fprintf(fp, _("# 2=From: (case sensitive) 3=From: (ignore case)\n"));
1280 fprintf(fp, _("# 4=Message-ID: & full References: line\n"));
1281 fprintf(fp, _("# 5=Message-ID: & last References: entry only\n"));
1282 fprintf(fp, _("# 6=Message-ID: entry only 7=Lines:\n"));
1283 fprintf(fp, _("# quick_select_scope=STRING\n"));
1284 fprintf(fp, _("# quick_select_expire=ON/OFF\n"));
1285 fprintf(fp, _("# quick_select_case=ON/OFF\n"));
1286 fprintf(fp, _("# quick_select_header=NUM\n"));
1287 fprintf(fp, _("# 0=Subject: (case sensitive) 1=Subject: (ignore case)\n"));
1288 fprintf(fp, _("# 2=From: (case sensitive) 3=From: (ignore case)\n"));
1289 fprintf(fp, _("# 4=Message-ID: & full References: line\n"));
1290 fprintf(fp, _("# 5=Message-ID: & last References: entry only\n"));
1291 fprintf(fp, _("# 6=Message-ID: entry only 7=Lines:\n"));
1292 fprintf(fp, _("# quote_chars=STRING (%%I for initials)\n"));
1293 #ifndef DISABLE_PRINTING
1294 fprintf(fp, _("# print_header=ON/OFF\n"));
1295 #endif /* !DISABLE_PRINTING */
1296 fprintf(fp, _("# process_only_unread=ON/OFF\n"));
1297 fprintf(fp, _("# prompt_followupto=ON/OFF\n"));
1298 fprintf(fp, _("# savedir=STRING (eg. ~user/News)\n"));
1299 fprintf(fp, _("# savefile=STRING (eg. =linux)\n"));
1300 fprintf(fp, _("# sigfile=STRING (eg. $var/sig)\n"));
1301 fprintf(fp, _("# show_author=NUM\n"));
1302 fprintf(fp, "# %d=%s, %d=%s, %d=%s, %d=%s\n",
1303 SHOW_FROM_NONE, _(txt_show_from[SHOW_FROM_NONE]),
1304 SHOW_FROM_ADDR, _(txt_show_from[SHOW_FROM_ADDR]),
1305 SHOW_FROM_NAME, _(txt_show_from[SHOW_FROM_NAME]),
1306 SHOW_FROM_BOTH, _(txt_show_from[SHOW_FROM_BOTH]));
1307 fprintf(fp, _("# show_signatures=ON/OFF\n"));
1308 fprintf(fp, _("# show_only_unread_arts=ON/OFF\n"));
1309 fprintf(fp, _("# sigdashes=ON/OFF\n"));
1310 fprintf(fp, _("# signature_repost=ON/OFF\n"));
1311 fprintf(fp, _("# sort_article_type=NUM\n"));
1312 fprintf(fp, "# %d=%s,\n",
1313 SORT_ARTICLES_BY_NOTHING, _(txt_sort_a_type[SORT_ARTICLES_BY_NOTHING]));
1314 fprintf(fp, "# %d=%s, %d=%s,\n",
1315 SORT_ARTICLES_BY_SUBJ_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SUBJ_DESCEND]),
1316 SORT_ARTICLES_BY_SUBJ_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SUBJ_ASCEND]));
1317 fprintf(fp, "# %d=%s, %d=%s,\n",
1318 SORT_ARTICLES_BY_FROM_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_FROM_DESCEND]),
1319 SORT_ARTICLES_BY_FROM_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_FROM_ASCEND]));
1320 fprintf(fp, "# %d=%s, %d=%s,\n",
1321 SORT_ARTICLES_BY_DATE_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_DATE_DESCEND]),
1322 SORT_ARTICLES_BY_DATE_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_DATE_ASCEND]));
1323 fprintf(fp, "# %d=%s, %d=%s,\n",
1324 SORT_ARTICLES_BY_SCORE_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SCORE_DESCEND]),
1325 SORT_ARTICLES_BY_SCORE_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_SCORE_ASCEND]));
1326 fprintf(fp, "# %d=%s, %d=%s\n",
1327 SORT_ARTICLES_BY_LINES_DESCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_LINES_DESCEND]),
1328 SORT_ARTICLES_BY_LINES_ASCEND, _(txt_sort_a_type[SORT_ARTICLES_BY_LINES_ASCEND]));
1329 fprintf(fp, _("# sort_threads_type=NUM\n"));
1330 fprintf(fp, "# %d=%s, %d=%s, %d=%s\n",
1331 SORT_THREADS_BY_NOTHING, _(txt_sort_t_type[SORT_THREADS_BY_NOTHING]),
1332 SORT_THREADS_BY_SCORE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_DESCEND]),
1333 SORT_THREADS_BY_SCORE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_SCORE_ASCEND]));
1334 fprintf(fp, "# %d=%s\n",
1335 SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_DESCEND]));
1336 fprintf(fp, "# %d=%s\n",
1337 SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND, _(txt_sort_t_type[SORT_THREADS_BY_LAST_POSTING_DATE_ASCEND]));
1338 fprintf(fp, _("# start_editor_offset=ON/OFF\n"));
1339 fprintf(fp, _("# tex2iso_conv=ON/OFF\n"));
1340 fprintf(fp, _("# thread_catchup_on_exit=ON/OFF\n"));
1341 fprintf(fp, _("# thread_articles=NUM"));
1342 for (i = 0; i <= THREAD_MAX; i++) {
1343 if (!(i % 2))
1344 fprintf(fp, "\n# ");
1345 fprintf(fp, "%d=%s, ", i, _(txt_threading[i]));
1346 }
1347 fprintf(fp, "\n");
1348 fprintf(fp, _("# thread_format=STRING (eg. %%n %%m [%%L] %%T %%F)\n"));
1349 fprintf(fp, _("# thread_perc=NUM\n"));
1350 fprintf(fp, _("# trim_article_body=NUM\n"));
1351 fprintf(fp, _("# 0 = Don't trim article body\n"));
1352 fprintf(fp, _("# 1 = Skip leading blank lines\n"));
1353 fprintf(fp, _("# 2 = Skip trailing blank lines\n"));
1354 fprintf(fp, _("# 3 = Skip leading and trailing blank lines\n"));
1355 fprintf(fp, _("# 4 = Compact multiple blank lines between text blocks\n"));
1356 fprintf(fp, _("# 5 = Compact multiple blank lines between text blocks and skip\n# leading blank lines\n"));
1357 fprintf(fp, _("# 6 = Compact multiple blank lines between text blocks and skip\n# trailing blank lines\n"));
1358 fprintf(fp, _("# 7 = Compact multiple blank lines between text blocks and skip\n# leading and trailing blank lines\n"));
1359 fprintf(fp, _("# verbatim_handling=ON/OFF\n"));
1360 #ifdef HAVE_COLOR
1361 fprintf(fp, _("# extquote_handling=ON/OFF\n"));
1362 #endif /* HAVE_COLOR */
1363 fprintf(fp, _("# wrap_on_next_unread=ON/OFF\n"));
1364 fprintf(fp, _("# x_body=STRING (eg. ~/.tin/extra-body-text)\n"));
1365 fprintf(fp, _("# x_comment_to=ON/OFF\n"));
1366 fprintf(fp, _("# x_headers=STRING (eg. ~/.tin/extra-headers)\n"));
1367 fprintf(fp, _("#\n# Note that it is best to put general (global scoping)\n"));
1368 fprintf(fp, _("# entries first followed by group specific entries.\n#\n"));
1369 fprintf(fp, _("############################################################################\n"));
1370
1371 /*
1372 * determine the file offset
1373 * this is necessary because a changed locale setting
1374 * may lead to an invalid offset
1375 */
1376 if ((fpos = ftell(fp)) <= 0) {
1377 clearerr(fp);
1378 fclose(fp);
1379 unlink(new_file);
1380 free(new_file);
1381 error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
1382 return;
1383 }
1384 rewind(fp);
1385 attrib_file_offset = 1;
1386 while ((i = fgetc(fp)) != EOF) {
1387 if (i == '\n')
1388 attrib_file_offset++;
1389 }
1390 if (fseek(fp, fpos, SEEK_SET)) {
1391 clearerr(fp);
1392 fclose(fp);
1393 unlink(new_file);
1394 free(new_file);
1395 error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
1396 return;
1397 }
1398
1399 if ((num_scope > 0) && (scopes != NULL)) {
1400 struct t_scope *scope;
1401
1402 for (i = 1; i < num_scope; i++) {
1403 scope = &scopes[i];
1404 if (!scope->global) {
1405 fprintf(fp, "\nscope=%s\n", scope->scope);
1406 if (scope->state->add_posted_to_filter)
1407 fprintf(fp, "add_posted_to_filter=%s\n", print_boolean(scope->attribute->add_posted_to_filter));
1408 if (scope->state->advertising)
1409 fprintf(fp, "advertising=%s\n", print_boolean(scope->attribute->advertising));
1410 if (scope->state->alternative_handling)
1411 fprintf(fp, "alternative_handling=%s\n", print_boolean(scope->attribute->alternative_handling));
1412 if (scope->state->ask_for_metamail)
1413 fprintf(fp, "ask_for_metamail=%s\n", print_boolean(scope->attribute->ask_for_metamail));
1414 if (scope->state->auto_cc_bcc)
1415 fprintf(fp, "auto_cc_bcc=%u\n", scope->attribute->auto_cc_bcc);
1416 if (scope->state->auto_list_thread)
1417 fprintf(fp, "auto_list_thread=%s\n", print_boolean(scope->attribute->auto_list_thread));
1418 if (scope->state->auto_select)
1419 fprintf(fp, "auto_select=%s\n", print_boolean(scope->attribute->auto_select));
1420 if (scope->state->auto_save)
1421 fprintf(fp, "auto_save=%s\n", print_boolean(scope->attribute->auto_save));
1422 if (scope->state->batch_save)
1423 fprintf(fp, "batch_save=%s\n", print_boolean(scope->attribute->batch_save));
1424 if (scope->state->date_format && scope->attribute->date_format)
1425 fprintf(fp, "date_format=%s\n", scope->attribute->date_format);
1426 if (scope->state->delete_tmp_files)
1427 fprintf(fp, "delete_tmp_files=%s\n", print_boolean(scope->attribute->delete_tmp_files));
1428 if (scope->state->editor_format && scope->attribute->editor_format)
1429 fprintf(fp, "editor_format=%s\n", scope->attribute->editor_format);
1430 #ifdef HAVE_COLOR
1431 if (scope->state->extquote_handling)
1432 fprintf(fp, "extquote_handling=%s\n", print_boolean(scope->attribute->extquote_handling));
1433 #endif /* HAVE_COLOR */
1434 if (scope->state->fcc && scope->attribute->fcc)
1435 fprintf(fp, "fcc=%s\n", scope->attribute->fcc);
1436 if (scope->state->followup_to && scope->attribute->followup_to)
1437 fprintf(fp, "followup_to=%s\n", scope->attribute->followup_to);
1438 if (scope->state->from && scope->attribute->from)
1439 fprintf(fp, "from=%s\n", scope->attribute->from);
1440 if (scope->state->group_catchup_on_exit)
1441 fprintf(fp, "group_catchup_on_exit=%s\n", print_boolean(scope->attribute->group_catchup_on_exit));
1442 if (scope->state->group_format && scope->attribute->group_format)
1443 fprintf(fp, "group_format=%s\n", scope->attribute->group_format);
1444 if (scope->state->mail_8bit_header)
1445 fprintf(fp, "mail_8bit_header=%s\n", print_boolean(scope->attribute->mail_8bit_header));
1446 if (scope->state->mail_mime_encoding)
1447 fprintf(fp, "mail_mime_encoding=%s\n", txt_mime_encodings[scope->attribute->mail_mime_encoding]);
1448 #ifdef HAVE_ISPELL
1449 if (scope->state->ispell && scope->attribute->ispell)
1450 fprintf(fp, "ispell=%s\n", scope->attribute->ispell);
1451 #endif /* HAVE_ISPELL */
1452 if (scope->state->maildir && scope->attribute->maildir)
1453 fprintf(fp, "maildir=%s\n", scope->attribute->maildir);
1454 if (scope->state->mailing_list && scope->attribute->mailing_list)
1455 fprintf(fp, "mailing_list=%s\n", scope->attribute->mailing_list);
1456 if (scope->state->mark_ignore_tags)
1457 fprintf(fp, "mark_ignore_tags=%s\n", print_boolean(scope->attribute->mark_ignore_tags));
1458 if (scope->state->mark_saved_read)
1459 fprintf(fp, "mark_saved_read=%s\n", print_boolean(scope->attribute->mark_saved_read));
1460 if (scope->state->mime_forward)
1461 fprintf(fp, "mime_forward=%s\n", print_boolean(scope->attribute->mime_forward));
1462 if (scope->state->mime_types_to_save && scope->attribute->mime_types_to_save)
1463 fprintf(fp, "mime_types_to_save=%s\n", scope->attribute->mime_types_to_save);
1464 #ifdef CHARSET_CONVERSION
1465 if (scope->state->mm_network_charset)
1466 fprintf(fp, "mm_network_charset=%s\n", txt_mime_charsets[scope->attribute->mm_network_charset]);
1467 if (scope->state->undeclared_charset && scope->attribute->undeclared_charset)
1468 fprintf(fp, "undeclared_charset=%s\n", scope->attribute->undeclared_charset);
1469 #endif /* CHARSET_CONVERSION */
1470 if (scope->state->news_headers_to_display && scope->attribute->news_headers_to_display)
1471 fprintf(fp, "news_headers_to_display=%s\n", scope->attribute->news_headers_to_display);
1472 if (scope->state->news_headers_to_not_display && scope->attribute->news_headers_to_not_display)
1473 fprintf(fp, "news_headers_to_not_display=%s\n", scope->attribute->news_headers_to_not_display);
1474 if (scope->state->news_quote_format && scope->attribute->news_quote_format)
1475 fprintf(fp, "news_quote_format=%s\n", scope->attribute->news_quote_format);
1476 if (scope->state->organization && scope->attribute->organization)
1477 fprintf(fp, "organization=%s\n", scope->attribute->organization);
1478 if (scope->state->pos_first_unread)
1479 fprintf(fp, "pos_first_unread=%s\n", print_boolean(scope->attribute->pos_first_unread));
1480 if (scope->state->post_8bit_header)
1481 fprintf(fp, "post_8bit_header=%s\n", print_boolean(scope->attribute->post_8bit_header));
1482 if (scope->state->post_mime_encoding)
1483 fprintf(fp, "post_mime_encoding=%s\n", txt_mime_encodings[scope->attribute->post_mime_encoding]);
1484 if (scope->state->post_process_view)
1485 fprintf(fp, "post_process_view=%s\n", print_boolean(scope->attribute->post_process_view));
1486 if (scope->state->post_process_type)
1487 fprintf(fp, "post_process_type=%u\n", scope->attribute->post_process_type);
1488 #ifndef DISABLE_PRINTING
1489 if (scope->state->print_header)
1490 fprintf(fp, "print_header=%s\n", print_boolean(scope->attribute->print_header));
1491 #endif /* !DISABLE_PRINTING */
1492 if (scope->state->process_only_unread)
1493 fprintf(fp, "process_only_unread=%s\n", print_boolean(scope->attribute->process_only_unread));
1494 if (scope->state->prompt_followupto)
1495 fprintf(fp, "prompt_followupto=%s\n", print_boolean(scope->attribute->prompt_followupto));
1496 if (scope->state->quick_kill_scope && scope->attribute->quick_kill_scope)
1497 fprintf(fp, "quick_kill_scope=%s\n", scope->attribute->quick_kill_scope);
1498 if (scope->state->quick_kill_case)
1499 fprintf(fp, "quick_kill_case=%s\n", print_boolean(scope->attribute->quick_kill_case));
1500 if (scope->state->quick_kill_expire)
1501 fprintf(fp, "quick_kill_expire=%s\n", print_boolean(scope->attribute->quick_kill_expire));
1502 if (scope->state->quick_kill_header)
1503 fprintf(fp, "quick_kill_header=%u\n", scope->attribute->quick_kill_header);
1504 if (scope->state->quick_select_scope && scope->attribute->quick_select_scope)
1505 fprintf(fp, "quick_select_scope=%s\n", scope->attribute->quick_select_scope);
1506 if (scope->state->quick_select_case)
1507 fprintf(fp, "quick_select_case=%s\n", print_boolean(scope->attribute->quick_select_case));
1508 if (scope->state->quick_select_expire)
1509 fprintf(fp, "quick_select_expire=%s\n", print_boolean(scope->attribute->quick_select_expire));
1510 if (scope->state->quick_select_header)
1511 fprintf(fp, "quick_select_header=%u\n", scope->attribute->quick_select_header);
1512 if (scope->state->quote_chars && scope->attribute->quote_chars)
1513 fprintf(fp, "quote_chars=%s\n", quote_space_to_dash(scope->attribute->quote_chars));
1514 if (scope->state->savedir && scope->attribute->savedir)
1515 fprintf(fp, "savedir=%s\n", scope->attribute->savedir);
1516 if (scope->state->savefile && scope->attribute->savefile)
1517 fprintf(fp, "savefile=%s\n", scope->attribute->savefile);
1518 if (scope->state->show_author)
1519 fprintf(fp, "show_author=%u\n", scope->attribute->show_author);
1520 if (scope->state->show_only_unread_arts)
1521 fprintf(fp, "show_only_unread_arts=%s\n", print_boolean(scope->attribute->show_only_unread_arts));
1522 if (scope->state->show_signatures)
1523 fprintf(fp, "show_signatures=%s\n", print_boolean(scope->attribute->show_signatures));
1524 if (scope->state->sigdashes)
1525 fprintf(fp, "sigdashes=%s\n", print_boolean(scope->attribute->sigdashes));
1526 if (scope->state->sigfile && scope->attribute->sigfile)
1527 fprintf(fp, "sigfile=%s\n", scope->attribute->sigfile);
1528 if (scope->state->signature_repost)
1529 fprintf(fp, "signature_repost=%s\n", print_boolean(scope->attribute->signature_repost));
1530 if (scope->state->sort_article_type)
1531 fprintf(fp, "sort_article_type=%u\n", scope->attribute->sort_article_type);
1532 if (scope->state->sort_threads_type)
1533 fprintf(fp, "sort_threads_type=%u\n", scope->attribute->sort_threads_type);
1534 if (scope->state->start_editor_offset)
1535 fprintf(fp, "start_editor_offset=%s\n", print_boolean(scope->attribute->start_editor_offset));
1536 if (scope->state->tex2iso_conv)
1537 fprintf(fp, "tex2iso_conv=%s\n", print_boolean(scope->attribute->tex2iso_conv));
1538 if (scope->state->thread_articles)
1539 fprintf(fp, "thread_articles=%u\n", scope->attribute->thread_articles);
1540 if (scope->state->thread_catchup_on_exit)
1541 fprintf(fp, "thread_catchup_on_exit=%s\n", print_boolean(scope->attribute->thread_catchup_on_exit));
1542 if (scope->state->thread_format && scope->attribute->thread_format)
1543 fprintf(fp, "thread_format=%s\n", scope->attribute->thread_format);
1544 if (scope->state->thread_perc)
1545 fprintf(fp, "thread_perc=%u\n", scope->attribute->thread_perc);
1546 if (scope->state->trim_article_body)
1547 fprintf(fp, "trim_article_body=%u\n", scope->attribute->trim_article_body);
1548 if (scope->state->verbatim_handling)
1549 fprintf(fp, "verbatim_handling=%s\n", print_boolean(scope->attribute->verbatim_handling));
1550 if (scope->state->wrap_on_next_unread)
1551 fprintf(fp, "wrap_on_next_unread=%s\n", print_boolean(scope->attribute->wrap_on_next_unread));
1552 if (scope->state->x_headers && scope->attribute->x_headers)
1553 fprintf(fp, "x_headers=%s\n", scope->attribute->x_headers);
1554 if (scope->state->x_body && scope->attribute->x_body)
1555 fprintf(fp, "x_body=%s\n", scope->attribute->x_body);
1556 if (scope->state->x_comment_to)
1557 fprintf(fp, "x_comment_to=%s\n", print_boolean(scope->attribute->x_comment_to));
1558 }
1559 }
1560 }
1561
1562 /* rename_file() preserves mode, so this is safe */
1563 #ifdef HAVE_FCHMOD
1564 fchmod(fileno(fp), (mode_t) (S_IRUSR|S_IWUSR));
1565 #else
1566 # ifdef HAVE_CHMOD
1567 chmod(new_file, (mode_t) (S_IRUSR|S_IWUSR));
1568 # endif /* HAVE_CHMOD */
1569 #endif /* HAVE_FCHMOD */
1570
1571 if ((i = ferror(fp)) || fclose(fp)) {
1572 error_message(2, _(txt_filesystem_full), ATTRIBUTES_FILE);
1573 unlink(new_file);
1574 if (i) {
1575 clearerr(fp);
1576 fclose(fp);
1577 }
1578 } else
1579 rename_file(new_file, file);
1580
1581 free(new_file);
1582 }
1583
1584
1585 #ifdef DEBUG
1586 # if 0
1587 static void
1588 debug_print_filter_attributes(
1589 void)
1590 {
1591 if (debug & DEBUG_ATTRIB) {
1592 int i;
1593 struct t_group *group;
1594
1595 my_printf("\nBEG ***\n");
1596
1597 for_each_group(i) {
1598 group = &active[i];
1599 my_printf("Grp=[%s] KILL header=[%d] scope=[%s] case=[%s] expire=[%s]\n",
1600 group->name, group->attribute->quick_kill_header,
1601 BlankIfNull(group->attribute->quick_kill_scope),
1602 txt_onoff[group->attribute->quick_kill_case != FALSE ? 1 : 0],
1603 txt_onoff[group->attribute->quick_kill_expire != FALSE ? 1 : 0]);
1604 my_printf("Grp=[%s] SELECT header=[%d] scope=[%s] case=[%s] expire=[%s]\n",
1605 group->name, group->attribute->quick_select_header,
1606 BlankIfNull(group->attribute->quick_select_scope),
1607 txt_onoff[group->attribute->quick_select_case != FALSE ? 1 : 0],
1608 txt_onoff[group->attribute->quick_select_expire != FALSE ? 1 : 0]);
1609 }
1610 my_printf("END ***\n");
1611 }
1612 }
1613 # endif /* 0 */
1614
1615
1616 static void
dump_attributes(void)1617 dump_attributes(
1618 void)
1619 {
1620 if (debug & DEBUG_ATTRIB) {
1621 int i, j;
1622 struct t_group *group;
1623
1624 for_each_group(i) {
1625 group = &active[i];
1626 if (!group->attribute)
1627 continue;
1628 debug_print_file("ATTRIBUTES", "group=%s", BlankIfNull(group->name));
1629 debug_print_file("ATTRIBUTES", "\tGlobal=%d", group->attribute->global);
1630 debug_print_file("ATTRIBUTES", "\tmaildir=%s", BlankIfNull(group->attribute->maildir));
1631 debug_print_file("ATTRIBUTES", "\tsavedir=%s", BlankIfNull(group->attribute->savedir));
1632 debug_print_file("ATTRIBUTES", "\tsavefile=%s", BlankIfNull(group->attribute->savefile));
1633 debug_print_file("ATTRIBUTES", "\tsigfile=%s", BlankIfNull(group->attribute->sigfile));
1634 debug_print_file("ATTRIBUTES", "\torganization=%s", BlankIfNull(group->attribute->organization));
1635 debug_print_file("ATTRIBUTES", "\tfollowup_to=%s", BlankIfNull(group->attribute->followup_to));
1636 debug_print_file("ATTRIBUTES", "\tmailing_list=%s", BlankIfNull(group->attribute->mailing_list));
1637 debug_print_file("ATTRIBUTES", "\tx_headers=%s", BlankIfNull(group->attribute->x_headers));
1638 debug_print_file("ATTRIBUTES", "\tx_body=%s", BlankIfNull(group->attribute->x_body));
1639 debug_print_file("ATTRIBUTES", "\tfrom=%s", BlankIfNull(group->attribute->from));
1640 debug_print_file("ATTRIBUTES", "\tnews_quote_format=%s", BlankIfNull(group->attribute->news_quote_format));
1641 debug_print_file("ATTRIBUTES", "\tquote_chars=%s", quote_space_to_dash(BlankIfNull(group->attribute->quote_chars)));
1642 debug_print_file("ATTRIBUTES", "\tmime_types_to_save=%s", BlankIfNull(group->attribute->mime_types_to_save));
1643 # ifdef HAVE_ISPELL
1644 debug_print_file("ATTRIBUTES", "\tispell=%s", BlankIfNull(group->attribute->ispell));
1645 # endif /* HAVE_ISPELL */
1646 debug_print_file("ATTRIBUTES", "\tshow_only_unread_arts=%s", print_boolean(group->attribute->show_only_unread_arts));
1647 debug_print_file("ATTRIBUTES", "\tthread_articles=%d", group->attribute->thread_articles);
1648 debug_print_file("ATTRIBUTES", "\tthread_perc=%d", group->attribute->thread_perc);
1649 debug_print_file("ATTRIBUTES", "\tadd_posted_to_filter=%s", print_boolean(group->attribute->add_posted_to_filter));
1650 debug_print_file("ATTRIBUTES", "\tadvertising=%s", print_boolean(group->attribute->advertising));
1651 debug_print_file("ATTRIBUTES", "\talternative_handling=%s", print_boolean(group->attribute->alternative_handling));
1652 debug_print_file("ATTRIBUTES", "\task_for_metamail=%s", print_boolean(group->attribute->ask_for_metamail));
1653 debug_print_file("ATTRIBUTES", "\tauto_cc_bcc=%d", group->attribute->auto_cc_bcc);
1654 debug_print_file("ATTRIBUTES", "\tauto_list_thread=%s", print_boolean(group->attribute->auto_list_thread));
1655 debug_print_file("ATTRIBUTES", "\tauto_select=%s", print_boolean(group->attribute->auto_select));
1656 debug_print_file("ATTRIBUTES", "\tauto_save=%s", print_boolean(group->attribute->auto_save));
1657 debug_print_file("ATTRIBUTES", "\tbatch_save=%s", print_boolean(group->attribute->batch_save));
1658 debug_print_file("ATTRIBUTES", "\tdate_format=%s", BlankIfNull(group->attribute->date_format));
1659 debug_print_file("ATTRIBUTES", "\tdelete_tmp_files=%s", print_boolean(group->attribute->delete_tmp_files));
1660 debug_print_file("ATTRIBUTES", "\teditor_format=%s", BlankIfNull(group->attribute->editor_format));
1661 # ifdef HAVE_COLOR
1662 debug_print_file("ATTRIBUTES", "\textquote_handling=%s", print_boolean(group->attribute->extquote_handling));
1663 # endif /* HAVE_COLOR */
1664 debug_print_file("ATTRIBUTES", "\tgroup_catchup_on_exit=%s", print_boolean(group->attribute->group_catchup_on_exit));
1665 debug_print_file("ATTRIBUTES", "\tgroup_format=%s", BlankIfNull(group->attribute->group_format));
1666 debug_print_file("ATTRIBUTES", "\tmail_8bit_header=%s", print_boolean(group->attribute->mail_8bit_header));
1667 debug_print_file("ATTRIBUTES", "\tmail_mime_encoding=%s", txt_mime_encodings[group->attribute->mail_mime_encoding]);
1668 debug_print_file("ATTRIBUTES", "\tmark_ignore_tags=%s", print_boolean(group->attribute->mark_ignore_tags));
1669 debug_print_file("ATTRIBUTES", "\tmark_saved_read=%s", print_boolean(group->attribute->mark_saved_read));
1670 debug_print_file("ATTRIBUTES", "\tnews_headers_to_display=%s", BlankIfNull(group->attribute->news_headers_to_display));
1671 if (group->attribute->headers_to_display) {
1672 debug_print_file("ATTRIBUTES", "\theaders_to_display->num=%d", group->attribute->headers_to_display->num);
1673 for (j = 0; j < group->attribute->headers_to_display->num; j++)
1674 debug_print_file("ATTRIBUTES", "\theaders_to_display->header[%d]=%s", j, group->attribute->headers_to_display->header[j]);
1675 }
1676 debug_print_file("ATTRIBUTES", "\tnews_headers_to_not_display=%s", BlankIfNull(group->attribute->news_headers_to_not_display));
1677 if (group->attribute->headers_to_not_display) {
1678 debug_print_file("ATTRIBUTES", "\theaders_to_not_display->num=%d", group->attribute->headers_to_not_display->num);
1679 for (j = 0; j < group->attribute->headers_to_not_display->num; j++)
1680 debug_print_file("ATTRIBUTES", "\theaders_to_not_display->header[%d]=%s", j, group->attribute->headers_to_not_display->header[j]);
1681 }
1682 debug_print_file("ATTRIBUTES", "\tpos_first_unread=%s", print_boolean(group->attribute->pos_first_unread));
1683 debug_print_file("ATTRIBUTES", "\tpost_8bit_header=%s", print_boolean(group->attribute->post_8bit_header));
1684 debug_print_file("ATTRIBUTES", "\tpost_mime_encoding=%s", txt_mime_encodings[group->attribute->post_mime_encoding]);
1685 debug_print_file("ATTRIBUTES", "\tpost_process_view=%s", print_boolean(group->attribute->post_process_view));
1686 # ifndef DISABLE_PRINTING
1687 debug_print_file("ATTRIBUTES", "\tprint_header=%s", print_boolean(group->attribute->print_header));
1688 # endif /* !DISABLE_PRINTING */
1689 debug_print_file("ATTRIBUTES", "\tprocess_only_unread=%s", print_boolean(group->attribute->process_only_unread));
1690 debug_print_file("ATTRIBUTES", "\tprompt_followupto=%s", print_boolean(group->attribute->prompt_followupto));
1691 debug_print_file("ATTRIBUTES", "\tsort_article_type=%d", group->attribute->sort_article_type);
1692 debug_print_file("ATTRIBUTES", "\tsort_threads_type=%d", group->attribute->sort_threads_type);
1693 debug_print_file("ATTRIBUTES", "\tshow_author=%d", group->attribute->show_author);
1694 debug_print_file("ATTRIBUTES", "\tshow_signatures=%s", print_boolean(group->attribute->show_signatures));
1695 debug_print_file("ATTRIBUTES", "\tsigdashes=%s", print_boolean(group->attribute->sigdashes));
1696 debug_print_file("ATTRIBUTES", "\tsignature_repost=%s", print_boolean(group->attribute->signature_repost));
1697 debug_print_file("ATTRIBUTES", "\tstart_editor_offset=%s", print_boolean(group->attribute->start_editor_offset));
1698 debug_print_file("ATTRIBUTES", "\tthread_catchup_on_exit=%s", print_boolean(group->attribute->thread_catchup_on_exit));
1699 debug_print_file("ATTRIBUTES", "\tthread_format=%s", BlankIfNull(group->attribute->thread_format));
1700 debug_print_file("ATTRIBUTES", "\ttrim_article_body=%d", group->attribute->trim_article_body);
1701 debug_print_file("ATTRIBUTES", "\tverbatim_handling=%s", print_boolean(group->attribute->verbatim_handling));
1702 debug_print_file("ATTRIBUTES", "\twrap_on_next_unread=%s", print_boolean(group->attribute->wrap_on_next_unread));
1703 debug_print_file("ATTRIBUTES", "\tpost_process_type=%d", group->attribute->post_process_type);
1704 debug_print_file("ATTRIBUTES", "\tquick_kill_scope=%s", BlankIfNull(group->attribute->quick_kill_scope));
1705 debug_print_file("ATTRIBUTES", "\tquick_kill_case=%s", print_boolean(group->attribute->quick_kill_case));
1706 debug_print_file("ATTRIBUTES", "\tquick_kill_expire=%s", print_boolean(group->attribute->quick_kill_expire));
1707 debug_print_file("ATTRIBUTES", "\tquick_kill_header=%d", group->attribute->quick_kill_header);
1708 debug_print_file("ATTRIBUTES", "\tquick_select_scope=%s", BlankIfNull(group->attribute->quick_select_scope));
1709 debug_print_file("ATTRIBUTES", "\tquick_select_case=%s", print_boolean(group->attribute->quick_select_case));
1710 debug_print_file("ATTRIBUTES", "\tquick_select_expire=%s", print_boolean(group->attribute->quick_select_expire));
1711 debug_print_file("ATTRIBUTES", "\tquick_select_header=%d", group->attribute->quick_select_header);
1712 debug_print_file("ATTRIBUTES", "\tx_comment_to=%s", print_boolean(group->attribute->x_comment_to));
1713 debug_print_file("ATTRIBUTES", "\tfcc=%s", BlankIfNull(group->attribute->fcc));
1714 debug_print_file("ATTRIBUTES", "\ttex2iso_conv=%s", print_boolean(group->attribute->tex2iso_conv));
1715 debug_print_file("ATTRIBUTES", "\tmime_forward=%s", print_boolean(group->attribute->mime_forward));
1716 # ifdef CHARSET_CONVERSION
1717 debug_print_file("ATTRIBUTES", "\tmm_network_charset=%s", txt_mime_charsets[group->attribute->mm_network_charset]);
1718 debug_print_file("ATTRIBUTES", "\tundeclared_charset=%s", BlankIfNull(group->attribute->undeclared_charset));
1719 # endif /* CHARSET_CONVERSION */
1720 debug_print_file("ATTRIBUTES", "");
1721 }
1722 }
1723 }
1724
1725
1726 #define DEBUG_PRINT_STATE(attrib) (scope->state->attrib ? "+ " : " ")
1727 #define DEBUG_PRINT_STRING(attrib) (scope->attribute->attrib ? scope->attribute->attrib : "NULL")
1728
1729
1730 static void
dump_scopes(const char * fname)1731 dump_scopes(
1732 const char *fname)
1733 {
1734 if (!scopes)
1735 return;
1736
1737 if (debug & DEBUG_ATTRIB) {
1738 int i, j;
1739 struct t_scope *scope;
1740
1741 for (i = 0; i < num_scope; i++) {
1742 scope = &scopes[i];
1743 debug_print_file(fname, "scopes[%d]", i);
1744 debug_print_file(fname, "scope=%s", scope->scope ? scope->scope : "NULL");
1745 debug_print_file(fname, "\t global=%d", scope->global);
1746 debug_print_file(fname, "\t%smaildir=%s", DEBUG_PRINT_STATE(maildir), DEBUG_PRINT_STRING(maildir));
1747 debug_print_file(fname, "\t%ssavedir=%s", DEBUG_PRINT_STATE(savedir), DEBUG_PRINT_STRING(savedir));
1748 debug_print_file(fname, "\t%ssavefile=%s", DEBUG_PRINT_STATE(savefile), DEBUG_PRINT_STRING(savefile));
1749 debug_print_file(fname, "\t%ssigfile=%s", DEBUG_PRINT_STATE(sigfile), DEBUG_PRINT_STRING(sigfile));
1750 debug_print_file(fname, "\t%sorganization=%s", DEBUG_PRINT_STATE(organization), DEBUG_PRINT_STRING(organization));
1751 debug_print_file(fname, "\t%sfollowup_to=%s", DEBUG_PRINT_STATE(followup_to), DEBUG_PRINT_STRING(followup_to));
1752 debug_print_file(fname, "\t%smailing_list=%s", DEBUG_PRINT_STATE(mailing_list), DEBUG_PRINT_STRING(mailing_list));
1753 debug_print_file(fname, "\t%sx_headers=%s", DEBUG_PRINT_STATE(x_headers), DEBUG_PRINT_STRING(x_headers));
1754 debug_print_file(fname, "\t%sx_body=%s", DEBUG_PRINT_STATE(x_body), DEBUG_PRINT_STRING(x_body));
1755 debug_print_file(fname, "\t%sfrom=%s", DEBUG_PRINT_STATE(from), DEBUG_PRINT_STRING(from));
1756 debug_print_file(fname, "\t%snews_quote_format=%s", DEBUG_PRINT_STATE(news_quote_format), DEBUG_PRINT_STRING(news_quote_format));
1757 debug_print_file(fname, "\t%squote_chars=%s", DEBUG_PRINT_STATE(quote_chars), quote_space_to_dash(DEBUG_PRINT_STRING(quote_chars)));
1758 debug_print_file(fname, "\t%smime_types_to_save=%s", DEBUG_PRINT_STATE(mime_types_to_save), DEBUG_PRINT_STRING(mime_types_to_save));
1759 # ifdef HAVE_ISPELL
1760 debug_print_file(fname, "\t%sispell=%s", DEBUG_PRINT_STATE(ispell), DEBUG_PRINT_STRING(ispell));
1761 # endif /* HAVE_ISPELL */
1762 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));
1763 debug_print_file(fname, "\t%sthread_articles=%d", DEBUG_PRINT_STATE(thread_articles), scope->attribute->thread_articles);
1764 debug_print_file(fname, "\t%sthread_perc=%d", DEBUG_PRINT_STATE(thread_perc), scope->attribute->thread_perc);
1765 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));
1766 debug_print_file(fname, "\t%sadvertising=%s", DEBUG_PRINT_STATE(advertising), print_boolean(scope->attribute->advertising));
1767 debug_print_file(fname, "\t%salternative_handling=%s", DEBUG_PRINT_STATE(alternative_handling), print_boolean(scope->attribute->alternative_handling));
1768 debug_print_file(fname, "\t%sask_for_metamail=%s", DEBUG_PRINT_STATE(ask_for_metamail), print_boolean(scope->attribute->ask_for_metamail));
1769 debug_print_file(fname, "\t%sauto_cc_bcc=%d", DEBUG_PRINT_STATE(auto_cc_bcc), scope->attribute->auto_cc_bcc);
1770 debug_print_file(fname, "\t%sauto_list_thread=%s", DEBUG_PRINT_STATE(auto_list_thread), print_boolean(scope->attribute->auto_list_thread));
1771 debug_print_file(fname, "\t%sauto_select=%s", DEBUG_PRINT_STATE(auto_select), print_boolean(scope->attribute->auto_select));
1772 debug_print_file(fname, "\t%sauto_save=%s", DEBUG_PRINT_STATE(auto_save), print_boolean(scope->attribute->auto_save));
1773 debug_print_file(fname, "\t%sbatch_save=%s", DEBUG_PRINT_STATE(batch_save), print_boolean(scope->attribute->batch_save));
1774 debug_print_file(fname, "\t%sdate_format=%s", DEBUG_PRINT_STATE(date_format), DEBUG_PRINT_STRING(date_format));
1775 debug_print_file(fname, "\t%sdelete_tmp_files=%s", DEBUG_PRINT_STATE(delete_tmp_files), print_boolean(scope->attribute->delete_tmp_files));
1776 debug_print_file(fname, "\t%seditor_format=%s", DEBUG_PRINT_STATE(editor_format), DEBUG_PRINT_STRING(editor_format));
1777 # ifdef HAVE_COLOR
1778 debug_print_file(fname, "\t%sextquote_handling=%s", DEBUG_PRINT_STATE(extquote_handling), print_boolean(scope->attribute->extquote_handling));
1779 # endif /* HAVE_COLOR */
1780 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));
1781 debug_print_file(fname, "\t%sgroup_format=%s", DEBUG_PRINT_STATE(group_format), DEBUG_PRINT_STRING(group_format));
1782 debug_print_file(fname, "\t%smail_8bit_header=%s", DEBUG_PRINT_STATE(mail_8bit_header), print_boolean(scope->attribute->mail_8bit_header));
1783 debug_print_file(fname, "\t%smail_mime_encoding=%s", DEBUG_PRINT_STATE(mail_mime_encoding), txt_mime_encodings[scope->attribute->mail_mime_encoding]);
1784 debug_print_file(fname, "\t%smark_ignore_tags=%s", DEBUG_PRINT_STATE(mark_ignore_tags), print_boolean(scope->attribute->mark_ignore_tags));
1785 debug_print_file(fname, "\t%smark_saved_read=%s", DEBUG_PRINT_STATE(mark_saved_read), print_boolean(scope->attribute->mark_saved_read));
1786 debug_print_file(fname, "\t%snews_headers_to_display=%s", DEBUG_PRINT_STATE(news_headers_to_display), DEBUG_PRINT_STRING(news_headers_to_display));
1787 if (scope->attribute->headers_to_display) {
1788 debug_print_file(fname, "\t headers_to_display->num=%d", scope->attribute->headers_to_display->num);
1789 for (j = 0; j < scope->attribute->headers_to_display->num; j++)
1790 debug_print_file(fname, "\t headers_to_display->header[%d]=%s", j, scope->attribute->headers_to_display->header[j]);
1791 }
1792 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));
1793 if (scope->attribute->headers_to_not_display) {
1794 debug_print_file(fname, "\t headers_to_not_display->num=%d", scope->attribute->headers_to_not_display->num);
1795 for (j = 0; j < scope->attribute->headers_to_not_display->num; j++)
1796 debug_print_file(fname, "\t headers_to_not_display->header[%d]=%s", j, scope->attribute->headers_to_not_display->header[j]);
1797 }
1798 debug_print_file(fname, "\t%spos_first_unread=%s", DEBUG_PRINT_STATE(pos_first_unread), print_boolean(scope->attribute->pos_first_unread));
1799 debug_print_file(fname, "\t%spost_8bit_header=%s", DEBUG_PRINT_STATE(post_8bit_header), print_boolean(scope->attribute->post_8bit_header));
1800 debug_print_file(fname, "\t%spost_mime_encoding=%s", DEBUG_PRINT_STATE(post_mime_encoding), txt_mime_encodings[scope->attribute->post_mime_encoding]);
1801 debug_print_file(fname, "\t%spost_process_view=%s", DEBUG_PRINT_STATE(post_process_view), print_boolean(scope->attribute->post_process_view));
1802 # ifndef DISABLE_PRINTING
1803 debug_print_file(fname, "\t%sprint_header=%s", DEBUG_PRINT_STATE(print_header), print_boolean(scope->attribute->print_header));
1804 # endif /* !DISABLE_PRINTING */
1805 debug_print_file(fname, "\t%sprocess_only_unread=%s", DEBUG_PRINT_STATE(process_only_unread), print_boolean(scope->attribute->process_only_unread));
1806 debug_print_file(fname, "\t%sprompt_followupto=%s", DEBUG_PRINT_STATE(prompt_followupto), print_boolean(scope->attribute->prompt_followupto));
1807 debug_print_file(fname, "\t%ssort_article_type=%d", DEBUG_PRINT_STATE(sort_article_type), scope->attribute->sort_article_type);
1808 debug_print_file(fname, "\t%ssort_threads_type=%d", DEBUG_PRINT_STATE(sort_threads_type), scope->attribute->sort_threads_type);
1809 debug_print_file(fname, "\t%sshow_author=%d", DEBUG_PRINT_STATE(show_author), scope->attribute->show_author);
1810 debug_print_file(fname, "\t%sshow_signatures=%s", DEBUG_PRINT_STATE(show_signatures), print_boolean(scope->attribute->show_signatures));
1811 debug_print_file(fname, "\t%ssigdashes=%s", DEBUG_PRINT_STATE(sigdashes), print_boolean(scope->attribute->sigdashes));
1812 debug_print_file(fname, "\t%ssignature_repost=%s", DEBUG_PRINT_STATE(signature_repost), print_boolean(scope->attribute->signature_repost));
1813 debug_print_file(fname, "\t%sstart_editor_offset=%s", DEBUG_PRINT_STATE(start_editor_offset), print_boolean(scope->attribute->start_editor_offset));
1814 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));
1815 debug_print_file(fname, "\t%sthread_format=%s", DEBUG_PRINT_STATE(thread_format), DEBUG_PRINT_STRING(thread_format));
1816 debug_print_file(fname, "\t%strim_article_body=%d", DEBUG_PRINT_STATE(trim_article_body), scope->attribute->trim_article_body);
1817 debug_print_file(fname, "\t%sverbatim_handling=%s", DEBUG_PRINT_STATE(verbatim_handling), print_boolean(scope->attribute->verbatim_handling));
1818 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));
1819 debug_print_file(fname, "\t%spost_process_type=%d", DEBUG_PRINT_STATE(post_process_type), scope->attribute->post_process_type);
1820 debug_print_file(fname, "\t%squick_kill_scope=%s", DEBUG_PRINT_STATE(quick_kill_scope), DEBUG_PRINT_STRING(quick_kill_scope));
1821 debug_print_file(fname, "\t%squick_kill_case=%s", DEBUG_PRINT_STATE(quick_kill_case), print_boolean(scope->attribute->quick_kill_case));
1822 debug_print_file(fname, "\t%squick_kill_expire=%s", DEBUG_PRINT_STATE(quick_kill_expire), print_boolean(scope->attribute->quick_kill_expire));
1823 debug_print_file(fname, "\t%squick_kill_header=%d", DEBUG_PRINT_STATE(quick_kill_header), scope->attribute->quick_kill_header);
1824 debug_print_file(fname, "\t%squick_select_scope=%s", DEBUG_PRINT_STATE(quick_select_scope), DEBUG_PRINT_STRING(quick_select_scope));
1825 debug_print_file(fname, "\t%squick_select_case=%s", DEBUG_PRINT_STATE(quick_select_case), print_boolean(scope->attribute->quick_select_case));
1826 debug_print_file(fname, "\t%squick_select_expire=%s", DEBUG_PRINT_STATE(quick_select_expire), print_boolean(scope->attribute->quick_select_expire));
1827 debug_print_file(fname, "\t%squick_select_header=%d", DEBUG_PRINT_STATE(quick_select_header), scope->attribute->quick_select_header);
1828 debug_print_file(fname, "\t%sx_comment_to=%s", DEBUG_PRINT_STATE(x_comment_to), print_boolean(scope->attribute->x_comment_to));
1829 debug_print_file(fname, "\t%sfcc=%s", DEBUG_PRINT_STATE(fcc), DEBUG_PRINT_STRING(fcc));
1830 debug_print_file(fname, "\t%stex2iso_conv=%s", DEBUG_PRINT_STATE(tex2iso_conv), print_boolean(scope->attribute->tex2iso_conv));
1831 debug_print_file(fname, "\t%smime_forward=%s", DEBUG_PRINT_STATE(mime_forward), print_boolean(scope->attribute->mime_forward));
1832 # ifdef CHARSET_CONVERSION
1833 debug_print_file(fname, "\t%smm_network_charset=%s", DEBUG_PRINT_STATE(mm_network_charset), txt_mime_charsets[scope->attribute->mm_network_charset]);
1834 debug_print_file(fname, "\t%sundeclared_charset=%s", DEBUG_PRINT_STATE(undeclared_charset), DEBUG_PRINT_STRING(undeclared_charset));
1835 # endif /* CHARSET_CONVERSION */
1836 debug_print_file(fname, "");
1837 }
1838 }
1839 }
1840 #endif /* DEBUG */
1841