"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.6.2/src/keymap.c" (9 Dec 2022, 107932 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "keymap.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.6.1_vs_2.6.2.

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