Linux console tools development discussion
 help / color / mirror / Atom feed
* [kbd] [PATCH] kbd_mode: Add -f option and deny dangerous mode switches without it
@ 2019-04-23 15:38 Balint Reczey
  2019-05-08  9:19 ` Alexey Gladkov
  0 siblings, 1 reply; 4+ messages in thread
From: Balint Reczey @ 2019-04-23 15:38 UTC (permalink / raw)
  To: kbd

kbd_mode(1) already had a warning but kbd_mode still performed all
mode changes even when they made keyboards unusable.

The added flag let's the callers try safe changes or force the risky
ones. This change may break scripts but the broken scripts most likely
made the keyboard unusable and should be updated.

Original bug report at:
https://bugs.launchpad.net/ubuntu/+source/kbd/+bug/520546

Signed-off-by: Balint Reczey <balint.reczey@canonical.com>
---
 docs/man/man1/kbd_mode.1 |  8 +++--
 src/kbd_mode.c           | 65 ++++++++++++++++++++++++++++------------
 2 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/docs/man/man1/kbd_mode.1 b/docs/man/man1/kbd_mode.1
index 960b36c..f605c02 100644
--- a/docs/man/man1/kbd_mode.1
+++ b/docs/man/man1/kbd_mode.1
@@ -7,6 +7,8 @@ kbd_mode \- report or set the keyboard mode
 [
 .I -a | -u | -k | -s 
 ] [
+.I -f
+] [
 .I -C CONSOLE
 ]
 .SH DESCRIPTION
@@ -36,11 +38,13 @@ kbd_mode operates on the console specified by the "\-C" option; if there
 is none, the console associated with stdin is used.
 
 Warning: changing the keyboard mode, other than between ASCII and
-Unicode, will probably make your keyboard unusable.
+Unicode, will probably make your keyboard unusable. Set the "\-f" option
+to force such changes.
 This command is only meant for use (say via remote login)
 when some program left your keyboard in the wrong state.
 Note that in some obsolete versions of this program the "\-u"
-option was a synonym for "\-s".
+option was a synonym for "\-s" and older versions of this program may
+not recognize the "\-f" option.
 .SH "SEE ALSO"
 .BR loadkeys (1)
 
diff --git a/src/kbd_mode.c b/src/kbd_mode.c
index 5d291b7..956ea51 100644
--- a/src/kbd_mode.c
+++ b/src/kbd_mode.c
@@ -20,13 +20,34 @@
 static void __attribute__((noreturn))
 usage(void)
 {
-	fprintf(stderr, _("usage: kbd_mode [-a|-u|-k|-s] [-C device]\n"));
+	fprintf(stderr, _("usage: kbd_mode [-a|-u|-k|-s] [-f] [-C device]\n"));
 	exit(EXIT_FAILURE);
 }
 
+static void
+fprint_mode(FILE *stream, int  mode)
+{
+	switch (mode) {
+		case K_RAW:
+			fprintf(stream, _("The keyboard is in raw (scancode) mode\n"));
+			break;
+		case K_MEDIUMRAW:
+			fprintf(stream, _("The keyboard is in mediumraw (keycode) mode\n"));
+			break;
+		case K_XLATE:
+			fprintf(stream, _("The keyboard is in the default (ASCII) mode\n"));
+			break;
+		case K_UNICODE:
+			fprintf(stream, _("The keyboard is in Unicode (UTF-8) mode\n"));
+			break;
+		default:
+			fprintf(stream, _("The keyboard is in some unknown mode\n"));
+        }
+}
+
 int main(int argc, char *argv[])
 {
-	int fd, mode, c, n = 0;
+	int fd, mode, orig_mode, c, n = 0, force = 0;
 	char *console = NULL;
 
 	set_progname(argv[0]);
@@ -38,7 +59,7 @@ int main(int argc, char *argv[])
 	if (argc == 2 && !strcmp(argv[1], "-V"))
 		print_version_and_exit();
 
-	while ((c = getopt(argc, argv, "auskC:")) != EOF) {
+	while ((c = getopt(argc, argv, "auskfC:")) != EOF) {
 		switch (c) {
 			case 'a':
 				if (n > 0)
@@ -64,6 +85,9 @@ int main(int argc, char *argv[])
 				mode = K_MEDIUMRAW;
 				n++;
 				break;
+			case 'f':
+				force = 1;
+				break;
 			case 'C':
 				if (!optarg || !optarg[0])
 					usage();
@@ -82,25 +106,28 @@ int main(int argc, char *argv[])
 		if (ioctl(fd, KDGKBMODE, &mode)) {
 			kbd_error(EXIT_FAILURE, errno, "ioctl KDGKBMODE");
 		}
-		switch (mode) {
-			case K_RAW:
-				printf(_("The keyboard is in raw (scancode) mode\n"));
-				break;
-			case K_MEDIUMRAW:
-				printf(_("The keyboard is in mediumraw (keycode) mode\n"));
-				break;
-			case K_XLATE:
-				printf(_("The keyboard is in the default (ASCII) mode\n"));
-				break;
-			case K_UNICODE:
-				printf(_("The keyboard is in Unicode (UTF-8) mode\n"));
-				break;
-			default:
-				printf(_("The keyboard is in some unknown mode\n"));
-		}
+		fprint_mode(stdout, mode);
 		return EXIT_SUCCESS;
 	}
 
+	if (force == 0) {
+		/* only perform safe mode switches */
+		if (ioctl(fd, KDGKBMODE, &orig_mode)) {
+			kbd_error(EXIT_FAILURE, errno, "ioctl KDGKBMODE");
+		}
+
+		if (mode == orig_mode) {
+			/* skip mode change */
+			return EXIT_SUCCESS;
+		}
+
+		if ((mode == K_XLATE && orig_mode != K_UNICODE) || (mode == K_UNICODE && orig_mode != K_XLATE)) {
+			fprint_mode(stderr, orig_mode);
+			fprintf(stderr, _("Changing to the requested mode may make "
+				"your keyboard unusable, please use -f to force the change.\n"));
+			return EXIT_FAILURE;
+		}
+	}
 	if (ioctl(fd, KDSKBMODE, mode)) {
 		kbd_error(EXIT_FAILURE, errno, "ioctl KDSKBMODE");
 	}
-- 
2.17.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [kbd] [PATCH] kbd_mode: Add -f option and deny dangerous mode switches without it
  2019-04-23 15:38 [kbd] [PATCH] kbd_mode: Add -f option and deny dangerous mode switches without it Balint Reczey
@ 2019-05-08  9:19 ` Alexey Gladkov
  2019-06-12 13:05   ` Bálint Réczey
  0 siblings, 1 reply; 4+ messages in thread
From: Alexey Gladkov @ 2019-05-08  9:19 UTC (permalink / raw)
  To: Linux console tools development discussion

On Tue, Apr 23, 2019 at 05:38:07PM +0200, Balint Reczey wrote:
> kbd_mode(1) already had a warning but kbd_mode still performed all
> mode changes even when they made keyboards unusable.
> 
> The added flag let's the callers try safe changes or force the risky
> ones. This change may break scripts but the broken scripts most likely
> made the keyboard unusable and should be updated.
> 
> Original bug report at:
> https://bugs.launchpad.net/ubuntu/+source/kbd/+bug/520546
> 
> Signed-off-by: Balint Reczey <balint.reczey@canonical.com>

It sounds sane. Applied. Thanks!

> ---
>  docs/man/man1/kbd_mode.1 |  8 +++--
>  src/kbd_mode.c           | 65 ++++++++++++++++++++++++++++------------
>  2 files changed, 52 insertions(+), 21 deletions(-)
> 
> diff --git a/docs/man/man1/kbd_mode.1 b/docs/man/man1/kbd_mode.1
> index 960b36c..f605c02 100644
> --- a/docs/man/man1/kbd_mode.1
> +++ b/docs/man/man1/kbd_mode.1
> @@ -7,6 +7,8 @@ kbd_mode \- report or set the keyboard mode
>  [
>  .I -a | -u | -k | -s 
>  ] [
> +.I -f
> +] [
>  .I -C CONSOLE
>  ]
>  .SH DESCRIPTION
> @@ -36,11 +38,13 @@ kbd_mode operates on the console specified by the "\-C" option; if there
>  is none, the console associated with stdin is used.
>  
>  Warning: changing the keyboard mode, other than between ASCII and
> -Unicode, will probably make your keyboard unusable.
> +Unicode, will probably make your keyboard unusable. Set the "\-f" option
> +to force such changes.
>  This command is only meant for use (say via remote login)
>  when some program left your keyboard in the wrong state.
>  Note that in some obsolete versions of this program the "\-u"
> -option was a synonym for "\-s".
> +option was a synonym for "\-s" and older versions of this program may
> +not recognize the "\-f" option.
>  .SH "SEE ALSO"
>  .BR loadkeys (1)
>  
> diff --git a/src/kbd_mode.c b/src/kbd_mode.c
> index 5d291b7..956ea51 100644
> --- a/src/kbd_mode.c
> +++ b/src/kbd_mode.c
> @@ -20,13 +20,34 @@
>  static void __attribute__((noreturn))
>  usage(void)
>  {
> -	fprintf(stderr, _("usage: kbd_mode [-a|-u|-k|-s] [-C device]\n"));
> +	fprintf(stderr, _("usage: kbd_mode [-a|-u|-k|-s] [-f] [-C device]\n"));
>  	exit(EXIT_FAILURE);
>  }
>  
> +static void
> +fprint_mode(FILE *stream, int  mode)
> +{
> +	switch (mode) {
> +		case K_RAW:
> +			fprintf(stream, _("The keyboard is in raw (scancode) mode\n"));
> +			break;
> +		case K_MEDIUMRAW:
> +			fprintf(stream, _("The keyboard is in mediumraw (keycode) mode\n"));
> +			break;
> +		case K_XLATE:
> +			fprintf(stream, _("The keyboard is in the default (ASCII) mode\n"));
> +			break;
> +		case K_UNICODE:
> +			fprintf(stream, _("The keyboard is in Unicode (UTF-8) mode\n"));
> +			break;
> +		default:
> +			fprintf(stream, _("The keyboard is in some unknown mode\n"));
> +        }
> +}
> +
>  int main(int argc, char *argv[])
>  {
> -	int fd, mode, c, n = 0;
> +	int fd, mode, orig_mode, c, n = 0, force = 0;
>  	char *console = NULL;
>  
>  	set_progname(argv[0]);
> @@ -38,7 +59,7 @@ int main(int argc, char *argv[])
>  	if (argc == 2 && !strcmp(argv[1], "-V"))
>  		print_version_and_exit();
>  
> -	while ((c = getopt(argc, argv, "auskC:")) != EOF) {
> +	while ((c = getopt(argc, argv, "auskfC:")) != EOF) {
>  		switch (c) {
>  			case 'a':
>  				if (n > 0)
> @@ -64,6 +85,9 @@ int main(int argc, char *argv[])
>  				mode = K_MEDIUMRAW;
>  				n++;
>  				break;
> +			case 'f':
> +				force = 1;
> +				break;
>  			case 'C':
>  				if (!optarg || !optarg[0])
>  					usage();
> @@ -82,25 +106,28 @@ int main(int argc, char *argv[])
>  		if (ioctl(fd, KDGKBMODE, &mode)) {
>  			kbd_error(EXIT_FAILURE, errno, "ioctl KDGKBMODE");
>  		}
> -		switch (mode) {
> -			case K_RAW:
> -				printf(_("The keyboard is in raw (scancode) mode\n"));
> -				break;
> -			case K_MEDIUMRAW:
> -				printf(_("The keyboard is in mediumraw (keycode) mode\n"));
> -				break;
> -			case K_XLATE:
> -				printf(_("The keyboard is in the default (ASCII) mode\n"));
> -				break;
> -			case K_UNICODE:
> -				printf(_("The keyboard is in Unicode (UTF-8) mode\n"));
> -				break;
> -			default:
> -				printf(_("The keyboard is in some unknown mode\n"));
> -		}
> +		fprint_mode(stdout, mode);
>  		return EXIT_SUCCESS;
>  	}
>  
> +	if (force == 0) {
> +		/* only perform safe mode switches */
> +		if (ioctl(fd, KDGKBMODE, &orig_mode)) {
> +			kbd_error(EXIT_FAILURE, errno, "ioctl KDGKBMODE");
> +		}
> +
> +		if (mode == orig_mode) {
> +			/* skip mode change */
> +			return EXIT_SUCCESS;
> +		}
> +
> +		if ((mode == K_XLATE && orig_mode != K_UNICODE) || (mode == K_UNICODE && orig_mode != K_XLATE)) {
> +			fprint_mode(stderr, orig_mode);
> +			fprintf(stderr, _("Changing to the requested mode may make "
> +				"your keyboard unusable, please use -f to force the change.\n"));
> +			return EXIT_FAILURE;
> +		}
> +	}
>  	if (ioctl(fd, KDSKBMODE, mode)) {
>  		kbd_error(EXIT_FAILURE, errno, "ioctl KDSKBMODE");
>  	}
> -- 
> 2.17.1
> 
> _______________________________________________
> kbd mailing list
> kbd@lists.altlinux.org
> https://lists.altlinux.org/mailman/listinfo/kbd
> 

-- 
Rgrds, legion



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [kbd] [PATCH] kbd_mode: Add -f option and deny dangerous mode switches without it
  2019-05-08  9:19 ` Alexey Gladkov
@ 2019-06-12 13:05   ` Bálint Réczey
  2019-06-17  8:40     ` Alexey Gladkov
  0 siblings, 1 reply; 4+ messages in thread
From: Bálint Réczey @ 2019-06-12 13:05 UTC (permalink / raw)
  To: Linux console tools development discussion

Hi Alexey,

Alexey Gladkov <gladkov.alexey@gmail.com> ezt írta (időpont: 2019.
máj. 8., Sze, 11:19):
>
> On Tue, Apr 23, 2019 at 05:38:07PM +0200, Balint Reczey wrote:
> > kbd_mode(1) already had a warning but kbd_mode still performed all
> > mode changes even when they made keyboards unusable.
> >
> > The added flag let's the callers try safe changes or force the risky
> > ones. This change may break scripts but the broken scripts most likely
> > made the keyboard unusable and should be updated.
> >
> > Original bug report at:
> > https://bugs.launchpad.net/ubuntu/+source/kbd/+bug/520546
> >
> > Signed-off-by: Balint Reczey <balint.reczey@canonical.com>
>
> It sounds sane. Applied. Thanks!

Thanks!

When do you plan making the next release?
It would be nice to have this change widely tested in distributions.
Debian starts a new release cycle soon and Ubuntu is around the middle
of the LTS cycle, too, thus we could start testing a new kbd release
soon.

Cheers,
Balint


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [kbd] [PATCH] kbd_mode: Add -f option and deny dangerous mode switches without it
  2019-06-12 13:05   ` Bálint Réczey
@ 2019-06-17  8:40     ` Alexey Gladkov
  0 siblings, 0 replies; 4+ messages in thread
From: Alexey Gladkov @ 2019-06-17  8:40 UTC (permalink / raw)
  To: balint, Linux console tools development discussion

On Wed, Jun 12, 2019 at 03:05:57PM +0200, Bálint Réczey wrote:
> Hi Alexey,
> 
> Alexey Gladkov <gladkov.alexey@gmail.com> ezt írta (időpont: 2019.
> máj. 8., Sze, 11:19):
> >
> > On Tue, Apr 23, 2019 at 05:38:07PM +0200, Balint Reczey wrote:
> > > kbd_mode(1) already had a warning but kbd_mode still performed all
> > > mode changes even when they made keyboards unusable.
> > >
> > > The added flag let's the callers try safe changes or force the risky
> > > ones. This change may break scripts but the broken scripts most likely
> > > made the keyboard unusable and should be updated.
> > >
> > > Original bug report at:
> > > https://bugs.launchpad.net/ubuntu/+source/kbd/+bug/520546
> > >
> > > Signed-off-by: Balint Reczey <balint.reczey@canonical.com>
> >
> > It sounds sane. Applied. Thanks!
> 
> Thanks!
> 
> When do you plan making the next release?
> It would be nice to have this change widely tested in distributions.
> Debian starts a new release cycle soon and Ubuntu is around the middle
> of the LTS cycle, too, thus we could start testing a new kbd release
> soon.

I'm planning a new release at the end of the month or the beginning of the
next.

-- 
Rgrds, legion



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-06-17  8:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-23 15:38 [kbd] [PATCH] kbd_mode: Add -f option and deny dangerous mode switches without it Balint Reczey
2019-05-08  9:19 ` Alexey Gladkov
2019-06-12 13:05   ` Bálint Réczey
2019-06-17  8:40     ` Alexey Gladkov

Linux console tools development discussion

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/kbd/0 kbd/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 kbd kbd/ http://lore.altlinux.org/kbd \
		kbd@lists.altlinux.org kbd@lists.altlinux.ru kbd@lists.altlinux.com
	public-inbox-index kbd

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.kbd


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git