1 /*
2  *  Project   : tin - a Usenet reader
3  *  Module    : options_menu.c
4  *  Author    : Michael Bienia <michael@vorlon.ping.de>
5  *  Created   : 2004-09-05
6  *  Updated   : 2020-06-10
7  *  Notes     : Split from config.c
8  *
9  * Copyright (c) 2004-2021 Michael Bienia <michael@vorlon.ping.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 TINCFG_H
45 #	include "tincfg.h"
46 #endif /* !TINCFG_H */
47 #ifndef TCURSES_H
48 #	include "tcurses.h"
49 #endif /* !TCURSES_H */
50 
51 
52 #define option_lines_per_page (cLINES - INDEX_TOP - 3)
53 
54 #define UPDATE_INT_ATTRIBUTES(option) do { \
55 		scopes[0].attribute->option = tinrc.option; \
56 		changed |= MISC_OPTS; \
57 	} while (0)
58 
59 #define CAO(A, O) A ## O
60 #define SET_NUM_ATTRIBUTE(option) do { \
61 		curr_scope->attribute->option = CAO(tinrc.attrib_, option); \
62 		curr_scope->state->option = TRUE; \
63 		changed |= MISC_OPTS; \
64 	} while (0)
65 #define SET_STRING_ATTRIBUTE(opt) do { \
66 		if (!strlen(CAO(tinrc.attrib_, opt))) { \
67 			reset_state(option); \
68 			redraw_screen(option); \
69 		} else { \
70 			FreeIfNeeded(curr_scope->attribute->opt); \
71 			curr_scope->state->opt = TRUE; \
72 			curr_scope->attribute->opt = my_strdup(CAO(tinrc.attrib_, opt)); \
73 		} \
74 		changed |= MISC_OPTS; \
75 	} while (0)
76 
77 static enum option_enum first_option_on_screen, last_option_on_screen, last_opt;
78 
79 /*
80  * local prototypes
81  */
82 static enum option_enum get_first_opt(void);
83 static enum option_enum move_cursor(enum option_enum cur_option, t_bool down);
84 static enum option_enum next_option(enum option_enum option, t_bool incl_titles);
85 static enum option_enum opt_scroll_down(enum option_enum option);
86 static enum option_enum opt_scroll_up(enum option_enum option);
87 static enum option_enum prev_option(enum option_enum option, t_bool incl_titles);
88 static enum option_enum set_option_num(int num);
89 static int add_new_scope(void);
90 static int find_scope(const char *scope);
91 static int get_option_num(enum option_enum option);
92 static int move_scope(int curr_pos);
93 static t_bool check_state(enum option_enum option);
94 static t_bool delete_scope(int curr_pos);
95 static t_bool option_is_title(enum option_enum option);
96 static t_bool option_on_page(enum option_enum option);
97 static t_bool rename_scope(struct t_scope *scope);
98 static t_bool scope_is_empty(void);
99 static t_function option_left(void);
100 static t_function option_right(void);
101 static t_function scope_left(void);
102 static t_function scope_right(void);
103 static void build_scope_line(int i);
104 static void do_delete_scope(int curr_pos);
105 static void do_move_scope(int from, int to);
106 static void draw_scope_arrow(void);
107 static void free_scopes_and_attributes(void);
108 static void highlight_option(enum option_enum option);
109 static void initialize_attributes(void);
110 static void print_any_option(enum option_enum option);
111 static void redraw_screen(enum option_enum option);
112 static void repaint_option(enum option_enum option);
113 static void reset_state(enum option_enum option);
114 static void scope_page(enum context level);
115 static void set_first_option_on_screen(enum option_enum last_option);
116 static void set_last_opt(void);
117 static void set_last_option_on_screen(enum option_enum first_option);
118 static void show_config_page(void);
119 static void show_scope_page(void);
120 static void unhighlight_option(enum option_enum option);
121 #ifdef USE_CURSES
122 	static void do_scroll(int jump);
123 #endif /* USE_CURSES */
124 
125 static t_menu scopemenu = { 0, 0, 0, show_scope_page, draw_scope_arrow, build_scope_line };
126 static struct t_scope *curr_scope = NULL;
127 
128 /*
129  * returns the row on the screen of an option
130  * note: option should be on this page
131  */
132 int
option_row(enum option_enum option)133 option_row(
134 	enum option_enum option)
135 {
136 	int i = 0;
137 	enum option_enum j = first_option_on_screen;
138 
139 	while (j < option) {
140 		if (option_is_visible(j))
141 			i++;
142 		j++;
143 	}
144 
145 	return INDEX_TOP + i;
146 }
147 
148 
149 /*
150  * returns the number of an option
151  */
152 static int
get_option_num(enum option_enum option)153 get_option_num(
154 	enum option_enum option)
155 {
156 	enum option_enum i;
157 	int result = 0;
158 
159 	for (i = 0; i < option && result < (int) last_opt; i = next_option(i, FALSE))
160 		result++;
161 
162 	return result;
163 }
164 
165 
166 /*
167  * returns the option with the given number
168  */
169 static enum option_enum
set_option_num(int num)170 set_option_num(
171 	int num)
172 {
173 	enum option_enum result = 0;
174 
175 	while (num > 0 && result < last_opt) {
176 		result = next_option(result, FALSE);
177 		num--;
178 	}
179 	return result;
180 }
181 
182 
183 /*
184  * returns TRUE if an option is visible in the menu
185  */
186 t_bool
option_is_visible(enum option_enum option)187 option_is_visible(
188 	enum option_enum option)
189 {
190 	switch (option) {
191 #ifdef HAVE_COLOR
192 		case OPT_COL_BACK:
193 		case OPT_COL_FROM:
194 		case OPT_COL_HEAD:
195 		case OPT_COL_HELP:
196 		case OPT_COL_INVERS_BG:
197 		case OPT_COL_INVERS_FG:
198 		case OPT_COL_MESSAGE:
199 		case OPT_COL_MINIHELP:
200 		case OPT_COL_NEWSHEADERS:
201 		case OPT_COL_NORMAL:
202 		case OPT_COL_QUOTE:
203 		case OPT_COL_QUOTE2:
204 		case OPT_COL_QUOTE3:
205 		case OPT_COL_EXTQUOTE:
206 		case OPT_COL_RESPONSE:
207 		case OPT_COL_SIGNATURE:
208 		case OPT_COL_SUBJECT:
209 		case OPT_COL_TEXT:
210 		case OPT_COL_TITLE:
211 		case OPT_COL_URLS:
212 		case OPT_QUOTE_REGEX:
213 		case OPT_QUOTE_REGEX2:
214 		case OPT_QUOTE_REGEX3:
215 		case OPT_EXTQUOTE_HANDLING:
216 			return curr_scope ? FALSE : tinrc.use_color;
217 
218 		case OPT_COL_MARKSTAR:
219 		case OPT_COL_MARKDASH:
220 		case OPT_COL_MARKSLASH:
221 		case OPT_COL_MARKSTROKE:
222 			return curr_scope ? FALSE : (tinrc.word_highlight && tinrc.use_color);
223 
224 		case OPT_COL_VERBATIM:
225 			return curr_scope ? FALSE : (tinrc.verbatim_handling && tinrc.use_color);
226 
227 		case OPT_EXTQUOTE_REGEX:
228 			return curr_scope ? FALSE : (tinrc.extquote_handling && tinrc.use_color);
229 #endif /* HAVE_COLOR */
230 
231 		case OPT_WORD_H_DISPLAY_MARKS:
232 		case OPT_SLASHES_REGEX:
233 		case OPT_STARS_REGEX:
234 		case OPT_STROKES_REGEX:
235 		case OPT_UNDERSCORES_REGEX:
236 			return curr_scope ? FALSE : tinrc.word_highlight;
237 
238 		case OPT_MONO_MARKSTAR:
239 		case OPT_MONO_MARKDASH:
240 		case OPT_MONO_MARKSLASH:
241 		case OPT_MONO_MARKSTROKE:
242 #ifdef HAVE_COLOR
243 			return curr_scope ? FALSE : (tinrc.word_highlight && !tinrc.use_color);
244 #else
245 			return curr_scope ? FALSE : tinrc.word_highlight;
246 #endif /* HAVE_COLOR */
247 
248 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
249 		case OPT_UTF8_GRAPHICS:
250 			return curr_scope ? FALSE : IS_LOCAL_CHARSET("UTF-8");
251 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
252 
253 		case OPT_VERBATIM_BEGIN_REGEX:
254 		case OPT_VERBATIM_END_REGEX:
255 			return curr_scope ? FALSE : tinrc.verbatim_handling;
256 
257 #ifndef USE_CURSES
258 		case OPT_STRIP_BLANKS:
259 #endif /* !USE_CURSES */
260 		case OPT_GETART_LIMIT_OPTIONS:
261 			return curr_scope ? FALSE : TRUE;
262 
263 #ifdef HAVE_COLOR
264 		case OPT_COLOR_OPTIONS:
265 			return curr_scope ? tinrc.use_color : TRUE;
266 #endif /* HAVE_COLOR */
267 
268 		case OPT_DISPLAY_OPTIONS:
269 		case OPT_FILTERING_OPTIONS:
270 		case OPT_SAVING_OPTIONS:
271 		case OPT_POSTING_OPTIONS:
272 		case OPT_EXPERT_OPTIONS:
273 			return TRUE;
274 
275 		case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
276 		case OPT_ATTRIB_ADVERTISING:
277 		case OPT_ATTRIB_ALTERNATIVE_HANDLING:
278 		case OPT_ATTRIB_ASK_FOR_METAMAIL:
279 		case OPT_ATTRIB_AUTO_CC_BCC:
280 		case OPT_ATTRIB_AUTO_LIST_THREAD:
281 		case OPT_ATTRIB_AUTO_SAVE:
282 		case OPT_ATTRIB_AUTO_SELECT:
283 		case OPT_ATTRIB_BATCH_SAVE:
284 		case OPT_ATTRIB_DATE_FORMAT:
285 		case OPT_ATTRIB_DELETE_TMP_FILES:
286 		case OPT_ATTRIB_EDITOR_FORMAT:
287 		case OPT_ATTRIB_FCC:
288 		case OPT_ATTRIB_FOLLOWUP_TO:
289 		case OPT_ATTRIB_FROM:
290 		case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
291 		case OPT_ATTRIB_GROUP_FORMAT:
292 #ifdef HAVE_ISPELL
293 		case OPT_ATTRIB_ISPELL:
294 #endif /* HAVE_ISPELL */
295 		case OPT_ATTRIB_MAILDIR:
296 		case OPT_ATTRIB_MAIL_8BIT_HEADER:
297 		case OPT_ATTRIB_MAIL_MIME_ENCODING:
298 		case OPT_ATTRIB_MAILING_LIST:
299 		case OPT_ATTRIB_MARK_IGNORE_TAGS:
300 		case OPT_ATTRIB_MARK_SAVED_READ:
301 		case OPT_ATTRIB_MIME_FORWARD:
302 		case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
303 		case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
304 		case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
305 		case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
306 		case OPT_ATTRIB_ORGANIZATION:
307 		case OPT_ATTRIB_POST_8BIT_HEADER:
308 		case OPT_ATTRIB_POST_MIME_ENCODING:
309 		case OPT_ATTRIB_POST_PROCESS_VIEW:
310 		case OPT_ATTRIB_POS_FIRST_UNREAD:
311 		case OPT_ATTRIB_QUICK_KILL_HEADER:
312 		case OPT_ATTRIB_QUICK_KILL_SCOPE:
313 		case OPT_ATTRIB_QUICK_KILL_EXPIRE:
314 		case OPT_ATTRIB_QUICK_KILL_CASE:
315 		case OPT_ATTRIB_QUICK_SELECT_HEADER:
316 		case OPT_ATTRIB_QUICK_SELECT_SCOPE:
317 		case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
318 		case OPT_ATTRIB_QUICK_SELECT_CASE:
319 #ifndef DISABLE_PRINTING
320 		case OPT_ATTRIB_PRINT_HEADER:
321 #endif /* !DISABLE_PRINTING */
322 		case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
323 		case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
324 		case OPT_ATTRIB_QUOTE_CHARS:
325 		case OPT_ATTRIB_SAVEDIR:
326 		case OPT_ATTRIB_SAVEFILE:
327 		case OPT_ATTRIB_SHOW_AUTHOR:
328 		case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
329 		case OPT_ATTRIB_SHOW_SIGNATURES:
330 		case OPT_ATTRIB_SIGDASHES:
331 		case OPT_ATTRIB_SIGFILE:
332 		case OPT_ATTRIB_SIGNATURE_REPOST:
333 		case OPT_ATTRIB_START_EDITOR_OFFSET:
334 		case OPT_ATTRIB_THREAD_ARTICLES:
335 		case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
336 		case OPT_ATTRIB_THREAD_FORMAT:
337 		case OPT_ATTRIB_THREAD_PERC:
338 		case OPT_ATTRIB_TRIM_ARTICLE_BODY:
339 		case OPT_ATTRIB_TEX2ISO_CONV:
340 		case OPT_ATTRIB_SORT_THREADS_TYPE:
341 #ifdef CHARSET_CONVERSION
342 		case OPT_ATTRIB_MM_NETWORK_CHARSET:
343 		case OPT_ATTRIB_UNDECLARED_CHARSET:
344 #endif /* CHARSET_CONVERSION */
345 		case OPT_ATTRIB_VERBATIM_HANDLING:
346 		case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
347 		case OPT_ATTRIB_SORT_ARTICLE_TYPE:
348 		case OPT_ATTRIB_POST_PROCESS_TYPE:
349 		case OPT_ATTRIB_X_BODY:
350 		case OPT_ATTRIB_X_COMMENT_TO:
351 		case OPT_ATTRIB_X_HEADERS:
352 			return curr_scope ? TRUE : FALSE;
353 
354 #ifdef HAVE_COLOR
355 		case OPT_ATTRIB_EXTQUOTE_HANDLING:
356 			return curr_scope ? tinrc.use_color : FALSE;
357 #endif /* HAVE_COLOR */
358 
359 		default:
360 			return curr_scope ? FALSE : TRUE;
361 	}
362 }
363 
364 
365 /*
366  * returns TRUE if option is OPT_TITLE else FALSE
367  */
368 static t_bool
option_is_title(enum option_enum option)369 option_is_title(
370 	enum option_enum option)
371 {
372 	return option_table[option].var_type == OPT_TITLE;
373 }
374 
375 
376 /*
377  * returns TRUE if option is on the current page else FALSE
378  */
379 static t_bool
option_on_page(enum option_enum option)380 option_on_page(
381 	enum option_enum option)
382 {
383 	return ((option >= first_option_on_screen) && (option <= last_option_on_screen));
384 }
385 
386 
387 char *
fmt_option_prompt(char * dst,size_t len,t_bool editing,enum option_enum option)388 fmt_option_prompt(
389 	char *dst,
390 	size_t len,
391 	t_bool editing,
392 	enum option_enum option)
393 {
394 	char *buf;
395 	size_t option_width = MAX(35, cCOLS / 2 - 9);
396 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
397 	wchar_t *wbuf, *wbuf2;
398 
399 	/* convert the option text to wchar_t */
400 	wbuf = char2wchar_t(_(option_table[option].txt->opt));
401 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
402 
403 	if (!option_is_title(option)) {
404 		char flag;
405 		int num = get_option_num(option);
406 
407 		flag = (curr_scope && check_state(option)) ? '+' : ' ';
408 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
409 		if (wbuf != NULL) {
410 			wbuf2 = wstrunc(wbuf, option_width);
411 			if ((buf = wchar_t2char(wbuf2)) == NULL) {
412 				/* conversion failed, truncate original string */
413 				buf = strunc(_(option_table[option].txt->opt), option_width);
414 				snprintf(dst, len, "%s %c%3d %-*.*s: ", editing ? "->" : "  ", flag, num, (int) option_width, (int) option_width, buf);
415 			} else
416 				snprintf(dst, len, "%s %c%3d %-*.*s: ", editing ? "->" : "  ", flag, num,
417 					(int) (strlen(buf) + option_width - wcswidth(wbuf2, option_width + 1)),
418 					(int) (strlen(buf) + option_width - wcswidth(wbuf2, option_width + 1)), buf);
419 			free(wbuf2);
420 		} else
421 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
422 		{
423 			/* truncate original string */
424 			buf = strunc(_(option_table[option].txt->opt), option_width);
425 			snprintf(dst, len, "%s %c%3d %-*.*s: ", editing ? "->" : "  ", flag, num, (int) option_width, (int) option_width, buf);
426 		}
427 	} else {
428 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
429 		if (wbuf != NULL) {
430 			wbuf2 = wstrunc(wbuf, cCOLS - 3);
431 			if ((buf = wchar_t2char(wbuf2)) == NULL)	/* conversion failed, truncate original string */
432 				buf = strunc(_(option_table[option].txt->opt), cCOLS - 3);
433 			free(wbuf2);
434 		} else
435 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
436 			buf = strunc(_(option_table[option].txt->opt), cCOLS - 3);	/* truncate original string */
437 		snprintf(dst, len, "  %s", buf);
438 	}
439 
440 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
441 	FreeIfNeeded(wbuf);
442 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
443 	FreeIfNeeded(buf);
444 	return dst;
445 }
446 
447 
448 static void
print_any_option(enum option_enum option)449 print_any_option(
450 	enum option_enum option)
451 {
452 	constext **list;
453 	char temp[LEN], *ptr, *ptr2;
454 	int row = option_row(option);
455 	size_t len = sizeof(temp) - 1;
456 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) && defined(USE_CURSES)
457 	char *buf;
458 #endif /* MULTIBYTE_ABLE && !NO_LOCALE && USE_CURSES */
459 
460 	MoveCursor(row, 0);
461 
462 	ptr = fmt_option_prompt(temp, len, FALSE, option);
463 	ptr += strlen(temp);
464 	len -= strlen(temp);
465 
466 	switch (option_table[option].var_type) {
467 		case OPT_ON_OFF:
468 			/* %-3s to match the length of OFF */
469 			snprintf(ptr, len, "%-3s", print_boolean(*OPT_ON_OFF_list[option_table[option].var_index]));
470 			break;
471 
472 		case OPT_LIST:
473 			list = option_table[option].opt_list;
474 			ptr2 = my_strdup(list[*(option_table[option].variable) + ((strcasecmp(_(list[0]), _(txt_default)) == 0) ? 1 : 0)]);
475 			strncpy(ptr, _(ptr2), len);
476 			free(ptr2);
477 			break;
478 
479 		case OPT_STRING:
480 			strncpy(ptr, OPT_STRING_list[option_table[option].var_index], len);
481 			break;
482 
483 		case OPT_NUM:
484 			snprintf(ptr, len, "%d", *(option_table[option].variable));
485 			break;
486 
487 		case OPT_CHAR:
488 			snprintf(ptr, len, "%c", *OPT_CHAR_list[option_table[option].var_index]);
489 			break;
490 
491 		default:
492 			break;
493 	}
494 #ifdef USE_CURSES
495 #	if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
496 	if ((buf = spart(temp, cCOLS - 1, FALSE)) != NULL) {
497 		my_printf("%s", buf);
498 		free(buf);
499 	} else
500 #	endif /* MULTIBYTE_ABLE && !NO_LOCALE */
501 		my_printf("%.*s", cCOLS - 1, temp);
502 	{
503 		int y, x;
504 
505 		getyx(stdscr, y, x);
506 		if (x < cCOLS)
507 			clrtoeol();
508 	}
509 #else
510 	my_printf("%.*s", cCOLS - 1, temp);
511 	/* draw_arrow_mark() will read this back for repainting */
512 	if (tinrc.strip_blanks)
513 		strncpy(screen[row - INDEX_TOP].col, temp, cCOLS - 1);
514 	else
515 		snprintf(screen[row - INDEX_TOP].col, cCOLS, "%-*s", cCOLS - 1, temp);
516 #endif /* USE_CURSES */
517 }
518 
519 
520 static void
repaint_option(enum option_enum option)521 repaint_option(
522 	enum option_enum option)
523 {
524 	if (option_on_page(option))
525 		print_any_option(option);
526 }
527 
528 
529 #ifdef USE_CURSES
530 static void
do_scroll(int jump)531 do_scroll(
532 	int jump)
533 {
534 	scrollok(stdscr, TRUE);
535 	MoveCursor(INDEX_TOP, 0);
536 	SetScrollRegion(INDEX_TOP, INDEX_TOP + option_lines_per_page - 1);
537 	ScrollScreen(jump);
538 	SetScrollRegion(0, LINES - 1);
539 	scrollok(stdscr, FALSE);
540 }
541 #endif /* USE_CURSES */
542 
543 
544 /*
545  * returns the option after moving 'move' positions up or down
546  * updates also first_option_on_screen and last_option_on screen accordingly
547  */
548 static enum option_enum
move_cursor(enum option_enum cur_option,t_bool down)549 move_cursor(
550 	enum option_enum cur_option,
551 	t_bool down)
552 {
553 	enum option_enum old_option = cur_option;
554 
555 	if (down) {		/* move down */
556 		do {
557 			cur_option = next_option(cur_option, TRUE);
558 			if (cur_option > last_option_on_screen) {
559 				/* move the markers one option down */
560 				last_option_on_screen = cur_option;
561 				first_option_on_screen = next_option(first_option_on_screen, TRUE);
562 #ifdef USE_CURSES
563 				do_scroll(1);
564 				print_any_option(cur_option);
565 #else
566 				show_config_page();
567 #endif /* USE_CURSES */
568 			} else if (cur_option < first_option_on_screen) {
569 				/* wrap around: set to begin of option list */
570 				first_option_on_screen = cur_option;
571 				set_last_option_on_screen(cur_option);
572 				show_config_page();
573 			}
574 		} while (option_is_title(cur_option) && old_option != cur_option);
575 	} else {		/* move up */
576 		do {
577 			cur_option = prev_option(cur_option, TRUE);
578 			if (cur_option < first_option_on_screen) {
579 				/* move the markers one option up */
580 				first_option_on_screen = cur_option;
581 				set_last_option_on_screen(cur_option);
582 #ifdef USE_CURSES
583 				do_scroll(-1);
584 				print_any_option(cur_option);
585 #else
586 				show_config_page();
587 #endif /* USE_CURSES */
588 			} else if (cur_option > last_option_on_screen) {
589 				/* wrap around: set to end of option list */
590 				last_option_on_screen = cur_option;
591 				set_first_option_on_screen(cur_option);
592 				show_config_page();
593 			}
594 		} while (option_is_title(cur_option) && old_option != cur_option);
595 	}
596 	return cur_option;
597 }
598 
599 
600 /*
601  * scroll the screen one line down
602  * the selected option is only moved if it is scrolled off the screen
603  */
604 static enum option_enum
opt_scroll_down(enum option_enum option)605 opt_scroll_down(
606 	enum option_enum option)
607 {
608 	if (last_option_on_screen < last_opt) {
609 		first_option_on_screen = next_option(first_option_on_screen, TRUE);
610 		set_last_option_on_screen(first_option_on_screen);
611 #ifdef USE_CURSES
612 		do_scroll(1);
613 		print_any_option(last_option_on_screen);
614 		stow_cursor();
615 #else
616 		show_config_page();
617 #endif /* USE_CURSES */
618 		if (option < first_option_on_screen) {
619 			option = first_option_on_screen;
620 			if (option_is_title(option))
621 				option = next_option(option, FALSE);
622 #ifdef USE_CURSES
623 			highlight_option(option);
624 #endif /* USE_CURSES */
625 		}
626 #ifndef USE_CURSES
627 		/* in the !USE_CURSES case we must always highlight the option */
628 		highlight_option(option);
629 #endif /* !USE_CURSES */
630 	}
631 	return option;
632 }
633 
634 
635 /*
636  * scroll the screen one line up
637  * the selected option is only moved if it is scrolled off the screen
638  */
639 static enum option_enum
opt_scroll_up(enum option_enum option)640 opt_scroll_up(
641 	enum option_enum option)
642 {
643 	if (first_option_on_screen > 0) {
644 		first_option_on_screen = prev_option(first_option_on_screen, TRUE);
645 		set_last_option_on_screen(first_option_on_screen);
646 #ifdef USE_CURSES
647 		do_scroll(-1);
648 		print_any_option(first_option_on_screen);
649 		stow_cursor();
650 #else
651 		show_config_page();
652 #endif /* USE_CURSES */
653 		if (option > last_option_on_screen) {
654 			option = last_option_on_screen;
655 			if (option_is_title(option))
656 				option = prev_option(option, FALSE);
657 #ifdef USE_CURSES
658 			highlight_option(option);
659 #endif /* USE_CURSES */
660 		}
661 #ifndef USE_CURSES
662 		/* in the !USE_CURSES case we must always highlight the option */
663 		highlight_option(option);
664 #endif /* !USE_CURSES */
665 	}
666 	return option;
667 }
668 
669 
670 /*
671  * returns the next visible option
672  * if 'incl_titles' is TRUE titles are also returned else they are skipped
673  */
674 static enum option_enum
next_option(enum option_enum option,t_bool incl_titles)675 next_option(
676 	enum option_enum option,
677 	t_bool incl_titles)
678 {
679 	do {
680 		option++;
681 		if (option > last_opt)
682 			option = 0;
683 	} while (!(option_is_visible(option) && (incl_titles || !option_is_title(option))));
684 
685 	return option;
686 }
687 
688 
689 /*
690  * returns the previous visible option
691  * if 'incl_titles' is TRUE titles are also returned else they are skipped
692  */
693 static enum option_enum
prev_option(enum option_enum option,t_bool incl_titles)694 prev_option(
695 	enum option_enum option,
696 	t_bool incl_titles)
697 {
698 	do {
699 		if (option == 0)
700 			option = last_opt;
701 		else
702 			option--;
703 	} while (!(option_is_visible(option) && (incl_titles || !option_is_title(option))));
704 
705 	return option;
706 }
707 
708 
709 /*
710  * set first_option_on_screen in such way that 'last_option' will be
711  * the last option on the screen
712  */
713 static void
set_first_option_on_screen(enum option_enum last_option)714 set_first_option_on_screen(
715 	enum option_enum last_option)
716 {
717 	int i;
718 
719 	first_option_on_screen = last_option;
720 	for (i = 1; i < option_lines_per_page && first_option_on_screen > 0; i++)
721 		first_option_on_screen = prev_option(first_option_on_screen, TRUE);
722 
723 	/*
724 	 * make sure that the first page is used completely
725 	 */
726 	if (first_option_on_screen == 0)
727 		set_last_option_on_screen(0);
728 }
729 
730 
731 /*
732  * set last_option_on_screen in such way that 'first_option' will be
733  * the first option on the screen
734  */
735 static void
set_last_option_on_screen(enum option_enum first_option)736 set_last_option_on_screen(
737 	enum option_enum first_option)
738 {
739 	int i;
740 
741 	last_option_on_screen = first_option;
742 	/*
743 	 * on last page, there need not be option_lines_per_page options
744 	 */
745 	for (i = 1; i < option_lines_per_page && last_option_on_screen < last_opt; i++)
746 		last_option_on_screen = next_option(last_option_on_screen, TRUE);
747 }
748 
749 
750 static void
highlight_option(enum option_enum option)751 highlight_option(
752 	enum option_enum option)
753 {
754 	refresh_config_page(option); /* to keep refresh_config_page():last_option up-to-date */
755 	draw_arrow_mark(option_row(option));
756 	info_message("%s", _(option_table[option].txt->opt));
757 }
758 
759 
760 static void
unhighlight_option(enum option_enum option)761 unhighlight_option(
762 	enum option_enum option)
763 {
764 	/* Astonishing hack */
765 	t_menu *savemenu = currmenu;
766 	t_menu cfgmenu = { 0, 1, 0, NULL, NULL, NULL };
767 
768 	currmenu = &cfgmenu;
769 	currmenu->curr = option_row(option) - INDEX_TOP;
770 	erase_arrow();
771 	currmenu = savemenu;
772 	clear_message();
773 }
774 
775 
776 /*
777  * Refresh the config page which holds the actual option. If act_option is
778  * smaller zero fall back on the last given option (first option if there was
779  * no last option) and refresh the screen.
780  */
781 void
refresh_config_page(enum option_enum act_option)782 refresh_config_page(
783 	enum option_enum act_option)
784 {
785 	static enum option_enum last_option = 0;
786 	/* t_bool force_redraw = FALSE; */
787 
788 	if (act_option == SIGNAL_HANDLER) {	/* called by signal handler */
789 		/* force_redraw = TRUE; */
790 		act_option = last_option;
791 		set_last_option_on_screen(first_option_on_screen); /* terminal size may have changed */
792 		if (!option_on_page(last_option)) {
793 			last_option_on_screen = last_option;
794 			set_first_option_on_screen(last_option);
795 		}
796 		redraw_screen(last_option);
797 	}
798 	last_option = act_option;
799 }
800 
801 
802 static void
redraw_screen(enum option_enum option)803 redraw_screen(
804 	enum option_enum option)
805 {
806 	show_config_page();
807 	highlight_option(option);
808 }
809 
810 
811 /*
812  * show_menu_help
813  */
814 void
show_menu_help(const char * help_message)815 show_menu_help(
816 	const char *help_message)
817 {
818 	MoveCursor(cLINES - 2, 0);
819 	CleartoEOLN();
820 	center_line(cLINES - 2, FALSE, _(help_message));
821 }
822 
823 
824 /*
825  * display current configuration page
826  */
827 static void
show_config_page(void)828 show_config_page(
829 	void)
830 {
831 	enum option_enum i;
832 
833 	signal_context = curr_scope ? cAttrib : cConfig;
834 	mark_offset = 0;
835 
836 	ClearScreen();
837 	center_line(0, TRUE, curr_scope ? curr_scope->scope : _(txt_options_menu));
838 
839 	for (i = first_option_on_screen; i <= last_option_on_screen; i++) {
840 		while (!option_is_visible(i))
841 			i++;
842 		if (i > last_opt)
843 			break;
844 		print_any_option(i);
845 	}
846 
847 	show_menu_help(txt_select_config_file_option);
848 	my_flush();
849 	stow_cursor();
850 }
851 
852 
853 /*
854  * Check if score_kill is <= score_limit_kill and if score_select >= score_limit_select
855  */
856 void
check_score_defaults(void)857 check_score_defaults(
858 	void)
859 {
860 	if (tinrc.score_kill > tinrc.score_limit_kill)
861 		tinrc.score_kill = tinrc.score_limit_kill;
862 
863 	if (tinrc.score_select < tinrc.score_limit_select)
864 		tinrc.score_select = tinrc.score_limit_select;
865 }
866 
867 
868 static t_function
option_left(void)869 option_left(
870 	void)
871 {
872 	return GLOBAL_QUIT;
873 }
874 
875 
876 static t_function
option_right(void)877 option_right(
878 	void)
879 {
880 	return CONFIG_SELECT;
881 }
882 
883 
884 /*
885  * set last_opt to the last visible option
886  */
887 static void
set_last_opt(void)888 set_last_opt(
889 	void)
890 {
891 	enum option_enum i;
892 
893 	for (i = 0; i <= LAST_OPT; i++) {
894 		if (option_is_visible(i))
895 			last_opt = i;
896 	}
897 }
898 
899 
900 /*
901  * returns the first visible option
902  */
903 static enum option_enum
get_first_opt(void)904 get_first_opt(
905 	void)
906 {
907 	enum option_enum i;
908 
909 	for (i = 0; i <= last_opt; i++) {
910 		if (option_is_visible(i) && !option_is_title(i))
911 			break;
912 	}
913 	return i;
914 }
915 
916 
917 /*
918  * options menu so that the user can dynamically change parameters
919  */
920 void
config_page(const char * grpname,enum context level)921 config_page(
922 	const char *grpname,
923 	enum context level)
924 {
925 	char key[MAXKEYLEN];
926 	enum option_enum option, old_option;
927 	enum {
928 		NOT_CHANGED			= 0,
929 		MISC_OPTS			= 1 << 0,
930 		DISPLAY_OPTS		= 1 << 1,
931 		SCORE_OPTS			= 1 << 2,
932 		SHOW_AUTHOR			= 1 << 3,
933 		SHOW_ONLY_UNREAD	= 1 << 4,
934 		SORT_OPTS			= 1 << 5,
935 		THREAD_ARTS			= 1 << 6,
936 		THREAD_SCORE		= 1 << 7
937 	} changed = NOT_CHANGED;
938 	int i, scope_idx = 0;
939 	t_bool change_option = FALSE;
940 	t_function func;
941 #ifdef CHARSET_CONVERSION
942 	t_bool is_7bit;
943 #endif /* CHARSET_CONVERSION */
944 	unsigned old_show_author = 0, old_show_unread = 0, old_thread_arts = 0;
945 
946 	if (curr_scope)
947 		initialize_attributes();
948 	if (grpname && curr_group) {
949 		/*
950 		 * These things can be toggled by the user,
951 		 * keep a copy of the current value to restore
952 		 * the state if necessary
953 		 */
954 		old_show_author = curr_group->attribute->show_author;
955 		old_show_unread = curr_group->attribute->show_only_unread_arts;
956 		old_thread_arts = curr_group->attribute->thread_articles;
957 	}
958 	set_last_opt();
959 	option = get_first_opt();
960 	first_option_on_screen = 0;
961 	set_last_option_on_screen(0);
962 
963 	redraw_screen(option);
964 	set_xclick_off();
965 
966 	forever {
967 		switch ((func = handle_keypad(option_left, option_right, NULL, option_menu_keys))) {
968 			case GLOBAL_QUIT:
969 				if (grpname) {
970 					if (curr_scope && scope_is_empty()) {
971 						/*
972 						 * Called via TAB from Config 'M'enu and all attributes
973 						 * have default values -> delete scope
974 						 */
975 						do_delete_scope(scope_idx);
976 						curr_scope = NULL;
977 					}
978 					if (changed) {
979 						/*
980 						 * At least one option or attribute has changed,
981 						 * write config files
982 						 */
983 						write_config_file(local_config_file);
984 						write_attributes_file(local_attributes_file);
985 					}
986 				}
987 				/* FALLTHROUGH */
988 			case CONFIG_NO_SAVE:
989 				if (grpname && curr_scope) {
990 					/*
991 					 * Called via TAB from Config 'M'enu,
992 					 * delete scope if all attributes have default values
993 					 */
994 					if (scope_is_empty())
995 						do_delete_scope(scope_idx);
996 					curr_scope = NULL;
997 				}
998 				assign_attributes_to_groups();
999 				if (grpname && curr_group) {
1000 					/*
1001 					 * These things can be toggled by the user,
1002 					 * restore the cached state if no changes were made
1003 					 */
1004 					if (!(changed & SHOW_AUTHOR))
1005 						curr_group->attribute->show_author = old_show_author;
1006 					if (!(changed & SHOW_ONLY_UNREAD))
1007 						curr_group->attribute->show_only_unread_arts = old_show_unread;
1008 					if (!(changed & THREAD_ARTS))
1009 						curr_group->attribute->thread_articles = old_thread_arts;
1010 
1011 					if (changed) {
1012 						t_bool filtered = FALSE;
1013 						t_bool old_keep_in_base = TRUE;
1014 
1015 						/*
1016 						 * recook if an article is open
1017 						 */
1018 						if (changed & DISPLAY_OPTS) {
1019 							if (pgart.raw)
1020 								resize_article(TRUE, &pgart);
1021 						}
1022 						/*
1023 						 * Clear art->keep_in_base if switching to !show_only_unread_arts
1024 						 */
1025 						if ((changed & SHOW_ONLY_UNREAD) && !curr_group->attribute->show_only_unread_arts) {
1026 							for_each_art(i)
1027 								arts[i].keep_in_base = FALSE;
1028 						}
1029 
1030 						if (changed & SCORE_OPTS) {
1031 							unfilter_articles(curr_group);
1032 							read_filter_file(filter_file);
1033 							filtered = filter_articles(curr_group);
1034 						}
1035 						/*
1036 						 * If the sorting/threading strategy of threads or filter options have
1037 						 * changed, fix things so that resorting will occur
1038 						 *
1039 						 * If show_only_unread_arts or the scoring of a thread has changed,
1040 						 * resort base[] (find_base() is called inside make_threads() too, so
1041 						 * do this only if make_threads() was not called before)
1042 						 *
1043 						 * If we were called from page level, keep the current article in
1044 						 * base[]. This prevents that find_base() removes the current article
1045 						 * after switching to show_only_unread.
1046 						 */
1047 						if (level == cPage) {
1048 							old_keep_in_base = arts[this_resp].keep_in_base;
1049 							arts[this_resp].keep_in_base = TRUE;
1050 						}
1051 						if (changed & (THREAD_ARTS | SORT_OPTS))
1052 							make_threads(curr_group, TRUE);
1053 						else if (filtered)
1054 							make_threads(curr_group, FALSE);
1055 						else if (changed & (SHOW_ONLY_UNREAD | THREAD_SCORE))
1056 							find_base(curr_group);
1057 
1058 						if (level == cPage)
1059 							arts[this_resp].keep_in_base = old_keep_in_base;
1060 					}
1061 				}
1062 				clear_note_area();
1063 				return;
1064 
1065 			case GLOBAL_BUGREPORT:
1066 				bug_report();
1067 				redraw_screen(option);
1068 				break;
1069 
1070 			case GLOBAL_HELP:
1071 				if (curr_scope)
1072 					show_help_page(ATTRIB_LEVEL, _(txt_attrib_menu_com));
1073 				else
1074 					show_help_page(CONFIG_LEVEL, _(txt_options_menu_com));
1075 				redraw_screen(option);
1076 				break;
1077 
1078 			case GLOBAL_LINE_UP:
1079 				unhighlight_option(option);
1080 				option = move_cursor(option, FALSE);
1081 				highlight_option(option);
1082 				break;
1083 
1084 			case GLOBAL_LINE_DOWN:
1085 				unhighlight_option(option);
1086 				option = move_cursor(option, TRUE);
1087 				highlight_option(option);
1088 				break;
1089 
1090 			case GLOBAL_FIRST_PAGE:
1091 				unhighlight_option(option);
1092 				option = get_first_opt();
1093 				first_option_on_screen = 0;
1094 				set_last_option_on_screen(0);
1095 				redraw_screen(option);
1096 				/* highlight_option(option); is already done by redraw_screen() */
1097 				break;
1098 
1099 			case GLOBAL_LAST_PAGE:
1100 				unhighlight_option(option);
1101 				option = last_opt;
1102 				last_option_on_screen = last_opt;
1103 				set_first_option_on_screen(last_opt);
1104 				redraw_screen(option);
1105 				/* highlight_option(option); is already done by redraw_screen() */
1106 				break;
1107 
1108 			case GLOBAL_PAGE_UP:
1109 				unhighlight_option(option);
1110 				if (option != first_option_on_screen && !(option_is_title(first_option_on_screen) && option == next_option(first_option_on_screen, FALSE))) {
1111 					option = first_option_on_screen;
1112 					if (option_is_title(option))
1113 						option = next_option(option, FALSE);
1114 					highlight_option(option);
1115 					break;
1116 				} else if (tinrc.scroll_lines == -2 && first_option_on_screen != 0) {
1117 					i = option_lines_per_page / 2;
1118 
1119 					for (; i > 0; i--) {
1120 						last_option_on_screen = prev_option(last_option_on_screen, TRUE);
1121 						if (last_option_on_screen == last_opt)	/* end on wrap around */
1122 							break;
1123 					}
1124 				} else
1125 					last_option_on_screen = prev_option(first_option_on_screen, TRUE);
1126 
1127 				set_first_option_on_screen(last_option_on_screen);
1128 				if (last_option_on_screen == last_opt)
1129 					option = last_option_on_screen;
1130 				else
1131 					option = first_option_on_screen;
1132 				if (option_is_title(option))
1133 					option = next_option(option, FALSE);
1134 				redraw_screen(option);
1135 				/* highlight_option(option); is already done by redraw_screen() */
1136 				break;
1137 
1138 			case GLOBAL_PAGE_DOWN:
1139 				unhighlight_option(option);
1140 				if (option == last_opt) {
1141 					/* wrap around */
1142 					first_option_on_screen = 0;
1143 					option = 0;
1144 				} else {
1145 					enum option_enum old_first = first_option_on_screen;
1146 
1147 					if (tinrc.scroll_lines == -2) {
1148 						i = option_lines_per_page / 2;
1149 
1150 						for (; i > 0; i--) {
1151 							first_option_on_screen = next_option(first_option_on_screen, TRUE);
1152 							if (first_option_on_screen == 0)	/* end on wrap_around */
1153 								break;
1154 						}
1155 					} else
1156 						first_option_on_screen = next_option(last_option_on_screen, TRUE);
1157 
1158 					if (first_option_on_screen == 0) {
1159 						first_option_on_screen = old_first;
1160 						option = last_opt;
1161 						highlight_option(option);
1162 						break;
1163 					} else
1164 						option = first_option_on_screen;
1165 				}
1166 
1167 				set_last_option_on_screen(first_option_on_screen);
1168 				if (option_is_title(option))
1169 					option = next_option(option, FALSE);
1170 				redraw_screen(option);
1171 				/* highlight_option(option); is already done by redraw_screen() */
1172 				break;
1173 
1174 			case GLOBAL_SCROLL_UP:
1175 				option = opt_scroll_up(option);
1176 				break;
1177 
1178 			case GLOBAL_SCROLL_DOWN:
1179 				option = opt_scroll_down(option);
1180 				break;
1181 
1182 			case DIGIT_1:
1183 			case DIGIT_2:
1184 			case DIGIT_3:
1185 			case DIGIT_4:
1186 			case DIGIT_5:
1187 			case DIGIT_6:
1188 			case DIGIT_7:
1189 			case DIGIT_8:
1190 			case DIGIT_9:
1191 				unhighlight_option(option);
1192 				option = set_option_num(prompt_num(func_to_key(func, option_menu_keys), _(txt_enter_option_num)));
1193 				if (!option_on_page(option)) {
1194 					first_option_on_screen = option;
1195 					set_last_option_on_screen(option);
1196 					redraw_screen(option);
1197 				} else
1198 					highlight_option(option);
1199 				break;
1200 
1201 #ifndef NO_SHELL_ESCAPE
1202 			case GLOBAL_SHELL_ESCAPE:
1203 				shell_escape();
1204 				redraw_screen(option);
1205 				break;
1206 #endif /* !NO_SHELL_ESCAPE */
1207 
1208 			case GLOBAL_SEARCH_SUBJECT_FORWARD:
1209 			case GLOBAL_SEARCH_SUBJECT_BACKWARD:
1210 			case GLOBAL_SEARCH_REPEAT:
1211 				if (func == GLOBAL_SEARCH_REPEAT && last_search != GLOBAL_SEARCH_SUBJECT_FORWARD && last_search != GLOBAL_SEARCH_SUBJECT_BACKWARD)
1212 					info_message(_(txt_no_prev_search));
1213 				else {
1214 					old_option = option;
1215 					option = search_config((func == GLOBAL_SEARCH_SUBJECT_FORWARD), (func == GLOBAL_SEARCH_REPEAT), option, last_opt);
1216 					if (option != old_option) {
1217 						unhighlight_option(old_option);
1218 						if (!option_on_page(option)) {
1219 							first_option_on_screen = option;
1220 							set_last_option_on_screen(option);
1221 							redraw_screen(option);
1222 						} else
1223 							highlight_option(option);
1224 					}
1225 				}
1226 				break;
1227 
1228 			case CONFIG_SCOPE_MENU:
1229 				if (!curr_scope) {
1230 					scope_page(level);
1231 					set_last_opt();
1232 					option = get_first_opt();
1233 					first_option_on_screen = 0;
1234 					set_last_option_on_screen(0);
1235 					redraw_screen(option);
1236 				}
1237 				break;
1238 
1239 			case CONFIG_RESET_ATTRIB:
1240 				if (curr_scope) {
1241 					if (curr_scope->global)
1242 						info_message(_(txt_scope_operation_not_allowed));
1243 					else if (check_state(option)) {
1244 						reset_state(option);
1245 						changed |= MISC_OPTS;
1246 						redraw_screen(option);
1247 					}
1248 				}
1249 				break;
1250 
1251 			case CONFIG_SELECT:
1252 				if (curr_scope && curr_scope->global)
1253 					info_message(_(txt_scope_operation_not_allowed));
1254 				else
1255 					change_option = TRUE;
1256 				break;
1257 
1258 			case CONFIG_TOGGLE_ATTRIB:
1259 				if (grpname) {
1260 					if (curr_scope) {
1261 						if (scope_is_empty()) {
1262 							do_delete_scope(scope_idx);
1263 							scope_idx = 0;
1264 						}
1265 						curr_scope = NULL;
1266 					} else {
1267 						if (!(scope_idx = find_scope(grpname)))
1268 							scope_idx = add_scope(grpname);
1269 						if (scope_idx) {
1270 							curr_scope = &scopes[scope_idx];
1271 							initialize_attributes();
1272 						}
1273 					}
1274 					set_last_opt();
1275 					option = get_first_opt();
1276 					first_option_on_screen = 0;
1277 					set_last_option_on_screen(0);
1278 					redraw_screen(option);
1279 				}
1280 				break;
1281 
1282 			case GLOBAL_REDRAW_SCREEN:
1283 				my_retouch();
1284 				set_xclick_off();
1285 				set_last_option_on_screen(first_option_on_screen);
1286 				redraw_screen(option);
1287 				break;
1288 
1289 			case GLOBAL_VERSION:
1290 				info_message(cvers);
1291 				break;
1292 
1293 			default:
1294 				info_message(_(txt_bad_command), printascii(key, func_to_key(GLOBAL_HELP, option_menu_keys)));
1295 				break;
1296 		} /* switch (ch) */
1297 
1298 		if (change_option) {
1299 			switch (option_table[option].var_type) {
1300 				case OPT_ON_OFF:
1301 					switch (option) {
1302 						case OPT_ABBREVIATE_GROUPNAME:
1303 						case OPT_AUTO_RECONNECT:
1304 						case OPT_CACHE_OVERVIEW_FILES:
1305 						case OPT_CATCHUP_READ_GROUPS:
1306 						case OPT_FORCE_SCREEN_REDRAW:
1307 						case OPT_KEEP_DEAD_ARTICLES:
1308 						case OPT_SHOW_ONLY_UNREAD_GROUPS:
1309 						case OPT_STRIP_NEWSRC:
1310 #if defined(HAVE_ICONV_OPEN_TRANSLIT) && defined(CHARSET_CONVERSION)
1311 						case OPT_TRANSLIT:
1312 #endif /* HAVE_ICONV_OPEN_TRANSLIT && CHARSET_CONVERSION */
1313 						case OPT_UNLINK_ARTICLE:
1314 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
1315 						case OPT_UTF8_GRAPHICS:
1316 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
1317 						case OPT_URL_HIGHLIGHT:
1318 #ifdef HAVE_KEYPAD
1319 						case OPT_USE_KEYPAD:
1320 #endif /* HAVE_KEYPAD */
1321 						case OPT_USE_MOUSE:
1322 							if (prompt_option_on_off(option))
1323 								changed |= MISC_OPTS;
1324 							break;
1325 
1326 						case OPT_ADD_POSTED_TO_FILTER:
1327 							if (prompt_option_on_off(option))
1328 								UPDATE_INT_ATTRIBUTES(add_posted_to_filter);
1329 							break;
1330 
1331 						case OPT_ADVERTISING:
1332 							if (prompt_option_on_off(option))
1333 								UPDATE_INT_ATTRIBUTES(advertising);
1334 							break;
1335 
1336 						case OPT_ALTERNATIVE_HANDLING:
1337 							if (prompt_option_on_off(option))
1338 								UPDATE_INT_ATTRIBUTES(alternative_handling);
1339 							break;
1340 
1341 						case OPT_ASK_FOR_METAMAIL:
1342 							if (prompt_option_on_off(option))
1343 								UPDATE_INT_ATTRIBUTES(ask_for_metamail);
1344 							break;
1345 
1346 						case OPT_AUTO_LIST_THREAD:
1347 							if (prompt_option_on_off(option))
1348 								UPDATE_INT_ATTRIBUTES(auto_list_thread);
1349 							break;
1350 
1351 						case OPT_AUTO_SAVE:
1352 							if (prompt_option_on_off(option))
1353 								UPDATE_INT_ATTRIBUTES(auto_save);
1354 							break;
1355 
1356 						case OPT_BATCH_SAVE:
1357 							if (prompt_option_on_off(option))
1358 								UPDATE_INT_ATTRIBUTES(batch_save);
1359 							break;
1360 
1361 #ifdef HAVE_COLOR
1362 						case OPT_EXTQUOTE_HANDLING:
1363 							/*
1364 							 * option toggles visibility of other
1365 							 * options -> needs redraw_screen()
1366 							 */
1367 							if (prompt_option_on_off(option)) {
1368 								UPDATE_INT_ATTRIBUTES(extquote_handling);
1369 								set_last_option_on_screen(first_option_on_screen);
1370 								redraw_screen(option);
1371 								changed |= DISPLAY_OPTS;
1372 							}
1373 							break;
1374 #endif /* HAVE_COLOR */
1375 
1376 						case OPT_GROUP_CATCHUP_ON_EXIT:
1377 							if (prompt_option_on_off(option))
1378 								UPDATE_INT_ATTRIBUTES(group_catchup_on_exit);
1379 							break;
1380 
1381 						case OPT_MARK_IGNORE_TAGS:
1382 							if (prompt_option_on_off(option))
1383 								UPDATE_INT_ATTRIBUTES(mark_ignore_tags);
1384 							break;
1385 
1386 						case OPT_MARK_SAVED_READ:
1387 							if (prompt_option_on_off(option))
1388 								UPDATE_INT_ATTRIBUTES(mark_saved_read);
1389 							break;
1390 
1391 						case OPT_POST_PROCESS_VIEW:
1392 							if (prompt_option_on_off(option))
1393 								UPDATE_INT_ATTRIBUTES(post_process_view);
1394 							break;
1395 
1396 						case OPT_POS_FIRST_UNREAD:
1397 							if (prompt_option_on_off(option))
1398 								UPDATE_INT_ATTRIBUTES(pos_first_unread);
1399 							break;
1400 
1401 #ifndef DISABLE_PRINTING
1402 						case OPT_PRINT_HEADER:
1403 							if (prompt_option_on_off(option))
1404 								UPDATE_INT_ATTRIBUTES(print_header);
1405 							break;
1406 #endif /* !DISABLE_PRINTING */
1407 
1408 						case OPT_PROCESS_ONLY_UNREAD:
1409 							if (prompt_option_on_off(option))
1410 								UPDATE_INT_ATTRIBUTES(process_only_unread);
1411 							break;
1412 
1413 						case OPT_PROMPT_FOLLOWUPTO:
1414 							if (prompt_option_on_off(option))
1415 								UPDATE_INT_ATTRIBUTES(prompt_followupto);
1416 							break;
1417 
1418 						case OPT_SHOW_SIGNATURES:
1419 							if (prompt_option_on_off(option))
1420 								UPDATE_INT_ATTRIBUTES(show_signatures);
1421 							break;
1422 
1423 						case OPT_SIGDASHES:
1424 							if (prompt_option_on_off(option))
1425 								UPDATE_INT_ATTRIBUTES(sigdashes);
1426 							break;
1427 
1428 						case OPT_SIGNATURE_REPOST:
1429 							if (prompt_option_on_off(option))
1430 								UPDATE_INT_ATTRIBUTES(signature_repost);
1431 							break;
1432 
1433 						case OPT_START_EDITOR_OFFSET:
1434 							if (prompt_option_on_off(option))
1435 								UPDATE_INT_ATTRIBUTES(start_editor_offset);
1436 							break;
1437 
1438 #ifndef USE_CURSES
1439 						case OPT_STRIP_BLANKS:
1440 							if (prompt_option_on_off(option)) {
1441 								redraw_screen(option);
1442 								changed |= MISC_OPTS;
1443 							}
1444 							break;
1445 #endif /* !USE_CURSES */
1446 
1447 						case OPT_TEX2ISO_CONV:
1448 							if (prompt_option_on_off(option))
1449 								UPDATE_INT_ATTRIBUTES(tex2iso_conv);
1450 							break;
1451 
1452 						case OPT_THREAD_CATCHUP_ON_EXIT:
1453 							if (prompt_option_on_off(option))
1454 								UPDATE_INT_ATTRIBUTES(thread_catchup_on_exit);
1455 							break;
1456 
1457 						case OPT_WRAP_ON_NEXT_UNREAD:
1458 							if (prompt_option_on_off(option))
1459 								UPDATE_INT_ATTRIBUTES(wrap_on_next_unread);
1460 							break;
1461 
1462 						case OPT_VERBATIM_HANDLING:
1463 							/*
1464 							 * option toggles visibility of other
1465 							 * options -> needs redraw_screen()
1466 							 */
1467 							if (prompt_option_on_off(option)) {
1468 								UPDATE_INT_ATTRIBUTES(verbatim_handling);
1469 								set_last_option_on_screen(first_option_on_screen);
1470 								redraw_screen(option);
1471 							}
1472 							break;
1473 
1474 						/* show mini help menu */
1475 						case OPT_BEGINNER_LEVEL:
1476 							if (prompt_option_on_off(option)) {
1477 								set_noteslines(cLINES);
1478 								changed |= MISC_OPTS;
1479 							}
1480 							break;
1481 
1482 						/* show all arts or just new/unread arts */
1483 						case OPT_SHOW_ONLY_UNREAD_ARTS:
1484 							if (prompt_option_on_off(option)) {
1485 								UPDATE_INT_ATTRIBUTES(show_only_unread_arts);
1486 								changed |= SHOW_ONLY_UNREAD;
1487 							}
1488 							break;
1489 
1490 						/* draw -> / highlighted bar */
1491 						case OPT_DRAW_ARROW:
1492 							if (prompt_option_on_off(option)) {
1493 								unhighlight_option(option);
1494 								if (!tinrc.draw_arrow && !tinrc.inverse_okay) {
1495 									tinrc.inverse_okay = TRUE;
1496 									repaint_option(OPT_INVERSE_OKAY);
1497 									center_line(0, TRUE, _(txt_options_menu));
1498 								}
1499 								changed |= MISC_OPTS;
1500 							}
1501 							break;
1502 
1503 						/* draw inversed screen header lines */
1504 						/* draw inversed group/article/option line if draw_arrow is OFF */
1505 						case OPT_INVERSE_OKAY:
1506 							if (prompt_option_on_off(option)) {
1507 								unhighlight_option(option);
1508 								if (!tinrc.draw_arrow && !tinrc.inverse_okay) {
1509 									tinrc.draw_arrow = TRUE;	/* we don't want to navigate blindly */
1510 									repaint_option(OPT_DRAW_ARROW);
1511 								}
1512 								center_line(0, TRUE, _(txt_options_menu));
1513 								changed |= MISC_OPTS;
1514 							}
1515 							break;
1516 
1517 						case OPT_MAIL_8BIT_HEADER:
1518 							if (prompt_option_on_off(option)) {
1519 								if (tinrc.mail_mime_encoding != MIME_ENCODING_8BIT) {
1520 									tinrc.mail_8bit_header = FALSE;
1521 									print_any_option(OPT_MAIL_8BIT_HEADER);
1522 								}
1523 								UPDATE_INT_ATTRIBUTES(mail_8bit_header);
1524 							}
1525 							break;
1526 
1527 						case OPT_POST_8BIT_HEADER:
1528 							if (prompt_option_on_off(option)) {
1529 								/* if post_mime_encoding != 8bit, post_8bit_header is disabled */
1530 								if (tinrc.post_mime_encoding != MIME_ENCODING_8BIT) {
1531 									tinrc.post_8bit_header = FALSE;
1532 									print_any_option(OPT_POST_8BIT_HEADER);
1533 								}
1534 								UPDATE_INT_ATTRIBUTES(post_8bit_header);
1535 							}
1536 							break;
1537 
1538 						/* show newsgroup description text next to newsgroups */
1539 						case OPT_SHOW_DESCRIPTION:
1540 							if (prompt_option_on_off(option)) {
1541 								show_description = tinrc.show_description;
1542 								if (show_description)			/* force reread of newgroups file */
1543 									read_descriptions(FALSE);
1544 								changed |= MISC_OPTS;
1545 							}
1546 							break;
1547 
1548 #ifdef HAVE_COLOR
1549 						/* use ANSI color */
1550 						case OPT_USE_COLOR:
1551 							if (prompt_option_on_off(option)) {
1552 #	ifdef USE_CURSES
1553 								if (!has_colors())
1554 									use_color = FALSE;
1555 								else
1556 #	endif /* USE_CURSES */
1557 									use_color = tinrc.use_color;
1558 								set_last_option_on_screen(first_option_on_screen);
1559 								redraw_screen(option);
1560 								changed |= MISC_OPTS;
1561 							}
1562 							break;
1563 #endif /* HAVE_COLOR */
1564 
1565 #ifdef XFACE_ABLE
1566 						/* use slrnface */
1567 						case OPT_USE_SLRNFACE:
1568 							if (prompt_option_on_off(option)) {
1569 								if (!tinrc.use_slrnface)
1570 									slrnface_stop();
1571 								else
1572 									slrnface_start();
1573 								changed |= MISC_OPTS;
1574 							}
1575 							break;
1576 #endif /* XFACE_ABLE */
1577 
1578 						/* word_highlight */
1579 						case OPT_WORD_HIGHLIGHT:
1580 							if (prompt_option_on_off(option)) {
1581 								word_highlight = tinrc.word_highlight;
1582 								set_last_option_on_screen(first_option_on_screen);
1583 								redraw_screen(option);
1584 								changed |= MISC_OPTS;
1585 							}
1586 							break;
1587 
1588 #if defined(HAVE_LIBICUUC) && defined(MULTIBYTE_ABLE) && defined(HAVE_UNICODE_UBIDI_H) && !defined(NO_LOCALE)
1589 						case OPT_RENDER_BIDI:
1590 							if (prompt_option_on_off(option))
1591 								changed |= MISC_OPTS;
1592 							break;
1593 #endif /* HAVE_LIBICUUC && MULTIBYTE_ABLE && HAVE_UNICODE_UBIDI_H && !NO_LOCALE */
1594 
1595 						case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
1596 							if (prompt_option_on_off(option))
1597 								SET_NUM_ATTRIBUTE(add_posted_to_filter);
1598 							break;
1599 
1600 						case OPT_ATTRIB_ADVERTISING:
1601 							if (prompt_option_on_off(option))
1602 								SET_NUM_ATTRIBUTE(advertising);
1603 							break;
1604 
1605 						case OPT_ATTRIB_ALTERNATIVE_HANDLING:
1606 							if (prompt_option_on_off(option))
1607 								SET_NUM_ATTRIBUTE(alternative_handling);
1608 							break;
1609 
1610 						case OPT_ATTRIB_ASK_FOR_METAMAIL:
1611 							if (prompt_option_on_off(option))
1612 								SET_NUM_ATTRIBUTE(ask_for_metamail);
1613 							break;
1614 
1615 						case OPT_ATTRIB_AUTO_LIST_THREAD:
1616 							if (prompt_option_on_off(option))
1617 								SET_NUM_ATTRIBUTE(auto_list_thread);
1618 							break;
1619 
1620 						case OPT_ATTRIB_AUTO_SAVE:
1621 							if (prompt_option_on_off(option))
1622 								SET_NUM_ATTRIBUTE(auto_save);
1623 							break;
1624 
1625 						case OPT_ATTRIB_AUTO_SELECT:
1626 							if (prompt_option_on_off(option))
1627 								SET_NUM_ATTRIBUTE(auto_select);
1628 							break;
1629 
1630 						case OPT_ATTRIB_BATCH_SAVE:
1631 							if (prompt_option_on_off(option))
1632 								SET_NUM_ATTRIBUTE(batch_save);
1633 							break;
1634 
1635 						case OPT_ATTRIB_DELETE_TMP_FILES:
1636 							if (prompt_option_on_off(option))
1637 								SET_NUM_ATTRIBUTE(delete_tmp_files);
1638 							break;
1639 
1640 #ifdef HAVE_COLOR
1641 						case OPT_ATTRIB_EXTQUOTE_HANDLING:
1642 							if (prompt_option_on_off(option))
1643 								SET_NUM_ATTRIBUTE(extquote_handling);
1644 							break;
1645 #endif /* HAVE_COLOR */
1646 
1647 						case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
1648 							if (prompt_option_on_off(option))
1649 								SET_NUM_ATTRIBUTE(group_catchup_on_exit);
1650 							break;
1651 
1652 						case OPT_ATTRIB_MAIL_8BIT_HEADER:
1653 							if (prompt_option_on_off(option))
1654 								SET_NUM_ATTRIBUTE(mail_8bit_header);
1655 							break;
1656 
1657 						case OPT_ATTRIB_MARK_IGNORE_TAGS:
1658 							if (prompt_option_on_off(option))
1659 								SET_NUM_ATTRIBUTE(mark_ignore_tags);
1660 							break;
1661 
1662 						case OPT_ATTRIB_MARK_SAVED_READ:
1663 							if (prompt_option_on_off(option))
1664 								SET_NUM_ATTRIBUTE(mark_saved_read);
1665 							break;
1666 
1667 						case OPT_ATTRIB_MIME_FORWARD:
1668 							if (prompt_option_on_off(option))
1669 								SET_NUM_ATTRIBUTE(mime_forward);
1670 							break;
1671 
1672 						case OPT_ATTRIB_POST_8BIT_HEADER:
1673 							if (prompt_option_on_off(option))
1674 								SET_NUM_ATTRIBUTE(post_8bit_header);
1675 							break;
1676 
1677 						case OPT_ATTRIB_POST_PROCESS_VIEW:
1678 							if (prompt_option_on_off(option))
1679 								SET_NUM_ATTRIBUTE(post_process_view);
1680 							break;
1681 
1682 						case OPT_ATTRIB_POS_FIRST_UNREAD:
1683 							if (prompt_option_on_off(option))
1684 								SET_NUM_ATTRIBUTE(pos_first_unread);
1685 							break;
1686 
1687 #ifndef DISABLE_PRINTING
1688 						case OPT_ATTRIB_PRINT_HEADER:
1689 							if (prompt_option_on_off(option))
1690 								SET_NUM_ATTRIBUTE(print_header);
1691 							break;
1692 #endif /* !DISABLE_PRINTING */
1693 
1694 						case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
1695 							if (prompt_option_on_off(option))
1696 								SET_NUM_ATTRIBUTE(process_only_unread);
1697 							break;
1698 
1699 						case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
1700 							if (prompt_option_on_off(option))
1701 								SET_NUM_ATTRIBUTE(prompt_followupto);
1702 							break;
1703 
1704 						case OPT_ATTRIB_QUICK_KILL_CASE:
1705 							if (prompt_option_on_off(option))
1706 								SET_NUM_ATTRIBUTE(quick_kill_case);
1707 							break;
1708 
1709 						case OPT_ATTRIB_QUICK_KILL_EXPIRE:
1710 							if (prompt_option_on_off(option))
1711 								SET_NUM_ATTRIBUTE(quick_kill_expire);
1712 							break;
1713 
1714 						case OPT_ATTRIB_QUICK_SELECT_CASE:
1715 							if (prompt_option_on_off(option))
1716 								SET_NUM_ATTRIBUTE(quick_select_case);
1717 							break;
1718 
1719 						case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
1720 							if (prompt_option_on_off(option))
1721 								SET_NUM_ATTRIBUTE(quick_select_expire);
1722 							break;
1723 
1724 						case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
1725 							if (prompt_option_on_off(option)) {
1726 								SET_NUM_ATTRIBUTE(show_only_unread_arts);
1727 								changed |= SHOW_ONLY_UNREAD;
1728 							}
1729 							break;
1730 
1731 						case OPT_ATTRIB_SHOW_SIGNATURES:
1732 							if (prompt_option_on_off(option))
1733 								SET_NUM_ATTRIBUTE(show_signatures);
1734 							break;
1735 
1736 						case OPT_ATTRIB_SIGDASHES:
1737 							if (prompt_option_on_off(option))
1738 								SET_NUM_ATTRIBUTE(sigdashes);
1739 							break;
1740 
1741 						case OPT_ATTRIB_SIGNATURE_REPOST:
1742 							if (prompt_option_on_off(option))
1743 								SET_NUM_ATTRIBUTE(signature_repost);
1744 							break;
1745 
1746 						case OPT_ATTRIB_START_EDITOR_OFFSET:
1747 							if (prompt_option_on_off(option))
1748 								SET_NUM_ATTRIBUTE(start_editor_offset);
1749 							break;
1750 
1751 						case OPT_ATTRIB_TEX2ISO_CONV:
1752 							if (prompt_option_on_off(option))
1753 								SET_NUM_ATTRIBUTE(tex2iso_conv);
1754 							break;
1755 
1756 						case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
1757 							if (prompt_option_on_off(option))
1758 								SET_NUM_ATTRIBUTE(thread_catchup_on_exit);
1759 							break;
1760 
1761 						case OPT_ATTRIB_VERBATIM_HANDLING:
1762 							if (prompt_option_on_off(option))
1763 								SET_NUM_ATTRIBUTE(verbatim_handling);
1764 							break;
1765 
1766 						case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
1767 							if (prompt_option_on_off(option))
1768 								SET_NUM_ATTRIBUTE(wrap_on_next_unread);
1769 							break;
1770 
1771 						case OPT_ATTRIB_X_COMMENT_TO:
1772 							if (prompt_option_on_off(option))
1773 								SET_NUM_ATTRIBUTE(x_comment_to);
1774 							break;
1775 
1776 						default:
1777 							break;
1778 					} /* switch (option) */
1779 					break;
1780 
1781 				case OPT_LIST:
1782 					switch (option) {
1783 #ifdef USE_CANLOCK
1784 						case OPT_CANCEL_LOCK_ALGO:
1785 #endif /* USE_CANLOCK */
1786 #ifdef HAVE_COLOR
1787 						case OPT_COL_FROM:
1788 						case OPT_COL_HEAD:
1789 						case OPT_COL_HELP:
1790 						case OPT_COL_INVERS_BG:
1791 						case OPT_COL_INVERS_FG:
1792 						case OPT_COL_MESSAGE:
1793 						case OPT_COL_MINIHELP:
1794 						case OPT_COL_NEWSHEADERS:
1795 						case OPT_COL_QUOTE:
1796 						case OPT_COL_QUOTE2:
1797 						case OPT_COL_QUOTE3:
1798 						case OPT_COL_EXTQUOTE:
1799 						case OPT_COL_RESPONSE:
1800 						case OPT_COL_SIGNATURE:
1801 						case OPT_COL_SUBJECT:
1802 						case OPT_COL_TEXT:
1803 						case OPT_COL_TITLE:
1804 						case OPT_COL_MARKSTAR:
1805 						case OPT_COL_MARKDASH:
1806 						case OPT_COL_MARKSLASH:
1807 						case OPT_COL_MARKSTROKE:
1808 						case OPT_COL_URLS:
1809 						case OPT_COL_VERBATIM:
1810 #endif /* HAVE_COLOR */
1811 						case OPT_CONFIRM_CHOICE:
1812 						case OPT_GOTO_NEXT_UNREAD:
1813 						case OPT_HIDE_UUE:
1814 						case OPT_INTERACTIVE_MAILER:
1815 						case OPT_KILL_LEVEL:
1816 						case OPT_MAILBOX_FORMAT:
1817 						case OPT_MONO_MARKDASH:
1818 						case OPT_MONO_MARKSLASH:
1819 						case OPT_MONO_MARKSTAR:
1820 						case OPT_MONO_MARKSTROKE:
1821 #ifdef HAVE_UNICODE_NORMALIZATION
1822 						case OPT_NORMALIZATION_FORM:
1823 #endif /* HAVE_UNICODE_NORMALIZATION */
1824 						case OPT_QUOTE_STYLE:
1825 						case OPT_STRIP_BOGUS:
1826 						case OPT_WILDCARD:
1827 						case OPT_WORD_H_DISPLAY_MARKS:
1828 #ifdef USE_HEAPSORT
1829 						case OPT_SORT_FUNCTION:
1830 #endif /* USE_HEAPSORT */
1831 							if (prompt_option_list(option))
1832 								changed |= MISC_OPTS;
1833 							break;
1834 
1835 #ifdef HAVE_COLOR
1836 						case OPT_COL_BACK:
1837 						case OPT_COL_NORMAL:
1838 							if (prompt_option_list(option)) {
1839 								redraw_screen(option);
1840 								changed |= MISC_OPTS;
1841 							}
1842 							break;
1843 #endif /* HAVE_COLOR */
1844 
1845 						case OPT_AUTO_CC_BCC:
1846 							if (prompt_option_list(option))
1847 								UPDATE_INT_ATTRIBUTES(auto_cc_bcc);
1848 							break;
1849 
1850 						case OPT_THREAD_ARTICLES:
1851 							if (prompt_option_list(option)) {
1852 								UPDATE_INT_ATTRIBUTES(thread_articles);
1853 								changed |= THREAD_ARTS;
1854 							}
1855 							break;
1856 
1857 						case OPT_SORT_ARTICLE_TYPE:
1858 							if (prompt_option_list(option)) {
1859 								UPDATE_INT_ATTRIBUTES(sort_article_type);
1860 								changed |= SORT_OPTS;
1861 							}
1862 							break;
1863 
1864 						case OPT_SORT_THREADS_TYPE:
1865 							if (prompt_option_list(option)) {
1866 								UPDATE_INT_ATTRIBUTES(sort_threads_type);
1867 								changed |= SORT_OPTS;
1868 							}
1869 							break;
1870 
1871 						case OPT_THREAD_SCORE:
1872 							if (prompt_option_list(option))
1873 								changed |= THREAD_SCORE;
1874 							break;
1875 
1876 						case OPT_TRIM_ARTICLE_BODY:
1877 							if (prompt_option_list(option))
1878 								UPDATE_INT_ATTRIBUTES(trim_article_body);
1879 							break;
1880 
1881 						case OPT_POST_PROCESS_TYPE:
1882 							if (prompt_option_list(option))
1883 								UPDATE_INT_ATTRIBUTES(post_process_type);
1884 							break;
1885 
1886 						case OPT_SHOW_AUTHOR:
1887 							if (prompt_option_list(option)) {
1888 								UPDATE_INT_ATTRIBUTES(show_author);
1889 								changed |= SHOW_AUTHOR;
1890 							}
1891 							break;
1892 
1893 						case OPT_MAIL_MIME_ENCODING:
1894 							if (prompt_option_list(option)) {
1895 #ifdef CHARSET_CONVERSION
1896 								/*
1897 								 * check if we have selected a !7bit encoding but a 7bit network charset
1898 								 * or a !8bit encoding but a 8bit network charset, update encoding if needed
1899 								 */
1900 								is_7bit = FALSE;
1901 								for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
1902 									if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
1903 										is_7bit = TRUE;
1904 										break;
1905 									}
1906 								}
1907 								if (is_7bit) {
1908 									if (tinrc.mail_mime_encoding != MIME_ENCODING_7BIT) {
1909 										tinrc.mail_mime_encoding = MIME_ENCODING_7BIT;
1910 										repaint_option(OPT_MAIL_MIME_ENCODING);
1911 									}
1912 								} else {
1913 									if (tinrc.mail_mime_encoding == MIME_ENCODING_7BIT) {
1914 										tinrc.mail_mime_encoding = MIME_ENCODING_QP;
1915 										repaint_option(OPT_MAIL_MIME_ENCODING);
1916 									}
1917 								}
1918 #endif /* CHARSET_CONVERSION */
1919 								UPDATE_INT_ATTRIBUTES(mail_mime_encoding);
1920 								/* do not use 8 bit headers if mime encoding is not 8bit */
1921 								if (tinrc.mail_mime_encoding != MIME_ENCODING_8BIT) {
1922 									tinrc.mail_8bit_header = FALSE;
1923 									repaint_option(OPT_MAIL_8BIT_HEADER);
1924 									UPDATE_INT_ATTRIBUTES(mail_8bit_header);
1925 								}
1926 							}
1927 							break;
1928 
1929 						case OPT_POST_MIME_ENCODING:
1930 							if (prompt_option_list(option)) {
1931 #ifdef CHARSET_CONVERSION
1932 								/*
1933 								 * check if we have selected a !7bit encoding but a 7bit network charset
1934 								 * or a !8bit encoding but a 8bit network charset, update encoding if needed
1935 								 */
1936 								is_7bit = FALSE;
1937 								for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
1938 									if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
1939 										is_7bit = TRUE;
1940 										break;
1941 									}
1942 								}
1943 								if (is_7bit) {
1944 									if (tinrc.post_mime_encoding != MIME_ENCODING_7BIT) {
1945 										tinrc.post_mime_encoding = MIME_ENCODING_7BIT;
1946 										repaint_option(OPT_POST_MIME_ENCODING);
1947 									}
1948 								} else {
1949 									if (tinrc.post_mime_encoding == MIME_ENCODING_7BIT) {
1950 										tinrc.post_mime_encoding = MIME_ENCODING_8BIT;
1951 										repaint_option(OPT_POST_MIME_ENCODING);
1952 									}
1953 								}
1954 #endif /* CHARSET_CONVERSION */
1955 								UPDATE_INT_ATTRIBUTES(post_mime_encoding);
1956 								/* do not use 8 bit headers if mime encoding is not 8bit */
1957 								if (tinrc.post_mime_encoding != MIME_ENCODING_8BIT) {
1958 									tinrc.post_8bit_header = FALSE;
1959 									repaint_option(OPT_POST_8BIT_HEADER);
1960 									UPDATE_INT_ATTRIBUTES(post_8bit_header);
1961 								}
1962 							}
1963 							break;
1964 
1965 #ifdef CHARSET_CONVERSION
1966 						case OPT_MM_NETWORK_CHARSET:
1967 							if (prompt_option_list(option)) {
1968 								/*
1969 								 * check if we have selected a 7bit charset but a !7bit encoding
1970 								 * or a 8bit charset but a !8bit encoding, update encoding if needed
1971 								 *
1972 								 * if (mail|post)_mime_encoding != 8bit, disable (mail|post)_8bit_header
1973 								 */
1974 								is_7bit = FALSE;
1975 								UPDATE_INT_ATTRIBUTES(mm_network_charset);
1976 								for (i = 0; txt_mime_7bit_charsets[i] != NULL; i++) {
1977 									if (!strcasecmp(txt_mime_charsets[tinrc.mm_network_charset], txt_mime_7bit_charsets[i])) {
1978 										is_7bit = TRUE;
1979 										break;
1980 									}
1981 								}
1982 								if (is_7bit) {
1983 									if (tinrc.mail_mime_encoding != MIME_ENCODING_7BIT) {
1984 										tinrc.mail_mime_encoding = MIME_ENCODING_7BIT;
1985 										tinrc.mail_8bit_header = FALSE;
1986 										repaint_option(OPT_MAIL_MIME_ENCODING);
1987 										repaint_option(OPT_MAIL_8BIT_HEADER);
1988 										UPDATE_INT_ATTRIBUTES(mail_mime_encoding);
1989 										UPDATE_INT_ATTRIBUTES(mail_8bit_header);
1990 									}
1991 									if (tinrc.post_mime_encoding != MIME_ENCODING_7BIT) {
1992 										tinrc.post_mime_encoding = MIME_ENCODING_7BIT;
1993 										tinrc.post_8bit_header = FALSE;
1994 										repaint_option(OPT_POST_MIME_ENCODING);
1995 										repaint_option(OPT_POST_8BIT_HEADER);
1996 										UPDATE_INT_ATTRIBUTES(post_mime_encoding);
1997 										UPDATE_INT_ATTRIBUTES(post_8bit_header);
1998 									}
1999 								} else {
2000 									if (tinrc.mail_mime_encoding == MIME_ENCODING_7BIT) {
2001 										tinrc.mail_mime_encoding = MIME_ENCODING_QP;
2002 										repaint_option(OPT_MAIL_MIME_ENCODING);
2003 										UPDATE_INT_ATTRIBUTES(mail_mime_encoding);
2004 									}
2005 									if (tinrc.post_mime_encoding == MIME_ENCODING_7BIT) {
2006 										tinrc.post_mime_encoding = MIME_ENCODING_8BIT;
2007 										repaint_option(OPT_POST_MIME_ENCODING);
2008 										UPDATE_INT_ATTRIBUTES(post_mime_encoding);
2009 									}
2010 								}
2011 							}
2012 							break;
2013 #endif /* CHARSET_CONVERSION */
2014 
2015 						case OPT_ATTRIB_AUTO_CC_BCC:
2016 							if (prompt_option_list(option))
2017 								SET_NUM_ATTRIBUTE(auto_cc_bcc);
2018 							break;
2019 
2020 						case OPT_ATTRIB_MAIL_MIME_ENCODING:
2021 							if (prompt_option_list(option))
2022 								SET_NUM_ATTRIBUTE(mail_mime_encoding);
2023 							break;
2024 
2025 #ifdef CHARSET_CONVERSION
2026 						case OPT_ATTRIB_MM_NETWORK_CHARSET:
2027 							if (prompt_option_list(option))
2028 								SET_NUM_ATTRIBUTE(mm_network_charset);
2029 							break;
2030 #endif /* CHARSET_CONVERSION */
2031 
2032 						case OPT_ATTRIB_POST_MIME_ENCODING:
2033 							if (prompt_option_list(option))
2034 								SET_NUM_ATTRIBUTE(post_mime_encoding);
2035 							break;
2036 
2037 						case OPT_ATTRIB_POST_PROCESS_TYPE:
2038 							if (prompt_option_list(option))
2039 								SET_NUM_ATTRIBUTE(post_process_type);
2040 							break;
2041 
2042 						case OPT_ATTRIB_QUICK_KILL_HEADER:
2043 							if (prompt_option_list(option))
2044 								SET_NUM_ATTRIBUTE(quick_kill_header);
2045 							break;
2046 
2047 						case OPT_ATTRIB_QUICK_SELECT_HEADER:
2048 							if (prompt_option_list(option))
2049 								SET_NUM_ATTRIBUTE(quick_select_header);
2050 							break;
2051 
2052 						case OPT_ATTRIB_SHOW_AUTHOR:
2053 							if (prompt_option_list(option)) {
2054 								SET_NUM_ATTRIBUTE(show_author);
2055 								changed |= SHOW_AUTHOR;
2056 							}
2057 							break;
2058 
2059 						case OPT_ATTRIB_SORT_ARTICLE_TYPE:
2060 							if (prompt_option_list(option)) {
2061 								SET_NUM_ATTRIBUTE(sort_article_type);
2062 								changed |= SORT_OPTS;
2063 							}
2064 							break;
2065 
2066 						case OPT_ATTRIB_SORT_THREADS_TYPE:
2067 							if (prompt_option_list(option)) {
2068 								SET_NUM_ATTRIBUTE(sort_threads_type);
2069 								changed |= SORT_OPTS;
2070 							}
2071 							break;
2072 
2073 						case OPT_ATTRIB_THREAD_ARTICLES:
2074 							if (prompt_option_list(option)) {
2075 								SET_NUM_ATTRIBUTE(thread_articles);
2076 								changed |= THREAD_ARTS;
2077 							}
2078 							break;
2079 
2080 						case OPT_ATTRIB_TRIM_ARTICLE_BODY:
2081 							if (prompt_option_list(option))
2082 								SET_NUM_ATTRIBUTE(trim_article_body);
2083 							break;
2084 
2085 						default:
2086 							break;
2087 					} /* switch (option) */
2088 					break;
2089 
2090 				case OPT_STRING:
2091 					switch (option) {
2092 						case OPT_INEWS_PROG:
2093 						case OPT_MAILDIR:
2094 						case OPT_MAILER_FORMAT:
2095 						case OPT_MAIL_ADDRESS:
2096 						case OPT_MAIL_QUOTE_FORMAT:
2097 						case OPT_METAMAIL_PROG:
2098 						case OPT_NEWS_QUOTE_FORMAT:
2099 						case OPT_SAVEDIR:
2100 						case OPT_SIGFILE:
2101 #ifndef DISABLE_PRINTING
2102 						case OPT_PRINTER:
2103 #endif /* !DISABLE_PRINTING */
2104 						case OPT_QUOTE_CHARS:
2105 						case OPT_SPAMTRAP_WARNING_ADDRESSES:
2106 						case OPT_URL_HANDLER:
2107 						case OPT_XPOST_QUOTE_FORMAT:
2108 							if (prompt_option_string(option))
2109 								changed |= MISC_OPTS;
2110 							break;
2111 
2112 						case OPT_EDITOR_FORMAT:
2113 							if (prompt_option_string(option)) {
2114 								if (!strlen(tinrc.editor_format))
2115 									STRCPY(tinrc.editor_format, TIN_EDITOR_FMT_ON);
2116 								changed |= MISC_OPTS;
2117 							}
2118 							break;
2119 
2120 						case OPT_GROUP_FORMAT:
2121 							if (prompt_option_string(option)) {
2122 								if (!strlen(tinrc.group_format))
2123 									STRCPY(tinrc.group_format, DEFAULT_GROUP_FORMAT);
2124 								changed |= MISC_OPTS;
2125 							}
2126 							break;
2127 
2128 						case OPT_ATTRIB_GROUP_FORMAT:
2129 							if (prompt_option_string(option))
2130 								SET_STRING_ATTRIBUTE(group_format);
2131 							break;
2132 
2133 #ifndef CHARSET_CONVERSION
2134 						case OPT_MM_CHARSET:
2135 							if (prompt_option_string(option)) {
2136 								/*
2137 								 * No charset conversion available, assume local charset
2138 								 * to be network charset.
2139 								 */
2140 								STRCPY(tinrc.mm_local_charset, tinrc.mm_charset);
2141 								changed |= MISC_OPTS;
2142 							}
2143 							break;
2144 #else
2145 #	ifdef NO_LOCALE
2146 						case OPT_MM_LOCAL_CHARSET:
2147 							if (prompt_option_string(option))
2148 							/* no locales -> can't guess local charset */
2149 								changed |= MISC_OPTS;
2150 							break;
2151 
2152 #	endif /* NO_LOCALE */
2153 #endif /* !CHARSET_CONVERSION */
2154 
2155 						case OPT_NEWS_HEADERS_TO_DISPLAY:
2156 							if (prompt_option_string(option)) {
2157 								build_news_headers_array(scopes[0].attribute, TRUE);
2158 								changed |= MISC_OPTS;
2159 							}
2160 							break;
2161 
2162 						case OPT_NEWS_HEADERS_TO_NOT_DISPLAY:
2163 							if (prompt_option_string(option)) {
2164 								build_news_headers_array(scopes[0].attribute, FALSE);
2165 								changed |= MISC_OPTS;
2166 							}
2167 							break;
2168 
2169 						case OPT_POSTED_ARTICLES_FILE:
2170 							if (prompt_option_string(option)) /* no expansion here, will be done in post_loop() */
2171 								changed |= MISC_OPTS;
2172 							break;
2173 
2174 #ifdef HAVE_COLOR
2175 						case OPT_QUOTE_REGEX:
2176 							if (prompt_option_string(option)) {
2177 								FreeIfNeeded(quote_regex.re);
2178 								FreeIfNeeded(quote_regex.extra);
2179 								if (!strlen(tinrc.quote_regex))
2180 									STRCPY(tinrc.quote_regex, DEFAULT_QUOTE_REGEX);
2181 								compile_regex(tinrc.quote_regex, &quote_regex, PCRE_CASELESS);
2182 								changed |= DISPLAY_OPTS;
2183 							}
2184 							break;
2185 
2186 						case OPT_QUOTE_REGEX2:
2187 							if (prompt_option_string(option)) {
2188 								FreeIfNeeded(quote_regex2.re);
2189 								FreeIfNeeded(quote_regex2.extra);
2190 								if (!strlen(tinrc.quote_regex2))
2191 									STRCPY(tinrc.quote_regex2, DEFAULT_QUOTE_REGEX2);
2192 								compile_regex(tinrc.quote_regex2, &quote_regex2, PCRE_CASELESS);
2193 								changed |= DISPLAY_OPTS;
2194 							}
2195 							break;
2196 
2197 						case OPT_QUOTE_REGEX3:
2198 							if (prompt_option_string(option)) {
2199 								FreeIfNeeded(quote_regex3.re);
2200 								FreeIfNeeded(quote_regex3.extra);
2201 								if (!strlen(tinrc.quote_regex3))
2202 									STRCPY(tinrc.quote_regex3, DEFAULT_QUOTE_REGEX3);
2203 								compile_regex(tinrc.quote_regex3, &quote_regex3, PCRE_CASELESS);
2204 								changed |= DISPLAY_OPTS;
2205 							}
2206 							break;
2207 
2208 						case OPT_EXTQUOTE_REGEX:
2209 							if (prompt_option_string(option)) {
2210 								FreeIfNeeded(extquote_regex.re);
2211 								FreeIfNeeded(extquote_regex.extra);
2212 								if (!strlen(tinrc.extquote_regex))
2213 									STRCPY(tinrc.extquote_regex, DEFAULT_EXTQUOTE_REGEX);
2214 								compile_regex(tinrc.extquote_regex, &extquote_regex, PCRE_CASELESS);
2215 								changed |= DISPLAY_OPTS;
2216 							}
2217 							break;
2218 #endif /* HAVE_COLOR */
2219 
2220 						case OPT_SELECT_FORMAT:
2221 							if (prompt_option_string(option)) {
2222 								if (!strlen(tinrc.select_format))
2223 									STRCPY(tinrc.select_format, DEFAULT_SELECT_FORMAT);
2224 								changed |= MISC_OPTS;
2225 							}
2226 							break;
2227 
2228 						case OPT_SLASHES_REGEX:
2229 							if (prompt_option_string(option)) {
2230 								FreeIfNeeded(slashes_regex.re);
2231 								FreeIfNeeded(slashes_regex.extra);
2232 								if (!strlen(tinrc.slashes_regex))
2233 									STRCPY(tinrc.slashes_regex, DEFAULT_SLASHES_REGEX);
2234 								compile_regex(tinrc.slashes_regex, &slashes_regex, PCRE_CASELESS);
2235 								changed |= DISPLAY_OPTS;
2236 							}
2237 							break;
2238 
2239 						case OPT_STARS_REGEX:
2240 							if (prompt_option_string(option)) {
2241 								FreeIfNeeded(stars_regex.re);
2242 								FreeIfNeeded(stars_regex.extra);
2243 								if (!strlen(tinrc.stars_regex))
2244 									STRCPY(tinrc.stars_regex, DEFAULT_STARS_REGEX);
2245 								compile_regex(tinrc.stars_regex, &stars_regex, PCRE_CASELESS);
2246 								changed |= DISPLAY_OPTS;
2247 							}
2248 							break;
2249 
2250 						case OPT_STROKES_REGEX:
2251 							if (prompt_option_string(option)) {
2252 								FreeIfNeeded(strokes_regex.re);
2253 								FreeIfNeeded(strokes_regex.extra);
2254 								if (!strlen(tinrc.strokes_regex))
2255 									STRCPY(tinrc.strokes_regex, DEFAULT_STROKES_REGEX);
2256 								compile_regex(tinrc.strokes_regex, &strokes_regex, PCRE_CASELESS);
2257 								changed |= DISPLAY_OPTS;
2258 							}
2259 							break;
2260 
2261 						case OPT_UNDERSCORES_REGEX:
2262 							if (prompt_option_string(option)) {
2263 								FreeIfNeeded(underscores_regex.re);
2264 								FreeIfNeeded(underscores_regex.extra);
2265 								if (!strlen(tinrc.underscores_regex))
2266 									STRCPY(tinrc.underscores_regex, DEFAULT_UNDERSCORES_REGEX);
2267 								compile_regex(tinrc.underscores_regex, &underscores_regex, PCRE_CASELESS);
2268 								changed |= DISPLAY_OPTS;
2269 							}
2270 							break;
2271 
2272 						case OPT_STRIP_RE_REGEX:
2273 							if (prompt_option_string(option)) {
2274 								FreeIfNeeded(strip_re_regex.re);
2275 								FreeIfNeeded(strip_re_regex.extra);
2276 								if (!strlen(tinrc.strip_re_regex))
2277 									STRCPY(tinrc.strip_re_regex, DEFAULT_STRIP_RE_REGEX);
2278 								compile_regex(tinrc.strip_re_regex, &strip_re_regex, PCRE_ANCHORED);
2279 								changed |= MISC_OPTS;
2280 							}
2281 							break;
2282 
2283 						case OPT_STRIP_WAS_REGEX:
2284 							if (prompt_option_string(option)) {
2285 								FreeIfNeeded(strip_was_regex.re);
2286 								FreeIfNeeded(strip_was_regex.extra);
2287 								if (!strlen(tinrc.strip_was_regex)) {
2288 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
2289 									if (IS_LOCAL_CHARSET("UTF-8") && utf8_pcre())
2290 										STRCPY(tinrc.strip_was_regex, DEFAULT_U8_STRIP_WAS_REGEX);
2291 									else
2292 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
2293 										STRCPY(tinrc.strip_was_regex, DEFAULT_STRIP_WAS_REGEX);
2294 								}
2295 								compile_regex(tinrc.strip_was_regex, &strip_was_regex, 0);
2296 								changed |= MISC_OPTS;
2297 							}
2298 							break;
2299 
2300 						case OPT_THREAD_FORMAT:
2301 							if (prompt_option_string(option)) {
2302 								if (!strlen(tinrc.thread_format))
2303 									STRCPY(tinrc.thread_format, DEFAULT_THREAD_FORMAT);
2304 								changed |= MISC_OPTS;
2305 							}
2306 							break;
2307 
2308 						case OPT_ATTRIB_THREAD_FORMAT:
2309 							if (prompt_option_string(option))
2310 								SET_STRING_ATTRIBUTE(thread_format);
2311 							break;
2312 
2313 						case OPT_VERBATIM_BEGIN_REGEX:
2314 							if (prompt_option_string(option)) {
2315 								FreeIfNeeded(verbatim_begin_regex.re);
2316 								FreeIfNeeded(verbatim_begin_regex.extra);
2317 								if (!strlen(tinrc.verbatim_begin_regex))
2318 									STRCPY(tinrc.verbatim_begin_regex, DEFAULT_VERBATIM_BEGIN_REGEX);
2319 								compile_regex(tinrc.verbatim_begin_regex, &verbatim_begin_regex, PCRE_ANCHORED);
2320 								changed |= DISPLAY_OPTS;
2321 							}
2322 							break;
2323 
2324 						case OPT_VERBATIM_END_REGEX:
2325 							if (prompt_option_string(option)) {
2326 								FreeIfNeeded(verbatim_end_regex.re);
2327 								FreeIfNeeded(verbatim_end_regex.extra);
2328 								if (!strlen(tinrc.verbatim_end_regex))
2329 									STRCPY(tinrc.verbatim_end_regex, DEFAULT_VERBATIM_END_REGEX);
2330 								compile_regex(tinrc.verbatim_end_regex, &verbatim_end_regex, PCRE_ANCHORED);
2331 								changed |= DISPLAY_OPTS;
2332 							}
2333 							break;
2334 
2335 						case OPT_DATE_FORMAT:
2336 							if (prompt_option_string(option)) {
2337 								if (!strlen(tinrc.date_format))
2338 									STRCPY(tinrc.date_format, DEFAULT_DATE_FORMAT);
2339 								changed |= MISC_OPTS;
2340 							}
2341 							break;
2342 
2343 						case OPT_ATTRIB_DATE_FORMAT:
2344 							if (prompt_option_string(option))
2345 								SET_STRING_ATTRIBUTE(date_format);
2346 							break;
2347 
2348 						case OPT_ATTRIB_EDITOR_FORMAT:
2349 							if (prompt_option_string(option))
2350 								SET_STRING_ATTRIBUTE(editor_format);
2351 							break;
2352 
2353 						case OPT_ATTRIB_FCC:
2354 							if (prompt_option_string(option))
2355 								SET_STRING_ATTRIBUTE(fcc);
2356 							break;
2357 
2358 						case OPT_ATTRIB_FOLLOWUP_TO:
2359 							if (prompt_option_string(option))
2360 								SET_STRING_ATTRIBUTE(followup_to);
2361 							break;
2362 
2363 						case OPT_ATTRIB_FROM:
2364 							if (prompt_option_string(option))
2365 								SET_STRING_ATTRIBUTE(from);
2366 							break;
2367 
2368 #ifdef HAVE_ISPELL
2369 						case OPT_ATTRIB_ISPELL:
2370 							if (prompt_option_string(option))
2371 								SET_STRING_ATTRIBUTE(ispell);
2372 							break;
2373 #endif /* HAVE_ISPELL */
2374 
2375 						case OPT_ATTRIB_MAILDIR:
2376 							if (prompt_option_string(option))
2377 								SET_STRING_ATTRIBUTE(maildir);
2378 							break;
2379 
2380 						case OPT_ATTRIB_MAILING_LIST:
2381 							if (prompt_option_string(option))
2382 								SET_STRING_ATTRIBUTE(mailing_list);
2383 							break;
2384 
2385 						case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
2386 							if (prompt_option_string(option))
2387 								SET_STRING_ATTRIBUTE(mime_types_to_save);
2388 							break;
2389 
2390 						case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
2391 							if (prompt_option_string(option)) {
2392 								SET_STRING_ATTRIBUTE(news_headers_to_display);
2393 								build_news_headers_array(curr_scope->attribute, TRUE);
2394 								changed |= DISPLAY_OPTS;
2395 							}
2396 							break;
2397 
2398 						case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
2399 							if (prompt_option_string(option)) {
2400 								SET_STRING_ATTRIBUTE(news_headers_to_not_display);
2401 								build_news_headers_array(curr_scope->attribute, FALSE);
2402 								changed |= DISPLAY_OPTS;
2403 							}
2404 							break;
2405 
2406 						case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
2407 							if (prompt_option_string(option))
2408 								SET_STRING_ATTRIBUTE(news_quote_format);
2409 							break;
2410 
2411 						case OPT_ATTRIB_ORGANIZATION:
2412 							if (prompt_option_string(option))
2413 								SET_STRING_ATTRIBUTE(organization);
2414 							break;
2415 
2416 						case OPT_ATTRIB_QUICK_KILL_SCOPE:
2417 							if (prompt_option_string(option))
2418 								SET_STRING_ATTRIBUTE(quick_kill_scope);
2419 							break;
2420 
2421 						case OPT_ATTRIB_QUICK_SELECT_SCOPE:
2422 							if (prompt_option_string(option))
2423 								SET_STRING_ATTRIBUTE(quick_select_scope);
2424 							break;
2425 
2426 						case OPT_ATTRIB_QUOTE_CHARS:
2427 							if (prompt_option_string(option))
2428 								SET_STRING_ATTRIBUTE(quote_chars);
2429 							break;
2430 
2431 						case OPT_ATTRIB_SAVEDIR:
2432 							if (prompt_option_string(option))
2433 								SET_STRING_ATTRIBUTE(savedir);
2434 							break;
2435 
2436 						case OPT_ATTRIB_SAVEFILE:
2437 							if (prompt_option_string(option))
2438 								SET_STRING_ATTRIBUTE(savefile);
2439 							break;
2440 
2441 						case OPT_ATTRIB_SIGFILE:
2442 							if (prompt_option_string(option))
2443 								SET_STRING_ATTRIBUTE(sigfile);
2444 							break;
2445 
2446 #ifdef CHARSET_CONVERSION
2447 						case OPT_ATTRIB_UNDECLARED_CHARSET:
2448 							if (prompt_option_string(option))
2449 								SET_STRING_ATTRIBUTE(undeclared_charset);
2450 							break;
2451 
2452 #endif /* CHARSET_CONVERSION */
2453 						case OPT_ATTRIB_X_BODY:
2454 							if (prompt_option_string(option))
2455 								SET_STRING_ATTRIBUTE(x_body);
2456 							break;
2457 
2458 						case OPT_ATTRIB_X_HEADERS:
2459 							if (prompt_option_string(option))
2460 								SET_STRING_ATTRIBUTE(x_headers);
2461 							break;
2462 
2463 						default:
2464 							break;
2465 					} /* switch (option) */
2466 
2467 					break;
2468 
2469 				case OPT_NUM:
2470 					switch (option) {
2471 						case OPT_GETART_LIMIT:
2472 						case OPT_SCROLL_LINES:
2473 							if (prompt_option_num(option))
2474 								changed |= MISC_OPTS;
2475 							break;
2476 
2477 #if defined(HAVE_ALARM) && defined(SIGALRM)
2478 						case OPT_NNTP_READ_TIMEOUT_SECS:
2479 							if (prompt_option_num(option)) {
2480 								if (tinrc.nntp_read_timeout_secs < 0)
2481 									tinrc.nntp_read_timeout_secs = 0;
2482 								changed |= MISC_OPTS;
2483 							}
2484 							break;
2485 #endif /* HAVE_ALARM && SIGALRM */
2486 
2487 						case OPT_REREAD_ACTIVE_FILE_SECS:
2488 							if (prompt_option_num(option)) {
2489 								if (tinrc.reread_active_file_secs < 0)
2490 									tinrc.reread_active_file_secs = 0;
2491 								changed |= MISC_OPTS;
2492 							}
2493 							break;
2494 
2495 						case OPT_RECENT_TIME:
2496 							if (prompt_option_num(option)) {
2497 								if (tinrc.recent_time < 0)
2498 									tinrc.recent_time = 0;
2499 								changed |= MISC_OPTS;
2500 							}
2501 							break;
2502 
2503 						case OPT_FILTER_DAYS:
2504 							if (prompt_option_num(option)) {
2505 								if (tinrc.filter_days <= 0)
2506 									tinrc.filter_days = 1;
2507 								changed |= MISC_OPTS;
2508 							}
2509 							break;
2510 
2511 						case OPT_SCORE_LIMIT_KILL:
2512 						case OPT_SCORE_KILL:
2513 						case OPT_SCORE_LIMIT_SELECT:
2514 						case OPT_SCORE_SELECT:
2515 							if (prompt_option_num(option)) {
2516 								check_score_defaults();
2517 								redraw_screen(option);
2518 								changed |= SCORE_OPTS;
2519 							}
2520 							break;
2521 
2522 						case OPT_THREAD_PERC:
2523 							if (prompt_option_num(option)) {
2524 								if (tinrc.thread_perc < 0 || tinrc.thread_perc > 100)
2525 									tinrc.thread_perc = THREAD_PERC_DEFAULT;
2526 								UPDATE_INT_ATTRIBUTES(thread_perc);
2527 							}
2528 							break;
2529 
2530 						case OPT_WRAP_COLUMN:
2531 							if (prompt_option_num(option))
2532 								changed |= DISPLAY_OPTS;
2533 							break;
2534 
2535 						case OPT_ATTRIB_THREAD_PERC:
2536 							if (prompt_option_num(option))
2537 								SET_NUM_ATTRIBUTE(thread_perc);
2538 							break;
2539 
2540 						default:
2541 							break;
2542 					} /* switch (option) */
2543 					break;
2544 
2545 				case OPT_CHAR:
2546 					switch (option) {
2547 						/*
2548 						 * TODO: do DASH_TO_SPACE/SPACE_TO_DASH conversion here?
2549 						 */
2550 						case OPT_ART_MARKED_DELETED:
2551 						case OPT_ART_MARKED_INRANGE:
2552 						case OPT_ART_MARKED_RETURN:
2553 						case OPT_ART_MARKED_SELECTED:
2554 						case OPT_ART_MARKED_RECENT:
2555 						case OPT_ART_MARKED_UNREAD:
2556 						case OPT_ART_MARKED_READ:
2557 						case OPT_ART_MARKED_KILLED:
2558 						case OPT_ART_MARKED_READ_SELECTED:
2559 							if (prompt_option_char(option))
2560 								changed |= MISC_OPTS;
2561 							break;
2562 
2563 						default:
2564 							break;
2565 					} /* switch (option) */
2566 					break;
2567 
2568 				default:
2569 					break;
2570 			} /* switch (option_table[option].var_type) */
2571 			change_option = FALSE;
2572 			show_menu_help(txt_select_config_file_option);
2573 			repaint_option(option);
2574 			highlight_option(option);
2575 		} /* if (change_option) */
2576 	} /* forever */
2577 	/* NOTREACHED */
2578 	return;
2579 }
2580 
2581 
2582 /*
2583  * scopes and attributes menu
2584  */
2585 
2586 static t_function
scope_left(void)2587 scope_left(
2588 	void)
2589 {
2590 	return GLOBAL_QUIT;
2591 }
2592 
2593 
2594 static t_function
scope_right(void)2595 scope_right(
2596 	void)
2597 {
2598 	return SCOPE_SELECT;
2599 }
2600 
2601 
2602 static void
show_scope_page(void)2603 show_scope_page(
2604 	void)
2605 {
2606 	int i;
2607 
2608 	signal_context = cScope;
2609 	currmenu = &scopemenu;
2610 	mark_offset = 0;
2611 
2612 	if (scopemenu.curr < 0)
2613 		scopemenu.curr = 0;
2614 
2615 	scopemenu.max = num_scope - 1;
2616 
2617 	ClearScreen();
2618 	set_first_screen_item();
2619 	center_line(0, TRUE, _(txt_scopes_menu));
2620 
2621 	for (i = scopemenu.first; i < scopemenu.first + NOTESLINES && i < scopemenu.max; ++i)
2622 		build_scope_line(i);
2623 
2624 	show_mini_help(SCOPE_LEVEL);
2625 
2626 	if (scopemenu.max <= 0) {
2627 		info_message(_(txt_no_scopes));
2628 		return;
2629 	}
2630 
2631 	draw_scope_arrow();
2632 }
2633 
2634 
2635 static void
scope_page(enum context level)2636 scope_page(
2637 	enum context level)
2638 {
2639 	char key[MAXKEYLEN];
2640 	int i;
2641 	t_bool changed = FALSE;
2642 	t_function func;
2643 	t_menu *oldmenu = NULL;
2644 
2645 	if (currmenu)
2646 		oldmenu = currmenu;
2647 	scopemenu.curr = 0;
2648 	clear_note_area();
2649 	show_scope_page();
2650 	set_xclick_off();
2651 
2652 	forever {
2653 		switch ((func = handle_keypad(scope_left, scope_right, NULL, scope_keys))) {
2654 			case GLOBAL_QUIT:
2655 				if (changed)
2656 					write_attributes_file(local_attributes_file);
2657 				clear_note_area();
2658 				if (oldmenu)
2659 					currmenu = oldmenu;
2660 				return;
2661 
2662 			case DIGIT_1:
2663 			case DIGIT_2:
2664 			case DIGIT_3:
2665 			case DIGIT_4:
2666 			case DIGIT_5:
2667 			case DIGIT_6:
2668 			case DIGIT_7:
2669 			case DIGIT_8:
2670 			case DIGIT_9:
2671 				if (scopemenu.max)
2672 					prompt_item_num(func_to_key(func, scope_keys), _(txt_scope_select));
2673 				break;
2674 
2675 #ifndef NO_SHELL_ESCAPE
2676 			case GLOBAL_SHELL_ESCAPE:
2677 				do_shell_escape();
2678 				break;
2679 #endif /* !NO_SHELL_ESCAPE */
2680 
2681 			case GLOBAL_HELP:
2682 				show_help_page(SCOPE_LEVEL, _(txt_scopes_menu_com));
2683 				show_scope_page();
2684 				break;
2685 
2686 			case GLOBAL_FIRST_PAGE:
2687 				top_of_list();
2688 				break;
2689 
2690 			case GLOBAL_LAST_PAGE:
2691 				end_of_list();
2692 				break;
2693 
2694 			case GLOBAL_REDRAW_SCREEN:
2695 				my_retouch();
2696 				set_xclick_off();
2697 				show_scope_page();
2698 				break;
2699 
2700 			case GLOBAL_LINE_DOWN:
2701 				move_down();
2702 				break;
2703 
2704 			case GLOBAL_LINE_UP:
2705 				move_up();
2706 				break;
2707 
2708 			case GLOBAL_PAGE_DOWN:
2709 				page_down();
2710 				break;
2711 
2712 			case GLOBAL_PAGE_UP:
2713 				page_up();
2714 				break;
2715 
2716 			case GLOBAL_SCROLL_DOWN:
2717 				scroll_down();
2718 				break;
2719 
2720 			case GLOBAL_SCROLL_UP:
2721 				scroll_up();
2722 				break;
2723 
2724 			case GLOBAL_TOGGLE_HELP_DISPLAY:
2725 				toggle_mini_help(SCOPE_LEVEL);
2726 				show_scope_page();
2727 				break;
2728 
2729 			case SCOPE_ADD:
2730 				if ((i = add_new_scope())) {
2731 					changed = TRUE;
2732 					scopemenu.curr = i;
2733 					show_scope_page();
2734 				}
2735 				break;
2736 
2737 			case SCOPE_DELETE:
2738 				if (scopemenu.max) {
2739 					if (scopes[scopemenu.curr + 1].global)
2740 						info_message(_(txt_scope_operation_not_allowed));
2741 					else if (delete_scope(scopemenu.curr + 1)) {
2742 						changed = TRUE;
2743 						show_scope_page();
2744 					}
2745 				}
2746 				break;
2747 
2748 			case SCOPE_EDIT_ATTRIBUTES_FILE:
2749 				if (changed)
2750 					write_attributes_file(local_attributes_file);
2751 				if (!invoke_editor(local_attributes_file, attrib_file_offset, NULL))
2752 					break;
2753 				free_scopes_and_attributes();
2754 				read_attributes_file(FALSE);
2755 				assign_attributes_to_groups();
2756 				changed = FALSE;
2757 				scopemenu.curr = 0;
2758 				show_scope_page();
2759 				break;
2760 
2761 			case SCOPE_MOVE:
2762 				if (scopemenu.max > 1) {
2763 					if (scopes[scopemenu.curr + 1].global)
2764 						info_message(_(txt_scope_operation_not_allowed));
2765 					else if ((i = move_scope(scopemenu.curr + 1))) {
2766 						changed = TRUE;
2767 						scopemenu.curr = i - 1;
2768 						show_scope_page();
2769 					}
2770 				}
2771 				break;
2772 
2773 			case SCOPE_RENAME:
2774 				if (scopemenu.max) {
2775 					if (scopes[scopemenu.curr + 1].global)
2776 						info_message(_(txt_scope_operation_not_allowed));
2777 					else if (rename_scope(&scopes[scopemenu.curr + 1])) {
2778 						changed = TRUE;
2779 						show_scope_page();
2780 					}
2781 				}
2782 				break;
2783 
2784 			case SCOPE_SELECT:
2785 				if (scopemenu.max) {
2786 					curr_scope = &scopes[scopemenu.curr + 1];
2787 					config_page(NULL, level);
2788 					if (!curr_scope->global && scope_is_empty())
2789 						do_delete_scope(scopemenu.curr + 1);
2790 					curr_scope = NULL;
2791 					changed = TRUE;
2792 					show_scope_page();
2793 				}
2794 				break;
2795 
2796 			default:
2797 				info_message(_(txt_bad_command), printascii(key, func_to_key(GLOBAL_HELP, scope_keys)));
2798 				break;
2799 		}
2800 	}
2801 }
2802 
2803 
2804 static void
draw_scope_arrow(void)2805 draw_scope_arrow(
2806 	void)
2807 {
2808 	draw_arrow_mark(INDEX_TOP + scopemenu.curr - scopemenu.first);
2809 	if (scopemenu.curr == scopemenu.max - 1)
2810 		info_message(_(txt_end_of_scopes));
2811 }
2812 
2813 
2814 static void
build_scope_line(int i)2815 build_scope_line(
2816 	int i)
2817 {
2818 	char *sptr;
2819 	int len = cCOLS - 11;
2820 
2821 #ifdef USE_CURSES
2822 	/*
2823 	 * Allocate line buffer
2824 	 * make it the same size like in !USE_CURSES case to simplify some code
2825 	 */
2826 	sptr = my_malloc(cCOLS + 2);
2827 #else
2828 	sptr = screen[INDEX2SNUM(i)].col;
2829 #endif /* USE_CURSES */
2830 
2831 	snprintf(sptr, cCOLS, "  %c %s  %-*.*s%s", (scopes[i + 1].global ? '!' : ' '), tin_ltoa(i + 1, 4), len, len, scopes[i + 1].scope, cCRLF);
2832 
2833 #ifndef USE_CURSES
2834 	if (tinrc.strip_blanks)
2835 		strcat(strip_line(sptr), cCRLF);
2836 #endif /* !USE_CURSES */
2837 
2838 	WriteLine(INDEX2LNUM(i), sptr);
2839 
2840 #ifdef USE_CURSES
2841 	free(sptr);
2842 #endif /* USE_CURSES */
2843 }
2844 
2845 
2846 /*
2847  * add a new scope and return the index
2848  */
2849 static int
add_new_scope(void)2850 add_new_scope(
2851 	void)
2852 {
2853 	char buf[LEN];
2854 	int new_pos = 0;
2855 
2856 	if (prompt_default_string(_(txt_scope_enter), buf, sizeof(buf), (char *) NULL, HIST_OTHER))
2857 		new_pos = add_scope(buf);
2858 
2859 	return new_pos;
2860 }
2861 
2862 
2863 /*
2864  * returns TRUE if the given scope was deleted
2865  */
2866 static t_bool
delete_scope(int curr_pos)2867 delete_scope(
2868 	int curr_pos)
2869 {
2870 	if (prompt_yn(_(txt_scope_delete), FALSE) == 1) {
2871 		do_delete_scope(curr_pos);
2872 		return TRUE;
2873 	}
2874 
2875 	return FALSE;
2876 }
2877 
2878 
2879 static void
do_delete_scope(int curr_pos)2880 do_delete_scope(
2881 	int curr_pos)
2882 {
2883 	do_move_scope(curr_pos, num_scope - 1);
2884 	free_scope(--num_scope);
2885 }
2886 
2887 
2888 /*
2889  * returns TRUE if scope was renamed
2890  */
2891 static t_bool
rename_scope(struct t_scope * scope)2892 rename_scope(
2893 	struct t_scope *scope)
2894 {
2895 	char buf[LEN];
2896 
2897 	if (prompt_default_string(_(txt_scope_rename), buf, sizeof(buf), scope->scope, HIST_OTHER)) {
2898 		if (buf[0] == '\0')
2899 			return FALSE;
2900 		FreeIfNeeded(scope->scope);
2901 		scope->scope = my_strdup(buf);
2902 		return TRUE;
2903 	}
2904 
2905 	return FALSE;
2906 }
2907 
2908 
2909 /*
2910  * look if an entry with the given scope exists and return the index
2911  */
2912 static int
find_scope(const char * scope)2913 find_scope(
2914 	const char *scope)
2915 {
2916 	int i;
2917 
2918 	if (!scope || !*scope)
2919 		return 0;
2920 
2921 	for (i = 1; i < num_scope; i++) {
2922 		if (!scopes[i].global && strcasecmp(scope, scopes[i].scope) == 0)
2923 			return i;
2924 	}
2925 
2926 	return 0;
2927 }
2928 
2929 
2930 /*
2931  * returns the new position of the moved scope or 0 if repositioning
2932  * is not possible
2933  */
2934 static int
move_scope(int curr_pos)2935 move_scope(
2936 	int curr_pos)
2937 {
2938 	char *p;
2939 	int new_pos;
2940 
2941 	clear_message();
2942 	if ((p = tin_getline(_(txt_scope_new_position), 1, NULL, 0, FALSE, HIST_OTHER)) != NULL)
2943 		new_pos = atoi(p);
2944 	else
2945 		new_pos = curr_pos;
2946 	clear_message();
2947 
2948 	if (new_pos == curr_pos || new_pos == 0)
2949 		return 0;
2950 
2951 	if (new_pos >= num_scope)
2952 		new_pos = num_scope - 1;
2953 
2954 	if (scopes[new_pos].global) {
2955 		info_message(_(txt_scope_new_position_is_global));
2956 		return 0;
2957 	}
2958 
2959 	do_move_scope(curr_pos, new_pos);
2960 
2961 	return new_pos;
2962 }
2963 
2964 
2965 /*
2966  * repositions a scope into scopes[]
2967  */
2968 static void
do_move_scope(int from,int to)2969 do_move_scope(
2970 	int from,
2971 	int to)
2972 {
2973 	struct t_scope tmp;
2974 
2975 	if (from == to)
2976 		return;
2977 
2978 	tmp = scopes[from];
2979 
2980 	if (from > to) {
2981 		while (from-- > to)
2982 			scopes[from + 1] = scopes[from];
2983 	} else {
2984 		while (from++ < to)
2985 			scopes[from - 1] = scopes[from];
2986 	}
2987 	scopes[to] = tmp;
2988 }
2989 
2990 
2991 /*
2992  * free all group->attribute arrays and all scopes which are
2993  * not marked as global
2994  */
2995 static void
free_scopes_and_attributes(void)2996 free_scopes_and_attributes(
2997 	void)
2998 {
2999 	int i;
3000 
3001 	for_each_group(i) {
3002 		if (active[i].attribute && !active[i].attribute->global) {
3003 			free(active[i].attribute);
3004 			active[i].attribute = (struct t_attribute *) 0;
3005 		}
3006 	}
3007 
3008 	while (num_scope > 1 && !scopes[num_scope - 1].global)
3009 			free_scope(--num_scope);
3010 }
3011 
3012 
3013 /*
3014  * returns TRUE if no attribute in curr_scope has state == TRUE
3015  */
3016 static t_bool
scope_is_empty(void)3017 scope_is_empty(
3018 	void)
3019 {
3020 	enum option_enum i;
3021 
3022 	for (i = 0; i <= last_opt; i++) {
3023 		if (option_is_visible(i) && !option_is_title(i) && check_state(i))
3024 			return FALSE;
3025 	}
3026 
3027 	return TRUE;
3028 }
3029 
3030 
3031 /*
3032  * returns the state of the given attribute
3033  */
3034 static t_bool
check_state(enum option_enum option)3035 check_state(
3036 	enum option_enum option)
3037 {
3038 	switch (option) {
3039 		case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
3040 			return curr_scope->state->add_posted_to_filter;
3041 		case OPT_ATTRIB_ADVERTISING:
3042 			return curr_scope->state->advertising;
3043 		case OPT_ATTRIB_ALTERNATIVE_HANDLING:
3044 			return curr_scope->state->alternative_handling;
3045 		case OPT_ATTRIB_ASK_FOR_METAMAIL:
3046 			return curr_scope->state->ask_for_metamail;
3047 		case OPT_ATTRIB_AUTO_CC_BCC:
3048 			return curr_scope->state->auto_cc_bcc;
3049 		case OPT_ATTRIB_AUTO_LIST_THREAD:
3050 			return curr_scope->state->auto_list_thread;
3051 		case OPT_ATTRIB_AUTO_SAVE:
3052 			return curr_scope->state->auto_save;
3053 		case OPT_ATTRIB_AUTO_SELECT:
3054 			return curr_scope->state->auto_select;
3055 		case OPT_ATTRIB_BATCH_SAVE:
3056 			return curr_scope->state->batch_save;
3057 		case OPT_ATTRIB_DATE_FORMAT:
3058 			return curr_scope->state->date_format;
3059 		case OPT_ATTRIB_DELETE_TMP_FILES:
3060 			return curr_scope->state->delete_tmp_files;
3061 		case OPT_ATTRIB_EDITOR_FORMAT:
3062 			return curr_scope->state->editor_format;
3063 #ifdef HAVE_COLOR
3064 		case OPT_ATTRIB_EXTQUOTE_HANDLING:
3065 			return curr_scope->state->extquote_handling;
3066 #endif /* HAVE_COLOR */
3067 		case OPT_ATTRIB_FCC:
3068 			return curr_scope->state->fcc;
3069 		case OPT_ATTRIB_FOLLOWUP_TO:
3070 			return curr_scope->state->followup_to;
3071 		case OPT_ATTRIB_FROM:
3072 			return curr_scope->state->from;
3073 		case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
3074 			return curr_scope->state->group_catchup_on_exit;
3075 		case OPT_ATTRIB_GROUP_FORMAT:
3076 			return curr_scope->state->group_format;
3077 #ifdef HAVE_ISPELL
3078 		case OPT_ATTRIB_ISPELL:
3079 			return curr_scope->state->ispell;
3080 #endif /* HAVE_ISPELL */
3081 		case OPT_ATTRIB_MAILDIR:
3082 			return curr_scope->state->maildir;
3083 		case OPT_ATTRIB_MAIL_8BIT_HEADER:
3084 			return curr_scope->state->mail_8bit_header;
3085 		case OPT_ATTRIB_MAIL_MIME_ENCODING:
3086 			return curr_scope->state->mail_mime_encoding;
3087 		case OPT_ATTRIB_MAILING_LIST:
3088 			return curr_scope->state->mailing_list;
3089 		case OPT_ATTRIB_MARK_IGNORE_TAGS:
3090 			return curr_scope->state->mark_ignore_tags;
3091 		case OPT_ATTRIB_MARK_SAVED_READ:
3092 			return curr_scope->state->mark_saved_read;
3093 		case OPT_ATTRIB_MIME_FORWARD:
3094 			return curr_scope->state->mime_forward;
3095 		case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
3096 			return curr_scope->state->mime_types_to_save;
3097 		case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
3098 			return curr_scope->state->news_headers_to_display;
3099 		case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
3100 			return curr_scope->state->news_headers_to_not_display;
3101 		case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
3102 			return curr_scope->state->news_quote_format;
3103 		case OPT_ATTRIB_ORGANIZATION:
3104 			return curr_scope->state->organization;
3105 		case OPT_ATTRIB_POST_8BIT_HEADER:
3106 			return curr_scope->state->post_8bit_header;
3107 		case OPT_ATTRIB_POST_MIME_ENCODING:
3108 			return curr_scope->state->post_mime_encoding;
3109 		case OPT_ATTRIB_POST_PROCESS_VIEW:
3110 			return curr_scope->state->post_process_view;
3111 		case OPT_ATTRIB_POS_FIRST_UNREAD:
3112 			return curr_scope->state->pos_first_unread;
3113 #ifndef DISABLE_PRINTING
3114 		case OPT_ATTRIB_PRINT_HEADER:
3115 			return curr_scope->state->print_header;
3116 #endif /* !DISABLE_PRINTING */
3117 		case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
3118 			return curr_scope->state->process_only_unread;
3119 		case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
3120 			return curr_scope->state->prompt_followupto;
3121 		case OPT_ATTRIB_QUICK_KILL_SCOPE:
3122 			return curr_scope->state->quick_kill_scope;
3123 		case OPT_ATTRIB_QUICK_KILL_HEADER:
3124 			return curr_scope->state->quick_kill_header;
3125 		case OPT_ATTRIB_QUICK_KILL_CASE:
3126 			return curr_scope->state->quick_kill_case;
3127 		case OPT_ATTRIB_QUICK_KILL_EXPIRE:
3128 			return curr_scope->state->quick_kill_expire;
3129 		case OPT_ATTRIB_QUICK_SELECT_SCOPE:
3130 			return curr_scope->state->quick_select_scope;
3131 		case OPT_ATTRIB_QUICK_SELECT_HEADER:
3132 			return curr_scope->state->quick_select_header;
3133 		case OPT_ATTRIB_QUICK_SELECT_CASE:
3134 			return curr_scope->state->quick_select_case;
3135 		case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
3136 			return curr_scope->state->quick_select_expire;
3137 		case OPT_ATTRIB_QUOTE_CHARS:
3138 			return curr_scope->state->quote_chars;
3139 		case OPT_ATTRIB_SAVEDIR:
3140 			return curr_scope->state->savedir;
3141 		case OPT_ATTRIB_SAVEFILE:
3142 			return curr_scope->state->savefile;
3143 		case OPT_ATTRIB_SHOW_AUTHOR:
3144 			return curr_scope->state->show_author;
3145 		case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
3146 			return curr_scope->state->show_only_unread_arts;
3147 		case OPT_ATTRIB_SHOW_SIGNATURES:
3148 			return curr_scope->state->show_signatures;
3149 		case OPT_ATTRIB_SIGDASHES:
3150 			return curr_scope->state->sigdashes;
3151 		case OPT_ATTRIB_SIGFILE:
3152 			return curr_scope->state->sigfile;
3153 		case OPT_ATTRIB_SIGNATURE_REPOST:
3154 			return curr_scope->state->signature_repost;
3155 		case OPT_ATTRIB_START_EDITOR_OFFSET:
3156 			return curr_scope->state->start_editor_offset;
3157 		case OPT_ATTRIB_THREAD_ARTICLES:
3158 			return curr_scope->state->thread_articles;
3159 		case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
3160 			return curr_scope->state->thread_catchup_on_exit;
3161 		case OPT_ATTRIB_THREAD_FORMAT:
3162 			return curr_scope->state->thread_format;
3163 		case OPT_ATTRIB_THREAD_PERC:
3164 			return curr_scope->state->thread_perc;
3165 		case OPT_ATTRIB_TRIM_ARTICLE_BODY:
3166 			return curr_scope->state->trim_article_body;
3167 		case OPT_ATTRIB_TEX2ISO_CONV:
3168 			return curr_scope->state->tex2iso_conv;
3169 		case OPT_ATTRIB_SORT_THREADS_TYPE:
3170 			return curr_scope->state->sort_threads_type;
3171 #ifdef CHARSET_CONVERSION
3172 		case OPT_ATTRIB_MM_NETWORK_CHARSET:
3173 			return curr_scope->state->mm_network_charset;
3174 		case OPT_ATTRIB_UNDECLARED_CHARSET:
3175 			return curr_scope->state->undeclared_charset;
3176 #endif /* CHARSET_CONVERSION */
3177 		case OPT_ATTRIB_VERBATIM_HANDLING:
3178 			return curr_scope->state->verbatim_handling;
3179 		case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
3180 			return curr_scope->state->wrap_on_next_unread;
3181 		case OPT_ATTRIB_SORT_ARTICLE_TYPE:
3182 			return curr_scope->state->sort_article_type;
3183 		case OPT_ATTRIB_POST_PROCESS_TYPE:
3184 			return curr_scope->state->post_process_type;
3185 		case OPT_ATTRIB_X_BODY:
3186 			return curr_scope->state->x_body;
3187 		case OPT_ATTRIB_X_COMMENT_TO:
3188 			return curr_scope->state->x_comment_to;
3189 		case OPT_ATTRIB_X_HEADERS:
3190 			return curr_scope->state->x_headers;
3191 
3192 		default:
3193 			return FALSE;
3194 	}
3195 }
3196 
3197 
3198 /*
3199  * set the state of the given attribute to FALSE and the corresponding
3200  * tinrc.attrib_* to a default value
3201  */
3202 static void
reset_state(enum option_enum option)3203 reset_state(
3204 	enum option_enum option)
3205 {
3206 	struct t_scope *default_scope = &scopes[0];
3207 
3208 	switch (option) {
3209 		case OPT_ATTRIB_ADD_POSTED_TO_FILTER:
3210 			curr_scope->state->add_posted_to_filter = FALSE;
3211 			tinrc.attrib_add_posted_to_filter = default_scope->attribute->add_posted_to_filter;
3212 			break;
3213 		case OPT_ATTRIB_ADVERTISING:
3214 			curr_scope->state->advertising = FALSE;
3215 			tinrc.attrib_advertising = default_scope->attribute->advertising;
3216 			break;
3217 		case OPT_ATTRIB_ALTERNATIVE_HANDLING:
3218 			curr_scope->state->alternative_handling = FALSE;
3219 			tinrc.attrib_alternative_handling = default_scope->attribute->alternative_handling;
3220 			break;
3221 		case OPT_ATTRIB_ASK_FOR_METAMAIL:
3222 			curr_scope->state->ask_for_metamail = FALSE;
3223 			tinrc.attrib_ask_for_metamail = default_scope->attribute->ask_for_metamail;
3224 			break;
3225 		case OPT_ATTRIB_AUTO_CC_BCC:
3226 			curr_scope->state->auto_cc_bcc = FALSE;
3227 			tinrc.attrib_auto_cc_bcc = default_scope->attribute->auto_cc_bcc;
3228 			break;
3229 		case OPT_ATTRIB_AUTO_LIST_THREAD:
3230 			curr_scope->state->auto_list_thread = FALSE;
3231 			tinrc.attrib_auto_list_thread = default_scope->attribute->auto_list_thread;
3232 			break;
3233 		case OPT_ATTRIB_AUTO_SAVE:
3234 			curr_scope->state->auto_save = FALSE;
3235 			tinrc.attrib_auto_save = default_scope->attribute->auto_save;
3236 			break;
3237 		case OPT_ATTRIB_AUTO_SELECT:
3238 			curr_scope->state->auto_select = FALSE;
3239 			tinrc.attrib_auto_select = default_scope->attribute->auto_select;
3240 			break;
3241 		case OPT_ATTRIB_BATCH_SAVE:
3242 			curr_scope->state->batch_save = FALSE;
3243 			tinrc.attrib_batch_save = default_scope->attribute->batch_save;
3244 			break;
3245 		case OPT_ATTRIB_DATE_FORMAT:
3246 			FreeAndNull(curr_scope->attribute->date_format);
3247 			curr_scope->state->date_format = FALSE;
3248 			snprintf(tinrc.attrib_date_format, sizeof(tinrc.attrib_date_format), "%s", BlankIfNull(default_scope->attribute->date_format));
3249 			break;
3250 		case OPT_ATTRIB_DELETE_TMP_FILES:
3251 			curr_scope->state->delete_tmp_files = FALSE;
3252 			tinrc.attrib_delete_tmp_files = default_scope->attribute->delete_tmp_files;
3253 			break;
3254 		case OPT_ATTRIB_EDITOR_FORMAT:
3255 			FreeAndNull(curr_scope->attribute->editor_format);
3256 			curr_scope->state->editor_format = FALSE;
3257 			snprintf(tinrc.attrib_editor_format, sizeof(tinrc.attrib_editor_format), "%s", BlankIfNull(default_scope->attribute->editor_format));
3258 			break;
3259 #ifdef HAVE_COLOR
3260 		case OPT_ATTRIB_EXTQUOTE_HANDLING:
3261 			curr_scope->state->extquote_handling = FALSE;
3262 			tinrc.attrib_extquote_handling = default_scope->attribute->extquote_handling;
3263 			break;
3264 #endif /* HAVE_COLOR */
3265 		case OPT_ATTRIB_FCC:
3266 			FreeAndNull(curr_scope->attribute->fcc);
3267 			curr_scope->state->fcc = FALSE;
3268 			snprintf(tinrc.attrib_fcc, sizeof(tinrc.attrib_fcc), "%s", BlankIfNull(default_scope->attribute->fcc));
3269 			break;
3270 		case OPT_ATTRIB_FOLLOWUP_TO:
3271 			FreeAndNull(curr_scope->attribute->followup_to);
3272 			curr_scope->state->followup_to = FALSE;
3273 			snprintf(tinrc.attrib_followup_to, sizeof(tinrc.attrib_followup_to), "%s", BlankIfNull(default_scope->attribute->followup_to));
3274 			break;
3275 		case OPT_ATTRIB_FROM:
3276 			FreeAndNull(curr_scope->attribute->from);
3277 			curr_scope->state->from = FALSE;
3278 			snprintf(tinrc.attrib_from, sizeof(tinrc.attrib_from), "%s", BlankIfNull(default_scope->attribute->from));
3279 			break;
3280 		case OPT_ATTRIB_GROUP_CATCHUP_ON_EXIT:
3281 			curr_scope->state->group_catchup_on_exit = FALSE;
3282 			tinrc.attrib_group_catchup_on_exit = default_scope->attribute->group_catchup_on_exit;
3283 			break;
3284 		case OPT_ATTRIB_GROUP_FORMAT:
3285 			FreeAndNull(curr_scope->attribute->group_format);
3286 			curr_scope->state->group_format = FALSE;
3287 			snprintf(tinrc.attrib_group_format, sizeof(tinrc.attrib_group_format), "%s", BlankIfNull(default_scope->attribute->group_format));
3288 			break;
3289 #ifdef HAVE_ISPELL
3290 		case OPT_ATTRIB_ISPELL:
3291 			FreeAndNull(curr_scope->attribute->ispell);
3292 			curr_scope->state->ispell = FALSE;
3293 			snprintf(tinrc.attrib_ispell, sizeof(tinrc.attrib_ispell), "%s", BlankIfNull(default_scope->attribute->ispell));
3294 			break;
3295 #endif /* HAVE_ISPELL */
3296 		case OPT_ATTRIB_MAILDIR:
3297 			FreeAndNull(curr_scope->attribute->maildir);
3298 			curr_scope->state->maildir = FALSE;
3299 			snprintf(tinrc.attrib_maildir, sizeof(tinrc.attrib_maildir), "%s", BlankIfNull(default_scope->attribute->maildir));
3300 			break;
3301 		case OPT_ATTRIB_MAIL_8BIT_HEADER:
3302 			curr_scope->state->mail_8bit_header = FALSE;
3303 			tinrc.attrib_mail_8bit_header = default_scope->attribute->mail_8bit_header;
3304 			break;
3305 		case OPT_ATTRIB_MAIL_MIME_ENCODING:
3306 			curr_scope->state->mail_mime_encoding = FALSE;
3307 			tinrc.attrib_mail_mime_encoding = default_scope->attribute->mail_mime_encoding;
3308 			break;
3309 		case OPT_ATTRIB_MAILING_LIST:
3310 			FreeAndNull(curr_scope->attribute->mailing_list);
3311 			curr_scope->state->mailing_list = FALSE;
3312 			snprintf(tinrc.attrib_mailing_list, sizeof(tinrc.attrib_mailing_list), "%s", BlankIfNull(default_scope->attribute->mailing_list));
3313 			break;
3314 		case OPT_ATTRIB_MARK_IGNORE_TAGS:
3315 			curr_scope->state->mark_ignore_tags = FALSE;
3316 			tinrc.attrib_mark_ignore_tags = default_scope->attribute->mark_ignore_tags;
3317 			break;
3318 		case OPT_ATTRIB_MARK_SAVED_READ:
3319 			curr_scope->state->mark_saved_read = FALSE;
3320 			tinrc.attrib_mark_saved_read = default_scope->attribute->mark_saved_read;
3321 			break;
3322 		case OPT_ATTRIB_MIME_FORWARD:
3323 			curr_scope->state->mime_forward = FALSE;
3324 			tinrc.attrib_mime_forward = default_scope->attribute->mime_forward;
3325 			break;
3326 		case OPT_ATTRIB_MIME_TYPES_TO_SAVE:
3327 			FreeAndNull(curr_scope->attribute->mime_types_to_save);
3328 			curr_scope->state->mime_types_to_save = FALSE;
3329 			snprintf(tinrc.attrib_mime_types_to_save, sizeof(tinrc.attrib_mime_types_to_save), "%s", BlankIfNull(default_scope->attribute->mime_types_to_save));
3330 			break;
3331 		case OPT_ATTRIB_NEWS_HEADERS_TO_DISPLAY:
3332 			FreeAndNull(curr_scope->attribute->news_headers_to_display);
3333 			build_news_headers_array(curr_scope->attribute, TRUE);
3334 			curr_scope->state->news_headers_to_display = FALSE;
3335 			snprintf(tinrc.attrib_news_headers_to_display, sizeof(tinrc.attrib_news_headers_to_display), "%s", BlankIfNull(default_scope->attribute->news_headers_to_display));
3336 			break;
3337 		case OPT_ATTRIB_NEWS_HEADERS_TO_NOT_DISPLAY:
3338 			FreeAndNull(curr_scope->attribute->news_headers_to_not_display);
3339 			build_news_headers_array(curr_scope->attribute, FALSE);
3340 			curr_scope->state->news_headers_to_not_display = FALSE;
3341 			snprintf(tinrc.attrib_news_headers_to_not_display, sizeof(tinrc.attrib_news_headers_to_not_display), "%s", BlankIfNull(default_scope->attribute->news_headers_to_not_display));
3342 			break;
3343 		case OPT_ATTRIB_QUICK_KILL_SCOPE:
3344 			FreeAndNull(curr_scope->attribute->quick_kill_scope);
3345 			curr_scope->state->quick_kill_scope = FALSE;
3346 			snprintf(tinrc.attrib_quick_kill_scope, sizeof(tinrc.attrib_quick_kill_scope), "%s", BlankIfNull(default_scope->attribute->quick_kill_scope));
3347 			break;
3348 		case OPT_ATTRIB_QUICK_KILL_HEADER:
3349 			curr_scope->state->quick_kill_header = FALSE;
3350 			tinrc.attrib_quick_kill_header = default_scope->attribute->quick_kill_header;
3351 			break;
3352 		case OPT_ATTRIB_QUICK_KILL_CASE:
3353 			curr_scope->state->quick_kill_case = FALSE;
3354 			tinrc.attrib_quick_kill_case = default_scope->attribute->quick_kill_case;
3355 			break;
3356 		case OPT_ATTRIB_QUICK_KILL_EXPIRE:
3357 			curr_scope->state->quick_kill_expire = FALSE;
3358 			tinrc.attrib_quick_kill_expire = default_scope->attribute->quick_kill_expire;
3359 			break;
3360 		case OPT_ATTRIB_QUICK_SELECT_SCOPE:
3361 			FreeAndNull(curr_scope->attribute->quick_select_scope);
3362 			curr_scope->state->quick_select_scope = FALSE;
3363 			snprintf(tinrc.attrib_quick_select_scope, sizeof(tinrc.attrib_quick_select_scope), "%s", BlankIfNull(default_scope->attribute->quick_select_scope));
3364 			break;
3365 		case OPT_ATTRIB_QUICK_SELECT_HEADER:
3366 			curr_scope->state->quick_select_header = FALSE;
3367 			tinrc.attrib_quick_select_header = default_scope->attribute->quick_select_header;
3368 			break;
3369 		case OPT_ATTRIB_QUICK_SELECT_CASE:
3370 			curr_scope->state->quick_select_case = FALSE;
3371 			tinrc.attrib_quick_select_case = default_scope->attribute->quick_select_case;
3372 			break;
3373 		case OPT_ATTRIB_QUICK_SELECT_EXPIRE:
3374 			curr_scope->state->quick_select_expire = FALSE;
3375 			tinrc.attrib_quick_select_expire = default_scope->attribute->quick_select_expire;
3376 			break;
3377 		case OPT_ATTRIB_NEWS_QUOTE_FORMAT:
3378 			FreeAndNull(curr_scope->attribute->news_quote_format);
3379 			curr_scope->state->news_quote_format = FALSE;
3380 			snprintf(tinrc.attrib_news_quote_format, sizeof(tinrc.attrib_news_quote_format), "%s", BlankIfNull(default_scope->attribute->news_quote_format));
3381 			break;
3382 		case OPT_ATTRIB_ORGANIZATION:
3383 			FreeAndNull(curr_scope->attribute->organization);
3384 			curr_scope->state->organization = FALSE;
3385 			snprintf(tinrc.attrib_organization, sizeof(tinrc.attrib_organization), "%s", BlankIfNull(default_scope->attribute->organization));
3386 			break;
3387 		case OPT_ATTRIB_POST_8BIT_HEADER:
3388 			curr_scope->state->post_8bit_header = FALSE;
3389 			tinrc.attrib_post_8bit_header = default_scope->attribute->post_8bit_header;
3390 			break;
3391 		case OPT_ATTRIB_POST_MIME_ENCODING:
3392 			curr_scope->state->post_mime_encoding = FALSE;
3393 			tinrc.attrib_post_mime_encoding = default_scope->attribute->post_mime_encoding;
3394 			break;
3395 		case OPT_ATTRIB_POST_PROCESS_VIEW:
3396 			curr_scope->state->post_process_view = FALSE;
3397 			tinrc.attrib_post_process_view = default_scope->attribute->post_process_view;
3398 			break;
3399 		case OPT_ATTRIB_POS_FIRST_UNREAD:
3400 			curr_scope->state->pos_first_unread = FALSE;
3401 			tinrc.attrib_pos_first_unread = default_scope->attribute->pos_first_unread;
3402 			break;
3403 #ifndef DISABLE_PRINTING
3404 		case OPT_ATTRIB_PRINT_HEADER:
3405 			curr_scope->state->print_header = FALSE;
3406 			tinrc.attrib_print_header = default_scope->attribute->print_header;
3407 			break;
3408 #endif /* !DISABLE_PRINTING */
3409 		case OPT_ATTRIB_PROCESS_ONLY_UNREAD:
3410 			curr_scope->state->process_only_unread = FALSE;
3411 			tinrc.attrib_process_only_unread = default_scope->attribute->process_only_unread;
3412 			break;
3413 		case OPT_ATTRIB_PROMPT_FOLLOWUPTO:
3414 			curr_scope->state->prompt_followupto = FALSE;
3415 			tinrc.attrib_prompt_followupto = default_scope->attribute->prompt_followupto;
3416 			break;
3417 		case OPT_ATTRIB_QUOTE_CHARS:
3418 			FreeAndNull(curr_scope->attribute->quote_chars);
3419 			curr_scope->state->quote_chars = FALSE;
3420 			snprintf(tinrc.attrib_quote_chars, sizeof(tinrc.attrib_quote_chars), "%s", BlankIfNull(default_scope->attribute->quote_chars));
3421 			break;
3422 		case OPT_ATTRIB_SAVEDIR:
3423 			FreeAndNull(curr_scope->attribute->savedir);
3424 			curr_scope->state->savedir = FALSE;
3425 			snprintf(tinrc.attrib_savedir, sizeof(tinrc.attrib_savedir), "%s", BlankIfNull(default_scope->attribute->savedir));
3426 			break;
3427 		case OPT_ATTRIB_SAVEFILE:
3428 			FreeAndNull(curr_scope->attribute->savefile);
3429 			curr_scope->state->savefile = FALSE;
3430 			snprintf(tinrc.attrib_savefile, sizeof(tinrc.attrib_savefile), "%s", BlankIfNull(default_scope->attribute->savefile));
3431 			break;
3432 		case OPT_ATTRIB_SHOW_AUTHOR:
3433 			curr_scope->state->show_author = FALSE;
3434 			tinrc.attrib_show_author = default_scope->attribute->show_author;
3435 			break;
3436 		case OPT_ATTRIB_SHOW_ONLY_UNREAD_ARTS:
3437 			curr_scope->state->show_only_unread_arts = FALSE;
3438 			tinrc.attrib_show_only_unread_arts = default_scope->attribute->show_only_unread_arts;
3439 			break;
3440 		case OPT_ATTRIB_SHOW_SIGNATURES:
3441 			curr_scope->state->show_signatures = FALSE;
3442 			tinrc.attrib_show_signatures = default_scope->attribute->show_signatures;
3443 			break;
3444 		case OPT_ATTRIB_SIGDASHES:
3445 			curr_scope->state->sigdashes = FALSE;
3446 			tinrc.attrib_sigdashes = default_scope->attribute->sigdashes;
3447 			break;
3448 		case OPT_ATTRIB_SIGFILE:
3449 			FreeAndNull(curr_scope->attribute->sigfile);
3450 			curr_scope->state->sigfile = FALSE;
3451 			snprintf(tinrc.attrib_sigfile, sizeof(tinrc.attrib_sigfile), "%s", BlankIfNull(default_scope->attribute->sigfile));
3452 			break;
3453 		case OPT_ATTRIB_SIGNATURE_REPOST:
3454 			curr_scope->state->signature_repost = FALSE;
3455 			tinrc.attrib_signature_repost = default_scope->attribute->signature_repost;
3456 			break;
3457 		case OPT_ATTRIB_START_EDITOR_OFFSET:
3458 			curr_scope->state->start_editor_offset = FALSE;
3459 			tinrc.attrib_start_editor_offset = default_scope->attribute->start_editor_offset;
3460 			break;
3461 		case OPT_ATTRIB_THREAD_ARTICLES:
3462 			curr_scope->state->thread_articles = FALSE;
3463 			tinrc.attrib_thread_articles = default_scope->attribute->thread_articles;
3464 			break;
3465 		case OPT_ATTRIB_THREAD_CATCHUP_ON_EXIT:
3466 			curr_scope->state->thread_catchup_on_exit = FALSE;
3467 			tinrc.attrib_thread_catchup_on_exit = default_scope->attribute->thread_catchup_on_exit;
3468 			break;
3469 		case OPT_ATTRIB_THREAD_FORMAT:
3470 			FreeAndNull(curr_scope->attribute->thread_format);
3471 			curr_scope->state->thread_format = FALSE;
3472 			snprintf(tinrc.attrib_thread_format, sizeof(tinrc.attrib_thread_format), "%s", BlankIfNull(default_scope->attribute->thread_format));
3473 			break;
3474 		case OPT_ATTRIB_THREAD_PERC:
3475 			curr_scope->state->thread_perc = FALSE;
3476 			tinrc.attrib_thread_perc = default_scope->attribute->thread_perc;
3477 			break;
3478 		case OPT_ATTRIB_TRIM_ARTICLE_BODY:
3479 			curr_scope->state->trim_article_body = FALSE;
3480 			tinrc.attrib_trim_article_body = default_scope->attribute->trim_article_body;
3481 			break;
3482 		case OPT_ATTRIB_TEX2ISO_CONV:
3483 			curr_scope->state->tex2iso_conv = FALSE;
3484 			tinrc.attrib_tex2iso_conv = default_scope->attribute->tex2iso_conv;
3485 			break;
3486 		case OPT_ATTRIB_SORT_THREADS_TYPE:
3487 			curr_scope->state->sort_threads_type = FALSE;
3488 			tinrc.attrib_sort_threads_type = default_scope->attribute->sort_threads_type;
3489 			break;
3490 #ifdef CHARSET_CONVERSION
3491 		case OPT_ATTRIB_MM_NETWORK_CHARSET:
3492 			curr_scope->state->mm_network_charset = FALSE;
3493 			tinrc.attrib_mm_network_charset = default_scope->attribute->mm_network_charset;
3494 			break;
3495 		case OPT_ATTRIB_UNDECLARED_CHARSET:
3496 			FreeAndNull(curr_scope->attribute->undeclared_charset);
3497 			curr_scope->state->undeclared_charset = FALSE;
3498 			snprintf(tinrc.attrib_undeclared_charset, sizeof(tinrc.attrib_undeclared_charset), "%s", BlankIfNull(default_scope->attribute->undeclared_charset));
3499 			break;
3500 #endif /* CHARSET_CONVERSION */
3501 		case OPT_ATTRIB_VERBATIM_HANDLING:
3502 			curr_scope->state->verbatim_handling = FALSE;
3503 			tinrc.attrib_verbatim_handling = default_scope->attribute->verbatim_handling;
3504 			break;
3505 		case OPT_ATTRIB_WRAP_ON_NEXT_UNREAD:
3506 			curr_scope->state->wrap_on_next_unread = FALSE;
3507 			tinrc.attrib_wrap_on_next_unread = default_scope->attribute->wrap_on_next_unread;
3508 			break;
3509 		case OPT_ATTRIB_SORT_ARTICLE_TYPE:
3510 			curr_scope->state->sort_article_type = FALSE;
3511 			tinrc.attrib_sort_article_type = default_scope->attribute->sort_article_type;
3512 			break;
3513 		case OPT_ATTRIB_POST_PROCESS_TYPE:
3514 			curr_scope->state->post_process_type = FALSE;
3515 			tinrc.attrib_post_process_type = default_scope->attribute->post_process_type;
3516 			break;
3517 		case OPT_ATTRIB_X_BODY:
3518 			FreeAndNull(curr_scope->attribute->x_body);
3519 			curr_scope->state->x_body = FALSE;
3520 			snprintf(tinrc.attrib_x_body, sizeof(tinrc.attrib_x_body), "%s", BlankIfNull(default_scope->attribute->x_body));
3521 			break;
3522 		case OPT_ATTRIB_X_COMMENT_TO:
3523 			curr_scope->state->x_comment_to = FALSE;
3524 			tinrc.attrib_x_comment_to = default_scope->attribute->x_comment_to;
3525 			break;
3526 		case OPT_ATTRIB_X_HEADERS:
3527 			FreeAndNull(curr_scope->attribute->x_headers);
3528 			curr_scope->state->x_headers = FALSE;
3529 			snprintf(tinrc.attrib_x_headers, sizeof(tinrc.attrib_x_headers), "%s", BlankIfNull(default_scope->attribute->x_headers));
3530 			break;
3531 
3532 		default:
3533 			break;
3534 	}
3535 }
3536 
3537 
3538 #define INITIALIZE_STRING_ATTRIBUTE(option) do { \
3539 		if (curr_scope->state->option) \
3540 			snprintf(CAO(tinrc.attrib_, option), sizeof(CAO(tinrc.attrib_, option)), "%s", curr_scope->attribute->option); \
3541 		else \
3542 			snprintf(CAO(tinrc.attrib_, option), sizeof(CAO(tinrc.attrib_, option)), "%s", BlankIfNull(default_scope->attribute->option)); \
3543 	} while (0)
3544 #define INITIALIZE_NUM_ATTRIBUTE(option) do { \
3545 		if (curr_scope->state->option) \
3546 			CAO(tinrc.attrib_, option) = curr_scope->attribute->option; \
3547 		else \
3548 			CAO(tinrc.attrib_, option) = default_scope->attribute->option; \
3549 	} while (0)
3550 
3551 static void
initialize_attributes(void)3552 initialize_attributes(
3553 	void)
3554 {
3555 	struct t_scope *default_scope = &scopes[0];
3556 
3557 	INITIALIZE_NUM_ATTRIBUTE(add_posted_to_filter);
3558 	INITIALIZE_NUM_ATTRIBUTE(advertising);
3559 	INITIALIZE_NUM_ATTRIBUTE(alternative_handling);
3560 	INITIALIZE_NUM_ATTRIBUTE(ask_for_metamail);
3561 	INITIALIZE_NUM_ATTRIBUTE(auto_cc_bcc);
3562 	INITIALIZE_NUM_ATTRIBUTE(auto_list_thread);
3563 	INITIALIZE_NUM_ATTRIBUTE(auto_save);
3564 	INITIALIZE_NUM_ATTRIBUTE(auto_select);
3565 	INITIALIZE_NUM_ATTRIBUTE(batch_save);
3566 	INITIALIZE_NUM_ATTRIBUTE(delete_tmp_files);
3567 #ifdef HAVE_COLOR
3568 	INITIALIZE_NUM_ATTRIBUTE(extquote_handling);
3569 #endif /* HAVE_COLOR */
3570 	INITIALIZE_NUM_ATTRIBUTE(group_catchup_on_exit);
3571 	INITIALIZE_NUM_ATTRIBUTE(mail_8bit_header);
3572 	INITIALIZE_NUM_ATTRIBUTE(mail_mime_encoding);
3573 	INITIALIZE_NUM_ATTRIBUTE(mark_ignore_tags);
3574 	INITIALIZE_NUM_ATTRIBUTE(mark_saved_read);
3575 	INITIALIZE_NUM_ATTRIBUTE(mime_forward);
3576 	INITIALIZE_NUM_ATTRIBUTE(pos_first_unread);
3577 	INITIALIZE_NUM_ATTRIBUTE(post_8bit_header);
3578 	INITIALIZE_NUM_ATTRIBUTE(post_mime_encoding);
3579 	INITIALIZE_NUM_ATTRIBUTE(post_process_view);
3580 #ifndef DISABLE_PRINTING
3581 	INITIALIZE_NUM_ATTRIBUTE(print_header);
3582 #endif /* !DISABLE_PRINTING */
3583 	INITIALIZE_NUM_ATTRIBUTE(process_only_unread);
3584 	INITIALIZE_NUM_ATTRIBUTE(prompt_followupto);
3585 	INITIALIZE_NUM_ATTRIBUTE(quick_kill_header);
3586 	INITIALIZE_NUM_ATTRIBUTE(quick_kill_case);
3587 	INITIALIZE_NUM_ATTRIBUTE(quick_kill_expire);
3588 	INITIALIZE_NUM_ATTRIBUTE(quick_select_header);
3589 	INITIALIZE_NUM_ATTRIBUTE(quick_select_case);
3590 	INITIALIZE_NUM_ATTRIBUTE(quick_select_expire);
3591 	INITIALIZE_NUM_ATTRIBUTE(show_author);
3592 	INITIALIZE_NUM_ATTRIBUTE(show_only_unread_arts);
3593 	INITIALIZE_NUM_ATTRIBUTE(show_signatures);
3594 	INITIALIZE_NUM_ATTRIBUTE(sigdashes);
3595 	INITIALIZE_NUM_ATTRIBUTE(signature_repost);
3596 	INITIALIZE_NUM_ATTRIBUTE(start_editor_offset);
3597 	INITIALIZE_NUM_ATTRIBUTE(thread_articles);
3598 	INITIALIZE_NUM_ATTRIBUTE(thread_catchup_on_exit);
3599 	INITIALIZE_NUM_ATTRIBUTE(thread_perc);
3600 	INITIALIZE_NUM_ATTRIBUTE(trim_article_body);
3601 	INITIALIZE_NUM_ATTRIBUTE(tex2iso_conv);
3602 	INITIALIZE_NUM_ATTRIBUTE(verbatim_handling);
3603 	INITIALIZE_NUM_ATTRIBUTE(wrap_on_next_unread);
3604 	INITIALIZE_NUM_ATTRIBUTE(sort_article_type);
3605 	INITIALIZE_NUM_ATTRIBUTE(sort_threads_type);
3606 	INITIALIZE_NUM_ATTRIBUTE(post_process_type);
3607 	INITIALIZE_NUM_ATTRIBUTE(x_comment_to);
3608 	INITIALIZE_STRING_ATTRIBUTE(date_format);
3609 	INITIALIZE_STRING_ATTRIBUTE(editor_format);
3610 	INITIALIZE_STRING_ATTRIBUTE(fcc);
3611 	INITIALIZE_STRING_ATTRIBUTE(followup_to);
3612 	INITIALIZE_STRING_ATTRIBUTE(from);
3613 	INITIALIZE_STRING_ATTRIBUTE(group_format);
3614 #ifdef HAVE_ISPELL
3615 	INITIALIZE_STRING_ATTRIBUTE(ispell);
3616 #endif /* HAVE_ISPELL */
3617 	INITIALIZE_STRING_ATTRIBUTE(maildir);
3618 	INITIALIZE_STRING_ATTRIBUTE(mailing_list);
3619 	INITIALIZE_STRING_ATTRIBUTE(mime_types_to_save);
3620 	INITIALIZE_STRING_ATTRIBUTE(news_headers_to_display);
3621 	INITIALIZE_STRING_ATTRIBUTE(news_headers_to_not_display);
3622 	INITIALIZE_STRING_ATTRIBUTE(news_quote_format);
3623 	INITIALIZE_STRING_ATTRIBUTE(organization);
3624 	INITIALIZE_STRING_ATTRIBUTE(quick_kill_scope);
3625 	INITIALIZE_STRING_ATTRIBUTE(quick_select_scope);
3626 	INITIALIZE_STRING_ATTRIBUTE(quote_chars);
3627 	INITIALIZE_STRING_ATTRIBUTE(savedir);
3628 	INITIALIZE_STRING_ATTRIBUTE(savefile);
3629 	INITIALIZE_STRING_ATTRIBUTE(sigfile);
3630 	INITIALIZE_STRING_ATTRIBUTE(thread_format);
3631 #ifdef CHARSET_CONVERSION
3632 	INITIALIZE_NUM_ATTRIBUTE(mm_network_charset);
3633 	INITIALIZE_STRING_ATTRIBUTE(undeclared_charset);
3634 #endif /* CHARSET_CONVERSION */
3635 	INITIALIZE_STRING_ATTRIBUTE(x_body);
3636 	INITIALIZE_STRING_ATTRIBUTE(x_headers);
3637 }
3638