Author: emaste
Date: Tue Apr 19 20:56:02 2016
New Revision: 298297
URL: https://svnweb.freebsd.org/changeset/base/298297

Log:
  MFC r296926: kbdcontrol: add -P path option to add keymap search paths
  
  PR:           193865
  Sponsored by: The FreeBSD Foundation

Modified:
  stable/10/usr.sbin/kbdcontrol/kbdcontrol.1
  stable/10/usr.sbin/kbdcontrol/kbdcontrol.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/kbdcontrol/kbdcontrol.1
==============================================================================
--- stable/10/usr.sbin/kbdcontrol/kbdcontrol.1  Tue Apr 19 20:47:14 2016        
(r298296)
+++ stable/10/usr.sbin/kbdcontrol/kbdcontrol.1  Tue Apr 19 20:56:02 2016        
(r298297)
@@ -13,7 +13,7 @@
 .\"     @(#)kbdcontrol.1
 .\" $FreeBSD$
 .\"
-.Dd January 29, 2008
+.Dd April 19, 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

Modified: stable/10/usr.sbin/kbdcontrol/kbdcontrol.c
==============================================================================
--- stable/10/usr.sbin/kbdcontrol/kbdcontrol.c  Tue Apr 19 20:47:14 2016        
(r298296)
+++ stable/10/usr.sbin/kbdcontrol/kbdcontrol.c  Tue Apr 19 20:56:02 2016        
(r298297)
@@ -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, 
 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, accen
 }
 
 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'));
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to