Blame src/setleds.c

Packit Service 50ad14
/*
Packit Service 50ad14
 * setleds.c - aeb, 940130, 940909, 991008
Packit Service 50ad14
 *
Packit Service 50ad14
 * Call: setleds [-L] [-D] [-F] [{+|-}{num|caps|scroll}]*
Packit Service 50ad14
 * will set or clear the indicated flags on the stdin tty,
Packit Service 50ad14
 * and report the settings before and after.
Packit Service 50ad14
 * In particular, setleds without arguments will only report.
Packit Service 50ad14
 */
Packit Service 50ad14
#include "config.h"
Packit Service 50ad14
Packit Service 50ad14
#include <stdio.h>
Packit Service 50ad14
#include <stdlib.h>
Packit Service 50ad14
#include <errno.h>
Packit Service 50ad14
#include <fcntl.h>
Packit Service 50ad14
#include <linux/kd.h>
Packit Service 50ad14
#include <sys/ioctl.h>
Packit Service 50ad14
#include "nls.h"
Packit Service 50ad14
#include "version.h"
Packit Service 50ad14
#include "kbd_error.h"
Packit Service 50ad14
Packit Service 50ad14
static void __attribute__((noreturn))
Packit Service 50ad14
usage(void)
Packit Service 50ad14
{
Packit Service 50ad14
	fprintf(stderr, _(
Packit Service 50ad14
	                    "Usage:\n"
Packit Service 50ad14
	                    "	setleds [-v] [-L] [-D] [-F] [[+|-][ num | caps | scroll %s]]\n"
Packit Service 50ad14
	                    "Thus,\n"
Packit Service 50ad14
	                    "	setleds +caps -num\n"
Packit Service 50ad14
	                    "will set CapsLock, clear NumLock and leave ScrollLock unchanged.\n"
Packit Service 50ad14
	                    "The settings before and after the change (if any) are reported\n"
Packit Service 50ad14
	                    "when the -v option is given or when no change is requested.\n"
Packit Service 50ad14
	                    "Normally, setleds influences the vt flag settings\n"
Packit Service 50ad14
	                    "(and these are usually reflected in the leds).\n"
Packit Service 50ad14
	                    "With -L, setleds only sets the leds, and leaves the flags alone.\n"
Packit Service 50ad14
	                    "With -D, setleds sets both the flags and the default flags, so\n"
Packit Service 50ad14
	                    "that a subsequent reset will not change the flags.\n"),
Packit Service 50ad14
#ifdef __sparc__
Packit Service 50ad14
	        "| compose "
Packit Service 50ad14
#else
Packit Service 50ad14
	        ""
Packit Service 50ad14
#endif
Packit Service 50ad14
	        );
Packit Service 50ad14
	exit(EXIT_FAILURE);
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
#define onoff(a) ((a) ? _("on ") : _("off"))
Packit Service 50ad14
Packit Service 50ad14
/* report the bits, in the order seen on the (my) keyboard */
Packit Service 50ad14
#define LED_NLOCK 1
Packit Service 50ad14
#define LED_CMPOSE 2
Packit Service 50ad14
#define LED_SCRLCK 4
Packit Service 50ad14
#define LED_CLOCK 8
Packit Service 50ad14
Packit Service 50ad14
static void
Packit Service 50ad14
sunreport(int leds)
Packit Service 50ad14
{
Packit Service 50ad14
	printf("NumLock %s   Compose %s   ScrollLock %s   CapsLock %s\n",
Packit Service 50ad14
	       onoff(leds & LED_NLOCK),
Packit Service 50ad14
	       onoff(leds & LED_CMPOSE),
Packit Service 50ad14
	       onoff(leds & LED_SCRLCK),
Packit Service 50ad14
	       onoff(leds & LED_CLOCK));
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
static void
Packit Service 50ad14
report(int leds)
Packit Service 50ad14
{
Packit Service 50ad14
	printf("NumLock %s   CapsLock %s   ScrollLock %s\n",
Packit Service 50ad14
	       onoff(leds & LED_NUM),
Packit Service 50ad14
	       onoff(leds & LED_CAP),
Packit Service 50ad14
	       onoff(leds & LED_SCR));
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
struct led {
Packit Service 50ad14
	char *name;
Packit Service 50ad14
	int bit;
Packit Service 50ad14
	int sunbit;
Packit Service 50ad14
} leds[] = {
Packit Service 50ad14
	{ "scroll", LED_SCR, LED_SCRLCK },
Packit Service 50ad14
	{ "num", LED_NUM, LED_NLOCK },
Packit Service 50ad14
	{ "caps", LED_CAP, LED_CLOCK },
Packit Service 50ad14
#ifdef __sparc__
Packit Service 50ad14
	{ "compose", 0, LED_CMPOSE }
Packit Service 50ad14
#endif
Packit Service 50ad14
};
Packit Service 50ad14
Packit Service 50ad14
static void
Packit Service 50ad14
getleds(char *cur_leds)
Packit Service 50ad14
{
Packit Service 50ad14
	if (ioctl(0, KDGETLED, cur_leds)) {
Packit Service 50ad14
		kbd_error(EXIT_FAILURE, errno, _("Error reading current led setting. "
Packit Service 50ad14
		                                 "Maybe stdin is not a VT?: "
Packit Service 50ad14
		                                 "ioctl KDGETLED"));
Packit Service 50ad14
	}
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
static int
Packit Service 50ad14
setleds(char cur_leds)
Packit Service 50ad14
{
Packit Service 50ad14
	if (ioctl(0, KDSETLED, cur_leds)) {
Packit Service 50ad14
		kbd_warning(errno, "ioctl KDSETLED");
Packit Service 50ad14
		return -1;
Packit Service 50ad14
	}
Packit Service 50ad14
	return 0;
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
static void
Packit Service 50ad14
getflags(char *flags)
Packit Service 50ad14
{
Packit Service 50ad14
	if (ioctl(0, KDGKBLED, flags)) {
Packit Service 50ad14
		kbd_error(EXIT_FAILURE, errno, _("Error reading current flags setting. "
Packit Service 50ad14
		                                 "Maybe you are not on the console?: "
Packit Service 50ad14
		                                 "ioctl KDGKBLED"));
Packit Service 50ad14
	}
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
static int sunkbdfd = -1;
Packit Service 50ad14
Packit Service 50ad14
#ifndef KIOCGLED
Packit Service 50ad14
#define arg_state __attribute__((unused))
Packit Service 50ad14
#else
Packit Service 50ad14
#define arg_state
Packit Service 50ad14
#endif
Packit Service 50ad14
Packit Service 50ad14
static void
Packit Service 50ad14
sungetleds(arg_state char *cur_leds)
Packit Service 50ad14
{
Packit Service 50ad14
#ifdef KIOCGLED
Packit Service 50ad14
	if (ioctl(sunkbdfd, KIOCGLED, cur_leds)) {
Packit Service 50ad14
		kbd_error(EXIT_FAILURE, errno, _("Error reading current led setting from /dev/kbd: "
Packit Service 50ad14
		                                 "ioctl KIOCGLED"));
Packit Service 50ad14
	}
Packit Service 50ad14
#else
Packit Service 50ad14
	kbd_error(EXIT_FAILURE, 0, _("KIOCGLED unavailable?\n"));
Packit Service 50ad14
#endif
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
#ifndef KIOCSLED
Packit Service 50ad14
#define arg_state __attribute__((unused))
Packit Service 50ad14
#else
Packit Service 50ad14
#define arg_state
Packit Service 50ad14
#endif
Packit Service 50ad14
Packit Service 50ad14
static void
Packit Service 50ad14
sunsetleds(arg_state char *cur_leds)
Packit Service 50ad14
{
Packit Service 50ad14
#ifdef KIOCSLED
Packit Service 50ad14
	if (ioctl(sunkbdfd, KIOCSLED, cur_leds)) {
Packit Service 50ad14
		kbd_error(EXIT_FAILURE, errno, _("Error reading current led setting from /dev/kbd: "
Packit Service 50ad14
		                                 "ioctl KIOCSLED"));
Packit Service 50ad14
	}
Packit Service 50ad14
#else
Packit Service 50ad14
	kbd_error(EXIT_FAILURE, 0, _("KIOCSLED unavailable?\n"));
Packit Service 50ad14
#endif
Packit Service 50ad14
}
Packit Service 50ad14
Packit Service 50ad14
int main(int argc, char **argv)
Packit Service 50ad14
{
Packit Service 50ad14
	int optL = 0, optD = 0, optF = 0, verbose = 0;
Packit Service 50ad14
	char oleds, nleds, oflags, nflags, odefflags, ndefflags;
Packit Service 50ad14
	char nval, ndef, sign;
Packit Service 50ad14
	char osunleds = 0, nsunleds, nsunval, nsundef;
Packit Service 50ad14
	char *ap;
Packit Service 50ad14
	struct led *lp;
Packit Service 50ad14
Packit Service 50ad14
	set_progname(argv[0]);
Packit Service 50ad14
Packit Service 50ad14
	setlocale(LC_ALL, "");
Packit Service 50ad14
	bindtextdomain(PACKAGE_NAME, LOCALEDIR);
Packit Service 50ad14
	textdomain(PACKAGE_NAME);
Packit Service 50ad14
Packit Service 50ad14
	if (argc == 2 && (!strcmp("-V", argv[1]) || !strcmp("--version", argv[1])))
Packit Service 50ad14
		print_version_and_exit();
Packit Service 50ad14
Packit Service 50ad14
#ifdef __sparc__
Packit Service 50ad14
	if ((sunkbdfd = open("/dev/kbd", O_RDONLY)) < 0) {
Packit Service 50ad14
		kbd_error(EXIT_FAILURE, errno, "open /dev/kbd");
Packit Service 50ad14
		/* exit(1); */
Packit Service 50ad14
	}
Packit Service 50ad14
#endif
Packit Service 50ad14
Packit Service 50ad14
	getflags(&oflags);
Packit Service 50ad14
	getleds(&oleds);
Packit Service 50ad14
	if (sunkbdfd >= 0)
Packit Service 50ad14
		sungetleds(&osunleds);
Packit Service 50ad14
Packit Service 50ad14
	while (argc > 1) {
Packit Service 50ad14
		if (!strcmp("-L", argv[1]))
Packit Service 50ad14
			optL = 1;
Packit Service 50ad14
		else if (!strcmp("-D", argv[1]))
Packit Service 50ad14
			optD = 1;
Packit Service 50ad14
		else if (!strcmp("-F", argv[1]))
Packit Service 50ad14
			optF = 1;
Packit Service 50ad14
		else if (!strcmp("-v", argv[1]))
Packit Service 50ad14
			verbose = 1;
Packit Service 50ad14
		else
Packit Service 50ad14
			break;
Packit Service 50ad14
		argc--;
Packit Service 50ad14
		argv++;
Packit Service 50ad14
	}
Packit Service 50ad14
Packit Service 50ad14
	odefflags = ndefflags = ((oflags >> 4) & 7);
Packit Service 50ad14
	oflags = nflags = (oflags & 7);
Packit Service 50ad14
Packit Service 50ad14
	if (argc <= 1) {
Packit Service 50ad14
		if (optL) {
Packit Service 50ad14
			nleds = 0xff;
Packit Service 50ad14
			if (setleds(nleds)) {
Packit Service 50ad14
				kbd_error(EXIT_FAILURE, 0, _("Error resetting ledmode\n"));
Packit Service 50ad14
			}
Packit Service 50ad14
		}
Packit Service 50ad14
Packit Service 50ad14
		/* If nothing to do, report, even if not verbose */
Packit Service 50ad14
		if (!optD && !optL && !optF)
Packit Service 50ad14
			optD = optL = optF = 1;
Packit Service 50ad14
		if (optD) {
Packit Service 50ad14
			printf(_("Current default flags:  "));
Packit Service 50ad14
			report(odefflags);
Packit Service 50ad14
		}
Packit Service 50ad14
		if (optF) {
Packit Service 50ad14
			printf(_("Current flags:          "));
Packit Service 50ad14
			report(oflags & 07);
Packit Service 50ad14
		}
Packit Service 50ad14
		if (optL) {
Packit Service 50ad14
			printf(_("Current leds:           "));
Packit Service 50ad14
			if (sunkbdfd >= 0)
Packit Service 50ad14
				sunreport(osunleds);
Packit Service 50ad14
			else
Packit Service 50ad14
				report(oleds);
Packit Service 50ad14
		}
Packit Service 50ad14
		exit(EXIT_SUCCESS);
Packit Service 50ad14
	}
Packit Service 50ad14
Packit Service 50ad14
	if (!optL)
Packit Service 50ad14
		optF = 1;
Packit Service 50ad14
	nval         = 0;
Packit Service 50ad14
	ndef         = 0;
Packit Service 50ad14
	nsunval      = 0;
Packit Service 50ad14
	nsundef      = 0;
Packit Service 50ad14
Packit Service 50ad14
	while (--argc) {
Packit Service 50ad14
		ap   = *++argv;
Packit Service 50ad14
		sign = 1; /* by default: set */
Packit Service 50ad14
		if (*ap == '+')
Packit Service 50ad14
			ap++;
Packit Service 50ad14
		else if (*ap == '-') {
Packit Service 50ad14
			sign = 0;
Packit Service 50ad14
			ap++;
Packit Service 50ad14
		}
Packit Service 50ad14
		for (lp = leds; (unsigned)(lp - leds) < sizeof(leds) / sizeof(leds[0]); lp++) {
Packit Service 50ad14
			if (!strcmp(ap, lp->name)) {
Packit Service 50ad14
				if (sign) {
Packit Service 50ad14
					nval |= lp->bit;
Packit Service 50ad14
					nsunval |= lp->sunbit;
Packit Service 50ad14
				}
Packit Service 50ad14
				ndef |= lp->bit;
Packit Service 50ad14
				nsundef |= lp->sunbit;
Packit Service 50ad14
				goto nxtarg;
Packit Service 50ad14
			}
Packit Service 50ad14
		}
Packit Service 50ad14
		fprintf(stderr, _("unrecognized argument: _%s_\n\n"), ap);
Packit Service 50ad14
		usage();
Packit Service 50ad14
Packit Service 50ad14
	nxtarg:;
Packit Service 50ad14
	}
Packit Service 50ad14
Packit Service 50ad14
	if (optD) {
Packit Service 50ad14
		ndefflags = (odefflags & ~ndef) | nval;
Packit Service 50ad14
		if (verbose) {
Packit Service 50ad14
			printf(_("Old default flags:    "));
Packit Service 50ad14
			report(odefflags);
Packit Service 50ad14
			printf(_("New default flags:    "));
Packit Service 50ad14
			report(ndefflags);
Packit Service 50ad14
		}
Packit Service 50ad14
	}
Packit Service 50ad14
	if (optF) {
Packit Service 50ad14
		nflags = ((oflags & ~ndef) | nval);
Packit Service 50ad14
		if (verbose) {
Packit Service 50ad14
			printf(_("Old flags:            "));
Packit Service 50ad14
			report(oflags & 07);
Packit Service 50ad14
			printf(_("New flags:            "));
Packit Service 50ad14
			report(nflags & 07);
Packit Service 50ad14
		}
Packit Service 50ad14
	}
Packit Service 50ad14
	if (optD || optF) {
Packit Service 50ad14
		if (ioctl(0, KDSKBLED, (ndefflags << 4) | nflags)) {
Packit Service 50ad14
			kbd_error(EXIT_FAILURE, errno, "ioctl KDSKBLED");
Packit Service 50ad14
		}
Packit Service 50ad14
	}
Packit Service 50ad14
	if (optL) {
Packit Service 50ad14
		if (sunkbdfd >= 0) {
Packit Service 50ad14
			nsunleds = (osunleds & ~nsundef) | nsunval;
Packit Service 50ad14
			if (verbose) {
Packit Service 50ad14
				printf(_("Old leds:             "));
Packit Service 50ad14
				sunreport(osunleds);
Packit Service 50ad14
				printf(_("New leds:             "));
Packit Service 50ad14
				sunreport(nsunleds);
Packit Service 50ad14
			}
Packit Service 50ad14
			sunsetleds(&nsunleds);
Packit Service 50ad14
		} else {
Packit Service 50ad14
			nleds = (oleds & ~ndef) | nval;
Packit Service 50ad14
			if (verbose) {
Packit Service 50ad14
				printf(_("Old leds:             "));
Packit Service 50ad14
				report(oleds);
Packit Service 50ad14
				printf(_("New leds:             "));
Packit Service 50ad14
				report(nleds);
Packit Service 50ad14
			}
Packit Service 50ad14
			if (setleds(nleds))
Packit Service 50ad14
				exit(EXIT_FAILURE);
Packit Service 50ad14
		}
Packit Service 50ad14
	}
Packit Service 50ad14
	exit(EXIT_SUCCESS);
Packit Service 50ad14
}