summaryrefslogtreecommitdiffstats
path: root/usr.sbin/kbdcontrol/kbdcontrol.c
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2016-03-16 04:05:02 +0000
committeremaste <emaste@FreeBSD.org>2016-03-16 04:05:02 +0000
commitd0976574d3998776fb6647b0d464ce2e9bcc4351 (patch)
tree4626dacbcd64aa347a5c2b0717c71bccdb134499 /usr.sbin/kbdcontrol/kbdcontrol.c
parent565ee84920b1a1b26a0ef22571abe4c42fd9c133 (diff)
downloadFreeBSD-src-d0976574d3998776fb6647b0d464ce2e9bcc4351.zip
FreeBSD-src-d0976574d3998776fb6647b0d464ce2e9bcc4351.tar.gz
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
Diffstat (limited to 'usr.sbin/kbdcontrol/kbdcontrol.c')
-rw-r--r--usr.sbin/kbdcontrol/kbdcontrol.c87
1 files changed, 65 insertions, 22 deletions
diff --git a/usr.sbin/kbdcontrol/kbdcontrol.c b/usr.sbin/kbdcontrol/kbdcontrol.c
index 0f927ef..f381bd7 100644
--- a/usr.sbin/kbdcontrol/kbdcontrol.c
+++ b/usr.sbin/kbdcontrol/kbdcontrol.c
@@ -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();
@@ -791,32 +800,57 @@ dump_accent_definition(char *name, accentmap_t *accentmap)
}
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);
-
- 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");
+ 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;
+ }
+
+ 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'));
OpenPOWER on IntegriCloud