kbdcontrol: add -P path option to add keymap search paths

PR:		193865
Reviewed by:	cem
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D5645
This commit is contained in:
emaste 2016-03-16 04:05:02 +00:00
parent 565ee84920
commit d0976574d3
2 changed files with 72 additions and 22 deletions

View File

@ -13,7 +13,7 @@
.\" @(#)kbdcontrol.1
.\" $FreeBSD$
.\"
.Dd January 29, 2008
.Dd March 16, 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,12 @@ and write the
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.
.El
.Sh ENVIRONMENT
The environment variable

View File

@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <fcntl.h>
#include <sys/kbio.h>
#include <sys/consio.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include "path.h"
#include "lex.h"
@ -112,11 +113,13 @@ static const int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63,
static const int ndelays = (sizeof(delays) / sizeof(int));
static const int nrepeats = (sizeof(repeats) / sizeof(int));
static int hex = 0;
static int paths_configured = 0;
static int token;
int number;
char letter;
static void add_keymap_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 +145,12 @@ static void set_keyrates(char *opt);
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)
@ -279,11 +288,11 @@ get_entry(void)
}
static int
get_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap)
get_definition_line(FILE *file, keymap_t *keymap, accentmap_t *accentmap)
{
int c;
yyin = fd;
yyin = file;
if (token < 0)
token = yylex();
@ -790,33 +799,58 @@ dump_accent_definition(char *name, accentmap_t *accentmap)
printf("} };\n\n");
}
static void
add_keymap_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;
FILE *fd;
int i, j;
struct pathent *pe;
FILE *file;
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);
if (!paths_configured) {
cp = getenv("KEYMAP_PATH");
if (cp != NULL)
add_keymap_path(cp);
add_keymap_path("");
if (is_vt4())
add_keymap_path(vt_keymap_path);
else
add_keymap_path(keymap_path);
paths_configured = 1;
}
fd = NULL;
for (i=0; prefix[i] && fd == NULL; i++) {
for (j=0; postfix[j] && fd == NULL; j++) {
name = mkfullname(prefix[i], opt, postfix[j]);
fd = fopen(name, "r");
file = NULL;
STAILQ_FOREACH(pe, &pathlist, next) {
for (j=0; postfix[j] && file == NULL; j++) {
name = mkfullname(pe->path, opt, postfix[j]);
file = fopen(name, "r");
if (file != NULL)
break;
}
}
if (fd == NULL) {
if (file == NULL) {
warn("keymap file \"%s\" not found", opt);
return;
}
@ -824,7 +858,7 @@ load_keymap(char *opt, int dumponly)
memset(&accentmap, 0, sizeof(accentmap));
token = -1;
while (1) {
if (get_definition_line(fd, &keymap, &accentmap) < 0)
if (get_definition_line(file, &keymap, &accentmap) < 0)
break;
}
if (dumponly) {
@ -841,13 +875,13 @@ load_keymap(char *opt, int dumponly)
}
if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) {
warn("setting keymap");
fclose(fd);
fclose(file);
return;
}
if ((accentmap.n_accs > 0)
&& (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) {
warn("setting accentmap");
fclose(fd);
fclose(file);
return;
}
}
@ -1170,7 +1204,7 @@ usage(void)
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);
}
@ -1178,9 +1212,16 @@ usage(void)
int
main(int argc, char **argv)
{
const char *optstring = "A:a:b:df:iKk:Fl:L:P:r:x";
int opt;
while((opt = getopt(argc, argv, "A:a:b:df:iKk:Fl:L:r:x")) != -1)
/* Collect any -P arguments, regardless of where they appear. */
while ((opt = getopt(argc, argv, optstring)) != -1)
if (opt == 'P')
add_keymap_path(optarg);
optind = optreset = 1;
while ((opt = getopt(argc, argv, optstring)) != -1)
switch(opt) {
case 'A':
case 'a':
@ -1198,6 +1239,8 @@ main(int argc, char **argv)
case 'L':
load_keymap(optarg, 1);
break;
case 'P':
break;
case 'f':
set_functionkey(optarg,
nextarg(argc, argv, &optind, 'f'));