summaryrefslogtreecommitdiff
path: root/console-tools
diff options
context:
space:
mode:
Diffstat (limited to 'console-tools')
-rw-r--r--console-tools/Config.in105
-rw-r--r--console-tools/Kbuild19
-rw-r--r--console-tools/chvt.c33
-rw-r--r--console-tools/clear.c21
-rw-r--r--console-tools/deallocvt.c37
-rw-r--r--console-tools/dumpkmap.c65
-rw-r--r--console-tools/loadfont.c193
-rw-r--r--console-tools/loadkmap.c61
-rw-r--r--console-tools/openvt.c45
-rw-r--r--console-tools/reset.c32
-rw-r--r--console-tools/resize.c38
-rw-r--r--console-tools/setconsole.c47
-rw-r--r--console-tools/setkeycodes.c53
-rw-r--r--console-tools/setlogcons.c31
14 files changed, 780 insertions, 0 deletions
diff --git a/console-tools/Config.in b/console-tools/Config.in
new file mode 100644
index 000000000..4a5710de6
--- /dev/null
+++ b/console-tools/Config.in
@@ -0,0 +1,105 @@
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Console Utilities"
+
+config CHVT
+ bool "chvt"
+ default n
+ help
+ This program is used to change to another terminal.
+ Example: chvt 4 (change to terminal /dev/tty4)
+
+config CLEAR
+ bool "clear"
+ default n
+ help
+ This program clears the terminal screen.
+
+config DEALLOCVT
+ bool "deallocvt"
+ default n
+ help
+ This program deallocates unused virtual consoles.
+
+config DUMPKMAP
+ bool "dumpkmap"
+ default n
+ help
+ This program dumps the kernel's keyboard translation table to
+ stdout, in binary format. You can then use loadkmap to load it.
+
+config LOADFONT
+ bool "loadfont"
+ default n
+ help
+ This program loads a console font from standard input.
+
+config LOADKMAP
+ bool "loadkmap"
+ default n
+ help
+ This program loads a keyboard translation table from
+ standard input.
+
+config OPENVT
+ bool "openvt"
+ default n
+ help
+ This program is used to start a command on an unused
+ virtual terminal.
+
+config RESET
+ bool "reset"
+ default n
+ help
+ This program is used to reset the terminal screen, if it
+ gets messed up.
+
+config RESIZE
+ bool "resize"
+ default n
+ help
+ This program is used to (re)set the width and height of your current
+ terminal.
+
+config FEATURE_RESIZE_PRINT
+ bool "print environment variables"
+ default n
+ depends on RESIZE
+ help
+ Prints the newly set size (number of columns and rows) of
+ the terminal.
+ E.g.:
+ COLUMNS=80;LINES=44;export COLUMNS LINES;
+
+config SETCONSOLE
+ bool "setconsole"
+ default n
+ help
+ This program redirects the system console to another device,
+ like the current tty while logged in via telnet.
+
+config FEATURE_SETCONSOLE_LONG_OPTIONS
+ bool "Enable long options"
+ default n
+ depends on SET_CONSOLE && GETOPT_LONG
+ help
+ Support long options for the setconsole applet.
+
+config SETKEYCODES
+ bool "setkeycodes"
+ default n
+ help
+ This program loads entries into the kernel's scancode-to-keycode
+ map, allowing unusual keyboards to generate usable keycodes.
+
+config SETLOGCONS
+ bool "setlogcons"
+ default n
+ help
+ This program redirects the output console of kernel messages.
+
+endmenu
diff --git a/console-tools/Kbuild b/console-tools/Kbuild
new file mode 100644
index 000000000..a55bc087c
--- /dev/null
+++ b/console-tools/Kbuild
@@ -0,0 +1,19 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
+#
+# Licensed under the GPL v2, see the file LICENSE in this tarball.
+
+lib-y:=
+lib-$(CONFIG_CHVT) += chvt.o
+lib-$(CONFIG_CLEAR) += clear.o
+lib-$(CONFIG_DEALLOCVT) += deallocvt.o
+lib-$(CONFIG_DUMPKMAP) += dumpkmap.o
+lib-$(CONFIG_SETCONSOLE) += setconsole.o
+lib-$(CONFIG_LOADFONT) += loadfont.o
+lib-$(CONFIG_LOADKMAP) += loadkmap.o
+lib-$(CONFIG_OPENVT) += openvt.o
+lib-$(CONFIG_RESET) += reset.o
+lib-$(CONFIG_RESIZE) += resize.o
+lib-$(CONFIG_SETKEYCODES) += setkeycodes.o
+lib-$(CONFIG_SETLOGCONS) += setlogcons.o
diff --git a/console-tools/chvt.c b/console-tools/chvt.c
new file mode 100644
index 000000000..bbc5a9c31
--- /dev/null
+++ b/console-tools/chvt.c
@@ -0,0 +1,33 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini chvt implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+/* From <linux/vt.h> */
+enum {
+ VT_ACTIVATE = 0x5606, /* make vt active */
+ VT_WAITACTIVE = 0x5607 /* wait for vt active */
+};
+
+int chvt_main(int argc, char **argv)
+{
+ int fd, num;
+
+ if (argc != 2) {
+ bb_show_usage();
+ }
+
+ fd = get_console_fd();
+ num = xatoul_range(argv[1], 1, 63);
+ if ((-1 == ioctl(fd, VT_ACTIVATE, num))
+ || (-1 == ioctl(fd, VT_WAITACTIVE, num))) {
+ bb_perror_msg_and_die("ioctl");
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/console-tools/clear.c b/console-tools/clear.c
new file mode 100644
index 000000000..9686d5004
--- /dev/null
+++ b/console-tools/clear.c
@@ -0,0 +1,21 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini clear implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ */
+
+/* no options, no getopt */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "busybox.h"
+
+
+int clear_main(int argc, char **argv)
+{
+ return printf("\033[H\033[J") != 6;
+}
diff --git a/console-tools/deallocvt.c b/console-tools/deallocvt.c
new file mode 100644
index 000000000..cd581b1c8
--- /dev/null
+++ b/console-tools/deallocvt.c
@@ -0,0 +1,37 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Disallocate virtual terminal(s)
+ *
+ * Copyright (C) 2003 by Tito Ragusa <farmatito@tiscali.it>
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* no options, no getopt */
+
+#include "busybox.h"
+
+/* From <linux/vt.h> */
+enum { VT_DISALLOCATE = 0x5608 }; /* free memory associated to vt */
+
+int deallocvt_main(int argc, char *argv[])
+{
+ /* num = 0 deallocate all unused consoles */
+ int num = 0;
+
+ switch (argc) {
+ case 2:
+ num = xatoul_range(argv[1], 1, 63);
+ /* Fallthrough */
+ case 1:
+ break;
+ default:
+ bb_show_usage();
+ }
+
+ if (-1 == ioctl(get_console_fd(), VT_DISALLOCATE, num)) {
+ bb_perror_msg_and_die("VT_DISALLOCATE");
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/console-tools/dumpkmap.c b/console-tools/dumpkmap.c
new file mode 100644
index 000000000..7c6633ae8
--- /dev/null
+++ b/console-tools/dumpkmap.c
@@ -0,0 +1,65 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini dumpkmap implementation for busybox
+ *
+ * Copyright (C) Arne Bernin <arne@matrix.loopback.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ */
+
+#include "busybox.h"
+
+/* From <linux/kd.h> */
+struct kbentry {
+ unsigned char kb_table;
+ unsigned char kb_index;
+ unsigned short kb_value;
+};
+#define KDGKBENT 0x4B46 /* gets one entry in translation table */
+
+/* From <linux/keyboard.h> */
+#define NR_KEYS 128
+#define MAX_NR_KEYMAPS 256
+
+int dumpkmap_main(int argc, char **argv)
+{
+ struct kbentry ke;
+ int i, j, fd;
+ char flags[MAX_NR_KEYMAPS], magic[] = "bkeymap";
+
+ if (argc >= 2 && *argv[1] == '-')
+ bb_show_usage();
+
+ fd = xopen(CURRENT_VC, O_RDWR);
+
+ write(1, magic, 7);
+
+ /* Here we want to set everything to 0 except for indexes:
+ * [0-2] [4-6] [8-10] [12] */
+ memset(flags, 0x00, MAX_NR_KEYMAPS);
+ memset(flags, 0x01, 13);
+ flags[3] = flags[7] = flags[11] = 0;
+
+ /* dump flags */
+ write(1, flags, MAX_NR_KEYMAPS);
+
+ for (i = 0; i < MAX_NR_KEYMAPS; i++) {
+ if (flags[i] == 1) {
+ for (j = 0; j < NR_KEYS; j++) {
+ ke.kb_index = j;
+ ke.kb_table = i;
+ if (ioctl(fd, KDGKBENT, &ke) < 0) {
+ bb_perror_msg("ioctl failed with %s, %s, %p",
+ (char *)&ke.kb_index,
+ (char *)&ke.kb_table,
+ &ke.kb_value);
+ } else {
+ write(1, (void*)&ke.kb_value, 2);
+ }
+ }
+ }
+ }
+ close(fd);
+ return EXIT_SUCCESS;
+}
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c
new file mode 100644
index 000000000..5a05876c2
--- /dev/null
+++ b/console-tools/loadfont.c
@@ -0,0 +1,193 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * loadfont.c - Eugene Crosser & Andries Brouwer
+ *
+ * Version 0.96bb
+ *
+ * Loads the console font, and possibly the corresponding screen map(s).
+ * (Adapted for busybox by Matej Vela.)
+ */
+#include "busybox.h"
+#include <sys/kd.h>
+
+enum {
+ PSF_MAGIC1 = 0x36,
+ PSF_MAGIC2 = 0x04,
+
+ PSF_MODE512 = 0x01,
+ PSF_MODEHASTAB = 0x02,
+ PSF_MAXMODE = 0x03,
+ PSF_SEPARATOR = 0xFFFF
+};
+
+struct psf_header {
+ unsigned char magic1, magic2; /* Magic number */
+ unsigned char mode; /* PSF font mode */
+ unsigned char charsize; /* Character size */
+};
+
+#define PSF_MAGIC_OK(x) ((x).magic1 == PSF_MAGIC1 && (x).magic2 == PSF_MAGIC2)
+
+static void loadnewfont(int fd);
+
+int loadfont_main(int argc, char **argv)
+{
+ int fd;
+
+ if (argc != 1)
+ bb_show_usage();
+
+ fd = xopen(CURRENT_VC, O_RDWR);
+ loadnewfont(fd);
+
+ return EXIT_SUCCESS;
+}
+
+static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
+{
+ char buf[16384];
+ int i;
+
+ memset(buf, 0, sizeof(buf));
+
+ if (unit < 1 || unit > 32)
+ bb_error_msg_and_die("bad character size %d", unit);
+
+ for (i = 0; i < fontsize; i++)
+ memcpy(buf + (32 * i), inbuf + (unit * i), unit);
+
+#if defined( PIO_FONTX ) && !defined( __sparc__ )
+ {
+ struct consolefontdesc cfd;
+
+ cfd.charcount = fontsize;
+ cfd.charheight = unit;
+ cfd.chardata = buf;
+
+ if (ioctl(fd, PIO_FONTX, &cfd) == 0)
+ return; /* success */
+ bb_perror_msg("PIO_FONTX ioctl error (trying PIO_FONT)");
+ }
+#endif
+ if (ioctl(fd, PIO_FONT, buf))
+ bb_perror_msg_and_die("PIO_FONT ioctl error");
+}
+
+static void
+do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
+{
+ struct unimapinit advice;
+ struct unimapdesc ud;
+ struct unipair *up;
+ int ct = 0, maxct;
+ int glyph;
+ u_short unicode;
+
+ maxct = tailsz; /* more than enough */
+ up = (struct unipair *) xmalloc(maxct * sizeof(struct unipair));
+
+ for (glyph = 0; glyph < fontsize; glyph++) {
+ while (tailsz >= 2) {
+ unicode = (((u_short) inbuf[1]) << 8) + inbuf[0];
+ tailsz -= 2;
+ inbuf += 2;
+ if (unicode == PSF_SEPARATOR)
+ break;
+ up[ct].unicode = unicode;
+ up[ct].fontpos = glyph;
+ ct++;
+ }
+ }
+
+ /* Note: after PIO_UNIMAPCLR and before PIO_UNIMAP
+ this printf did not work on many kernels */
+
+ advice.advised_hashsize = 0;
+ advice.advised_hashstep = 0;
+ advice.advised_hashlevel = 0;
+ if (ioctl(fd, PIO_UNIMAPCLR, &advice)) {
+#ifdef ENOIOCTLCMD
+ if (errno == ENOIOCTLCMD) {
+ bb_error_msg("it seems this kernel is older than 1.1.92");
+ bb_error_msg_and_die("no Unicode mapping table loaded");
+ } else
+#endif
+ bb_perror_msg_and_die("PIO_UNIMAPCLR");
+ }
+ ud.entry_ct = ct;
+ ud.entries = up;
+ if (ioctl(fd, PIO_UNIMAP, &ud)) {
+ bb_perror_msg_and_die("PIO_UNIMAP");
+ }
+}
+
+static void loadnewfont(int fd)
+{
+ int unit;
+ unsigned char inbuf[32768]; /* primitive */
+ unsigned int inputlth, offset;
+
+ /*
+ * We used to look at the length of the input file
+ * with stat(); now that we accept compressed files,
+ * just read the entire file.
+ */
+ inputlth = fread(inbuf, 1, sizeof(inbuf), stdin);
+ if (ferror(stdin))
+ bb_perror_msg_and_die("error reading input font");
+ /* use malloc/realloc in case of giant files;
+ maybe these do not occur: 16kB for the font,
+ and 16kB for the map leaves 32 unicode values
+ for each font position */
+ if (!feof(stdin))
+ bb_perror_msg_and_die("font too large");
+
+ /* test for psf first */
+ {
+ struct psf_header psfhdr;
+ int fontsize;
+ int hastable;
+ unsigned int head0, head;
+
+ if (inputlth < sizeof(struct psf_header))
+ goto no_psf;
+
+ psfhdr = *(struct psf_header *) &inbuf[0];
+
+ if (!PSF_MAGIC_OK(psfhdr))
+ goto no_psf;
+
+ if (psfhdr.mode > PSF_MAXMODE)
+ bb_error_msg_and_die("unsupported psf file mode");
+ fontsize = ((psfhdr.mode & PSF_MODE512) ? 512 : 256);
+#if !defined( PIO_FONTX ) || defined( __sparc__ )
+ if (fontsize != 256)
+ bb_error_msg_and_die("only fontsize 256 supported");
+#endif
+ hastable = (psfhdr.mode & PSF_MODEHASTAB);
+ unit = psfhdr.charsize;
+ head0 = sizeof(struct psf_header);
+
+ head = head0 + fontsize * unit;
+ if (head > inputlth || (!hastable && head != inputlth))
+ bb_error_msg_and_die("input file: bad length");
+ do_loadfont(fd, inbuf + head0, unit, fontsize);
+ if (hastable)
+ do_loadtable(fd, inbuf + head, inputlth - head, fontsize);
+ return;
+ }
+ no_psf:
+
+ /* file with three code pages? */
+ if (inputlth == 9780) {
+ offset = 40;
+ unit = 16;
+ } else {
+ /* bare font */
+ if (inputlth & 0377)
+ bb_error_msg_and_die("bad input file size");
+ offset = 0;
+ unit = inputlth / 256;
+ }
+ do_loadfont(fd, inbuf + offset, unit, 256);
+}
diff --git a/console-tools/loadkmap.c b/console-tools/loadkmap.c
new file mode 100644
index 000000000..ce9b6817c
--- /dev/null
+++ b/console-tools/loadkmap.c
@@ -0,0 +1,61 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini loadkmap implementation for busybox
+ *
+ * Copyright (C) 1998 Enrique Zanardi <ezanardi@ull.es>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ *
+ */
+
+#include "busybox.h"
+
+#define BINARY_KEYMAP_MAGIC "bkeymap"
+
+/* From <linux/kd.h> */
+struct kbentry {
+ unsigned char kb_table;
+ unsigned char kb_index;
+ unsigned short kb_value;
+};
+/* sets one entry in translation table */
+#define KDSKBENT 0x4B47
+
+/* From <linux/keyboard.h> */
+#define NR_KEYS 128
+#define MAX_NR_KEYMAPS 256
+
+int loadkmap_main(int argc, char **argv)
+{
+ struct kbentry ke;
+ int i, j, fd;
+ u_short ibuff[NR_KEYS];
+ char flags[MAX_NR_KEYMAPS];
+ char buff[7];
+
+ if (argc != 1)
+ bb_show_usage();
+
+ fd = xopen(CURRENT_VC, O_RDWR);
+
+ xread(0, buff, 7);
+ if (strncmp(buff, BINARY_KEYMAP_MAGIC, 7))
+ bb_error_msg_and_die("this is not a valid binary keymap");
+
+ xread(0, flags, MAX_NR_KEYMAPS);
+
+ for (i = 0; i < MAX_NR_KEYMAPS; i++) {
+ if (flags[i] == 1) {
+ xread(0, ibuff, NR_KEYS * sizeof(u_short));
+ for (j = 0; j < NR_KEYS; j++) {
+ ke.kb_index = j;
+ ke.kb_table = i;
+ ke.kb_value = ibuff[j];
+ ioctl(fd, KDSKBENT, &ke);
+ }
+ }
+ }
+
+ if (ENABLE_FEATURE_CLEAN_UP) close(fd);
+ return 0;
+}
diff --git a/console-tools/openvt.c b/console-tools/openvt.c
new file mode 100644
index 000000000..f1cf5645b
--- /dev/null
+++ b/console-tools/openvt.c
@@ -0,0 +1,45 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * openvt.c - open a vt to run a command.
+ *
+ * busyboxed by Quy Tonthat <quy@signal3.com>
+ * hacked by Tito <farmatito@tiscali.it>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* getopt not needed */
+
+#include "busybox.h"
+
+int openvt_main(int argc, char **argv)
+{
+ int fd;
+ char vtname[sizeof(VC_FORMAT) + 2];
+
+
+ if (argc < 3) {
+ bb_show_usage();
+ }
+ /* check for illegal vt number: < 1 or > 63 */
+ sprintf(vtname, VC_FORMAT, (int)xatoul_range(argv[1], 1, 63));
+
+ if (fork() == 0) {
+ /* leave current vt */
+ if (setsid() < 0) {
+ bb_perror_msg_and_die("setsid");
+ }
+ close(0); /* so that new vt becomes stdin */
+
+ /* and grab new one */
+ fd = xopen(vtname, O_RDWR);
+
+ /* Reassign stdout and sterr */
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+
+ execvp(argv[2], &argv[2]);
+ _exit(1);
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/console-tools/reset.c b/console-tools/reset.c
new file mode 100644
index 000000000..26aab667b
--- /dev/null
+++ b/console-tools/reset.c
@@ -0,0 +1,32 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini reset implementation for busybox
+ *
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ * Written by Erik Andersen and Kent Robotti <robotti@metconnect.com>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+/* no options, no getopt */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "busybox.h"
+
+int reset_main(int argc, char **argv)
+{
+ if (isatty(1)) {
+ /* See 'man 4 console_codes' for details:
+ * "ESC c" -- Reset
+ * "ESC ( K" -- Select user mapping
+ * "ESC [ J" -- Erase display
+ * "ESC [ 0 m" -- Reset all display attributes
+ * "ESC [ ? 25 h" -- Make cursor visible.
+ */
+ printf("\033c\033(K\033[J\033[0m\033[?25h");
+ }
+ return EXIT_SUCCESS;
+}
+
diff --git a/console-tools/resize.c b/console-tools/resize.c
new file mode 100644
index 000000000..c405629aa
--- /dev/null
+++ b/console-tools/resize.c
@@ -0,0 +1,38 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * resize - set terminal width and height.
+ *
+ * Copyright 2006 Bernhard Fischer
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+/* no options, no getopt */
+#include "busybox.h"
+
+int resize_main(int argc, char **argv)
+{
+ struct termios old, new;
+ struct winsize w = {0,0,0,0};
+ int ret;
+
+ tcgetattr(STDOUT_FILENO, &old); /* fiddle echo */
+ new = old;
+ new.c_cflag |= (CLOCAL | CREAD);
+ new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ tcsetattr(STDOUT_FILENO, TCSANOW, &new);
+ /* save_cursor_pos 7
+ * scroll_whole_screen [r
+ * put_cursor_waaaay_off [$x;$yH
+ * get_cursor_pos [6n
+ * restore_cursor_pos 8
+ */
+ printf("\0337\033[r\033[999;999H\033[6n");
+ scanf("\033[%hu;%huR", &w.ws_row, &w.ws_col);
+ ret = ioctl(STDOUT_FILENO, TIOCSWINSZ, &w);
+ printf("\0338");
+ tcsetattr(STDOUT_FILENO, TCSANOW, &old);
+ if (ENABLE_FEATURE_RESIZE_PRINT)
+ printf("COLUMNS=%d;LINES=%d;export COLUMNS LINES;\n",
+ w.ws_col, w.ws_row);
+ return ret;
+}
diff --git a/console-tools/setconsole.c b/console-tools/setconsole.c
new file mode 100644
index 000000000..ef81f298b
--- /dev/null
+++ b/console-tools/setconsole.c
@@ -0,0 +1,47 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * setconsole.c - redirect system console output
+ *
+ * Copyright (C) 2004,2005 Enrik Berkhan <Enrik.Berkhan@inka.de>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+#if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS
+static const struct option setconsole_long_options[] = {
+ { "reset", 0, NULL, 'r' },
+ { 0, 0, 0, 0 }
+};
+#endif
+
+#define OPT_SETCONS_RESET 1
+
+int setconsole_main(int argc, char **argv)
+{
+ unsigned long flags;
+ const char *device = CURRENT_TTY;
+
+#if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS
+ applet_long_options = setconsole_long_options;
+#endif
+ flags = getopt32(argc, argv, "r");
+
+ if (argc - optind > 1)
+ bb_show_usage();
+
+ if (argc - optind == 1) {
+ if (flags & OPT_SETCONS_RESET)
+ bb_show_usage();
+ device = argv[optind];
+ } else {
+ if (flags & OPT_SETCONS_RESET)
+ device = CONSOLE_DEV;
+ }
+
+ if (-1 == ioctl(xopen(device, O_RDONLY), TIOCCONS)) {
+ bb_perror_msg_and_die("TIOCCONS");
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/console-tools/setkeycodes.c b/console-tools/setkeycodes.c
new file mode 100644
index 000000000..d82525786
--- /dev/null
+++ b/console-tools/setkeycodes.c
@@ -0,0 +1,53 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * setkeycodes
+ *
+ * Copyright (C) 1994-1998 Andries E. Brouwer <aeb@cwi.nl>
+ *
+ * Adjusted for BusyBox by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "busybox.h"
+
+
+/* From <linux/kd.h> */
+struct kbkeycode {
+ unsigned int scancode, keycode;
+};
+enum {
+ KDSETKEYCODE = 0x4B4D /* write kernel keycode table entry */
+};
+
+extern int
+setkeycodes_main(int argc, char** argv)
+{
+ int fd, sc;
+ struct kbkeycode a;
+
+ if (argc % 2 != 1 || argc < 2) {
+ bb_show_usage();
+ }
+
+ fd = get_console_fd();
+
+ while (argc > 2) {
+ a.keycode = xatoul_range(argv[2], 0, 127);
+ a.scancode = sc = xstrtoul_range(argv[1], 16, 0, 255);
+ if (a.scancode > 127) {
+ a.scancode -= 0xe000;
+ a.scancode += 128;
+ }
+ if (ioctl(fd, KDSETKEYCODE, &a)) {
+ bb_perror_msg_and_die("failed to set SCANCODE %x to KEYCODE %d", sc, a.keycode);
+ }
+ argc -= 2;
+ argv += 2;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/console-tools/setlogcons.c b/console-tools/setlogcons.c
new file mode 100644
index 000000000..ae15b9b28
--- /dev/null
+++ b/console-tools/setlogcons.c
@@ -0,0 +1,31 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * setlogcons: Send kernel messages to the current console or to console N
+ *
+ * Copyright (C) 2006 by Jan Kiszka <jan.kiszka@web.de>
+ *
+ * Based on setlogcons (kbd-1.12) by Andries E. Brouwer
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "busybox.h"
+
+extern int setlogcons_main(int argc, char **argv)
+{
+ struct {
+ char fn;
+ char subarg;
+ } arg;
+
+ arg.fn = 11; /* redirect kernel messages */
+ arg.subarg = 0; /* to specified console (current as default) */
+
+ if (argc == 2)
+ arg.subarg = xatoul_range(argv[1], 0, 63);
+
+ if (ioctl(xopen(VC_1, O_RDONLY), TIOCLINUX, &arg))
+ bb_perror_msg_and_die("TIOCLINUX");
+
+ return 0;
+}