1 /*
2  *  Project   : tin - a Usenet reader
3  *  Module    : keymap.c
4  *  Author    : D. Nimmich, J. Faultless
5  *  Created   : 2000-05-25
6  *  Updated   : 2020-06-10
7  *  Notes     : This file contains key mapping routines and variables.
8  *
9  * Copyright (c) 2000-2021 Dirk Nimmich <nimmich@muenster.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 #ifndef TIN_H
41 #	include "tin.h"
42 #endif /* !TIN_H */
43 #ifndef VERSION_H
44 #	include "version.h"
45 #endif /* !VERSION_H */
46 
47 /*
48  * local prototypes
49  */
50 static void add_default_key(struct keylist *key_list, const char *keys, t_function func);
51 static void add_global_keys(struct keylist *keys);
52 static void free_keylist(struct keylist *keys);
53 static void upgrade_keymap_file(char *old);
54 static t_bool process_keys(t_function func, const char *keys, struct keylist *kl);
55 static t_bool process_mapping(char *keyname, char *keys);
56 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
57 	static t_bool add_key(struct keylist *keys, const wchar_t key, t_function func, t_bool override);
58 #else
59 	static t_bool add_key(struct keylist *keys, const char key, t_function func, t_bool override);
60 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
61 
62 struct keylist attachment_keys = { NULL, 0, 0};
63 struct keylist feed_post_process_keys = { NULL, 0, 0 };
64 struct keylist feed_supersede_article_keys = { NULL, 0, 0 };
65 struct keylist feed_type_keys = { NULL, 0, 0 };
66 struct keylist filter_keys = { NULL, 0, 0 };
67 struct keylist group_keys = { NULL, 0, 0 };
68 struct keylist info_keys = { NULL, 0, 0 };
69 struct keylist option_menu_keys = { NULL, 0, 0 };
70 struct keylist page_keys = { NULL, 0, 0 };
71 #ifdef HAVE_PGP_GPG
72 	struct keylist pgp_mail_keys = { NULL, 0, 0 };
73 	struct keylist pgp_news_keys = { NULL, 0, 0 };
74 #endif /* HAVE_PGP_GPG */
75 struct keylist post_cancel_keys = { NULL, 0, 0 };
76 struct keylist post_continue_keys = { NULL, 0, 0 };
77 struct keylist post_delete_keys = { NULL, 0, 0 };
78 struct keylist post_edit_keys = { NULL, 0, 0 };
79 struct keylist post_edit_ext_keys = { NULL, 0, 0 };
80 struct keylist post_ignore_fupto_keys = { NULL, 0, 0 };
81 struct keylist post_mail_fup_keys = { NULL, 0, 0 };
82 struct keylist post_post_keys = { NULL, 0, 0 };
83 struct keylist post_postpone_keys = { NULL, 0, 0 };
84 struct keylist post_send_keys = { NULL, 0, 0 };
85 struct keylist prompt_keys = { NULL, 0, 0 };
86 struct keylist save_append_overwrite_keys = { NULL, 0, 0 };
87 struct keylist scope_keys = { NULL, 0, 0 };
88 struct keylist select_keys = { NULL, 0, 0 };
89 struct keylist thread_keys = { NULL, 0, 0 };
90 struct keylist url_keys = { NULL, 0, 0 };
91 
92 
93 /*
94  * lookup the associated function to the specified key
95  */
96 t_function
key_to_func(const wchar_t key,const struct keylist keys)97 key_to_func(
98 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
99 	const wchar_t key,
100 #else
101 	const char key,
102 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
103 	const struct keylist keys)
104 {
105 	size_t i;
106 
107 	for (i = 0; i < keys.used; i++) {
108 		if (keys.list[i].key == key)
109 			return keys.list[i].function;
110 	}
111 
112 	return NOT_ASSIGNED;
113 }
114 
115 
116 /*
117  * lookup the associated key to the specified function
118  */
119 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
120 wchar_t
121 #else
122 char
123 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
func_to_key(t_function func,const struct keylist keys)124 func_to_key(
125 	t_function func,
126 	const struct keylist keys)
127 {
128 	size_t i;
129 
130 	for (i = 0; i < keys.used; i++) {
131 		if (keys.list[i].function == func)
132 			return keys.list[i].key;
133 	}
134 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
135 	return (wchar_t) '?';
136 #else
137 	return '?';
138 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
139 }
140 
141 
142 /*
143  * adds a key to a keylist
144  * default_key: TRUE if a default key should be added
145  * returns TRUE if the key was successfully added else FALSE
146  */
147 static t_bool
add_key(struct keylist * keys,const wchar_t key,t_function func,t_bool override)148 add_key(
149 	struct keylist *keys,
150 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
151 	const wchar_t key,
152 #else
153 	const char key,
154 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
155 	t_function func,
156 	t_bool override)
157 {
158 	size_t i;
159 	struct keynode *entry = NULL;
160 
161 	/* is a function already associated with this key */
162 	for (i = 0; key != '\0' && i < keys->used; i++) {
163 		if (keys->list[i].key == key)
164 			entry = &keys->list[i];
165 	}
166 
167 	if (entry != NULL) {
168 		if (override) {
169 			entry->function = func;
170 			return TRUE;
171 		} else
172 			return FALSE;
173 	} else {
174 		/* add a new entry */
175 		if (keys->used >= keys->max) {
176 			if (keys->list == NULL) {
177 				keys->max = DEFAULT_MAPKEYS_NUM;
178 				keys->list = my_malloc(keys->max * sizeof(struct keynode));
179 			} else {
180 				keys->max++;
181 				keys->list = my_realloc(keys->list, keys->max * sizeof(struct keynode));
182 			}
183 		}
184 		keys->list[keys->used].key = key;
185 		keys->list[keys->used].function = func;
186 		keys->used++;
187 
188 		return TRUE;
189 	}
190 }
191 
192 
193 /*
194  * FIXME:
195  * as long as we use only ASCII for default keys no need to change 'keys' to wchar_t
196  */
197 static void
add_default_key(struct keylist * key_list,const char * keys,t_function func)198 add_default_key(
199 	struct keylist *key_list,
200 	const char *keys,
201 	t_function func)
202 {
203 	const char *key = keys;
204 	/* check if the function has already a key assigned before we add the default one */
205 	if (func_to_key(func, *key_list) != '?')
206 		return;
207 
208 	for (; *key != '\0'; key++)
209 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
210 		add_key(key_list, (wchar_t) *key, func, FALSE);
211 #else
212 		add_key(key_list, *key, func, FALSE);
213 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
214 }
215 
216 
217 static void
free_keylist(struct keylist * keys)218 free_keylist(
219 	struct keylist *keys)
220 {
221 	FreeAndNull(keys->list);
222 	keys->used = keys->max = 0;
223 }
224 
225 
226 /*
227  * Free all memory for keymaps.
228  */
229 void
free_keymaps(void)230 free_keymaps(
231 	void)
232 {
233 	free_keylist(&attachment_keys);
234 	free_keylist(&select_keys);
235 	free_keylist(&group_keys);
236 	free_keylist(&thread_keys);
237 	free_keylist(&option_menu_keys);
238 	free_keylist(&page_keys);
239 	free_keylist(&info_keys);
240 	free_keylist(&post_send_keys);
241 	free_keylist(&post_edit_keys);
242 	free_keylist(&post_edit_ext_keys);
243 	free_keylist(&post_post_keys);
244 	free_keylist(&post_postpone_keys);
245 	free_keylist(&post_mail_fup_keys);
246 	free_keylist(&post_ignore_fupto_keys);
247 	free_keylist(&post_continue_keys);
248 	free_keylist(&post_delete_keys);
249 	free_keylist(&post_cancel_keys);
250 	free_keylist(&filter_keys);
251 #ifdef HAVE_PGP_GPG
252 	free_keylist(&pgp_mail_keys);
253 	free_keylist(&pgp_news_keys);
254 #endif /* HAVE_PGP_GPG */
255 	free_keylist(&save_append_overwrite_keys);
256 	free_keylist(&scope_keys);
257 	free_keylist(&feed_type_keys);
258 	free_keylist(&feed_post_process_keys);
259 	free_keylist(&feed_supersede_article_keys);
260 	free_keylist(&prompt_keys);
261 	free_keylist(&url_keys);
262 }
263 
264 
265 /*
266  * Render ch in human readable ASCII
267  * Is there no lib function to do this ?
268  * *buf must have a size of at least MAXKEYLEN
269  */
270 char *
printascii(char * buf,wint_t ch)271 printascii(
272 	char *buf,
273 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
274 	wint_t ch)
275 #else
276 	int ch)
277 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
278 {
279 	if (ch == 0)
280 		snprintf(buf, MAXKEYLEN, "%s", _("NULL"));
281 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
282 	else if (iswgraph(ch)) {	/* Regular printables */
283 		int i = wctomb(buf, ch);
284 
285 		if (i > 0)
286 			buf[i] = '\0';
287 		else
288 			buf[0] = '\0';
289 	}
290 #else
291 	else if (isgraph(ch)) {		/* Regular printables */
292 		buf[0] = ch;
293 		buf[1] = '\0';
294 	}
295 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
296 	else if (ch == '\t') {	/* TAB */
297 		snprintf(buf, MAXKEYLEN, "%s", _(txt_tab));
298 	} else if ((ch == '\n') || (ch == '\r')) {	/* LF, CR */
299 		snprintf(buf, MAXKEYLEN, "%s", _(txt_cr));
300 	} else if (ch == ESC) {		/* Escape */
301 		snprintf(buf, MAXKEYLEN, "%s", _(txt_esc));
302 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
303 	} else if (iswcntrl(ch)) {	/* Control keys */
304 #else
305 	} else if (iscntrl(ch)) {	/* Control keys */
306 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
307 		buf[0] = '^';
308 		buf[1] = ((int) ch & 0xFF) + '@';
309 		buf[2] = '\0';
310 	} else if (ch == ' ')		/* SPACE */
311 		snprintf(buf, MAXKEYLEN, "%s", _(txt_space));
312 	else
313 		strcpy(buf, "???");	/* Never happens? */
314 
315 	return buf;
316 }
317 
318 
319 #define KEYSEPS		" \t\n"
320 /*
321  * read the keymap file
322  * returns TRUE if the keymap file was read without an error else FALSE
323  */
324 t_bool
read_keymap_file(void)325 read_keymap_file(
326 	void)
327 {
328 	FILE *fp = (FILE *) 0;
329 	char *line, *keydef, *kname;
330 	char *map, *ptr;
331 	char buf[LEN], buff[NAME_LEN + 1], filename[PATH_LEN];
332 	struct t_version *upgrade = NULL;
333 	t_bool ret = TRUE;
334 
335 	/*
336 	 * checks TIN_HOMEDIR/HOME/TIN_DEFAULTS_DIR
337 	 * for KEYMAP_FILE."locale" or KEYMAP_FILE
338 	 *
339 	 * locale is first match from LC_ALL, LC_CTYPE, LC_MESSAGES, LANG
340 	 *
341 	 * TODO: LC_CTYPE has higher priority than LC_MESSAGES, does this make sense?
342 	 */
343 	/* get locale suffix */
344 	map = my_strdup(get_val("LC_ALL", get_val("LC_CTYPE", get_val("LC_MESSAGES", get_val("LANG", "")))));
345 	if (strlen(map)) {
346 		if ((ptr = strchr(map, '.')))
347 			*ptr = '\0';
348 		snprintf(buff, sizeof(buff), "%s.%s", KEYMAP_FILE, map);
349 		joinpath(filename, sizeof(filename), rcdir, buff);
350 		fp = fopen(filename, "r");
351 	}
352 	if (!fp) {
353 		joinpath(filename, sizeof(filename), rcdir, KEYMAP_FILE);
354 		fp = fopen(filename, "r");
355 	}
356 #ifdef TIN_DEFAULTS_DIR
357 	if (strlen(map) && !fp) {
358 		joinpath(filename, sizeof(filename), TIN_DEFAULTS_DIR, buff);
359 		fp = fopen(filename, "r");
360 	}
361 	if (!fp) {
362 		joinpath(filename, sizeof(filename), TIN_DEFAULTS_DIR, KEYMAP_FILE);
363 		fp = fopen(filename, "r");
364 	}
365 #endif /* TIN_DEFAULTS_DIR */
366 
367 	FreeIfNeeded(map);
368 
369 	if (!fp)
370 		return TRUE; /* no keymap file is not an error */
371 
372 	map = my_strdup(filename); /* remember keymap-name */
373 
374 	/* check if keymap file is up-to-date */
375 	while ((line = fgets(buf, sizeof(buf), fp)) != NULL) {
376 		if (line[0] == '#') {
377 			if (upgrade == NULL && match_string(buf, "# Keymap file V", NULL, 0)) {
378 				/* TODO: keymap downgrade */
379 				upgrade = check_upgrade(line, "# Keymap file V", KEYMAP_VERSION);
380 				if (upgrade->state == RC_UPGRADE) {
381 					fclose(fp);
382 					upgrade_keymap_file(map);
383 					upgrade->state = RC_IGNORE;
384 					if (!(fp = fopen(map, "r"))) { /* TODO: issue error message? */
385 						free(map);
386 						FreeAndNull(upgrade);
387 						return TRUE;
388 					}
389 				}
390 				break;
391 			}
392 		}
393 	}
394 	rewind(fp);
395 
396 	free_keymaps();
397 	while ((line = fgets(buf, sizeof(buf), fp)) != NULL) {
398 		/*
399 		 * Ignore blank and comment lines
400 		 */
401 		if (line[0] == '#' || line[0] == '\n')
402 			continue;
403 
404 		if ((kname = strsep(&line, KEYSEPS)) != NULL) {
405 			keydef = str_trim(line);
406 			/*
407 			 * Warn about basic syntax errors
408 			 */
409 			if (keydef == NULL || !strlen(keydef)) {
410 				error_message(0, _(txt_keymap_missing_key), kname);
411 				ret = FALSE;
412 				continue;
413 			}
414 		} else
415 			continue;
416 
417 		/*
418 		 * TODO: useful? shared keymaps (NFS-Home) may differ
419 		 * depending on the OS (i.e. one tin has color the other has not)
420 		 */
421 		if (!process_mapping(kname, keydef)) {
422 			error_message(0, _(txt_keymap_invalid_name), kname);
423 			prompt_continue();
424 			ret = FALSE;
425 			continue;
426 		}
427 
428 	}
429 	fclose(fp);
430 	setup_default_keys();
431 	if (upgrade && upgrade->state != RC_IGNORE)
432 		upgrade_prompt_quit(upgrade, map);
433 
434 	free(map);
435 	FreeAndNull(upgrade);
436 	return ret;
437 }
438 
439 
440 /*
441  * associate the keys with the internal function and add them to the keylist
442  * returns TRUE if all keys could be recognized else FALSE
443  */
444 static t_bool
process_keys(t_function func,const char * keys,struct keylist * kl)445 process_keys(
446 	t_function func,
447 	const char *keys,
448 	struct keylist *kl)
449 {
450 	char *keydef, *tmp;
451 	t_bool error, ret = TRUE;
452 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
453 	wchar_t *wkeydef;
454 	wchar_t key = '\0';
455 #else
456 	char key = '\0';
457 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
458 
459 	tmp = my_strdup(keys);		/* don't change "keys" */
460 	keydef = strtok(tmp, KEYSEPS);
461 
462 	while (keydef != NULL) {
463 		error = FALSE;
464 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
465 		if ((wkeydef = char2wchar_t(keydef)) == NULL) {
466 			error_message(1, _(txt_invalid_multibyte_sequence));
467 			ret = FALSE;
468 
469 			keydef = strtok(NULL, KEYSEPS);
470 			continue;
471 		}
472 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
473 
474 		/*
475 		 * Parse the key sequence into 'key'
476 		 * Special sequences are:
477 		 * ^A -> control chars
478 		 * TAB -> ^I
479 		 * SPACE -> ' '
480 		 */
481 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
482 		if (wcslen(wkeydef) > 1) {
483 			switch (wkeydef[0])	/* Only test 1st char - crude but effective */
484 #else
485 		if (strlen(keydef) > 1) {
486 			switch (keydef[0])	/* Only test 1st char - crude but effective */
487 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
488 			{
489 				case 'N':
490 					key = '\0';
491 					break;
492 
493 				case 'S':
494 					key = ' ';
495 					break;
496 
497 				case 'T':
498 					key = ctrl('I');
499 					break;
500 
501 				case '^':
502 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
503 					/* allow only ^A to ^Z */
504 					if (wkeydef[1] >= 'A' && wkeydef[1] <= 'Z') {
505 						key = ctrl(wkeydef[1]);
506 						break;
507 					}
508 #else
509 					if (isupper((int)(unsigned char) keydef[1])) {
510 						key = ctrl(keydef[1]);
511 						break;
512 					}
513 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
514 					/* FALLTHROUGH */
515 				default:
516 					error_message(0, _(txt_keymap_invalid_key), keydef);
517 					ret = FALSE;
518 					error = TRUE;
519 					break;
520 			}
521 		} else {
522 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
523 			if (iswdigit(key = wkeydef[0]))
524 #else
525 			if (isdigit(key = keydef[0]))
526 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
527 			{
528 				error_message(0, _(txt_keymap_invalid_key), keydef);
529 				ret = FALSE;
530 				error = TRUE;
531 			}
532 		}
533 
534 		if (!error)
535 			add_key(kl, key, func, TRUE);
536 
537 		keydef = strtok(NULL, KEYSEPS);
538 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
539 		FreeIfNeeded(wkeydef);
540 #endif /* MULTIBYTE_ABLE && !NO_LOCALE */
541 	}
542 	free(tmp);
543 
544 	return ret;
545 }
546 
547 
548 /*
549  * map a keyname to the internal function name and assign the keys
550  * returns TRUE if a mapping was found else FALSE
551  */
552 static t_bool
553 process_mapping(
554 	char *keyname,				/* Keyname we're searching for */
555 	char *keys)				/* Key to assign to keyname if found */
556 {
557 	switch (keyname[0]) {
558 		case 'A':
559 			if (strcmp(keyname, "AttachPipe") == 0) {
560 				process_keys(ATTACHMENT_PIPE, keys, &attachment_keys);
561 
562 				return TRUE;
563 			}
564 			if (strcmp(keyname, "AttachSelect") == 0) {
565 				process_keys(ATTACHMENT_SELECT, keys, &attachment_keys);
566 
567 				return TRUE;
568 			}
569 			if (strcmp(keyname, "AttachSave") == 0) {
570 				process_keys(ATTACHMENT_SAVE, keys, &attachment_keys);
571 
572 				return TRUE;
573 			}
574 			if (strcmp(keyname, "AttachTag") == 0) {
575 				process_keys(ATTACHMENT_TAG, keys, &attachment_keys);
576 
577 				return TRUE;
578 			}
579 			if (strcmp(keyname, "AttachTagPattern") == 0) {
580 				process_keys(ATTACHMENT_TAG_PATTERN, keys, &attachment_keys);
581 
582 				return TRUE;
583 			}
584 			if (strcmp(keyname, "AttachToggleTagged") == 0) {
585 				process_keys(ATTACHMENT_TOGGLE_TAGGED, keys, &attachment_keys);
586 
587 				return TRUE;
588 			}
589 			if (strcmp(keyname, "AttachUntag") == 0) {
590 				process_keys(ATTACHMENT_UNTAG, keys, &attachment_keys);
591 
592 				return TRUE;
593 			}
594 			break;
595 
596 		case 'B':
597 			if (strcmp(keyname, "BugReport") == 0) {
598 				process_keys(GLOBAL_BUGREPORT, keys, &attachment_keys);
599 				process_keys(GLOBAL_BUGREPORT, keys, &group_keys);
600 				process_keys(GLOBAL_BUGREPORT, keys, &option_menu_keys);
601 				process_keys(GLOBAL_BUGREPORT, keys, &select_keys);
602 				process_keys(GLOBAL_BUGREPORT, keys, &thread_keys);
603 
604 				return TRUE;
605 			}
606 			break;
607 
608 		case 'C':
609 			if (strcmp(keyname, "Catchup") == 0) {
610 				process_keys(CATCHUP, keys, &group_keys);
611 				process_keys(CATCHUP, keys, &page_keys);
612 				process_keys(CATCHUP, keys, &select_keys);
613 				process_keys(CATCHUP, keys, &thread_keys);
614 
615 				return TRUE;
616 			}
617 			if (strcmp(keyname, "CatchupNextUnread") == 0) {
618 				process_keys(CATCHUP_NEXT_UNREAD, keys, &group_keys);
619 				process_keys(CATCHUP_NEXT_UNREAD, keys, &page_keys);
620 				process_keys(CATCHUP_NEXT_UNREAD, keys, &select_keys);
621 				process_keys(CATCHUP_NEXT_UNREAD, keys, &thread_keys);
622 
623 				return TRUE;
624 			}
625 			if (strcmp(keyname, "ConfigFirstPage") == 0) {
626 				process_keys(GLOBAL_FIRST_PAGE, keys, &option_menu_keys);
627 
628 				return TRUE;
629 			}
630 			if (strcmp(keyname, "ConfigLastPage") == 0) {
631 				process_keys(GLOBAL_LAST_PAGE, keys, &option_menu_keys);
632 
633 				return TRUE;
634 			}
635 			if (strcmp(keyname, "ConfigNoSave") == 0) {
636 				process_keys(CONFIG_NO_SAVE, keys, &option_menu_keys);
637 
638 				return TRUE;
639 			}
640 			if (strcmp(keyname, "ConfigResetAttrib") == 0) {
641 				process_keys(CONFIG_RESET_ATTRIB, keys, &option_menu_keys);
642 
643 				return TRUE;
644 			}
645 			if (strcmp(keyname, "ConfigScopeMenu") == 0) {
646 				process_keys(CONFIG_SCOPE_MENU, keys, &option_menu_keys);
647 
648 				return TRUE;
649 			}
650 			if (strcmp(keyname, "ConfigSelect") == 0) {
651 				process_keys(CONFIG_SELECT, keys, &option_menu_keys);
652 
653 				return TRUE;
654 			}
655 			if (strcmp(keyname, "ConfigToggleAttrib") == 0) {
656 				process_keys(CONFIG_TOGGLE_ATTRIB, keys, &option_menu_keys);
657 
658 				return TRUE;
659 			}
660 			break;
661 
662 		case 'D':
663 			if (strcmp(keyname, "DisplayPostHist") == 0) {
664 				process_keys(GLOBAL_DISPLAY_POST_HISTORY, keys, &group_keys);
665 				process_keys(GLOBAL_DISPLAY_POST_HISTORY, keys, &page_keys);
666 				process_keys(GLOBAL_DISPLAY_POST_HISTORY, keys, &select_keys);
667 				process_keys(GLOBAL_DISPLAY_POST_HISTORY, keys, &thread_keys);
668 
669 				return TRUE;
670 			}
671 			if (strcmp(keyname, "Down") == 0) {
672 				process_keys(GLOBAL_LINE_DOWN, keys, &attachment_keys);
673 				process_keys(GLOBAL_LINE_DOWN, keys, &group_keys);
674 				process_keys(GLOBAL_LINE_DOWN, keys, &info_keys);
675 				process_keys(GLOBAL_LINE_DOWN, keys, &option_menu_keys);
676 				process_keys(GLOBAL_LINE_DOWN, keys, &page_keys);
677 				process_keys(GLOBAL_LINE_DOWN, keys, &scope_keys);
678 				process_keys(GLOBAL_LINE_DOWN, keys, &select_keys);
679 				process_keys(GLOBAL_LINE_DOWN, keys, &thread_keys);
680 				process_keys(GLOBAL_LINE_DOWN, keys, &url_keys);
681 
682 				return TRUE;
683 			}
684 			break;
685 
686 		case 'E':
687 			if (strcmp(keyname, "EditFilter") == 0) {
688 				process_keys(GLOBAL_EDIT_FILTER, keys, &group_keys);
689 				process_keys(GLOBAL_EDIT_FILTER, keys, &page_keys);
690 				process_keys(GLOBAL_EDIT_FILTER, keys, &select_keys);
691 				process_keys(GLOBAL_EDIT_FILTER, keys, &thread_keys);
692 
693 				return TRUE;
694 			}
695 			break;
696 
697 		case 'F':
698 			if (strcmp(keyname, "FeedArt") == 0) {
699 				process_keys(FEED_ARTICLE, keys, &feed_type_keys);
700 
701 				return TRUE;
702 			}
703 			if (strcmp(keyname, "FeedHot") == 0) {
704 				process_keys(FEED_HOT, keys, &feed_type_keys);
705 
706 				return TRUE;
707 			}
708 			if (strcmp(keyname, "FeedPat") == 0) {
709 				process_keys(FEED_PATTERN, keys, &feed_type_keys);
710 
711 				return TRUE;
712 			}
713 			if (strcmp(keyname, "FeedRange") == 0) {
714 				process_keys(FEED_RANGE, keys, &feed_type_keys);
715 
716 				return TRUE;
717 			}
718 			if (strcmp(keyname, "FeedRepost") == 0) {
719 				process_keys(FEED_KEY_REPOST, keys, &feed_supersede_article_keys);
720 
721 				return TRUE;
722 			}
723 			if (strcmp(keyname, "FeedSupersede") == 0) {
724 				process_keys(FEED_SUPERSEDE, keys, &feed_supersede_article_keys);
725 
726 				return TRUE;
727 			}
728 			if (strcmp(keyname, "FeedTag") == 0) {
729 				process_keys(FEED_TAGGED, keys, &feed_type_keys);
730 
731 				return TRUE;
732 			}
733 			if (strcmp(keyname, "FeedThd") == 0) {
734 				process_keys(FEED_THREAD, keys, &feed_type_keys);
735 
736 				return TRUE;
737 			}
738 			if (strcmp(keyname, "FilterEdit") == 0) {
739 				process_keys(FILTER_EDIT, keys, &filter_keys);
740 
741 				return TRUE;
742 			}
743 			if (strcmp(keyname, "FilterSave") == 0) {
744 				process_keys(FILTER_SAVE, keys, &filter_keys);
745 
746 				return TRUE;
747 			}
748 			if (strcmp(keyname, "FirstPage") == 0) {
749 				process_keys(GLOBAL_FIRST_PAGE, keys, &attachment_keys);
750 				process_keys(GLOBAL_FIRST_PAGE, keys, &group_keys);
751 				process_keys(GLOBAL_FIRST_PAGE, keys, &info_keys);
752 				process_keys(GLOBAL_FIRST_PAGE, keys, &option_menu_keys);
753 				process_keys(GLOBAL_FIRST_PAGE, keys, &page_keys);
754 				process_keys(GLOBAL_FIRST_PAGE, keys, &scope_keys);
755 				process_keys(GLOBAL_FIRST_PAGE, keys, &select_keys);
756 				process_keys(GLOBAL_FIRST_PAGE, keys, &thread_keys);
757 				process_keys(GLOBAL_FIRST_PAGE, keys, &url_keys);
758 
759 				return TRUE;
760 			}
761 			break;
762 
763 		case 'G':
764 			if (strcmp(keyname, "GroupAutoSave") == 0) {
765 				process_keys(GROUP_AUTOSAVE, keys, &group_keys);
766 
767 				return TRUE;
768 			}
769 			if (strcmp(keyname, "GroupCancel") == 0) {
770 				process_keys(GROUP_CANCEL, keys, &group_keys);
771 
772 				return TRUE;
773 			}
774 			if (strcmp(keyname, "GroupDoAutoSel") == 0) {
775 				process_keys(GROUP_DO_AUTOSELECT, keys, &group_keys);
776 
777 				return TRUE;
778 			}
779 			if (strcmp(keyname, "GroupGoto") == 0) {
780 				process_keys(GROUP_GOTO, keys, &group_keys);
781 
782 				return TRUE;
783 			}
784 			if (strcmp(keyname, "GroupListThd") == 0) {
785 				process_keys(GROUP_LIST_THREAD, keys, &group_keys);
786 
787 				return TRUE;
788 			}
789 			if (strcmp(keyname, "GroupMail") == 0) {
790 				process_keys(GROUP_MAIL, keys, &group_keys);
791 
792 				return TRUE;
793 			}
794 			if (strcmp(keyname, "GroupMarkThdRead") == 0) {
795 				process_keys(GROUP_MARK_THREAD_READ, keys, &group_keys);
796 
797 				return TRUE;
798 			}
799 			if (strcmp(keyname, "GroupMarkUnselArtRead") == 0) {
800 				process_keys(GROUP_MARK_UNSELECTED_ARTICLES_READ, keys, &group_keys);
801 
802 				return TRUE;
803 			}
804 			if (strcmp(keyname, "GroupNextGroup") == 0) {
805 				process_keys(GROUP_NEXT_GROUP, keys, &group_keys);
806 
807 				return TRUE;
808 			}
809 			if (strcmp(keyname, "GroupNextUnreadArt") == 0) {
810 				process_keys(GROUP_NEXT_UNREAD_ARTICLE, keys, &group_keys);
811 
812 				return TRUE;
813 			}
814 			if (strcmp(keyname, "GroupNextUnreadArtOrGrp") == 0) {
815 				process_keys(GROUP_NEXT_UNREAD_ARTICLE_OR_GROUP, keys, &group_keys);
816 
817 				return TRUE;
818 			}
819 			if (strcmp(keyname, "GroupPrevGroup") == 0) {
820 				process_keys(GROUP_PREVIOUS_GROUP, keys, &group_keys);
821 
822 				return TRUE;
823 			}
824 			if (strcmp(keyname, "GroupPrevUnreadArt") == 0) {
825 				process_keys(GROUP_PREVIOUS_UNREAD_ARTICLE, keys, &group_keys);
826 
827 				return TRUE;
828 			}
829 			if (strcmp(keyname, "GroupReadBasenote") == 0) {
830 				process_keys(GROUP_READ_BASENOTE, keys, &group_keys);
831 
832 				return TRUE;
833 			}
834 			if (strcmp(keyname, "GroupRepost") == 0) {
835 				process_keys(GROUP_REPOST, keys, &group_keys);
836 
837 				return TRUE;
838 			}
839 			if (strcmp(keyname, "GroupReverseSel") == 0) {
840 				process_keys(GROUP_REVERSE_SELECTIONS, keys, &group_keys);
841 
842 				return TRUE;
843 			}
844 			if (strcmp(keyname, "GroupSave") == 0) {
845 				process_keys(GROUP_SAVE, keys, &group_keys);
846 
847 				return TRUE;
848 			}
849 			if (strcmp(keyname, "GroupSelPattern") == 0) {
850 				process_keys(GROUP_SELECT_PATTERN, keys, &group_keys);
851 
852 				return TRUE;
853 			}
854 			if (strcmp(keyname, "GroupSelThd") == 0) {
855 				process_keys(GROUP_SELECT_THREAD, keys, &group_keys);
856 
857 				return TRUE;
858 			}
859 			if (strcmp(keyname, "GroupSelThdIfUnreadSelected") == 0) {
860 				process_keys(GROUP_SELECT_THREAD_IF_UNREAD_SELECTED, keys, &group_keys);
861 
862 				return TRUE;
863 			}
864 			if (strcmp(keyname, "GroupTag") == 0) {
865 				process_keys(GROUP_TAG, keys, &group_keys);
866 
867 				return TRUE;
868 			}
869 			if (strcmp(keyname, "GroupTagParts") == 0) {
870 				process_keys(GROUP_TAG_PARTS, keys, &group_keys);
871 
872 				return TRUE;
873 			}
874 			if (strcmp(keyname, "GroupToggleGetartLimit") == 0) {
875 				process_keys(GROUP_TOGGLE_GET_ARTICLES_LIMIT, keys, &group_keys);
876 
877 				return TRUE;
878 			}
879 			if (strcmp(keyname, "GroupToggleReadUnread") == 0) {
880 				process_keys(GROUP_TOGGLE_READ_UNREAD, keys, &group_keys);
881 
882 				return TRUE;
883 			}
884 			if (strcmp(keyname, "GroupToggleSubjDisplay") == 0) {
885 				process_keys(GROUP_TOGGLE_SUBJECT_DISPLAY, keys, &group_keys);
886 
887 				return TRUE;
888 			}
889 			if (strcmp(keyname, "GroupToggleThdSel") == 0) {
890 				process_keys(GROUP_TOGGLE_SELECT_THREAD, keys, &group_keys);
891 
892 				return TRUE;
893 			}
894 			if (strcmp(keyname, "GroupToggleThreading") == 0) {
895 				process_keys(GROUP_TOGGLE_THREADING, keys, &group_keys);
896 
897 				return TRUE;
898 			}
899 			if (strcmp(keyname, "GroupUndoSel") == 0) {
900 				process_keys(GROUP_UNDO_SELECTIONS, keys, &group_keys);
901 
902 				return TRUE;
903 			}
904 			if (strcmp(keyname, "GroupUntag") == 0) {
905 				process_keys(GROUP_UNTAG, keys, &group_keys);
906 
907 				return TRUE;
908 			}
909 			break;
910 
911 		case 'H':
912 			if (strcmp(keyname, "Help") == 0) {
913 				process_keys(GLOBAL_HELP, keys, &attachment_keys);
914 				process_keys(GLOBAL_HELP, keys, &group_keys);
915 				process_keys(GLOBAL_HELP, keys, &option_menu_keys);
916 				process_keys(GLOBAL_HELP, keys, &page_keys);
917 				process_keys(GLOBAL_HELP, keys, &scope_keys);
918 				process_keys(GLOBAL_HELP, keys, &select_keys);
919 				process_keys(GLOBAL_HELP, keys, &thread_keys);
920 				process_keys(GLOBAL_HELP, keys, &url_keys);
921 
922 				return TRUE;
923 			}
924 			if (strcmp(keyname, "HelpFirstPage") == 0) {
925 				process_keys(GLOBAL_FIRST_PAGE, keys, &info_keys);
926 
927 				return TRUE;
928 			}
929 			if (strcmp(keyname, "HelpLastPage") == 0) {
930 				process_keys(GLOBAL_LAST_PAGE, keys, &info_keys);
931 
932 				return TRUE;
933 			}
934 			break;
935 
936 		case 'L':
937 			if (strcmp(keyname, "LastPage") == 0) {
938 				process_keys(GLOBAL_LAST_PAGE, keys, &attachment_keys);
939 				process_keys(GLOBAL_LAST_PAGE, keys, &group_keys);
940 				process_keys(GLOBAL_LAST_PAGE, keys, &info_keys);
941 				process_keys(GLOBAL_LAST_PAGE, keys, &option_menu_keys);
942 				process_keys(GLOBAL_LAST_PAGE, keys, &page_keys);
943 				process_keys(GLOBAL_LAST_PAGE, keys, &scope_keys);
944 				process_keys(GLOBAL_LAST_PAGE, keys, &select_keys);
945 				process_keys(GLOBAL_LAST_PAGE, keys, &thread_keys);
946 				process_keys(GLOBAL_LAST_PAGE, keys, &url_keys);
947 
948 				return TRUE;
949 			}
950 			if (strcmp(keyname, "LastViewed") == 0) {
951 				process_keys(GLOBAL_LAST_VIEWED, keys, &group_keys);
952 				process_keys(GLOBAL_LAST_VIEWED, keys, &page_keys);
953 				process_keys(GLOBAL_LAST_VIEWED, keys, &thread_keys);
954 
955 				return TRUE;
956 			}
957 			if (strcmp(keyname, "LookupMessage") == 0) {
958 				process_keys(GLOBAL_LOOKUP_MESSAGEID, keys, &group_keys);
959 				process_keys(GLOBAL_LOOKUP_MESSAGEID, keys, &page_keys);
960 #ifdef NNTP_ABLE
961 				process_keys(GLOBAL_LOOKUP_MESSAGEID, keys, &select_keys);
962 #endif /* NNTP_ABLE */
963 				process_keys(GLOBAL_LOOKUP_MESSAGEID, keys, &thread_keys);
964 
965 				return TRUE;
966 			}
967 			break;
968 
969 		case 'M':
970 			if (strcmp(keyname, "MarkArticleUnread") == 0) {
971 				process_keys(MARK_ARTICLE_UNREAD, keys, &group_keys);
972 				process_keys(MARK_ARTICLE_UNREAD, keys, &page_keys);
973 				process_keys(MARK_ARTICLE_UNREAD, keys, &thread_keys);
974 
975 				return TRUE;
976 			}
977 			if (strcmp(keyname, "MarkThreadUnread") == 0) {
978 				process_keys(MARK_THREAD_UNREAD, keys, &group_keys);
979 				process_keys(MARK_THREAD_UNREAD, keys, &page_keys);
980 				process_keys(MARK_THREAD_UNREAD, keys, &thread_keys);
981 
982 				return TRUE;
983 			}
984 			if (strcmp(keyname, "MarkFeedRead") == 0) {
985 				process_keys(MARK_FEED_READ, keys, &group_keys);
986 				process_keys(MARK_FEED_READ, keys, &thread_keys);
987 
988 				return TRUE;
989 			}
990 			if (strcmp(keyname, "MarkFeedUnread") == 0) {
991 				process_keys(MARK_FEED_UNREAD, keys, &group_keys);
992 				process_keys(MARK_FEED_UNREAD, keys, &thread_keys);
993 
994 				return TRUE;
995 			}
996 			if (strcmp(keyname, "MenuFilterKill") == 0) {
997 				process_keys(GLOBAL_MENU_FILTER_KILL, keys, &group_keys);
998 				process_keys(GLOBAL_MENU_FILTER_KILL, keys, &page_keys);
999 				process_keys(GLOBAL_MENU_FILTER_KILL, keys, &thread_keys);
1000 
1001 				return TRUE;
1002 			}
1003 			if (strcmp(keyname, "MenuFilterSelect") == 0) {
1004 				process_keys(GLOBAL_MENU_FILTER_SELECT, keys, &group_keys);
1005 				process_keys(GLOBAL_MENU_FILTER_SELECT, keys, &page_keys);
1006 				process_keys(GLOBAL_MENU_FILTER_SELECT, keys, &thread_keys);
1007 
1008 				return TRUE;
1009 			}
1010 			break;
1011 
1012 		case 'O':
1013 			if (strcmp(keyname, "OptionMenu") == 0) {
1014 				process_keys(GLOBAL_OPTION_MENU, keys, &group_keys);
1015 				process_keys(GLOBAL_OPTION_MENU, keys, &page_keys);
1016 				process_keys(GLOBAL_OPTION_MENU, keys, &post_edit_ext_keys);
1017 				process_keys(GLOBAL_OPTION_MENU, keys, &post_post_keys);
1018 				process_keys(GLOBAL_OPTION_MENU, keys, &select_keys);
1019 				process_keys(GLOBAL_OPTION_MENU, keys, &thread_keys);
1020 
1021 				return TRUE;
1022 			}
1023 			break;
1024 
1025 		case 'P':
1026 			if (strcmp(keyname, "PageAutoSave") == 0) {
1027 				process_keys(PAGE_AUTOSAVE, keys, &page_keys);
1028 
1029 				return TRUE;
1030 			}
1031 			if (strcmp(keyname, "PageBotThd") == 0) {
1032 				process_keys(PAGE_BOTTOM_THREAD, keys, &page_keys);
1033 
1034 				return TRUE;
1035 			}
1036 			if (strcmp(keyname, "PageCancel") == 0) {
1037 				process_keys(PAGE_CANCEL, keys, &page_keys);
1038 
1039 				return TRUE;
1040 			}
1041 			if (strcmp(keyname, "PageDown") == 0) {
1042 				process_keys(GLOBAL_PAGE_DOWN, keys, &attachment_keys);
1043 				process_keys(GLOBAL_PAGE_DOWN, keys, &group_keys);
1044 				process_keys(GLOBAL_PAGE_DOWN, keys, &info_keys);
1045 				process_keys(GLOBAL_PAGE_DOWN, keys, &option_menu_keys);
1046 				process_keys(GLOBAL_PAGE_DOWN, keys, &page_keys);
1047 				process_keys(GLOBAL_PAGE_DOWN, keys, &scope_keys);
1048 				process_keys(GLOBAL_PAGE_DOWN, keys, &select_keys);
1049 				process_keys(GLOBAL_PAGE_DOWN, keys, &thread_keys);
1050 				process_keys(GLOBAL_PAGE_DOWN, keys, &url_keys);
1051 
1052 				return TRUE;
1053 			}
1054 			if (strcmp(keyname, "PageEditArticle") == 0) {
1055 				process_keys(PAGE_EDIT_ARTICLE, keys, &page_keys);
1056 
1057 				return TRUE;
1058 			}
1059 			if (strcmp(keyname, "PageFirstPage") == 0) {
1060 				process_keys(GLOBAL_FIRST_PAGE, keys, &page_keys);
1061 
1062 				return TRUE;
1063 			}
1064 			if (strcmp(keyname, "PageFollowup") == 0) {
1065 				process_keys(PAGE_FOLLOWUP, keys, &page_keys);
1066 
1067 				return TRUE;
1068 			}
1069 			if (strcmp(keyname, "PageFollowupQuote") == 0) {
1070 				process_keys(PAGE_FOLLOWUP_QUOTE, keys, &page_keys);
1071 
1072 				return TRUE;
1073 			}
1074 			if (strcmp(keyname, "PageFollowupQuoteHeaders") == 0) {
1075 				process_keys(PAGE_FOLLOWUP_QUOTE_HEADERS, keys, &page_keys);
1076 
1077 				return TRUE;
1078 			}
1079 			if (strcmp(keyname, "PageGotoParent") == 0) {
1080 				process_keys(PAGE_GOTO_PARENT, keys, &page_keys);
1081 
1082 				return TRUE;
1083 			}
1084 			if (strcmp(keyname, "PageGroupSel") == 0) {
1085 				process_keys(PAGE_GROUP_SELECT, keys, &page_keys);
1086 
1087 				return TRUE;
1088 			}
1089 			if (strcmp(keyname, "PageLastPage") == 0) {
1090 				process_keys(GLOBAL_LAST_PAGE, keys, &page_keys);
1091 
1092 				return TRUE;
1093 			}
1094 			if (strcmp(keyname, "PageListThd") == 0) {
1095 				process_keys(PAGE_LIST_THREAD, keys, &page_keys);
1096 
1097 				return TRUE;
1098 			}
1099 			if (strcmp(keyname, "PageKillThd") == 0) {
1100 				process_keys(PAGE_MARK_THREAD_READ, keys, &page_keys);
1101 
1102 				return TRUE;
1103 			}
1104 			if (strcmp(keyname, "PageMail") == 0) {
1105 				process_keys(PAGE_MAIL, keys, &page_keys);
1106 
1107 				return TRUE;
1108 			}
1109 			if (strcmp(keyname, "PageNextArt") == 0) {
1110 				process_keys(PAGE_NEXT_ARTICLE, keys, &page_keys);
1111 
1112 				return TRUE;
1113 			}
1114 			if (strcmp(keyname, "PageNextThd") == 0) {
1115 				process_keys(PAGE_NEXT_THREAD, keys, &page_keys);
1116 
1117 				return TRUE;
1118 			}
1119 			if (strcmp(keyname, "PageNextUnread") == 0) {
1120 				process_keys(PAGE_NEXT_UNREAD, keys, &page_keys);
1121 
1122 				return TRUE;
1123 			}
1124 			if (strcmp(keyname, "PageNextUnreadArt") == 0) {
1125 				process_keys(PAGE_NEXT_UNREAD_ARTICLE, keys, &page_keys);
1126 
1127 				return TRUE;
1128 			}
1129 			if (strcmp(keyname, "PagePGPCheckArticle") == 0) {
1130 #ifdef HAVE_PGP_GPG
1131 				process_keys(PAGE_PGP_CHECK_ARTICLE, keys, &page_keys);
1132 #endif /* HAVE_PGP_GPG */
1133 
1134 				return TRUE;
1135 			}
1136 			if (strcmp(keyname, "PagePrevArt") == 0) {
1137 				process_keys(PAGE_PREVIOUS_ARTICLE, keys, &page_keys);
1138 
1139 				return TRUE;
1140 			}
1141 			if (strcmp(keyname, "PagePrevUnreadArt") == 0) {
1142 				process_keys(PAGE_PREVIOUS_UNREAD_ARTICLE, keys, &page_keys);
1143 
1144 				return TRUE;
1145 			}
1146 			if (strcmp(keyname, "PageReply") == 0) {
1147 				process_keys(PAGE_REPLY, keys, &page_keys);
1148 
1149 				return TRUE;
1150 			}
1151 			if (strcmp(keyname, "PageReplyQuote") == 0) {
1152 				process_keys(PAGE_REPLY_QUOTE, keys, &page_keys);
1153 
1154 				return TRUE;
1155 			}
1156 			if (strcmp(keyname, "PageReplyQuoteHeaders") == 0) {
1157 				process_keys(PAGE_REPLY_QUOTE_HEADERS, keys, &page_keys);
1158 
1159 				return TRUE;
1160 			}
1161 			if (strcmp(keyname, "PageRepost") == 0) {
1162 				process_keys(PAGE_REPOST, keys, &page_keys);
1163 
1164 				return TRUE;
1165 			}
1166 			if (strcmp(keyname, "PageReveal") == 0) {
1167 				process_keys(PAGE_REVEAL, keys, &page_keys);
1168 
1169 				return TRUE;
1170 			}
1171 			if (strcmp(keyname, "PageSave") == 0) {
1172 				process_keys(PAGE_SAVE, keys, &page_keys);
1173 
1174 				return TRUE;
1175 			}
1176 			if (strcmp(keyname, "PageSkipIncludedText") == 0) {
1177 				process_keys(PAGE_SKIP_INCLUDED_TEXT, keys, &page_keys);
1178 
1179 				return TRUE;
1180 			}
1181 			if (strcmp(keyname, "PageTag") == 0) {
1182 				process_keys(PAGE_TAG, keys, &page_keys);
1183 
1184 				return TRUE;
1185 			}
1186 			if (strcmp(keyname, "PageTopThd") == 0) {
1187 				process_keys(PAGE_TOP_THREAD, keys, &page_keys);
1188 
1189 				return TRUE;
1190 			}
1191 			if (strcmp(keyname, "PageToggleAllHeaders") == 0) {
1192 				process_keys(PAGE_TOGGLE_HEADERS, keys, &page_keys);
1193 
1194 				return TRUE;
1195 			}
1196 			if (strcmp(keyname, "PageToggleHighlight") == 0) {
1197 				process_keys(PAGE_TOGGLE_HIGHLIGHTING, keys, &page_keys);
1198 
1199 				return TRUE;
1200 			}
1201 			if (strcmp(keyname, "PageToggleRaw") == 0) {
1202 				process_keys(PAGE_TOGGLE_RAW, keys, &page_keys);
1203 
1204 				return TRUE;
1205 			}
1206 			if (strcmp(keyname, "PageToggleRot") == 0) {
1207 				process_keys(PAGE_TOGGLE_ROT13, keys, &page_keys);
1208 
1209 				return TRUE;
1210 			}
1211 			if (strcmp(keyname, "PageToggleTabs") == 0) {
1212 				process_keys(PAGE_TOGGLE_TABS, keys, &page_keys);
1213 
1214 				return TRUE;
1215 			}
1216 			if (strcmp(keyname, "PageToggleTex2iso") == 0) {
1217 				process_keys(PAGE_TOGGLE_TEX2ISO, keys, &page_keys);
1218 
1219 				return TRUE;
1220 			}
1221 			if (strcmp(keyname, "PageToggleUue") == 0) {
1222 				process_keys(PAGE_TOGGLE_UUE, keys, &page_keys);
1223 
1224 				return TRUE;
1225 			}
1226 			if (strcmp(keyname, "PageUp") == 0) {
1227 				process_keys(GLOBAL_PAGE_UP, keys, &attachment_keys);
1228 				process_keys(GLOBAL_PAGE_UP, keys, &group_keys);
1229 				process_keys(GLOBAL_PAGE_UP, keys, &info_keys);
1230 				process_keys(GLOBAL_PAGE_UP, keys, &option_menu_keys);
1231 				process_keys(GLOBAL_PAGE_UP, keys, &page_keys);
1232 				process_keys(GLOBAL_PAGE_UP, keys, &scope_keys);
1233 				process_keys(GLOBAL_PAGE_UP, keys, &select_keys);
1234 				process_keys(GLOBAL_PAGE_UP, keys, &thread_keys);
1235 				process_keys(GLOBAL_PAGE_UP, keys, &url_keys);
1236 
1237 				return TRUE;
1238 			}
1239 			if (strcmp(keyname, "PageViewAttach") == 0) {
1240 				process_keys(PAGE_VIEW_ATTACHMENTS, keys, &page_keys);
1241 
1242 				return TRUE;
1243 			}
1244 			if (strcmp(keyname, "PageViewUrl") == 0) {
1245 				process_keys(PAGE_VIEW_URL, keys, &page_keys);
1246 
1247 				return TRUE;
1248 			}
1249 			if (strcmp(keyname, "PgpEncrypt") == 0) {
1250 #ifdef HAVE_PGP_GPG
1251 				process_keys(PGP_KEY_ENCRYPT, keys, &pgp_mail_keys);
1252 #endif /* HAVE_PGP_GPG */
1253 
1254 				return TRUE;
1255 			}
1256 			if (strcmp(keyname, "PgpEncSign") == 0) {
1257 #ifdef HAVE_PGP_GPG
1258 				process_keys(PGP_KEY_ENCRYPT_SIGN, keys, &pgp_mail_keys);
1259 #endif /* HAVE_PGP_GPG */
1260 
1261 				return TRUE;
1262 			}
1263 			if (strcmp(keyname, "PgpIncludekey") == 0) {
1264 #ifdef HAVE_PGP_GPG
1265 				process_keys(PGP_INCLUDE_KEY, keys, &pgp_news_keys);
1266 #endif /* HAVE_PGP_GPG */
1267 
1268 				return TRUE;
1269 			}
1270 			if (strcmp(keyname, "PgpSign") == 0) {
1271 #ifdef HAVE_PGP_GPG
1272 				process_keys(PGP_KEY_SIGN, keys, &pgp_news_keys);
1273 				process_keys(PGP_KEY_SIGN, keys, &pgp_mail_keys);
1274 #endif /* HAVE_PGP_GPG */
1275 
1276 				return TRUE;
1277 			}
1278 			if (strcmp(keyname, "Pipe") == 0) {
1279 				process_keys(GLOBAL_PIPE, keys, &attachment_keys);
1280 				process_keys(GLOBAL_PIPE, keys, &group_keys);
1281 				process_keys(GLOBAL_PIPE, keys, &page_keys);
1282 				process_keys(GLOBAL_PIPE, keys, &thread_keys);
1283 
1284 				return TRUE;
1285 			}
1286 			if (strcmp(keyname, "Post") == 0) {
1287 				process_keys(GLOBAL_POST, keys, &group_keys);
1288 				process_keys(GLOBAL_POST, keys, &page_keys);
1289 				process_keys(GLOBAL_POST, keys, &post_ignore_fupto_keys);
1290 				process_keys(GLOBAL_POST, keys, &post_mail_fup_keys);
1291 				process_keys(GLOBAL_POST, keys, &post_post_keys);
1292 				process_keys(GLOBAL_POST, keys, &select_keys);
1293 				process_keys(GLOBAL_POST, keys, &thread_keys);
1294 
1295 				return TRUE;
1296 			}
1297 			if (strcmp(keyname, "PostAbort") == 0) {
1298 				process_keys(POST_ABORT, keys, &post_continue_keys);
1299 
1300 				return TRUE;
1301 			}
1302 			if (strcmp(keyname, "PostCancel") == 0) {
1303 				process_keys(POST_CANCEL, keys, &post_cancel_keys);
1304 				process_keys(POST_CANCEL, keys, &post_delete_keys);
1305 
1306 				return TRUE;
1307 			}
1308 			if (strcmp(keyname, "PostContinue") == 0) {
1309 				process_keys(POST_CONTINUE, keys, &post_continue_keys);
1310 
1311 				return TRUE;
1312 			}
1313 			if (strcmp(keyname, "PostEdit") == 0) {
1314 				process_keys(POST_EDIT, keys, &post_cancel_keys);
1315 				process_keys(POST_EDIT, keys, &post_edit_keys);
1316 				process_keys(POST_EDIT, keys, &post_edit_ext_keys);
1317 				process_keys(POST_EDIT, keys, &post_post_keys);
1318 				process_keys(POST_EDIT, keys, &post_send_keys);
1319 
1320 				return TRUE;
1321 			}
1322 			if (strcmp(keyname, "PostIgnore") == 0) {
1323 				process_keys(POST_IGNORE_FUPTO, keys, &post_ignore_fupto_keys);
1324 
1325 				return TRUE;
1326 			}
1327 			if (strcmp(keyname, "PostIspell") == 0) {
1328 #ifdef HAVE_ISPELL
1329 				process_keys(POST_ISPELL, keys, &post_post_keys);
1330 				process_keys(POST_ISPELL, keys, &post_send_keys);
1331 #endif /* HAVE_ISPELL */
1332 
1333 				return TRUE;
1334 			}
1335 			if (strcmp(keyname, "PostMail") == 0) {
1336 				process_keys(POST_MAIL, keys, &post_mail_fup_keys);
1337 
1338 				return TRUE;
1339 			}
1340 			if (strcmp(keyname, "PostPGP") == 0) {
1341 #ifdef HAVE_PGP_GPG
1342 				process_keys(POST_PGP, keys, &post_post_keys);
1343 				process_keys(POST_PGP, keys, &post_send_keys);
1344 #endif /* HAVE_PGP_GPG */
1345 
1346 				return TRUE;
1347 			}
1348 			if (strcmp(keyname, "PostponeAll") == 0) {
1349 				process_keys(POSTPONE_ALL, keys, &post_postpone_keys);
1350 
1351 				return TRUE;
1352 			}
1353 			if (strcmp(keyname, "Postponed") == 0) {
1354 				process_keys(GLOBAL_POSTPONED, keys, &group_keys);
1355 				process_keys(GLOBAL_POSTPONED, keys, &page_keys);
1356 				process_keys(GLOBAL_POSTPONED, keys, &select_keys);
1357 				process_keys(GLOBAL_POSTPONED, keys, &thread_keys);
1358 
1359 				return TRUE;
1360 			}
1361 			if (strcmp(keyname, "PostponeOverride") == 0) {
1362 				process_keys(POSTPONE_OVERRIDE, keys, &post_postpone_keys);
1363 
1364 				return TRUE;
1365 			}
1366 			if (strcmp(keyname, "PostPost") == 0) {
1367 				process_keys(GLOBAL_POST, keys, &post_ignore_fupto_keys);
1368 				process_keys(GLOBAL_POST, keys, &post_mail_fup_keys);
1369 				process_keys(GLOBAL_POST, keys, &post_post_keys);
1370 
1371 				return TRUE;
1372 			}
1373 			if (strcmp(keyname, "PostPostpone") == 0) {
1374 				process_keys(POST_POSTPONE, keys, &post_edit_keys);
1375 				process_keys(POST_POSTPONE, keys, &post_post_keys);
1376 
1377 				return TRUE;
1378 			}
1379 			if (strcmp(keyname, "PostSend") == 0) {
1380 				process_keys(POST_SEND, keys, &post_send_keys);
1381 
1382 				return TRUE;
1383 			}
1384 			if (strcmp(keyname, "PostSupersede") == 0) {
1385 				process_keys(POST_SUPERSEDE, keys, &post_delete_keys);
1386 
1387 				return TRUE;
1388 			}
1389 			if (strcmp(keyname, "PProcNo") == 0) {
1390 				process_keys(POSTPROCESS_NO, keys, &feed_post_process_keys);
1391 
1392 				return TRUE;
1393 			}
1394 			if (strcmp(keyname, "PProcShar") == 0) {
1395 				process_keys(POSTPROCESS_SHAR, keys, &feed_post_process_keys);
1396 
1397 				return TRUE;
1398 			}
1399 			if (strcmp(keyname, "PProcYes") == 0) {
1400 				process_keys(POSTPROCESS_YES, keys, &feed_post_process_keys);
1401 
1402 				return TRUE;
1403 			}
1404 			if (strcmp(keyname, "Print") == 0) {
1405 #ifndef DISABLE_PRINTING
1406 				process_keys(GLOBAL_PRINT, keys, &group_keys);
1407 				process_keys(GLOBAL_PRINT, keys, &page_keys);
1408 				process_keys(GLOBAL_PRINT, keys, &thread_keys);
1409 #endif /* !DISABLE_PRINTING */
1410 
1411 				return TRUE;
1412 			}
1413 			if (strcmp(keyname, "PromptNo") == 0) {
1414 				process_keys(PROMPT_NO, keys, &post_postpone_keys);
1415 				process_keys(PROMPT_NO, keys, &prompt_keys);
1416 
1417 				return TRUE;
1418 			}
1419 			if (strcmp(keyname, "PromptYes") == 0) {
1420 				process_keys(PROMPT_YES, keys, &post_postpone_keys);
1421 				process_keys(PROMPT_YES, keys, &prompt_keys);
1422 
1423 				return TRUE;
1424 			}
1425 			break;
1426 
1427 		case 'Q':
1428 			if (strcmp(keyname, "QuickFilterKill") == 0) {
1429 				process_keys(GLOBAL_QUICK_FILTER_KILL, keys, &group_keys);
1430 				process_keys(GLOBAL_QUICK_FILTER_KILL, keys, &page_keys);
1431 
1432 				return TRUE;
1433 			}
1434 			if (strcmp(keyname, "QuickFilterSelect") == 0) {
1435 				process_keys(GLOBAL_QUICK_FILTER_SELECT, keys, &group_keys);
1436 				process_keys(GLOBAL_QUICK_FILTER_SELECT, keys, &page_keys);
1437 
1438 				return TRUE;
1439 			}
1440 			if (strcmp(keyname, "Quit") == 0) {
1441 				process_keys(GLOBAL_QUIT, keys, &attachment_keys);
1442 				process_keys(GLOBAL_QUIT, keys, &feed_post_process_keys);
1443 				process_keys(GLOBAL_QUIT, keys, &feed_supersede_article_keys);
1444 				process_keys(GLOBAL_QUIT, keys, &feed_type_keys);
1445 				process_keys(GLOBAL_QUIT, keys, &filter_keys);
1446 				process_keys(GLOBAL_QUIT, keys, &group_keys);
1447 				process_keys(GLOBAL_QUIT, keys, &info_keys);
1448 				process_keys(GLOBAL_QUIT, keys, &option_menu_keys);
1449 				process_keys(GLOBAL_QUIT, keys, &page_keys);
1450 #ifdef HAVE_PGP_GPG
1451 				process_keys(GLOBAL_QUIT, keys, &pgp_mail_keys);
1452 				process_keys(GLOBAL_QUIT, keys, &pgp_news_keys);
1453 #endif /* HAVE_PGP_GPG */
1454 				process_keys(GLOBAL_QUIT, keys, &post_cancel_keys);
1455 				process_keys(GLOBAL_QUIT, keys, &post_continue_keys);
1456 				process_keys(GLOBAL_QUIT, keys, &post_delete_keys);
1457 				process_keys(GLOBAL_QUIT, keys, &post_edit_keys);
1458 				process_keys(GLOBAL_QUIT, keys, &post_edit_ext_keys);
1459 				process_keys(GLOBAL_QUIT, keys, &post_ignore_fupto_keys);
1460 				process_keys(GLOBAL_QUIT, keys, &post_mail_fup_keys);
1461 				process_keys(GLOBAL_QUIT, keys, &post_post_keys);
1462 				process_keys(GLOBAL_QUIT, keys, &post_postpone_keys);
1463 				process_keys(GLOBAL_QUIT, keys, &post_send_keys);
1464 				process_keys(GLOBAL_QUIT, keys, &prompt_keys);
1465 				process_keys(GLOBAL_QUIT, keys, &save_append_overwrite_keys);
1466 				process_keys(GLOBAL_QUIT, keys, &scope_keys);
1467 				process_keys(GLOBAL_QUIT, keys, &select_keys);
1468 				process_keys(GLOBAL_QUIT, keys, &thread_keys);
1469 				process_keys(GLOBAL_QUIT, keys, &url_keys);
1470 
1471 				return TRUE;
1472 			}
1473 			if (strcmp(keyname, "QuitTin") == 0) {
1474 				process_keys(GLOBAL_QUIT_TIN, keys, &group_keys);
1475 				process_keys(GLOBAL_QUIT_TIN, keys, &page_keys);
1476 				process_keys(GLOBAL_QUIT_TIN, keys, &select_keys);
1477 				process_keys(GLOBAL_QUIT_TIN, keys, &thread_keys);
1478 
1479 				return TRUE;
1480 			}
1481 			break;
1482 
1483 		case 'R':
1484 			if (strcmp(keyname, "RedrawScr") == 0) {
1485 				process_keys(GLOBAL_REDRAW_SCREEN, keys, &attachment_keys);
1486 				process_keys(GLOBAL_REDRAW_SCREEN, keys, &group_keys);
1487 				process_keys(GLOBAL_REDRAW_SCREEN, keys, &option_menu_keys);
1488 				process_keys(GLOBAL_REDRAW_SCREEN, keys, &page_keys);
1489 				process_keys(GLOBAL_REDRAW_SCREEN, keys, &scope_keys);
1490 				process_keys(GLOBAL_REDRAW_SCREEN, keys, &select_keys);
1491 				process_keys(GLOBAL_REDRAW_SCREEN, keys, &thread_keys);
1492 
1493 				return TRUE;
1494 			}
1495 			break;
1496 
1497 		case 'S':
1498 			if (strcmp(keyname, "SaveAppendFile") == 0) {
1499 				process_keys(SAVE_APPEND_FILE, keys, &save_append_overwrite_keys);
1500 
1501 				return TRUE;
1502 			}
1503 			if (strcmp(keyname, "SaveOverwriteFile") == 0) {
1504 				process_keys(SAVE_OVERWRITE_FILE, keys, &save_append_overwrite_keys);
1505 
1506 				return TRUE;
1507 			}
1508 			if (strcmp(keyname, "ScopeAdd") == 0) {
1509 				process_keys(SCOPE_ADD, keys, &scope_keys);
1510 
1511 				return TRUE;
1512 			}
1513 			if (strcmp(keyname, "ScopeDelete") == 0) {
1514 				process_keys(SCOPE_DELETE, keys, &scope_keys);
1515 
1516 				return TRUE;
1517 			}
1518 			if (strcmp(keyname, "ScopeEditAttributesFile") == 0) {
1519 				process_keys(SCOPE_EDIT_ATTRIBUTES_FILE, keys, &scope_keys);
1520 
1521 				return TRUE;
1522 			}
1523 			if (strcmp(keyname, "ScopeMove") == 0) {
1524 				process_keys(SCOPE_MOVE, keys, &scope_keys);
1525 
1526 				return TRUE;
1527 			}
1528 			if (strcmp(keyname, "ScopeRename") == 0) {
1529 				process_keys(SCOPE_RENAME, keys, &scope_keys);
1530 
1531 				return TRUE;
1532 			}
1533 			if (strcmp(keyname, "ScopeSelect") == 0) {
1534 				process_keys(SCOPE_SELECT, keys, &scope_keys);
1535 
1536 				return TRUE;
1537 			}
1538 			if (strcmp(keyname, "ScrollDown") == 0) {
1539 				process_keys(GLOBAL_SCROLL_DOWN, keys, &attachment_keys);
1540 				process_keys(GLOBAL_SCROLL_DOWN, keys, &group_keys);
1541 				process_keys(GLOBAL_SCROLL_DOWN, keys, &option_menu_keys);
1542 				process_keys(GLOBAL_SCROLL_DOWN, keys, &scope_keys);
1543 				process_keys(GLOBAL_SCROLL_DOWN, keys, &select_keys);
1544 				process_keys(GLOBAL_SCROLL_DOWN, keys, &thread_keys);
1545 				process_keys(GLOBAL_SCROLL_DOWN, keys, &url_keys);
1546 
1547 				return TRUE;
1548 			}
1549 			if (strcmp(keyname, "ScrollUp") == 0) {
1550 				process_keys(GLOBAL_SCROLL_UP, keys, &attachment_keys);
1551 				process_keys(GLOBAL_SCROLL_UP, keys, &group_keys);
1552 				process_keys(GLOBAL_SCROLL_UP, keys, &option_menu_keys);
1553 				process_keys(GLOBAL_SCROLL_UP, keys, &scope_keys);
1554 				process_keys(GLOBAL_SCROLL_UP, keys, &select_keys);
1555 				process_keys(GLOBAL_SCROLL_UP, keys, &thread_keys);
1556 				process_keys(GLOBAL_SCROLL_UP, keys, &url_keys);
1557 
1558 				return TRUE;
1559 			}
1560 			if (strcmp(keyname, "SearchAuthB") == 0) {
1561 				process_keys(GLOBAL_SEARCH_AUTHOR_BACKWARD, keys, &group_keys);
1562 				process_keys(GLOBAL_SEARCH_AUTHOR_BACKWARD, keys, &page_keys);
1563 				process_keys(GLOBAL_SEARCH_AUTHOR_BACKWARD, keys, &thread_keys);
1564 
1565 				return TRUE;
1566 			}
1567 			if (strcmp(keyname, "SearchAuthF") == 0) {
1568 				process_keys(GLOBAL_SEARCH_AUTHOR_FORWARD, keys, &group_keys);
1569 				process_keys(GLOBAL_SEARCH_AUTHOR_FORWARD, keys, &page_keys);
1570 				process_keys(GLOBAL_SEARCH_AUTHOR_FORWARD, keys, &thread_keys);
1571 
1572 				return TRUE;
1573 			}
1574 			if (strcmp(keyname, "SearchBody") == 0) {
1575 				process_keys(GLOBAL_SEARCH_BODY, keys, &group_keys);
1576 				process_keys(GLOBAL_SEARCH_BODY, keys, &page_keys);
1577 				process_keys(GLOBAL_SEARCH_BODY, keys, &thread_keys);
1578 
1579 				return TRUE;
1580 			}
1581 			if (strcmp(keyname, "SearchRepeat") == 0) {
1582 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &attachment_keys);
1583 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &group_keys);
1584 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &info_keys);
1585 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &option_menu_keys);
1586 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &page_keys);
1587 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &select_keys);
1588 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &thread_keys);
1589 				process_keys(GLOBAL_SEARCH_REPEAT, keys, &url_keys);
1590 
1591 				return TRUE;
1592 			}
1593 			if (strcmp(keyname, "SearchSubjB") == 0) {
1594 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &attachment_keys);
1595 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &group_keys);
1596 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &info_keys);
1597 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &option_menu_keys);
1598 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &page_keys);
1599 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &select_keys);
1600 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &thread_keys);
1601 				process_keys(GLOBAL_SEARCH_SUBJECT_BACKWARD, keys, &url_keys);
1602 
1603 				return TRUE;
1604 			}
1605 			if (strcmp(keyname, "SearchSubjF") == 0) {
1606 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &attachment_keys);
1607 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &group_keys);
1608 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &info_keys);
1609 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &option_menu_keys);
1610 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &page_keys);
1611 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &select_keys);
1612 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &thread_keys);
1613 				process_keys(GLOBAL_SEARCH_SUBJECT_FORWARD, keys, &url_keys);
1614 
1615 				return TRUE;
1616 			}
1617 			if (strcmp(keyname, "SelectEnterNextUnreadGrp") == 0) {
1618 				process_keys(SELECT_ENTER_NEXT_UNREAD_GROUP, keys, &select_keys);
1619 
1620 				return TRUE;
1621 			}
1622 			if (strcmp(keyname, "SelectGoto") == 0) {
1623 				process_keys(SELECT_GOTO, keys, &select_keys);
1624 
1625 				return TRUE;
1626 			}
1627 			if (strcmp(keyname, "SelectMarkGrpUnread") == 0) {
1628 				process_keys(SELECT_MARK_GROUP_UNREAD, keys, &select_keys);
1629 
1630 				return TRUE;
1631 			}
1632 			if (strcmp(keyname, "SelectMoveGrp") == 0) {
1633 				process_keys(SELECT_MOVE_GROUP, keys, &select_keys);
1634 
1635 				return TRUE;
1636 			}
1637 			if (strcmp(keyname, "SelectNextUnreadGrp") == 0) {
1638 				process_keys(SELECT_NEXT_UNREAD_GROUP, keys, &select_keys);
1639 
1640 				return TRUE;
1641 			}
1642 			if (strcmp(keyname, "SelectQuitNoWrite") == 0) {
1643 				process_keys(SELECT_QUIT_NO_WRITE, keys, &select_keys);
1644 
1645 				return TRUE;
1646 			}
1647 			if (strcmp(keyname, "SelectReadGrp") == 0) {
1648 				process_keys(SELECT_ENTER_GROUP, keys, &select_keys);
1649 
1650 				return TRUE;
1651 			}
1652 			if (strcmp(keyname, "SelectResetNewsrc") == 0) {
1653 				process_keys(SELECT_RESET_NEWSRC, keys, &select_keys);
1654 
1655 				return TRUE;
1656 			}
1657 			if (strcmp(keyname, "SelectSortActive") == 0) {
1658 				process_keys(SELECT_SORT_ACTIVE, keys, &select_keys);
1659 
1660 				return TRUE;
1661 			}
1662 			if (strcmp(keyname, "SelectSubscribe") == 0) {
1663 				process_keys(SELECT_SUBSCRIBE, keys, &select_keys);
1664 
1665 				return TRUE;
1666 			}
1667 			if (strcmp(keyname, "SelectSubscribePat") == 0) {
1668 				process_keys(SELECT_SUBSCRIBE_PATTERN, keys, &select_keys);
1669 
1670 				return TRUE;
1671 			}
1672 			if (strcmp(keyname, "SelectSyncWithActive") == 0) {
1673 				process_keys(SELECT_SYNC_WITH_ACTIVE, keys, &select_keys);
1674 
1675 				return TRUE;
1676 			}
1677 			if (strcmp(keyname, "SelectToggleDescriptions") == 0) {
1678 				process_keys(SELECT_TOGGLE_DESCRIPTIONS, keys, &select_keys);
1679 
1680 				return TRUE;
1681 			}
1682 			if (strcmp(keyname, "SelectToggleReadDisplay") == 0) {
1683 				process_keys(SELECT_TOGGLE_READ_DISPLAY, keys, &select_keys);
1684 
1685 				return TRUE;
1686 			}
1687 			if (strcmp(keyname, "SelectUnsubscribe") == 0) {
1688 				process_keys(SELECT_UNSUBSCRIBE, keys, &select_keys);
1689 
1690 				return TRUE;
1691 			}
1692 			if (strcmp(keyname, "SelectUnsubscribePat") == 0) {
1693 				process_keys(SELECT_UNSUBSCRIBE_PATTERN, keys, &select_keys);
1694 
1695 				return TRUE;
1696 			}
1697 			if (strcmp(keyname, "SelectYankActive") == 0) {
1698 				process_keys(SELECT_YANK_ACTIVE, keys, &select_keys);
1699 
1700 				return TRUE;
1701 			}
1702 			if (strcmp(keyname, "SetRange") == 0) {
1703 				process_keys(GLOBAL_SET_RANGE, keys, &group_keys);
1704 				process_keys(GLOBAL_SET_RANGE, keys, &select_keys);
1705 				process_keys(GLOBAL_SET_RANGE, keys, &thread_keys);
1706 
1707 				return TRUE;
1708 			}
1709 			if (strcmp(keyname, "ShellEscape") == 0) {
1710 #ifndef NO_SHELL_ESCAPE
1711 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &attachment_keys);
1712 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &group_keys);
1713 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &option_menu_keys);
1714 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &page_keys);
1715 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &scope_keys);
1716 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &select_keys);
1717 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &thread_keys);
1718 				process_keys(GLOBAL_SHELL_ESCAPE, keys, &url_keys);
1719 #endif /* !NO_SHELL_ESCAPE */
1720 
1721 				return TRUE;
1722 			}
1723 			break;
1724 
1725 		case 'T':
1726 			if (strcmp(keyname, "ThreadAutoSave") == 0) {
1727 				process_keys(THREAD_AUTOSAVE, keys, &thread_keys);
1728 
1729 				return TRUE;
1730 			}
1731 			if (strcmp(keyname, "ThreadCancel") == 0) {
1732 				process_keys(THREAD_CANCEL, keys, &thread_keys);
1733 
1734 				return TRUE;
1735 			}
1736 			if (strcmp(keyname, "ThreadMail") == 0) {
1737 				process_keys(THREAD_MAIL, keys, &thread_keys);
1738 
1739 				return TRUE;
1740 			}
1741 			if (strcmp(keyname, "ThreadMarkArtRead") == 0) {
1742 				process_keys(THREAD_MARK_ARTICLE_READ, keys, &thread_keys);
1743 
1744 				return TRUE;
1745 			}
1746 			if (strcmp(keyname, "ThreadReadArt") == 0) {
1747 				process_keys(THREAD_READ_ARTICLE, keys, &thread_keys);
1748 
1749 				return TRUE;
1750 			}
1751 			if (strcmp(keyname, "ThreadReadNextArtOrThread") == 0) {
1752 				process_keys(THREAD_READ_NEXT_ARTICLE_OR_THREAD, keys, &thread_keys);
1753 
1754 				return TRUE;
1755 			}
1756 			if (strcmp(keyname, "ThreadReverseSel") == 0) {
1757 				process_keys(THREAD_REVERSE_SELECTIONS, keys, &thread_keys);
1758 
1759 				return TRUE;
1760 			}
1761 			if (strcmp(keyname, "ThreadSave") == 0) {
1762 				process_keys(THREAD_SAVE, keys, &thread_keys);
1763 
1764 				return TRUE;
1765 			}
1766 			if (strcmp(keyname, "ThreadSelArt") == 0) {
1767 				process_keys(THREAD_SELECT_ARTICLE, keys, &thread_keys);
1768 
1769 				return TRUE;
1770 			}
1771 			if (strcmp(keyname, "ThreadTag") == 0) {
1772 				process_keys(THREAD_TAG, keys, &thread_keys);
1773 
1774 				return TRUE;
1775 			}
1776 			if (strcmp(keyname, "ThreadTagParts") == 0) {
1777 				process_keys(THREAD_TAG_PARTS, keys, &thread_keys);
1778 
1779 				return TRUE;
1780 			}
1781 			if (strcmp(keyname, "ThreadToggleArtSel") == 0) {
1782 				process_keys(THREAD_TOGGLE_ARTICLE_SELECTION, keys, &thread_keys);
1783 
1784 				return TRUE;
1785 			}
1786 			if (strcmp(keyname, "ThreadToggleSubjDisplay") == 0) {
1787 				process_keys(THREAD_TOGGLE_SUBJECT_DISPLAY, keys, &thread_keys);
1788 
1789 				return TRUE;
1790 			}
1791 			if (strcmp(keyname, "ThreadUndoSel") == 0) {
1792 				process_keys(THREAD_UNDO_SELECTIONS, keys, &thread_keys);
1793 
1794 				return TRUE;
1795 			}
1796 			if (strcmp(keyname, "ThreadUntag") == 0) {
1797 				process_keys(THREAD_UNTAG, keys, &thread_keys);
1798 
1799 				return TRUE;
1800 			}
1801 			if (strcmp(keyname, "ToggleColor") == 0) {
1802 #ifdef HAVE_COLOR
1803 				process_keys(GLOBAL_TOGGLE_COLOR, keys, &group_keys);
1804 				process_keys(GLOBAL_TOGGLE_COLOR, keys, &page_keys);
1805 				process_keys(GLOBAL_TOGGLE_COLOR, keys, &select_keys);
1806 				process_keys(GLOBAL_TOGGLE_COLOR, keys, &thread_keys);
1807 #endif /* HAVE_COLOR */
1808 
1809 				return TRUE;
1810 			}
1811 			if (strcmp(keyname, "ToggleHelpDisplay") == 0) {
1812 				process_keys(GLOBAL_TOGGLE_HELP_DISPLAY, keys, &attachment_keys);
1813 				process_keys(GLOBAL_TOGGLE_HELP_DISPLAY, keys, &group_keys);
1814 				process_keys(GLOBAL_TOGGLE_HELP_DISPLAY, keys, &info_keys);
1815 				process_keys(GLOBAL_TOGGLE_HELP_DISPLAY, keys, &page_keys);
1816 				process_keys(GLOBAL_TOGGLE_HELP_DISPLAY, keys, &scope_keys);
1817 				process_keys(GLOBAL_TOGGLE_HELP_DISPLAY, keys, &select_keys);
1818 				process_keys(GLOBAL_TOGGLE_HELP_DISPLAY, keys, &thread_keys);
1819 
1820 				return TRUE;
1821 			}
1822 			if (strcmp(keyname, "ToggleInfoLastLine") == 0) {
1823 				process_keys(GLOBAL_TOGGLE_INFO_LAST_LINE, keys, &attachment_keys);
1824 				process_keys(GLOBAL_TOGGLE_INFO_LAST_LINE, keys, &group_keys);
1825 				process_keys(GLOBAL_TOGGLE_INFO_LAST_LINE, keys, &page_keys);
1826 				process_keys(GLOBAL_TOGGLE_INFO_LAST_LINE, keys, &select_keys);
1827 				process_keys(GLOBAL_TOGGLE_INFO_LAST_LINE, keys, &thread_keys);
1828 
1829 				return TRUE;
1830 			}
1831 			if (strcmp(keyname, "ToggleInverseVideo") == 0) {
1832 				process_keys(GLOBAL_TOGGLE_INVERSE_VIDEO, keys, &group_keys);
1833 				process_keys(GLOBAL_TOGGLE_INVERSE_VIDEO, keys, &page_keys);
1834 				process_keys(GLOBAL_TOGGLE_INVERSE_VIDEO, keys, &select_keys);
1835 				process_keys(GLOBAL_TOGGLE_INVERSE_VIDEO, keys, &thread_keys);
1836 
1837 				return TRUE;
1838 			}
1839 			break;
1840 
1841 		case 'U':
1842 			if (strcmp(keyname, "Up") == 0) {
1843 				process_keys(GLOBAL_LINE_UP, keys, &attachment_keys);
1844 				process_keys(GLOBAL_LINE_UP, keys, &group_keys);
1845 				process_keys(GLOBAL_LINE_UP, keys, &info_keys);
1846 				process_keys(GLOBAL_LINE_UP, keys, &option_menu_keys);
1847 				process_keys(GLOBAL_LINE_UP, keys, &page_keys);
1848 				process_keys(GLOBAL_LINE_UP, keys, &scope_keys);
1849 				process_keys(GLOBAL_LINE_UP, keys, &select_keys);
1850 				process_keys(GLOBAL_LINE_UP, keys, &thread_keys);
1851 				process_keys(GLOBAL_LINE_UP, keys, &url_keys);
1852 
1853 				return TRUE;
1854 			}
1855 			if (strcmp(keyname, "UrlSelect") == 0) {
1856 				process_keys(URL_SELECT, keys, &url_keys);
1857 
1858 				return TRUE;
1859 			}
1860 			break;
1861 
1862 		case 'V':
1863 			if (strcmp(keyname, "Version") == 0) {
1864 				process_keys(GLOBAL_VERSION, keys, &group_keys);
1865 				process_keys(GLOBAL_VERSION, keys, &page_keys);
1866 				process_keys(GLOBAL_VERSION, keys, &select_keys);
1867 				process_keys(GLOBAL_VERSION, keys, &thread_keys);
1868 
1869 				return TRUE;
1870 			}
1871 			break;
1872 
1873 		default:
1874 			break;
1875 	}
1876 
1877 	return FALSE;
1878 }
1879 
1880 
1881 /*
1882  * upgrades the keymap file to the current version
1883  */
1884 static void
1885 upgrade_keymap_file(
1886 	char *old)
1887 {
1888 	FILE *oldfp, *newfp;
1889 	char *line, *backup;
1890 	const char *keyname, *keydef;
1891 	char newk[NAME_LEN + 1], buf[LEN];
1892 	char *bugreport[3] = { NULL, NULL, NULL };
1893 	char *catchup[4] = { NULL, NULL, NULL, NULL };
1894 	char *catchup_next_unread[4] = { NULL, NULL, NULL, NULL };
1895 	char *config_select[2] = { NULL, NULL };
1896 	char *edit_filter[2] = { NULL, NULL };
1897 	char *down[2] = { NULL, NULL };
1898 	char *groupreadbasenote[2] = { NULL, NULL };
1899 	char *mark_article_unread[3] = { NULL, NULL, NULL };
1900 	char *mark_thread_unread[3] = { NULL, NULL, NULL };
1901 	char *menu_filter_kill[3] = { NULL, NULL, NULL };
1902 	char *menu_filter_select[3] = { NULL, NULL, NULL };
1903 	char *pagedown[3] = { NULL, NULL, NULL };
1904 	char *pagenextthd[2] = { NULL, NULL };
1905 	char *pageup[3] = { NULL, NULL, NULL };
1906 	char *postponed[2] = { NULL, NULL };
1907 	char *postpost[3] = { NULL, NULL, NULL };
1908 	char *postsend[2] = { NULL, NULL };
1909 	char *quick_filter_kill[2] = { NULL, NULL };
1910 	char *quick_filter_select[2] = { NULL, NULL };
1911 	char *selectentergroup[2] = { NULL, NULL };
1912 	char *selectmarkgrpunread[2] = { NULL, NULL };
1913 	char *selectreadgrp[2] = { NULL, NULL };
1914 	char *threadreadart[2] = { NULL, NULL };
1915 	char *up[2] = { NULL, NULL };
1916 
1917 	if ((oldfp = fopen(old, "r")) == NULL)
1918 		return;
1919 
1920 	snprintf(newk, sizeof(newk), "%s.%ld", old, (long) process_id);
1921 	if ((newfp = fopen(newk, "w")) == NULL) {
1922 		fclose(oldfp);
1923 		return;
1924 	}
1925 	fprintf(newfp, "# Keymap file V%s for the TIN newsreader\n", KEYMAP_VERSION);
1926 
1927 	forever {
1928 		line = fgets(buf, sizeof(buf), oldfp);
1929 
1930 		if (line == NULL || line[0] == '\n') {
1931 			/*
1932 			 * we are at the end of a block or file
1933 			 * write out the merged lines (if available)
1934 			 */
1935 			if (config_select[0] || config_select[1]) {
1936 				fprintf(newfp, "ConfigSelect\t\t");
1937 				if (config_select[0])
1938 					fprintf(newfp, "\t%s", config_select[0]);
1939 				if (config_select[1])
1940 					fprintf(newfp, "\t%s", config_select[1]);
1941 				fprintf(newfp, "\n");
1942 				FreeAndNull(config_select[0]);
1943 				FreeAndNull(config_select[1]);
1944 			}
1945 			if (down[0] || down[1]) {
1946 				fprintf(newfp, "Down\t\t\t");
1947 				if (down[0])
1948 					fprintf(newfp, "\t%s", down[0]);
1949 				if (down[1])
1950 					fprintf(newfp, "\t%s", down[1]);
1951 				fprintf(newfp, "\n");
1952 				FreeAndNull(down[0]);
1953 				FreeAndNull(down[1]);
1954 			}
1955 			if (groupreadbasenote[0] || groupreadbasenote[1]) {
1956 				fprintf(newfp, "GroupReadBasenote\t");
1957 				if (groupreadbasenote[0])
1958 					fprintf(newfp, "\t%s", groupreadbasenote[0]);
1959 				if (groupreadbasenote[1])
1960 					fprintf(newfp, "\t%s", groupreadbasenote[1]);
1961 				fprintf(newfp, "\n");
1962 				FreeAndNull(groupreadbasenote[0]);
1963 				FreeAndNull(groupreadbasenote[1]);
1964 			}
1965 			if (pagedown[0] || pagedown[1] || pagedown[2]) {
1966 				fprintf(newfp, "PageDown\t\t");
1967 				if (pagedown[0])
1968 					fprintf(newfp, "\t%s", pagedown[0]);
1969 				if (pagedown[1])
1970 					fprintf(newfp, "\t%s", pagedown[1]);
1971 				if (pagedown[2])
1972 					fprintf(newfp, "\t%s", pagedown[2]);
1973 				fprintf(newfp, "\n");
1974 				FreeAndNull(pagedown[0]);
1975 				FreeAndNull(pagedown[1]);
1976 				FreeAndNull(pagedown[2]);
1977 			}
1978 			if (pagenextthd[0] || pagenextthd[1]) {
1979 				fprintf(newfp, "PageNextThd\t\t");
1980 				if (pagenextthd[0])
1981 					fprintf(newfp, "\t%s", pagenextthd[0]);
1982 				if (pagenextthd[1])
1983 					fprintf(newfp, "\t%s", pagenextthd[1]);
1984 				fprintf(newfp, "\n");
1985 				FreeAndNull(pagenextthd[0]);
1986 				FreeAndNull(pagenextthd[1]);
1987 			}
1988 			if (pageup[0] || pageup[1] || pageup[2]) {
1989 				fprintf(newfp, "PageUp\t\t\t");
1990 				if (pageup[0])
1991 					fprintf(newfp, "\t%s", pageup[0]);
1992 				if (pageup[1])
1993 					fprintf(newfp, "\t%s", pageup[1]);
1994 				if (pageup[2])
1995 					fprintf(newfp, "\t%s", pageup[2]);
1996 				fprintf(newfp, "\n");
1997 				FreeAndNull(pageup[0]);
1998 				FreeAndNull(pageup[1]);
1999 				FreeAndNull(pageup[2]);
2000 			}
2001 			if (postponed[0] || postponed[1]) {
2002 				fprintf(newfp, "Postponed\t\t");
2003 				if (postponed[0])
2004 					fprintf(newfp, "\t%s", postponed[0]);
2005 				if (postponed[1])
2006 					fprintf(newfp, "\t%s", postponed[1]);
2007 				fprintf(newfp, "\n");
2008 				FreeAndNull(postponed[0]);
2009 				FreeAndNull(postponed[1]);
2010 			}
2011 			if (postpost[0] || postpost[1] || postpost[2]) {
2012 				fprintf(newfp, "PostPost\t\t");
2013 				if (postpost[0])
2014 					fprintf(newfp, "\t%s", postpost[0]);
2015 				if (postpost[1])
2016 					fprintf(newfp, "\t%s", postpost[1]);
2017 				if (postpost[2])
2018 					fprintf(newfp, "\t%s", postpost[2]);
2019 				fprintf(newfp, "\n");
2020 				FreeAndNull(postpost[0]);
2021 				FreeAndNull(postpost[1]);
2022 				FreeAndNull(postpost[2]);
2023 			}
2024 			if (postsend[0] || postsend[1]) {
2025 				fprintf(newfp, "PostSend\t\t");
2026 				if (postsend[0])
2027 					fprintf(newfp, "\t%s", postsend[0]);
2028 				if (postsend[1])
2029 					fprintf(newfp, "\t%s", postsend[1]);
2030 				fprintf(newfp, "\n");
2031 				FreeAndNull(postsend[0]);
2032 				FreeAndNull(postsend[1]);
2033 			}
2034 			if (selectentergroup[0] || selectentergroup[1]) {
2035 				fprintf(newfp, "SelectEnterNextUnreadGrp");
2036 				if (selectentergroup[0])
2037 					fprintf(newfp, "\t%s", selectentergroup[0]);
2038 				if (selectentergroup[1])
2039 					fprintf(newfp, "\t%s", selectentergroup[1]);
2040 				fprintf(newfp, "\n");
2041 				FreeAndNull(selectentergroup[0]);
2042 				FreeAndNull(selectentergroup[1]);
2043 			}
2044 			if (selectmarkgrpunread[0] || selectmarkgrpunread[1]) {
2045 				fprintf(newfp, "SelectMarkGrpUnread\t");
2046 				if (selectmarkgrpunread[0])
2047 					fprintf(newfp, "\t%s", selectmarkgrpunread[0]);
2048 				if (selectmarkgrpunread[1])
2049 					fprintf(newfp, "\t%s", selectmarkgrpunread[1]);
2050 				fprintf(newfp, "\n");
2051 				FreeAndNull(selectmarkgrpunread[0]);
2052 				FreeAndNull(selectmarkgrpunread[1]);
2053 			}
2054 			if (selectreadgrp[0] || selectreadgrp[1]) {
2055 				fprintf(newfp, "SelectReadGrp\t\t");
2056 				if (selectreadgrp[0])
2057 					fprintf(newfp, "\t%s", selectreadgrp[0]);
2058 				if (selectreadgrp[1])
2059 					fprintf(newfp, "\t%s", selectreadgrp[1]);
2060 				fprintf(newfp, "\n");
2061 				FreeAndNull(selectreadgrp[0]);
2062 				FreeAndNull(selectreadgrp[1]);
2063 			}
2064 			if (threadreadart[0] || threadreadart[1]) {
2065 				fprintf(newfp, "ThreadReadArt\t\t");
2066 				if (threadreadart[0])
2067 					fprintf(newfp, "\t%s", threadreadart[0]);
2068 				if (threadreadart[1])
2069 					fprintf(newfp, "\t%s", threadreadart[1]);
2070 				fprintf(newfp, "\n");
2071 				FreeAndNull(threadreadart[0]);
2072 				FreeAndNull(threadreadart[1]);
2073 			}
2074 			if (up[0] || up[1]) {
2075 				fprintf(newfp, "Up\t\t\t");
2076 				if (up[0])
2077 					fprintf(newfp, "\t%s", up[0]);
2078 				if (up[1])
2079 					fprintf(newfp, "\t%s", up[1]);
2080 				fprintf(newfp, "\n");
2081 				FreeAndNull(up[0]);
2082 				FreeAndNull(up[1]);
2083 			}
2084 			if (line == NULL)
2085 				break;	/* jump out of the while loop */
2086 			else {
2087 				fprintf(newfp, "\n");
2088 				continue;
2089 			}
2090 		}
2091 
2092 		if (line[0] == '#') {
2093 			if (strncmp(line, "# Keymap file V", strlen("# Keymap file V")) != 0)
2094 				fprintf(newfp, "%s", line);
2095 			continue;
2096 		}
2097 
2098 		backup = my_strdup(line);
2099 
2100 		if ((keyname = strsep(&line, KEYSEPS)) == NULL) {
2101 			free(backup);
2102 			continue;
2103 		}
2104 		if ((keydef = str_trim(line)) == NULL)
2105 			keydef = "";
2106 
2107 		switch (keyname[0]) {
2108 			case 'C':
2109 				if (strcmp(keyname, "ConfigFirstPage2") == 0)
2110 					fprintf(newfp, "ConfigFirstPage\t\t\t%s\n", keydef);
2111 				else if (strcmp(keyname, "ConfigLastPage2") == 0)
2112 					fprintf(newfp, "ConfigLastPage\t\t\t%s\n", keydef);
2113 				else if (strcmp(keyname, "ConfigSelect") == 0)
2114 					config_select[0] = my_strdup(keydef);
2115 				else if (strcmp(keyname, "ConfigSelect2") == 0)
2116 					config_select[1] = my_strdup(keydef);
2117 				else
2118 					fprintf(newfp, "%s", backup);
2119 				break;
2120 
2121 			case 'D':
2122 				if (strcmp(keyname, "Down") == 0)
2123 					down[0] = my_strdup(keydef);
2124 				else if (strcmp(keyname, "Down2") == 0)
2125 					down[1] = my_strdup(keydef);
2126 				else
2127 					fprintf(newfp, "%s", backup);
2128 				break;
2129 
2130 			case 'G':
2131 				if (strcmp(keyname, "GroupAutoSel") == 0)
2132 					menu_filter_select[0] = my_strdup(keydef);
2133 				else if (strcmp(keyname, "GroupQuickAutoSel") == 0)
2134 					quick_filter_select[0] = my_strdup(keydef);
2135 				else if (strcmp(keyname, "GroupQuickKill") == 0)
2136 					quick_filter_kill[0] = my_strdup(keydef);
2137 				else if (strcmp(keyname, "GroupKill") == 0)
2138 					menu_filter_kill[0] = my_strdup(keydef);
2139 				else if (strcmp(keyname, "GroupReadBasenote") == 0)
2140 					groupreadbasenote[0] = my_strdup(keydef);
2141 				else if (strcmp(keyname, "GroupReadBasenote2") == 0)
2142 					groupreadbasenote[1] = my_strdup(keydef);
2143 				else if (strcmp(keyname, "GroupEditFilter") == 0)
2144 					edit_filter[0] = my_strdup(keydef);
2145 				else if (strcmp(keyname, "GroupBugReport") == 0)
2146 					bugreport[0] = my_strdup(keydef);
2147 				else if (strcmp(keyname, "GroupMarkArtUnread") == 0)
2148 					mark_article_unread[0] = my_strdup(keydef);
2149 				else if (strcmp(keyname, "GroupMarkThdUnread") == 0)
2150 					mark_thread_unread[0] = my_strdup(keydef);
2151 				else if (strcmp(keyname, "GroupCatchup") == 0)
2152 					catchup[0] = my_strdup(keydef);
2153 				else if (strcmp(keyname, "GroupCatchupNextUnread") == 0)
2154 					catchup_next_unread[0] = my_strdup(keydef);
2155 				else
2156 					fprintf(newfp, "%s", backup);
2157 				break;
2158 
2159 			case 'H':
2160 				if (strcmp(keyname, "HelpFirstPage2") == 0)
2161 					fprintf(newfp, "HelpFirstPage\t\t\t%s\n", keydef);
2162 				else if (strcmp(keyname, "HelpLastPage2") == 0)
2163 					fprintf(newfp, "HelpLastPage\t\t\t%s\n", keydef);
2164 				else
2165 					fprintf(newfp, "%s", backup);
2166 				break;
2167 
2168 			case 'N':
2169 				/* Nrc* got removed */
2170 				if (strcmp(keyname, "NrctblCreate") == 0)
2171 					;
2172 				else if (strcmp(keyname, "NrctblDefault") == 0)
2173 					;
2174 				else if (strcmp(keyname, "NrctblAlternative") == 0)
2175 					;
2176 				else if (strcmp(keyname, "NrctblQuit") == 0)
2177 					;
2178 				else
2179 					fprintf(newfp, "%s", backup);
2180 				break;
2181 
2182 			case 'P':
2183 				if (strcmp(keyname, "PageAutoSel") == 0)
2184 					menu_filter_select[1] = my_strdup(keydef);
2185 				else if (strcmp(keyname, "PageQuickAutoSel") == 0)
2186 					quick_filter_select[1] = my_strdup(keydef);
2187 				else if (strcmp(keyname, "PageQuickKill") == 0)
2188 					quick_filter_kill[1] = my_strdup(keydef);
2189 				else if (strcmp(keyname, "PageAutoKill") == 0)
2190 					menu_filter_kill[1] = my_strdup(keydef);
2191 				else if (strcmp(keyname, "PageDown") == 0)
2192 					pagedown[0] = my_strdup(keydef);
2193 				else if (strcmp(keyname, "PageDown2") == 0)
2194 					pagedown[1] = my_strdup(keydef);
2195 				else if (strcmp(keyname, "PageDown3") == 0)
2196 					pagedown[2] = my_strdup(keydef);
2197 				else if (strcmp(keyname, "PageEditFilter") == 0)
2198 					edit_filter[1] = my_strdup(keydef);
2199 				else if (strcmp(keyname, "PageNextThd") == 0)
2200 					pagenextthd[0] = my_strdup(keydef);
2201 				else if (strcmp(keyname, "PageNextThd2") == 0)
2202 					pagenextthd[1] = my_strdup(keydef);
2203 				else if (strcmp(keyname, "PageUp") == 0)
2204 					pageup[0] = my_strdup(keydef);
2205 				else if (strcmp(keyname, "PageUp2") == 0)
2206 					pageup[1] = my_strdup(keydef);
2207 				else if (strcmp(keyname, "PageUp3") == 0)
2208 					pageup[2] = my_strdup(keydef);
2209 				else if (strcmp(keyname, "Postponed") == 0)
2210 					postponed[0] = my_strdup(keydef);
2211 				else if (strcmp(keyname, "Postponed2") == 0)
2212 					postponed[1] = my_strdup(keydef);
2213 				else if (strcmp(keyname, "PostPost") == 0)
2214 					postpost[0] = my_strdup(keydef);
2215 				else if (strcmp(keyname, "PostPost2") == 0)
2216 					postpost[1] = my_strdup(keydef);
2217 				else if (strcmp(keyname, "PostPost3") == 0)
2218 					postpost[2] = my_strdup(keydef);
2219 				else if (strcmp(keyname, "PostSend") == 0)
2220 					postsend[0] = my_strdup(keydef);
2221 				else if (strcmp(keyname, "PostSend2") == 0)
2222 					postsend[1] = my_strdup(keydef);
2223 				else if (strcmp(keyname, "PageMarkArtUnread") == 0)
2224 					mark_article_unread[1] = my_strdup(keydef);
2225 				else if (strcmp(keyname, "PageMarkThdUnread") == 0)
2226 					mark_thread_unread[1] = my_strdup(keydef);
2227 				else if (strcmp(keyname, "PageCatchup") == 0)
2228 					catchup[1] = my_strdup(keydef);
2229 				else if (strcmp(keyname, "PageCatchupNextUnread") == 0)
2230 					catchup_next_unread[1] = my_strdup(keydef);
2231 				else if (strcmp(keyname, "PageToggleHeaders") == 0)
2232 					fprintf(newfp, "PageToggleRaw\t\t\t%s\n", keydef);
2233 				else if (strcmp(keyname, "PromptNo") == 0 || strcmp(keyname, "PromptYes") == 0) {
2234 					if (strlen(keydef) == 1 && islower((int)(unsigned char) keydef[0]))
2235 						fprintf(newfp, "%s\t\t\t%c\t%c\n", keyname, keydef[0], my_toupper((int)(unsigned char) keydef[0]));
2236 					else
2237 						fprintf(newfp, "%s", backup);
2238 				} else
2239 					fprintf(newfp, "%s", backup);
2240 				break;
2241 
2242 			case 'S':
2243 				if (strcmp(keyname, "SelectEditFilter") == 0)
2244 					;
2245 				else if (strcmp(keyname, "SelectEnterNextUnreadGrp") == 0)
2246 					selectentergroup[0] = my_strdup(keydef);
2247 				else if (strcmp(keyname, "SelectEnterNextUnreadGrp2") == 0)
2248 					selectentergroup[1] = my_strdup(keydef);
2249 				else if (strcmp(keyname, "SelectMarkGrpUnread") == 0)
2250 					selectmarkgrpunread[0] = my_strdup(keydef);
2251 				else if (strcmp(keyname, "SelectMarkGrpUnread2") == 0)
2252 					selectmarkgrpunread[1] = my_strdup(keydef);
2253 				else if (strcmp(keyname, "SelectReadGrp") == 0)
2254 					selectreadgrp[0] = my_strdup(keydef);
2255 				else if (strcmp(keyname, "SelectReadGrp2") == 0)
2256 					selectreadgrp[1] = my_strdup(keydef);
2257 				else if (strcmp(keyname, "SelectBugReport") == 0)
2258 					bugreport[1] = my_strdup(keydef);
2259 				else if (strcmp(keyname, "SelectCatchup") == 0)
2260 					catchup[2] = my_strdup(keydef);
2261 				else if (strcmp(keyname, "SelectCatchupNextUnread") == 0)
2262 					catchup_next_unread[2] = my_strdup(keydef);
2263 				else
2264 					fprintf(newfp, "%s", backup);
2265 				break;
2266 
2267 			case 'T':
2268 				if (strcmp(keyname, "ThreadEditFilter") == 0)
2269 					;
2270 				else if (strcmp(keyname, "ThreadAutoSel") == 0)
2271 					menu_filter_select[2] = my_strdup(keydef);
2272 				else if (strcmp(keyname, "ThreadKill") == 0)
2273 					menu_filter_kill[2] = my_strdup(keydef);
2274 				else if (strcmp(keyname, "ThreadReadArt") == 0)
2275 					threadreadart[0] = my_strdup(keydef);
2276 				else if (strcmp(keyname, "ThreadReadArt2") == 0)
2277 					threadreadart[1] = my_strdup(keydef);
2278 				else if (strcmp(keyname, "ThreadBugReport") == 0)
2279 					bugreport[2] = my_strdup(keydef);
2280 				else if (strcmp(keyname, "ThreadMarkArtUnread") == 0)
2281 					mark_article_unread[2] = my_strdup(keydef);
2282 				else if (strcmp(keyname, "ThreadMarkThdUnread") == 0)
2283 					mark_thread_unread[2] = my_strdup(keydef);
2284 				else if (strcmp(keyname, "ThreadCatchup") == 0)
2285 					catchup[3] = my_strdup(keydef);
2286 				else if (strcmp(keyname, "ThreadCatchupNextUnread") == 0)
2287 					catchup_next_unread[3] = my_strdup(keydef);
2288 				else
2289 					fprintf(newfp, "%s", backup);
2290 				break;
2291 
2292 			case 'U':
2293 				if (strcmp(keyname, "Up") == 0)
2294 					up[0] = my_strdup(keydef);
2295 				else if (strcmp(keyname, "Up2") == 0)
2296 					up[1] = my_strdup(keydef);
2297 				else
2298 					fprintf(newfp, "%s", backup);
2299 				break;
2300 
2301 			default:
2302 				fprintf(newfp, "%s", backup);
2303 		}
2304 		free(backup);
2305 	}
2306 	fprintf(newfp, "\n#####\n");
2307 	/* joined/renamed keys from different sections */
2308 	if (bugreport[0] || bugreport[1] || bugreport[2]) {
2309 		fprintf(newfp, "BugReport\t");
2310 		if (bugreport[0] && bugreport[1] && !strcmp(bugreport[0], bugreport[1]))
2311 			FreeAndNull(bugreport[1]);
2312 		if (bugreport[0] && bugreport[2] && !strcmp(bugreport[0], bugreport[2]))
2313 			FreeAndNull(bugreport[2]);
2314 		if (bugreport[1] && bugreport[2] && !strcmp(bugreport[1], bugreport[2]))
2315 			FreeAndNull(bugreport[2]);
2316 		if (bugreport[0])
2317 			fprintf(newfp, "\t%s", bugreport[0]);
2318 		if (bugreport[1])
2319 			fprintf(newfp, "\t%s", bugreport[1]);
2320 		if (bugreport[2])
2321 			fprintf(newfp, "\t%s", bugreport[2]);
2322 		fprintf(newfp, "\n");
2323 		FreeAndNull(bugreport[0]);
2324 		FreeAndNull(bugreport[1]);
2325 		FreeAndNull(bugreport[2]);
2326 	}
2327 	if (catchup[0] || catchup[1] || catchup[2] || catchup[3]) {
2328 		fprintf(newfp, "Catchup\t");
2329 		if (catchup[0] && catchup[1] && !strcmp(catchup[0], catchup[1]))
2330 			FreeAndNull(catchup[1]);
2331 		if (catchup[0] && catchup[2] && !strcmp(catchup[0], catchup[2]))
2332 			FreeAndNull(catchup[2]);
2333 		if (catchup[0] && catchup[3] && !strcmp(catchup[0], catchup[3]))
2334 			FreeAndNull(catchup[3]);
2335 		if (catchup[1] && catchup[2] && !strcmp(catchup[1], catchup[2]))
2336 			FreeAndNull(catchup[2]);
2337 		if (catchup[1] && catchup[3] && !strcmp(catchup[1], catchup[3]))
2338 			FreeAndNull(catchup[3]);
2339 		if (catchup[2] && catchup[3] && !strcmp(catchup[2], catchup[3]))
2340 			FreeAndNull(catchup[3]);
2341 		if (catchup[0])
2342 			fprintf(newfp, "\t%s", catchup[0]);
2343 		if (catchup[1])
2344 			fprintf(newfp, "\t%s", catchup[1]);
2345 		if (catchup[2])
2346 			fprintf(newfp, "\t%s", catchup[2]);
2347 		if (catchup[3])
2348 			fprintf(newfp, "\t%s", catchup[3]);
2349 		fprintf(newfp, "\n");
2350 		FreeAndNull(catchup[0]);
2351 		FreeAndNull(catchup[1]);
2352 		FreeAndNull(catchup[2]);
2353 		FreeAndNull(catchup[3]);
2354 	}
2355 	if (catchup_next_unread[0] || catchup_next_unread[1] || catchup_next_unread[2] || catchup_next_unread[3]) {
2356 		fprintf(newfp, "CatchupNextUnread\t");
2357 		if (catchup_next_unread[0] && catchup_next_unread[1] && !strcmp(catchup_next_unread[0], catchup_next_unread[1]))
2358 			FreeAndNull(catchup_next_unread[1]);
2359 		if (catchup_next_unread[0] && catchup_next_unread[2] && !strcmp(catchup_next_unread[0], catchup_next_unread[2]))
2360 			FreeAndNull(catchup_next_unread[2]);
2361 		if (catchup_next_unread[0] && catchup_next_unread[3] && !strcmp(catchup_next_unread[0], catchup_next_unread[3]))
2362 			FreeAndNull(catchup_next_unread[3]);
2363 		if (catchup_next_unread[1] && catchup_next_unread[2] && !strcmp(catchup_next_unread[1], catchup_next_unread[2]))
2364 			FreeAndNull(catchup_next_unread[2]);
2365 		if (catchup_next_unread[1] && catchup_next_unread[3] && !strcmp(catchup_next_unread[1], catchup_next_unread[3]))
2366 			FreeAndNull(catchup_next_unread[3]);
2367 		if (catchup_next_unread[2] && catchup_next_unread[3] && !strcmp(catchup_next_unread[2], catchup_next_unread[3]))
2368 			FreeAndNull(catchup_next_unread[3]);
2369 		if (catchup_next_unread[0])
2370 			fprintf(newfp, "\t%s", catchup_next_unread[0]);
2371 		if (catchup_next_unread[1])
2372 			fprintf(newfp, "\t%s", catchup_next_unread[1]);
2373 		if (catchup_next_unread[2])
2374 			fprintf(newfp, "\t%s", catchup_next_unread[2]);
2375 		if (catchup_next_unread[3])
2376 			fprintf(newfp, "\t%s", catchup_next_unread[3]);
2377 		fprintf(newfp, "\n");
2378 		FreeAndNull(catchup_next_unread[0]);
2379 		FreeAndNull(catchup_next_unread[1]);
2380 		FreeAndNull(catchup_next_unread[2]);
2381 		FreeAndNull(catchup_next_unread[3]);
2382 	}
2383 	if (edit_filter[0] || edit_filter[1]) {
2384 		fprintf(newfp, "EditFilter\t");
2385 		if (edit_filter[0])
2386 			fprintf(newfp, "\t%s", edit_filter[0]);
2387 		if (edit_filter[1] && edit_filter[0] && strcmp(edit_filter[0], edit_filter[1]))
2388 			fprintf(newfp, "\t%s", edit_filter[1]);
2389 		fprintf(newfp, "\n");
2390 		FreeAndNull(edit_filter[0]);
2391 		FreeAndNull(edit_filter[1]);
2392 	}
2393 	if (mark_article_unread[0] || mark_article_unread[1] || mark_article_unread[2]) {
2394 		fprintf(newfp, "MarkArticleUnread\t");
2395 		if (mark_article_unread[0] && mark_article_unread[1] && !strcmp(mark_article_unread[0], mark_article_unread[1]))
2396 			FreeAndNull(mark_article_unread[1]);
2397 		if (mark_article_unread[0] && mark_article_unread[2] && !strcmp(mark_article_unread[0], mark_article_unread[2]))
2398 			FreeAndNull(mark_article_unread[2]);
2399 		if (mark_article_unread[1] && mark_article_unread[2] && !strcmp(mark_article_unread[1], mark_article_unread[2]))
2400 			FreeAndNull(mark_article_unread[2]);
2401 		if (mark_article_unread[0])
2402 			fprintf(newfp, "\t%s", mark_article_unread[0]);
2403 		if (mark_article_unread[1])
2404 			fprintf(newfp, "\t%s", mark_article_unread[1]);
2405 		if (mark_article_unread[2])
2406 			fprintf(newfp, "\t%s", mark_article_unread[2]);
2407 		fprintf(newfp, "\n");
2408 		FreeAndNull(mark_article_unread[0]);
2409 		FreeAndNull(mark_article_unread[1]);
2410 		FreeAndNull(mark_article_unread[2]);
2411 	}
2412 	if (mark_thread_unread[0] || mark_thread_unread[1] || mark_thread_unread[2]) {
2413 		fprintf(newfp, "MarkThreadUnread\t");
2414 		if (mark_thread_unread[0] && mark_thread_unread[1] && !strcmp(mark_thread_unread[0], mark_thread_unread[1]))
2415 			FreeAndNull(mark_thread_unread[1]);
2416 		if (mark_thread_unread[0] && mark_thread_unread[2] && !strcmp(mark_thread_unread[0], mark_thread_unread[2]))
2417 			FreeAndNull(mark_thread_unread[2]);
2418 		if (mark_thread_unread[1] && mark_thread_unread[2] && !strcmp(mark_thread_unread[1], mark_thread_unread[2]))
2419 			FreeAndNull(mark_thread_unread[2]);
2420 		if (mark_thread_unread[0])
2421 			fprintf(newfp, "\t%s", mark_thread_unread[0]);
2422 		if (mark_thread_unread[1])
2423 			fprintf(newfp, "\t%s", mark_thread_unread[1]);
2424 		if (mark_thread_unread[2])
2425 			fprintf(newfp, "\t%s", mark_thread_unread[2]);
2426 		fprintf(newfp, "\n");
2427 		FreeAndNull(mark_thread_unread[0]);
2428 		FreeAndNull(mark_thread_unread[1]);
2429 		FreeAndNull(mark_thread_unread[2]);
2430 	}
2431 	if (menu_filter_kill[0] || menu_filter_kill[1] || menu_filter_kill[2]) {
2432 		fprintf(newfp, "MenuFilterKill\t");
2433 		if (menu_filter_kill[0] && menu_filter_kill[1] && !strcmp(menu_filter_kill[0], menu_filter_kill[1]))
2434 			FreeAndNull(menu_filter_kill[1]);
2435 		if (menu_filter_kill[0] && menu_filter_kill[2] && !strcmp(menu_filter_kill[0], menu_filter_kill[2]))
2436 			FreeAndNull(menu_filter_kill[2]);
2437 		if (menu_filter_kill[1] && menu_filter_kill[2] && !strcmp(menu_filter_kill[1], menu_filter_kill[2]))
2438 			FreeAndNull(menu_filter_kill[2]);
2439 		if (menu_filter_kill[0])
2440 			fprintf(newfp, "\t%s", menu_filter_kill[0]);
2441 		if (menu_filter_kill[1])
2442 			fprintf(newfp, "\t%s", menu_filter_kill[1]);
2443 		if (menu_filter_kill[2])
2444 			fprintf(newfp, "\t%s", menu_filter_kill[2]);
2445 		fprintf(newfp, "\n");
2446 		FreeAndNull(menu_filter_kill[0]);
2447 		FreeAndNull(menu_filter_kill[1]);
2448 		FreeAndNull(menu_filter_kill[2]);
2449 	}
2450 	if (menu_filter_select[0] || menu_filter_select[1] || menu_filter_select[2]) {
2451 		fprintf(newfp, "MenuFilterSelect\t");
2452 		if (menu_filter_select[0] && menu_filter_select[1] && !strcmp(menu_filter_select[0], menu_filter_select[1]))
2453 			FreeAndNull(menu_filter_select[1]);
2454 		if (menu_filter_select[0] && menu_filter_select[2] && !strcmp(menu_filter_select[0], menu_filter_select[2]))
2455 			FreeAndNull(menu_filter_select[2]);
2456 		if (menu_filter_select[1] && menu_filter_select[2] && !strcmp(menu_filter_select[1], menu_filter_select[2]))
2457 			FreeAndNull(menu_filter_select[2]);
2458 		if (menu_filter_select[0])
2459 			fprintf(newfp, "\t%s", menu_filter_select[0]);
2460 		if (menu_filter_select[1])
2461 			fprintf(newfp, "\t%s", menu_filter_select[1]);
2462 		if (menu_filter_select[2])
2463 			fprintf(newfp, "\t%s", menu_filter_select[2]);
2464 		fprintf(newfp, "\n");
2465 		FreeAndNull(menu_filter_select[0]);
2466 		FreeAndNull(menu_filter_select[1]);
2467 		FreeAndNull(menu_filter_select[2]);
2468 	}
2469 	if (quick_filter_kill[0] || quick_filter_kill[1]) {
2470 		fprintf(newfp, "QuickFilterKill\t");
2471 		if (quick_filter_kill[0])
2472 			fprintf(newfp, "\t%s", quick_filter_kill[0]);
2473 		if (quick_filter_kill[1] && quick_filter_kill[0] && strcmp(quick_filter_kill[0], quick_filter_kill[1]))
2474 			fprintf(newfp, "\t%s", quick_filter_kill[1]);
2475 		fprintf(newfp, "\n");
2476 		FreeAndNull(quick_filter_kill[0]);
2477 		FreeAndNull(quick_filter_kill[1]);
2478 	}
2479 	if (quick_filter_select[0] || quick_filter_select[1]) {
2480 		fprintf(newfp, "QuickFilterSelect\t");
2481 		if (quick_filter_select[0])
2482 			fprintf(newfp, "\t%s", quick_filter_select[0]);
2483 		if (quick_filter_select[1] && quick_filter_select[0] && strcmp(quick_filter_select[0], quick_filter_select[1]))
2484 			fprintf(newfp, "\t%s", quick_filter_select[1]);
2485 		fprintf(newfp, "\n");
2486 		FreeAndNull(quick_filter_select[0]);
2487 		FreeAndNull(quick_filter_select[1]);
2488 	}
2489 
2490 	fclose(oldfp);
2491 	fclose(newfp);
2492 	rename(newk, old);
2493 	wait_message(0, _(txt_keymap_upgraded), KEYMAP_VERSION);
2494 	prompt_continue();
2495 }
2496 
2497 
2498 /*
2499  * add the default key bindings for still free keys
2500  */
2501 void
2502 setup_default_keys(
2503 	void)
2504 {
2505 	/* attachment level */
2506 	add_default_key(&attachment_keys, "1", DIGIT_1);
2507 	add_default_key(&attachment_keys, "2", DIGIT_2);
2508 	add_default_key(&attachment_keys, "3", DIGIT_3);
2509 	add_default_key(&attachment_keys, "4", DIGIT_4);
2510 	add_default_key(&attachment_keys, "5", DIGIT_5);
2511 	add_default_key(&attachment_keys, "6", DIGIT_6);
2512 	add_default_key(&attachment_keys, "7", DIGIT_7);
2513 	add_default_key(&attachment_keys, "8", DIGIT_8);
2514 	add_default_key(&attachment_keys, "9", DIGIT_9);
2515 	add_default_key(&attachment_keys, "b", GLOBAL_PAGE_UP);
2516 	add_default_key(&attachment_keys, " ", GLOBAL_PAGE_DOWN);
2517 	add_default_key(&attachment_keys, "h", GLOBAL_HELP);
2518 	add_default_key(&attachment_keys, "\n\r", ATTACHMENT_SELECT);
2519 	add_default_key(&attachment_keys, "H", GLOBAL_TOGGLE_HELP_DISPLAY);
2520 	add_default_key(&attachment_keys, "", GLOBAL_REDRAW_SCREEN);
2521 	add_default_key(&attachment_keys, "j", GLOBAL_LINE_DOWN);
2522 	add_default_key(&attachment_keys, "k", GLOBAL_LINE_UP);
2523 	add_default_key(&attachment_keys, "g^", GLOBAL_FIRST_PAGE);
2524 	add_default_key(&attachment_keys, "G$", GLOBAL_LAST_PAGE);
2525 	add_default_key(&attachment_keys, "i", GLOBAL_TOGGLE_INFO_LAST_LINE);
2526 	add_default_key(&attachment_keys, "p", ATTACHMENT_PIPE);
2527 	add_default_key(&attachment_keys, "q", GLOBAL_QUIT);
2528 	add_default_key(&attachment_keys, "s", ATTACHMENT_SAVE);
2529 	add_default_key(&attachment_keys, "t", ATTACHMENT_TAG);
2530 	add_default_key(&attachment_keys, "U", ATTACHMENT_UNTAG);
2531 	add_default_key(&attachment_keys, "=", ATTACHMENT_TAG_PATTERN);
2532 	add_default_key(&attachment_keys, "@", ATTACHMENT_TOGGLE_TAGGED);
2533 	add_default_key(&attachment_keys, "|", GLOBAL_PIPE);
2534 	add_default_key(&attachment_keys, ">", GLOBAL_SCROLL_DOWN);
2535 	add_default_key(&attachment_keys, "<", GLOBAL_SCROLL_UP);
2536 	add_default_key(&attachment_keys, "/", GLOBAL_SEARCH_SUBJECT_FORWARD);
2537 	add_default_key(&attachment_keys, "?", GLOBAL_SEARCH_SUBJECT_BACKWARD);
2538 	add_default_key(&attachment_keys, "\\", GLOBAL_SEARCH_REPEAT);
2539 #ifndef NO_SHELL_ESCAPE
2540 	add_default_key(&attachment_keys, "!", GLOBAL_SHELL_ESCAPE);
2541 #endif /* !NO_SHELL_ESCAPE */
2542 
2543 	/* scope level */
2544 	add_default_key(&scope_keys, "1", DIGIT_1);
2545 	add_default_key(&scope_keys, "2", DIGIT_2);
2546 	add_default_key(&scope_keys, "3", DIGIT_3);
2547 	add_default_key(&scope_keys, "4", DIGIT_4);
2548 	add_default_key(&scope_keys, "5", DIGIT_5);
2549 	add_default_key(&scope_keys, "6", DIGIT_6);
2550 	add_default_key(&scope_keys, "7", DIGIT_7);
2551 	add_default_key(&scope_keys, "8", DIGIT_8);
2552 	add_default_key(&scope_keys, "9", DIGIT_9);
2553 	add_default_key(&scope_keys, "a", SCOPE_ADD);
2554 	add_default_key(&scope_keys, "b", GLOBAL_PAGE_UP);
2555 	add_default_key(&scope_keys, " ", GLOBAL_PAGE_DOWN);
2556 	add_default_key(&scope_keys, "d", SCOPE_DELETE);
2557 	add_default_key(&scope_keys, "h", GLOBAL_HELP);
2558 	add_default_key(&scope_keys, "\n\r", SCOPE_SELECT);
2559 	add_default_key(&scope_keys, "E", SCOPE_EDIT_ATTRIBUTES_FILE);
2560 	add_default_key(&scope_keys, "H", GLOBAL_TOGGLE_HELP_DISPLAY);
2561 	add_default_key(&scope_keys, "", GLOBAL_REDRAW_SCREEN);
2562 	add_default_key(&scope_keys, "m", SCOPE_MOVE);
2563 	add_default_key(&scope_keys, "j", GLOBAL_LINE_DOWN);
2564 	add_default_key(&scope_keys, "k", GLOBAL_LINE_UP);
2565 	add_default_key(&scope_keys, "g^", GLOBAL_FIRST_PAGE);
2566 	add_default_key(&scope_keys, "G$", GLOBAL_LAST_PAGE);
2567 	add_default_key(&scope_keys, "q", GLOBAL_QUIT);
2568 	add_default_key(&scope_keys, "r", SCOPE_RENAME);
2569 	add_default_key(&scope_keys, ">", GLOBAL_SCROLL_DOWN);
2570 	add_default_key(&scope_keys, "<", GLOBAL_SCROLL_UP);
2571 #ifndef NO_SHELL_ESCAPE
2572 	add_default_key(&scope_keys, "!", GLOBAL_SHELL_ESCAPE);
2573 #endif /* !NO_SHELL_ESCAPE */
2574 
2575 	/* select level */
2576 	add_global_keys(&select_keys);
2577 	add_default_key(&select_keys, "\n\r", SELECT_ENTER_GROUP);
2578 	add_default_key(&select_keys, "", SELECT_RESET_NEWSRC);
2579 	add_default_key(&select_keys, "c", CATCHUP);
2580 	add_default_key(&select_keys, "d", SELECT_TOGGLE_DESCRIPTIONS);
2581 	add_default_key(&select_keys, "g", SELECT_GOTO);
2582 	add_default_key(&select_keys, "m", SELECT_MOVE_GROUP);
2583 	add_default_key(&select_keys, "n\t", SELECT_ENTER_NEXT_UNREAD_GROUP);
2584 	add_default_key(&select_keys, "r", SELECT_TOGGLE_READ_DISPLAY);
2585 	add_default_key(&select_keys, "s", SELECT_SUBSCRIBE);
2586 	add_default_key(&select_keys, "u", SELECT_UNSUBSCRIBE);
2587 	add_default_key(&select_keys, "y", SELECT_YANK_ACTIVE);
2588 	add_default_key(&select_keys, "z", SELECT_MARK_GROUP_UNREAD);
2589 	add_default_key(&select_keys, "C", CATCHUP_NEXT_UNREAD);
2590 	add_default_key(&select_keys, "E", GLOBAL_EDIT_FILTER);
2591 #ifdef NNTP_ABLE
2592 	add_default_key(&select_keys, "L", GLOBAL_LOOKUP_MESSAGEID);
2593 #endif /* NNTP_ABLE */
2594 	add_default_key(&select_keys, "N", SELECT_NEXT_UNREAD_GROUP);
2595 	add_default_key(&select_keys, "S", SELECT_SUBSCRIBE_PATTERN);
2596 	add_default_key(&select_keys, "U", SELECT_UNSUBSCRIBE_PATTERN);
2597 	add_default_key(&select_keys, "X", SELECT_QUIT_NO_WRITE);
2598 	add_default_key(&select_keys, "Y", SELECT_SYNC_WITH_ACTIVE);
2599 	add_default_key(&select_keys, "Z", SELECT_MARK_GROUP_UNREAD);
2600 	add_default_key(&select_keys, ".", SELECT_SORT_ACTIVE);
2601 	add_default_key(&select_keys, ">", GLOBAL_SCROLL_DOWN);
2602 	add_default_key(&select_keys, "<", GLOBAL_SCROLL_UP);
2603 
2604 	/* group level */
2605 	add_global_keys(&group_keys);
2606 	add_default_key(&group_keys, "", GLOBAL_MENU_FILTER_SELECT);
2607 	add_default_key(&group_keys, "\n\r", GROUP_READ_BASENOTE);
2608 	add_default_key(&group_keys, "", GLOBAL_MENU_FILTER_KILL);
2609 	add_default_key(&group_keys, "", MARK_FEED_READ);
2610 	add_default_key(&group_keys, "", MARK_FEED_UNREAD);
2611 	add_default_key(&group_keys, "a", GLOBAL_SEARCH_AUTHOR_FORWARD);
2612 	add_default_key(&group_keys, "c", CATCHUP);
2613 	add_default_key(&group_keys, "d", GROUP_TOGGLE_SUBJECT_DISPLAY);
2614 	add_default_key(&group_keys, "g", GROUP_GOTO);
2615 	add_default_key(&group_keys, "l", GROUP_LIST_THREAD);
2616 	add_default_key(&group_keys, "m", GROUP_MAIL);
2617 	add_default_key(&group_keys, "n", GROUP_NEXT_GROUP);
2618 #ifndef DISABLE_PRINTING
2619 	add_default_key(&group_keys, "o", GLOBAL_PRINT);
2620 #endif /* !DISABLE_PRINTING */
2621 	add_default_key(&group_keys, "p", GROUP_PREVIOUS_GROUP);
2622 	add_default_key(&group_keys, "r", GROUP_TOGGLE_READ_UNREAD);
2623 	add_default_key(&group_keys, "s", GROUP_SAVE);
2624 	add_default_key(&group_keys, "t", GROUP_TAG);
2625 	add_default_key(&group_keys, "u", GROUP_TOGGLE_THREADING);
2626 	add_default_key(&group_keys, "x", GROUP_REPOST);
2627 	add_default_key(&group_keys, "z", MARK_ARTICLE_UNREAD);
2628 	add_default_key(&group_keys, "A", GLOBAL_SEARCH_AUTHOR_BACKWARD);
2629 	add_default_key(&group_keys, "B", GLOBAL_SEARCH_BODY);
2630 	add_default_key(&group_keys, "C", CATCHUP_NEXT_UNREAD);
2631 	add_default_key(&group_keys, "D", GROUP_CANCEL);
2632 	add_default_key(&group_keys, "E", GLOBAL_EDIT_FILTER);
2633 	add_default_key(&group_keys, "G", GROUP_TOGGLE_GET_ARTICLES_LIMIT);
2634 	add_default_key(&group_keys, "K", GROUP_MARK_THREAD_READ);
2635 	add_default_key(&group_keys, "L", GLOBAL_LOOKUP_MESSAGEID);
2636 	add_default_key(&group_keys, "N", GROUP_NEXT_UNREAD_ARTICLE);
2637 	add_default_key(&group_keys, "P", GROUP_PREVIOUS_UNREAD_ARTICLE);
2638 	add_default_key(&group_keys, "S", GROUP_AUTOSAVE);
2639 	add_default_key(&group_keys, "T", GROUP_TAG_PARTS);
2640 	add_default_key(&group_keys, "U", GROUP_UNTAG);
2641 	add_default_key(&group_keys, "X", GROUP_MARK_UNSELECTED_ARTICLES_READ);
2642 	add_default_key(&group_keys, "Z", MARK_THREAD_UNREAD);
2643 	add_default_key(&group_keys, "\t", GROUP_NEXT_UNREAD_ARTICLE_OR_GROUP);
2644 	add_default_key(&group_keys, "-", GLOBAL_LAST_VIEWED);
2645 	add_default_key(&group_keys, "|", GLOBAL_PIPE);
2646 	add_default_key(&group_keys, "[", GLOBAL_QUICK_FILTER_SELECT);
2647 	add_default_key(&group_keys, "]", GLOBAL_QUICK_FILTER_KILL);
2648 	add_default_key(&group_keys, "*", GROUP_SELECT_THREAD);
2649 	add_default_key(&group_keys, ".", GROUP_TOGGLE_SELECT_THREAD);
2650 	add_default_key(&group_keys, "@", GROUP_REVERSE_SELECTIONS);
2651 	add_default_key(&group_keys, "~", GROUP_UNDO_SELECTIONS);
2652 	add_default_key(&group_keys, "=", GROUP_SELECT_PATTERN);
2653 	add_default_key(&group_keys, ";", GROUP_SELECT_THREAD_IF_UNREAD_SELECTED);
2654 	add_default_key(&group_keys, "+", GROUP_DO_AUTOSELECT);
2655 	add_default_key(&group_keys, ">", GLOBAL_SCROLL_DOWN);
2656 	add_default_key(&group_keys, "<", GLOBAL_SCROLL_UP);
2657 
2658 	/* thread keys */
2659 	add_global_keys(&thread_keys);
2660 	add_default_key(&thread_keys, "", GLOBAL_MENU_FILTER_SELECT);
2661 	add_default_key(&thread_keys, "", GLOBAL_MENU_FILTER_KILL);
2662 	add_default_key(&thread_keys, "", MARK_FEED_READ);
2663 	add_default_key(&thread_keys, "", MARK_FEED_UNREAD);
2664 	add_default_key(&thread_keys, "\n\r", THREAD_READ_ARTICLE);
2665 	add_default_key(&thread_keys, "a", GLOBAL_SEARCH_AUTHOR_FORWARD);
2666 	add_default_key(&thread_keys, "c", CATCHUP);
2667 	add_default_key(&thread_keys, "d", THREAD_TOGGLE_SUBJECT_DISPLAY);
2668 	add_default_key(&thread_keys, "m", THREAD_MAIL);
2669 #ifndef DISABLE_PRINTING
2670 	add_default_key(&thread_keys, "o", GLOBAL_PRINT);
2671 #endif /* !DISABLE_PRINTING */
2672 	add_default_key(&thread_keys, "s", THREAD_SAVE);
2673 	add_default_key(&thread_keys, "t", THREAD_TAG);
2674 	add_default_key(&thread_keys, "z", MARK_ARTICLE_UNREAD);
2675 	add_default_key(&thread_keys, "A", GLOBAL_SEARCH_AUTHOR_BACKWARD);
2676 	add_default_key(&thread_keys, "B", GLOBAL_SEARCH_BODY);
2677 	add_default_key(&thread_keys, "C", CATCHUP_NEXT_UNREAD);
2678 	add_default_key(&thread_keys, "D", THREAD_CANCEL);
2679 	add_default_key(&thread_keys, "E", GLOBAL_EDIT_FILTER);
2680 	add_default_key(&thread_keys, "K", THREAD_MARK_ARTICLE_READ);
2681 	add_default_key(&thread_keys, "L", GLOBAL_LOOKUP_MESSAGEID);
2682 	add_default_key(&thread_keys, "S", THREAD_AUTOSAVE);
2683 	add_default_key(&thread_keys, "T", THREAD_TAG_PARTS);
2684 	add_default_key(&thread_keys, "U", THREAD_UNTAG);
2685 	add_default_key(&thread_keys, "Z", MARK_THREAD_UNREAD);
2686 	add_default_key(&thread_keys, "\t", THREAD_READ_NEXT_ARTICLE_OR_THREAD);
2687 	add_default_key(&thread_keys, "-", GLOBAL_LAST_VIEWED);
2688 	add_default_key(&thread_keys, "|", GLOBAL_PIPE);
2689 	add_default_key(&thread_keys, "*", THREAD_SELECT_ARTICLE);
2690 	add_default_key(&thread_keys, ".", THREAD_TOGGLE_ARTICLE_SELECTION);
2691 	add_default_key(&thread_keys, "@", THREAD_REVERSE_SELECTIONS);
2692 	add_default_key(&thread_keys, "~", THREAD_UNDO_SELECTIONS);
2693 	add_default_key(&thread_keys, ">", GLOBAL_SCROLL_DOWN);
2694 	add_default_key(&thread_keys, "<", GLOBAL_SCROLL_UP);
2695 
2696 	/* page level */
2697 	add_global_keys(&page_keys);
2698 	add_default_key(&page_keys, "", GLOBAL_MENU_FILTER_SELECT);
2699 	add_default_key(&page_keys, "", PAGE_REPLY_QUOTE_HEADERS);
2700 #ifdef HAVE_PGP_GPG
2701 	add_default_key(&page_keys, "", PAGE_PGP_CHECK_ARTICLE);
2702 #endif /* HAVE_PGP_GPG */
2703 	add_default_key(&page_keys, "", PAGE_TOGGLE_RAW);
2704 	add_default_key(&page_keys, "", GLOBAL_MENU_FILTER_KILL);
2705 	add_default_key(&page_keys, "\n\r", PAGE_NEXT_THREAD);
2706 	add_default_key(&page_keys, "", PAGE_TOGGLE_TABS);
2707 	add_default_key(&page_keys, "", PAGE_FOLLOWUP_QUOTE_HEADERS);
2708 	add_default_key(&page_keys, "a", GLOBAL_SEARCH_AUTHOR_FORWARD);
2709 	add_default_key(&page_keys, "c", CATCHUP);
2710 	add_default_key(&page_keys, "e", PAGE_EDIT_ARTICLE);
2711 	add_default_key(&page_keys, "f", PAGE_FOLLOWUP_QUOTE);
2712 	add_default_key(&page_keys, "g", GLOBAL_FIRST_PAGE);
2713 	add_default_key(&page_keys, "l", PAGE_LIST_THREAD);
2714 	add_default_key(&page_keys, "m", PAGE_MAIL);
2715 	add_default_key(&page_keys, "n", PAGE_NEXT_ARTICLE);
2716 #ifndef DISABLE_PRINTING
2717 	add_default_key(&page_keys, "o", GLOBAL_PRINT);
2718 #endif /* !DISABLE_PRINTING */
2719 	add_default_key(&page_keys, "p", PAGE_PREVIOUS_ARTICLE);
2720 	add_default_key(&page_keys, "r", PAGE_REPLY_QUOTE);
2721 	add_default_key(&page_keys, "s", PAGE_SAVE);
2722 	add_default_key(&page_keys, "t", PAGE_TAG);
2723 	add_default_key(&page_keys, "u", PAGE_GOTO_PARENT);
2724 	add_default_key(&page_keys, "x", PAGE_REPOST);
2725 	add_default_key(&page_keys, "z", MARK_ARTICLE_UNREAD);
2726 	add_default_key(&page_keys, "A", GLOBAL_SEARCH_AUTHOR_BACKWARD);
2727 	add_default_key(&page_keys, "B", GLOBAL_SEARCH_BODY);
2728 	add_default_key(&page_keys, "C", CATCHUP_NEXT_UNREAD);
2729 	add_default_key(&page_keys, "D", PAGE_CANCEL);
2730 	add_default_key(&page_keys, "E", GLOBAL_EDIT_FILTER);
2731 	add_default_key(&page_keys, "F", PAGE_FOLLOWUP);
2732 	add_default_key(&page_keys, "G", GLOBAL_LAST_PAGE);
2733 	add_default_key(&page_keys, "K", PAGE_MARK_THREAD_READ);
2734 	add_default_key(&page_keys, "L", GLOBAL_LOOKUP_MESSAGEID);
2735 	add_default_key(&page_keys, "N", PAGE_NEXT_UNREAD_ARTICLE);
2736 	add_default_key(&page_keys, "P", PAGE_PREVIOUS_UNREAD_ARTICLE);
2737 	add_default_key(&page_keys, "R", PAGE_REPLY);
2738 	add_default_key(&page_keys, "S", PAGE_AUTOSAVE);
2739 	add_default_key(&page_keys, "T", PAGE_GROUP_SELECT);
2740 	add_default_key(&page_keys, "U", PAGE_VIEW_URL);
2741 	add_default_key(&page_keys, "V", PAGE_VIEW_ATTACHMENTS);
2742 	add_default_key(&page_keys, "Z", MARK_THREAD_UNREAD);
2743 	add_default_key(&page_keys, "\t", PAGE_NEXT_UNREAD);
2744 	add_default_key(&page_keys, "-", GLOBAL_LAST_VIEWED);
2745 	add_default_key(&page_keys, "|", GLOBAL_PIPE);
2746 	add_default_key(&page_keys, "<", PAGE_TOP_THREAD);
2747 	add_default_key(&page_keys, ">", PAGE_BOTTOM_THREAD);
2748 	add_default_key(&page_keys, "\"", PAGE_TOGGLE_TEX2ISO);
2749 	add_default_key(&page_keys, "(", PAGE_TOGGLE_UUE);
2750 	add_default_key(&page_keys, ")", PAGE_REVEAL);
2751 	add_default_key(&page_keys, "[", GLOBAL_QUICK_FILTER_SELECT);
2752 	add_default_key(&page_keys, "]", GLOBAL_QUICK_FILTER_KILL);
2753 	add_default_key(&page_keys, "%", PAGE_TOGGLE_ROT13);
2754 	add_default_key(&page_keys, "*", PAGE_TOGGLE_HEADERS);
2755 	add_default_key(&page_keys, ":", PAGE_SKIP_INCLUDED_TEXT);
2756 	add_default_key(&page_keys, "_", PAGE_TOGGLE_HIGHLIGHTING);
2757 
2758 	/* info pager */
2759 	add_default_key(&info_keys, "", GLOBAL_ABORT);
2760 	add_default_key(&info_keys, "j", GLOBAL_LINE_DOWN);
2761 	add_default_key(&info_keys, "k", GLOBAL_LINE_UP);
2762 	add_default_key(&info_keys, " ", GLOBAL_PAGE_DOWN);
2763 	add_default_key(&info_keys, "b", GLOBAL_PAGE_UP);
2764 	add_default_key(&info_keys, "g^", GLOBAL_FIRST_PAGE);
2765 	add_default_key(&info_keys, "G$", GLOBAL_LAST_PAGE);
2766 	add_default_key(&info_keys, "q", GLOBAL_QUIT);
2767 	add_default_key(&info_keys, "H", GLOBAL_TOGGLE_HELP_DISPLAY);
2768 	add_default_key(&info_keys, "/", GLOBAL_SEARCH_SUBJECT_FORWARD);
2769 	add_default_key(&info_keys, "?", GLOBAL_SEARCH_SUBJECT_BACKWARD);
2770 	add_default_key(&info_keys, "\\", GLOBAL_SEARCH_REPEAT);
2771 
2772 	/* options menu */
2773 	add_default_key(&option_menu_keys, "1", DIGIT_1);
2774 	add_default_key(&option_menu_keys, "2", DIGIT_2);
2775 	add_default_key(&option_menu_keys, "3", DIGIT_3);
2776 	add_default_key(&option_menu_keys, "4", DIGIT_4);
2777 	add_default_key(&option_menu_keys, "5", DIGIT_5);
2778 	add_default_key(&option_menu_keys, "6", DIGIT_6);
2779 	add_default_key(&option_menu_keys, "7", DIGIT_7);
2780 	add_default_key(&option_menu_keys, "8", DIGIT_8);
2781 	add_default_key(&option_menu_keys, "9", DIGIT_9);
2782 	add_default_key(&option_menu_keys, "b", GLOBAL_PAGE_UP);
2783 	add_default_key(&option_menu_keys, " ", GLOBAL_PAGE_DOWN);
2784 	add_default_key(&option_menu_keys, "\n\r", CONFIG_SELECT);
2785 	add_default_key(&option_menu_keys, "\t", CONFIG_TOGGLE_ATTRIB);
2786 	add_default_key(&option_menu_keys, "", GLOBAL_REDRAW_SCREEN);
2787 	add_default_key(&option_menu_keys, "j", GLOBAL_LINE_DOWN);
2788 	add_default_key(&option_menu_keys, "k", GLOBAL_LINE_UP);
2789 	add_default_key(&option_menu_keys, "g^", GLOBAL_FIRST_PAGE);
2790 	add_default_key(&option_menu_keys, "G$", GLOBAL_LAST_PAGE);
2791 	add_default_key(&option_menu_keys, "h", GLOBAL_HELP);
2792 	add_default_key(&option_menu_keys, "q", GLOBAL_QUIT);
2793 	add_default_key(&option_menu_keys, "r", CONFIG_RESET_ATTRIB);
2794 	add_default_key(&option_menu_keys, "v", GLOBAL_VERSION);
2795 	add_default_key(&option_menu_keys, "Q", CONFIG_NO_SAVE);
2796 	add_default_key(&option_menu_keys, "S", CONFIG_SCOPE_MENU);
2797 	add_default_key(&option_menu_keys, ">", GLOBAL_SCROLL_DOWN);
2798 	add_default_key(&option_menu_keys, "<", GLOBAL_SCROLL_UP);
2799 	add_default_key(&option_menu_keys, "/", GLOBAL_SEARCH_SUBJECT_FORWARD);
2800 	add_default_key(&option_menu_keys, "?", GLOBAL_SEARCH_SUBJECT_BACKWARD);
2801 	add_default_key(&option_menu_keys, "\\", GLOBAL_SEARCH_REPEAT);
2802 #ifndef NO_SHELL_ESCAPE
2803 	add_default_key(&option_menu_keys, "!", GLOBAL_SHELL_ESCAPE);
2804 #endif /* !NO_SHELL_ESCAPE */
2805 
2806 	/* prompt keys */
2807 	add_default_key(&prompt_keys, "", GLOBAL_ABORT);
2808 	add_default_key(&prompt_keys, "nN", PROMPT_NO);
2809 	add_default_key(&prompt_keys, "q", GLOBAL_QUIT);
2810 	add_default_key(&prompt_keys, "yY", PROMPT_YES);
2811 
2812 	/* post keys */
2813 	add_default_key(&post_send_keys, "", GLOBAL_ABORT);
2814 	add_default_key(&post_send_keys, "e", POST_EDIT);
2815 #ifdef HAVE_PGP_GPG
2816 	add_default_key(&post_send_keys, "g", POST_PGP);
2817 #endif /* HAVE_PGP_GPG */
2818 #ifdef HAVE_ISPELL
2819 	add_default_key(&post_send_keys, "i", POST_ISPELL);
2820 #endif /* HAVE_ISPELL */
2821 	add_default_key(&post_send_keys, "q", GLOBAL_QUIT);
2822 	add_default_key(&post_send_keys, "s", POST_SEND);
2823 
2824 	add_default_key(&post_edit_keys, "", GLOBAL_ABORT);
2825 	add_default_key(&post_edit_keys, "e", POST_EDIT);
2826 	add_default_key(&post_edit_keys, "o", POST_POSTPONE);
2827 	add_default_key(&post_edit_keys, "q", GLOBAL_QUIT);
2828 
2829 	add_default_key(&post_edit_ext_keys, "", GLOBAL_ABORT);
2830 	add_default_key(&post_edit_ext_keys, "e", POST_EDIT);
2831 	add_default_key(&post_edit_ext_keys, "q", GLOBAL_QUIT);
2832 	add_default_key(&post_edit_ext_keys, "M", GLOBAL_OPTION_MENU);
2833 
2834 	add_default_key(&post_post_keys, "", GLOBAL_ABORT);
2835 	add_default_key(&post_post_keys, "e", POST_EDIT);
2836 #ifdef HAVE_PGP_GPG
2837 	add_default_key(&post_post_keys, "g", POST_PGP);
2838 #endif /* HAVE_PGP_GPG */
2839 #ifdef HAVE_ISPELL
2840 	add_default_key(&post_post_keys, "i", POST_ISPELL);
2841 #endif /* HAVE_ISPELL */
2842 	add_default_key(&post_post_keys, "o", POST_POSTPONE);
2843 	add_default_key(&post_post_keys, "p", GLOBAL_POST);
2844 	add_default_key(&post_post_keys, "q", GLOBAL_QUIT);
2845 	add_default_key(&post_post_keys, "M", GLOBAL_OPTION_MENU);
2846 
2847 	add_default_key(&post_postpone_keys, "", GLOBAL_ABORT);
2848 	add_default_key(&post_postpone_keys, "n", PROMPT_NO);
2849 	add_default_key(&post_postpone_keys, "q", GLOBAL_QUIT);
2850 	add_default_key(&post_postpone_keys, "y", PROMPT_YES);
2851 	add_default_key(&post_postpone_keys, "A", POSTPONE_ALL);
2852 	add_default_key(&post_postpone_keys, "Y", POSTPONE_OVERRIDE);
2853 
2854 	add_default_key(&post_mail_fup_keys, "", GLOBAL_ABORT);
2855 	add_default_key(&post_mail_fup_keys, "m", POST_MAIL);
2856 	add_default_key(&post_mail_fup_keys, "p", GLOBAL_POST);
2857 	add_default_key(&post_mail_fup_keys, "q", GLOBAL_QUIT);
2858 
2859 	add_default_key(&post_ignore_fupto_keys, "", GLOBAL_ABORT);
2860 	add_default_key(&post_ignore_fupto_keys, "i", POST_IGNORE_FUPTO);
2861 	add_default_key(&post_ignore_fupto_keys, "p", GLOBAL_POST);
2862 	add_default_key(&post_ignore_fupto_keys, "q", GLOBAL_QUIT);
2863 
2864 	add_default_key(&post_continue_keys, "", GLOBAL_ABORT);
2865 	add_default_key(&post_continue_keys, "a", POST_ABORT);
2866 	add_default_key(&post_continue_keys, "c", POST_CONTINUE);
2867 	add_default_key(&post_continue_keys, "q", GLOBAL_QUIT);
2868 
2869 	add_default_key(&post_delete_keys, "", GLOBAL_ABORT);
2870 	add_default_key(&post_delete_keys, "d", POST_CANCEL);
2871 	add_default_key(&post_delete_keys, "q", GLOBAL_QUIT);
2872 	add_default_key(&post_delete_keys, "s", POST_SUPERSEDE);
2873 
2874 	add_default_key(&post_cancel_keys, "", GLOBAL_ABORT);
2875 	add_default_key(&post_cancel_keys, "e", POST_EDIT);
2876 	add_default_key(&post_cancel_keys, "d", POST_CANCEL);
2877 	add_default_key(&post_cancel_keys, "q", GLOBAL_QUIT);
2878 
2879 	/* feed keys */
2880 	add_default_key(&feed_post_process_keys, "", GLOBAL_ABORT);
2881 	add_default_key(&feed_post_process_keys, "n", POSTPROCESS_NO);
2882 	add_default_key(&feed_post_process_keys, "s", POSTPROCESS_SHAR);
2883 	add_default_key(&feed_post_process_keys, "y", POSTPROCESS_YES);
2884 	add_default_key(&feed_post_process_keys, "q", GLOBAL_QUIT);
2885 
2886 	add_default_key(&feed_type_keys, "", GLOBAL_ABORT);
2887 	add_default_key(&feed_type_keys, "a", FEED_ARTICLE);
2888 	add_default_key(&feed_type_keys, "h", FEED_HOT);
2889 	add_default_key(&feed_type_keys, "p", FEED_PATTERN);
2890 	add_default_key(&feed_type_keys, "r", FEED_RANGE);
2891 	add_default_key(&feed_type_keys, "q", GLOBAL_QUIT);
2892 	add_default_key(&feed_type_keys, "t", FEED_THREAD);
2893 	add_default_key(&feed_type_keys, "T", FEED_TAGGED);
2894 
2895 	add_default_key(&feed_supersede_article_keys, "", GLOBAL_ABORT);
2896 	add_default_key(&feed_supersede_article_keys, "q", GLOBAL_QUIT);
2897 	add_default_key(&feed_supersede_article_keys, "r", FEED_KEY_REPOST);
2898 	add_default_key(&feed_supersede_article_keys, "s", FEED_SUPERSEDE);
2899 
2900 	/* filter keys */
2901 	add_default_key(&filter_keys, "", GLOBAL_ABORT);
2902 	add_default_key(&filter_keys, "e", FILTER_EDIT);
2903 	add_default_key(&filter_keys, "q", GLOBAL_QUIT);
2904 	add_default_key(&filter_keys, "s", FILTER_SAVE);
2905 
2906 #ifdef HAVE_PGP_GPG
2907 	/* pgp mail */
2908 	add_default_key(&pgp_mail_keys, "", GLOBAL_ABORT);
2909 	add_default_key(&pgp_mail_keys, "b", PGP_KEY_ENCRYPT_SIGN);
2910 	add_default_key(&pgp_mail_keys, "e", PGP_KEY_ENCRYPT);
2911 	add_default_key(&pgp_mail_keys, "q", GLOBAL_QUIT);
2912 	add_default_key(&pgp_mail_keys, "s", PGP_KEY_SIGN);
2913 
2914 	/* pgp news */
2915 	add_default_key(&pgp_news_keys, "", GLOBAL_ABORT);
2916 	add_default_key(&pgp_news_keys, "i", PGP_INCLUDE_KEY);
2917 	add_default_key(&pgp_news_keys, "q", GLOBAL_QUIT);
2918 	add_default_key(&pgp_news_keys, "s", PGP_KEY_SIGN);
2919 #endif /* HAVE_PGP_GPG */
2920 
2921 	/* save */
2922 	add_default_key(&save_append_overwrite_keys, "", GLOBAL_ABORT);
2923 	add_default_key(&save_append_overwrite_keys, "a", SAVE_APPEND_FILE);
2924 	add_default_key(&save_append_overwrite_keys, "o", SAVE_OVERWRITE_FILE);
2925 	add_default_key(&save_append_overwrite_keys, "q", GLOBAL_QUIT);
2926 
2927 	/* url level */
2928 	add_default_key(&url_keys, "", GLOBAL_ABORT);
2929 	add_default_key(&url_keys, "1", DIGIT_1);
2930 	add_default_key(&url_keys, "2", DIGIT_2);
2931 	add_default_key(&url_keys, "3", DIGIT_3);
2932 	add_default_key(&url_keys, "4", DIGIT_4);
2933 	add_default_key(&url_keys, "5", DIGIT_5);
2934 	add_default_key(&url_keys, "6", DIGIT_6);
2935 	add_default_key(&url_keys, "7", DIGIT_7);
2936 	add_default_key(&url_keys, "8", DIGIT_8);
2937 	add_default_key(&url_keys, "9", DIGIT_9);
2938 	add_default_key(&url_keys, "b", GLOBAL_PAGE_UP);
2939 	add_default_key(&url_keys, " ", GLOBAL_PAGE_DOWN);
2940 	add_default_key(&url_keys, "h", GLOBAL_HELP);
2941 	add_default_key(&url_keys, "\n\r", URL_SELECT);
2942 	add_default_key(&url_keys, "H", GLOBAL_TOGGLE_HELP_DISPLAY);
2943 	add_default_key(&url_keys, "", GLOBAL_REDRAW_SCREEN);
2944 	add_default_key(&url_keys, "j", GLOBAL_LINE_DOWN);
2945 	add_default_key(&url_keys, "k", GLOBAL_LINE_UP);
2946 	add_default_key(&url_keys, "g^", GLOBAL_FIRST_PAGE);
2947 	add_default_key(&url_keys, "G$", GLOBAL_LAST_PAGE);
2948 	add_default_key(&url_keys, "i", GLOBAL_TOGGLE_INFO_LAST_LINE);
2949 	add_default_key(&url_keys, "q", GLOBAL_QUIT);
2950 	add_default_key(&url_keys, ">", GLOBAL_SCROLL_DOWN);
2951 	add_default_key(&url_keys, "<", GLOBAL_SCROLL_UP);
2952 	add_default_key(&url_keys, "/", GLOBAL_SEARCH_SUBJECT_FORWARD);
2953 	add_default_key(&url_keys, "?", GLOBAL_SEARCH_SUBJECT_BACKWARD);
2954 	add_default_key(&url_keys, "\\", GLOBAL_SEARCH_REPEAT);
2955 #ifndef NO_SHELL_ESCAPE
2956 	add_default_key(&url_keys, "!", GLOBAL_SHELL_ESCAPE);
2957 #endif /* !NO_SHELL_ESCAPE */
2958 }
2959 
2960 
2961 /*
2962  * used to add the common keys of SELECT_LEVEL, GROUP_LEVEL, THREAD_LEVEL
2963  * and PAGE_LEVEL
2964  */
2965 static void
2966 add_global_keys(
2967 	struct keylist *keys)
2968 {
2969 	add_default_key(keys, "", GLOBAL_ABORT);
2970 	add_default_key(keys, "0", DIGIT_0);
2971 	add_default_key(keys, "1", DIGIT_1);
2972 	add_default_key(keys, "2", DIGIT_2);
2973 	add_default_key(keys, "3", DIGIT_3);
2974 	add_default_key(keys, "4", DIGIT_4);
2975 	add_default_key(keys, "5", DIGIT_5);
2976 	add_default_key(keys, "6", DIGIT_6);
2977 	add_default_key(keys, "7", DIGIT_7);
2978 	add_default_key(keys, "8", DIGIT_8);
2979 	add_default_key(keys, "9", DIGIT_9);
2980 	add_default_key(keys, "b", GLOBAL_PAGE_UP);
2981 	add_default_key(keys, " ", GLOBAL_PAGE_DOWN);
2982 	add_default_key(keys, "", GLOBAL_REDRAW_SCREEN);
2983 	add_default_key(keys, "j", GLOBAL_LINE_DOWN);
2984 	add_default_key(keys, "k", GLOBAL_LINE_UP);
2985 	add_default_key(keys, "O", GLOBAL_POSTPONED);
2986 	add_default_key(keys, "h", GLOBAL_HELP);
2987 	add_default_key(keys, "i", GLOBAL_TOGGLE_INFO_LAST_LINE);
2988 	add_default_key(keys, "q", GLOBAL_QUIT);
2989 	add_default_key(keys, "v", GLOBAL_VERSION);
2990 	add_default_key(keys, "w", GLOBAL_POST);
2991 	add_default_key(keys, "H", GLOBAL_TOGGLE_HELP_DISPLAY);
2992 	add_default_key(keys, "I", GLOBAL_TOGGLE_INVERSE_VIDEO);
2993 	add_default_key(keys, "M", GLOBAL_OPTION_MENU);
2994 	add_default_key(keys, "Q", GLOBAL_QUIT_TIN);
2995 	add_default_key(keys, "R", GLOBAL_BUGREPORT);
2996 	add_default_key(keys, "W", GLOBAL_DISPLAY_POST_HISTORY);
2997 	add_default_key(keys, "^", GLOBAL_FIRST_PAGE);
2998 	add_default_key(keys, "$", GLOBAL_LAST_PAGE);
2999 	add_default_key(keys, "/", GLOBAL_SEARCH_SUBJECT_FORWARD);
3000 	add_default_key(keys, "?", GLOBAL_SEARCH_SUBJECT_BACKWARD);
3001 	add_default_key(keys, "\\", GLOBAL_SEARCH_REPEAT);
3002 	add_default_key(keys, "#", GLOBAL_SET_RANGE);
3003 #ifndef NO_SHELL_ESCAPE
3004 	add_default_key(keys, "!", GLOBAL_SHELL_ESCAPE);
3005 #endif /* !NO_SHELL_ESCAPE */
3006 #ifdef HAVE_COLOR
3007 	add_default_key(keys, "&", GLOBAL_TOGGLE_COLOR);
3008 #endif /* HAVE COLOR */
3009 }
3010