Index: usr.sbin/kbdcontrol/kbdcontrol.1 =================================================================== --- usr.sbin/kbdcontrol/kbdcontrol.1 +++ usr.sbin/kbdcontrol/kbdcontrol.1 @@ -13,7 +13,7 @@ .\" @(#)kbdcontrol.1 .\" $FreeBSD$ .\" -.Dd January 29, 2008 +.Dd March 15, 2016 .Dt KBDCONTROL 1 .Os .Sh NAME @@ -36,6 +36,7 @@ .Op Fl f Ar # Ar string .Op Fl k Ar keyboard_device .Op Fl L Ar keymap_file +.Op Fl P Ar path .Sh DESCRIPTION The .Nm @@ -171,6 +172,16 @@ compiled from it to stdout. This option is primarily intended for programmers and is probably of little use under normal circumstances. +.It Fl P Ar path +Search for the keymap file in +.Ar path . +The +.Fl P +option may be specified multiple times, and must appear before the +.Fl l +or +.Fl L +option. .El .Sh ENVIRONMENT The environment variable Index: usr.sbin/kbdcontrol/kbdcontrol.c =================================================================== --- usr.sbin/kbdcontrol/kbdcontrol.c +++ usr.sbin/kbdcontrol/kbdcontrol.c @@ -29,6 +29,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -117,6 +118,7 @@ int number; char letter; +static void add_path(const char *path); static void dump_accent_definition(char *name, accentmap_t *accentmap); static void dump_entry(int value); static void dump_key_definition(char *name, keymap_t *keymap); @@ -142,6 +144,12 @@ static void show_kbd_info(void); static void usage(void) __dead2; +struct pathent { + STAILQ_ENTRY(pathent) next; + char *path; +}; +static STAILQ_HEAD(, pathent) pathlist = STAILQ_HEAD_INITIALIZER(pathlist); + /* Detect presence of vt(4). */ static int is_vt4(void) @@ -791,29 +799,51 @@ } static void +add_path(const char *path) +{ + struct pathent* pe; + size_t len; + + len = strlen(path); + if ((pe = malloc(sizeof(*pe))) == NULL || + (pe->path = malloc(len + 2)) == NULL) + err(1, "malloc"); + memcpy(pe->path, path, len); + if (len > 0 && path[len - 1] != '/') + pe->path[len++] = '/'; + pe->path[len] = '\0'; + STAILQ_INSERT_TAIL(&pathlist, pe, next); +} + +static void load_keymap(char *opt, int dumponly) { keymap_t keymap; accentmap_t accentmap; + struct pathent *pe; FILE *fd; - int i, j; + int j; char *name, *cp; char blank[] = "", keymap_path[] = KEYMAP_PATH; char vt_keymap_path[] = VT_KEYMAP_PATH, dotkbd[] = ".kbd"; - char *prefix[] = {blank, blank, keymap_path, NULL}; char *postfix[] = {blank, dotkbd, NULL}; - if (is_vt4()) - prefix[2] = vt_keymap_path; cp = getenv("KEYMAP_PATH"); if (cp != NULL) - asprintf(&(prefix[0]), "%s/", cp); + add_path(cp); + add_path(""); + if (is_vt4()) + add_path(vt_keymap_path); + else + add_path(keymap_path); fd = NULL; - for (i=0; prefix[i] && fd == NULL; i++) { + STAILQ_FOREACH(pe, &pathlist, next) { for (j=0; postfix[j] && fd == NULL; j++) { - name = mkfullname(prefix[i], opt, postfix[j]); + name = mkfullname(pe->path, opt, postfix[j]); fd = fopen(name, "r"); + if (fd != NULL) + break; } } if (fd == NULL) { @@ -1170,7 +1200,7 @@ fprintf(stderr, "%s\n%s\n%s\n", "usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]", " [-r delay.repeat | speed] [-l mapfile] [-f # string]", -" [-k device] [-L mapfile]"); +" [-k device] [-L mapfile] [-P path]"); exit(1); } @@ -1180,7 +1210,7 @@ { int opt; - while((opt = getopt(argc, argv, "A:a:b:df:iKk:Fl:L:r:x")) != -1) + while((opt = getopt(argc, argv, "A:a:b:df:iKk:Fl:L:P:r:x")) != -1) switch(opt) { case 'A': case 'a': @@ -1198,6 +1228,9 @@ case 'L': load_keymap(optarg, 1); break; + case 'P': + add_path(optarg); + break; case 'f': set_functionkey(optarg, nextarg(argc, argv, &optind, 'f'));