summaryrefslogtreecommitdiff
path: root/release/src/router/busybox/console-tools
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2015-01-03 13:58:15 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2015-01-03 13:58:15 +0100
commit4aca87515a5083ae0e31ce3177189fd43b6d05ac (patch)
tree7b1d9a31393ca090757dc6f0d3859b4fcd93f271 /release/src/router/busybox/console-tools
parent008d0be72b2f160382c6e880765e96b64a050c65 (diff)
downloadtomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.gz
tomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.bz2
patch to Vanilla Tomato 1.28
Diffstat (limited to 'release/src/router/busybox/console-tools')
-rw-r--r--[-rwxr-xr-x]release/src/router/busybox/console-tools/Config.in88
-rw-r--r--release/src/router/busybox/console-tools/Kbuild22
-rw-r--r--release/src/router/busybox/console-tools/Makefile30
-rwxr-xr-xrelease/src/router/busybox/console-tools/Makefile.in41
-rw-r--r--release/src/router/busybox/console-tools/chvt.c43
-rw-r--r--release/src/router/busybox/console-tools/clear.c27
-rw-r--r--release/src/router/busybox/console-tools/deallocvt.c59
-rw-r--r--release/src/router/busybox/console-tools/dumpkmap.c88
-rw-r--r--release/src/router/busybox/console-tools/kbd_mode.c55
-rw-r--r--release/src/router/busybox/console-tools/loadacm.c357
-rw-r--r--release/src/router/busybox/console-tools/loadfont.c406
-rw-r--r--release/src/router/busybox/console-tools/loadkmap.c80
-rw-r--r--release/src/router/busybox/console-tools/openvt.c224
-rw-r--r--release/src/router/busybox/console-tools/reset.c58
-rw-r--r--release/src/router/busybox/console-tools/resize.c71
-rw-r--r--release/src/router/busybox/console-tools/setconsole.c39
-rw-r--r--release/src/router/busybox/console-tools/setkeycodes.c77
-rw-r--r--release/src/router/busybox/console-tools/setlogcons.c30
-rw-r--r--release/src/router/busybox/console-tools/showkey.c138
19 files changed, 1034 insertions, 899 deletions
diff --git a/release/src/router/busybox/console-tools/Config.in b/release/src/router/busybox/console-tools/Config.in
index 83694a82..994140b7 100755..100644
--- a/release/src/router/busybox/console-tools/Config.in
+++ b/release/src/router/busybox/console-tools/Config.in
@@ -5,70 +5,134 @@
menu "Console Utilities"
-config CONFIG_CHVT
+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 CONFIG_CLEAR
+config CLEAR
bool "clear"
default n
help
This program clears the terminal screen.
-config CONFIG_DEALLOCVT
+config DEALLOCVT
bool "deallocvt"
default n
help
This program deallocates unused virtual consoles.
-config CONFIG_DUMPKMAP
+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 CONFIG_LOADACM
- bool "loadacm"
+config KBD_MODE
+ bool "kbd_mode"
default n
help
- This program loads an acm from standard input.
+ This program reports and sets keyboard mode.
-config CONFIG_LOADFONT
+config LOADFONT
bool "loadfont"
default n
help
This program loads a console font from standard input.
-config CONFIG_LOADKMAP
+config LOADKMAP
bool "loadkmap"
default n
help
This program loads a keyboard translation table from
standard input.
-config CONFIG_OPENVT
+config OPENVT
bool "openvt"
default n
help
This program is used to start a command on an unused
virtual terminal.
-config CONFIG_RESET
+config RESET
bool "reset"
default n
help
This program is used to reset the terminal screen, if it
gets messed up.
-config CONFIG_SETKEYCODES
+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 SETCONSOLE && GETOPT_LONG
+ help
+ Support long options for the setconsole applet.
+
+config SETFONT
+ bool "setfont"
+ default n
+ help
+ Allows to load console screen map. Useful for i18n.
+
+config FEATURE_SETFONT_TEXTUAL_MAP
+ bool "Support reading textual screen maps"
+ default n
+ depends on SETFONT
+ help
+ Support reading textual screen maps.
+
+config DEFAULT_SETFONT_DIR
+ string "Default directory for console-tools files"
+ default ""
+ depends on SETFONT
+ help
+ Directory to use if setfont's params are simple filenames
+ (not /path/to/file or ./file). Default is "" (no default directory).
+
+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.
+
+config SHOWKEY
+ bool "showkey"
+ default n
+ help
+ Shows keys pressed.
+
endmenu
diff --git a/release/src/router/busybox/console-tools/Kbuild b/release/src/router/busybox/console-tools/Kbuild
new file mode 100644
index 00000000..df5ffdb9
--- /dev/null
+++ b/release/src/router/busybox/console-tools/Kbuild
@@ -0,0 +1,22 @@
+# 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_KBD_MODE) += kbd_mode.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_SETFONT) += loadfont.o
+lib-$(CONFIG_SETKEYCODES) += setkeycodes.o
+lib-$(CONFIG_SETLOGCONS) += setlogcons.o
+lib-$(CONFIG_SHOWKEY) += showkey.o
diff --git a/release/src/router/busybox/console-tools/Makefile b/release/src/router/busybox/console-tools/Makefile
deleted file mode 100644
index d54c778d..00000000
--- a/release/src/router/busybox/console-tools/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# Makefile for busybox
-#
-# Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-TOPDIR:= ../
-CONSOLETOOLS_DIR:=./
-include $(TOPDIR).config
-include $(TOPDIR)Rules.mak
-include Makefile.in
-all: $(libraries-y)
--include $(TOPDIR).depend
-
-clean:
- rm -f *.o *.a $(AR_TARGET)
-
diff --git a/release/src/router/busybox/console-tools/Makefile.in b/release/src/router/busybox/console-tools/Makefile.in
deleted file mode 100755
index 1c4ac522..00000000
--- a/release/src/router/busybox/console-tools/Makefile.in
+++ /dev/null
@@ -1,41 +0,0 @@
-# Makefile for busybox
-#
-# Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-CONSOLETOOLS_AR:=console-tools.a
-ifndef $(CONSOLETOOLS_DIR)
-CONSOLETOOLS_DIR:=$(TOPDIR)console-tools/
-endif
-
-CONSOLETOOLS_DIR-y:=
-CONSOLETOOLS_DIR-$(CONFIG_CHVT) += chvt.o
-CONSOLETOOLS_DIR-$(CONFIG_CLEAR) += clear.o
-CONSOLETOOLS_DIR-$(CONFIG_DEALLOCVT) += deallocvt.o
-CONSOLETOOLS_DIR-$(CONFIG_DUMPKMAP) += dumpkmap.o
-CONSOLETOOLS_DIR-$(CONFIG_LOADACM) += loadacm.o
-CONSOLETOOLS_DIR-$(CONFIG_LOADFONT) += loadfont.o
-CONSOLETOOLS_DIR-$(CONFIG_LOADKMAP) += loadkmap.o
-CONSOLETOOLS_DIR-$(CONFIG_OPENVT) += openvt.o
-CONSOLETOOLS_DIR-$(CONFIG_RESET) += reset.o
-CONSOLETOOLS_DIR-$(CONFIG_SETKEYCODES) += setkeycodes.o
-
-libraries-y+=$(CONSOLETOOLS_DIR)$(CONSOLETOOLS_AR)
-
-$(CONSOLETOOLS_DIR)$(CONSOLETOOLS_AR): $(patsubst %,$(CONSOLETOOLS_DIR)%, $(CONSOLETOOLS_DIR-y))
- $(AR) -ro $@ $(patsubst %,$(CONSOLETOOLS_DIR)%, $(CONSOLETOOLS_DIR-y))
-
diff --git a/release/src/router/busybox/console-tools/chvt.c b/release/src/router/busybox/console-tools/chvt.c
index 11e1078b..302ffb4f 100644
--- a/release/src/router/busybox/console-tools/chvt.c
+++ b/release/src/router/busybox/console-tools/chvt.c
@@ -1,43 +1,24 @@
/* vi: set sw=4 ts=4: */
/*
- * chvt.c - aeb - 940227 - Change virtual terminal
+ * Mini chvt implementation for busybox
*
- * busyboxed by Erik Andersen
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
-/* getopt not needed */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include "busybox.h"
-
-/* From <linux/vt.h> */
-static const int VT_ACTIVATE = 0x5606; /* make vt active */
-static const int VT_WAITACTIVE = 0x5607; /* wait for vt active */
+#include "libbb.h"
+int chvt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int chvt_main(int argc, char **argv)
{
- int fd, num;
+ int num;
- if ((argc != 2) || (**(argv + 1) == '-'))
+ if (argc != 2) {
bb_show_usage();
- fd = get_console_fd();
- num = atoi(argv[1]);
- if (ioctl(fd, VT_ACTIVATE, num))
- bb_perror_msg_and_die("VT_ACTIVATE");
- if (ioctl(fd, VT_WAITACTIVE, num))
- bb_perror_msg_and_die("VT_WAITACTIVE");
+ }
+
+ num = xatou_range(argv[1], 1, 63);
+ console_make_active(get_console_fd_or_die(), num);
return EXIT_SUCCESS;
}
-
-
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
diff --git a/release/src/router/busybox/console-tools/clear.c b/release/src/router/busybox/console-tools/clear.c
index 5dbe214e..8b727b39 100644
--- a/release/src/router/busybox/console-tools/clear.c
+++ b/release/src/router/busybox/console-tools/clear.c
@@ -2,31 +2,18 @@
/*
* Mini clear implementation for busybox
*
- * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include "busybox.h"
+/* no options, no getopt */
+#include "libbb.h"
-extern int clear_main(int argc, char **argv)
+int clear_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int clear_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
{
- printf("\033[H\033[J");
- return EXIT_SUCCESS;
+ return printf("\033[H\033[J") != 6;
}
diff --git a/release/src/router/busybox/console-tools/deallocvt.c b/release/src/router/busybox/console-tools/deallocvt.c
index f641be8d..09748834 100644
--- a/release/src/router/busybox/console-tools/deallocvt.c
+++ b/release/src/router/busybox/console-tools/deallocvt.c
@@ -1,46 +1,33 @@
/* vi: set sw=4 ts=4: */
/*
- * disalloc.c - aeb - 940501 - Disallocate virtual terminal(s)
- * Renamed deallocvt.
+ * 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.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include "busybox.h"
-/* From <linux/vt.h> */
-static const int VT_DISALLOCATE = 0x5608; /* free memory associated to vt */
-
-int deallocvt_main(int argc, char *argv[])
-{
- int fd, num=0;
+/* no options, no getopt */
- if (argc > 2)
- bb_show_usage();
+#include "libbb.h"
- fd = get_console_fd();
-
- /* num=0 deallocate all unused consoles */
- if (argc == 1)
- goto disallocate_all;
+/* From <linux/vt.h> */
+enum { VT_DISALLOCATE = 0x5608 }; /* free memory associated to vt */
- num=bb_xgetlarg(argv[1], 10, 0, INT_MAX);
+int deallocvt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int deallocvt_main(int argc UNUSED_PARAM, char **argv)
+{
+ /* num = 0 deallocate all unused consoles */
+ int num = 0;
- switch(num)
- {
- case 0:
- bb_error_msg("0: illegal VT number");
- break;
- case 1:
- bb_error_msg("VT 1 cannot be deallocated");
- break;
- default:
-disallocate_all:
- if (ioctl(fd, VT_DISALLOCATE, num))
- bb_perror_msg_and_die("VT_DISALLOCATE");
- return EXIT_SUCCESS;
+ if (argv[1]) {
+ if (argv[2])
+ bb_show_usage();
+ num = xatou_range(argv[1], 1, 63);
}
- return EXIT_FAILURE;
+
+ /* double cast suppresses "cast to ptr from int of different size" */
+ xioctl(get_console_fd_or_die(), VT_DISALLOCATE, (void *)(ptrdiff_t)num);
+ return EXIT_SUCCESS;
}
diff --git a/release/src/router/busybox/console-tools/dumpkmap.c b/release/src/router/busybox/console-tools/dumpkmap.c
index 85926556..c382b5af 100644
--- a/release/src/router/busybox/console-tools/dumpkmap.c
+++ b/release/src/router/busybox/console-tools/dumpkmap.c
@@ -4,30 +4,12 @@
*
* Copyright (C) Arne Bernin <arne@matrix.loopback.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
*/
+/* no options, no getopt */
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include "busybox.h"
+#include "libbb.h"
/* From <linux/kd.h> */
struct kbentry {
@@ -35,61 +17,53 @@ struct kbentry {
unsigned char kb_index;
unsigned short kb_value;
};
-static const int KDGKBENT = 0x4B46; /* gets one entry in translation table */
+#define KDGKBENT 0x4B46 /* gets one entry in translation table */
/* From <linux/keyboard.h> */
-static const int NR_KEYS = 128;
-static const int MAX_NR_KEYMAPS = 256;
+#define NR_KEYS 128
+#define MAX_NR_KEYMAPS 256
-int dumpkmap_main(int argc, char **argv)
+int dumpkmap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int dumpkmap_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
{
struct kbentry ke;
int i, j, fd;
- char flags[MAX_NR_KEYMAPS], magic[] = "bkeymap";
+ RESERVE_CONFIG_BUFFER(flags,MAX_NR_KEYMAPS);
- if (argc>=2 && *argv[1]=='-') {
- bb_show_usage();
- }
+/* bb_warn_ignoring_args(argc>=2);*/
- fd = open(CURRENT_VC, O_RDWR);
- if (fd < 0) {
- bb_perror_msg("Error opening " CURRENT_VC);
- return EXIT_FAILURE;
- }
+ fd = get_console_fd_or_die();
+
+ write(STDOUT_FILENO, "bkeymap", 7);
- 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;
- for (i=0; i < MAX_NR_KEYMAPS; i++) flags[i]=0;
- flags[0]=1;
- flags[1]=1;
- flags[2]=1;
- flags[4]=1;
- flags[5]=1;
- flags[6]=1;
- flags[8]=1;
- flags[9]=1;
- flags[10]=1;
- flags[12]=1;
-
/* dump flags */
- for (i=0; i < MAX_NR_KEYMAPS; i++) write(1,&flags[i],1);
+ write(STDOUT_FILENO, 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_error_msg("ioctl returned: %m, %s, %s, %xqq", (char *)&ke.kb_index,(char *)&ke.kb_table,(int)&ke.kb_value);
- }
- else {
- write(1,(void*)&ke.kb_value,2);
- }
-
+ if (!ioctl_or_perror(fd, KDGKBENT, &ke,
+ "ioctl failed with %s, %s, %p",
+ (char *)&ke.kb_index,
+ (char *)&ke.kb_table,
+ &ke.kb_value)
+ ) {
+ write(STDOUT_FILENO, (void*)&ke.kb_value, 2);
+ }
}
}
}
- close(fd);
+ if (ENABLE_FEATURE_CLEAN_UP) {
+ close(fd);
+ RELEASE_CONFIG_BUFFER(flags);
+ }
return EXIT_SUCCESS;
}
diff --git a/release/src/router/busybox/console-tools/kbd_mode.c b/release/src/router/busybox/console-tools/kbd_mode.c
new file mode 100644
index 00000000..544bbb78
--- /dev/null
+++ b/release/src/router/busybox/console-tools/kbd_mode.c
@@ -0,0 +1,55 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini kbd_mode implementation for busybox
+ *
+ * Copyright (C) 2007 Loic Grenie <loic.grenie@gmail.com>
+ * written using Andries Brouwer <aeb@cwi.nl>'s kbd_mode from
+ * console-utils v0.2.3, licensed under GNU GPLv2
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+#include "libbb.h"
+#include <linux/kd.h>
+
+int kbd_mode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int kbd_mode_main(int argc UNUSED_PARAM, char **argv)
+{
+ enum {
+ SCANCODE = (1 << 0),
+ ASCII = (1 << 1),
+ MEDIUMRAW = (1 << 2),
+ UNICODE = (1 << 3),
+ };
+ int fd;
+ unsigned opt;
+ const char *tty_name = CURRENT_TTY;
+
+ opt = getopt32(argv, "sakuC:", &tty_name);
+ fd = xopen(tty_name, O_NONBLOCK);
+ opt &= 0xf; /* clear -C bit, see (*) */
+
+ if (!opt) { /* print current setting */
+ const char *mode = "unknown";
+ int m;
+
+ xioctl(fd, KDGKBMODE, &m);
+ if (m == K_RAW)
+ mode = "raw (scancode)";
+ else if (m == K_XLATE)
+ mode = "default (ASCII)";
+ else if (m == K_MEDIUMRAW)
+ mode = "mediumraw (keycode)";
+ else if (m == K_UNICODE)
+ mode = "Unicode (UTF-8)";
+ printf("The keyboard is in %s mode\n", mode);
+ } else {
+ /* here we depend on specific bits assigned to options (*) */
+ opt = opt & UNICODE ? 3 : opt >> 1;
+ /* double cast prevents warnings about widening conversion */
+ xioctl(fd, KDSKBMODE, (void*)(ptrdiff_t)opt);
+ }
+
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close(fd);
+ return EXIT_SUCCESS;
+}
diff --git a/release/src/router/busybox/console-tools/loadacm.c b/release/src/router/busybox/console-tools/loadacm.c
deleted file mode 100644
index 640aa440..00000000
--- a/release/src/router/busybox/console-tools/loadacm.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * Derived from
- * mapscrn.c - version 0.92
- *
- * Was taken from console-tools and adapted by
- * Peter Novodvorsky <petya@logic.ru>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/kd.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include "busybox.h"
-
-typedef unsigned short unicode;
-
-static long int ctoi(unsigned char *s, int *is_unicode);
-static int old_screen_map_read_ascii(FILE * fp, unsigned char buf[]);
-static int uni_screen_map_read_ascii(FILE * fp, unicode buf[], int *is_unicode);
-static unicode utf8_to_ucs2(char *buf);
-static int screen_map_load(int fd, FILE * fp);
-
-int loadacm_main(int argc, char **argv)
-{
- int fd;
-
- if (argc>=2 && *argv[1]=='-') {
- bb_show_usage();
- }
-
- fd = open(CURRENT_VC, O_RDWR);
- if (fd < 0) {
- bb_perror_msg_and_die("Error opening " CURRENT_VC);
- }
-
- if (screen_map_load(fd, stdin)) {
- bb_perror_msg_and_die("Error loading acm");
- }
-
- write(fd, "\033(K", 3);
-
- return EXIT_SUCCESS;
-}
-
-static int screen_map_load(int fd, FILE * fp)
-{
- struct stat stbuf;
- unicode wbuf[E_TABSZ];
- unsigned char buf[E_TABSZ];
- int parse_failed = 0;
- int is_unicode;
-
- if (fstat(fileno(fp), &stbuf))
- bb_perror_msg_and_die("Cannot stat map file");
-
- /* first try a UTF screen-map: either ASCII (no restriction) or binary (regular file) */
- if (!
- (parse_failed =
- (-1 == uni_screen_map_read_ascii(fp, wbuf, &is_unicode)))
-|| (S_ISREG(stbuf.st_mode) && (stbuf.st_size == (sizeof(unicode) * E_TABSZ)))) { /* test for binary UTF map by size */
- if (parse_failed) {
- if (-1 == fseek(fp, 0, SEEK_SET)) {
- if (errno == ESPIPE)
- bb_error_msg_and_die("16bit screen-map MUST be a regular file.");
- else
- bb_perror_msg_and_die("fseek failed reading binary 16bit screen-map");
- }
-
- if (fread(wbuf, sizeof(unicode) * E_TABSZ, 1, fp) != 1)
- bb_perror_msg_and_die("Cannot read [new] map from file");
-#if 0
- else
- bb_error_msg("Input screen-map is binary.");
-#endif
- }
-
- /* if it was effectively a 16-bit ASCII, OK, else try to read as 8-bit map */
- /* same if it was binary, ie. if parse_failed */
- if (parse_failed || is_unicode) {
- if (ioctl(fd, PIO_UNISCRNMAP, wbuf))
- bb_perror_msg_and_die("PIO_UNISCRNMAP ioctl");
- else
- return 0;
- }
- }
-
- /* rewind... */
- if (-1 == fseek(fp, 0, SEEK_SET)) {
- if (errno == ESPIPE)
- bb_error_msg("Assuming 8bit screen-map - MUST be a regular file."),
- exit(1);
- else
- bb_perror_msg_and_die("fseek failed assuming 8bit screen-map");
- }
-
- /* ... and try an old 8-bit screen-map */
- if (!(parse_failed = (-1 == old_screen_map_read_ascii(fp, buf))) ||
- (S_ISREG(stbuf.st_mode) && (stbuf.st_size == E_TABSZ))) { /* test for binary old 8-bit map by size */
- if (parse_failed) {
- if (-1 == fseek(fp, 0, SEEK_SET)) {
- if (errno == ESPIPE)
- /* should not - it succedeed above */
- bb_error_msg_and_die("fseek() returned ESPIPE !");
- else
- bb_perror_msg_and_die("fseek for binary 8bit screen-map");
- }
-
- if (fread(buf, E_TABSZ, 1, fp) != 1)
- bb_perror_msg_and_die("Cannot read [old] map from file");
-#if 0
- else
- bb_error_msg("Input screen-map is binary.");
-#endif
- }
-
- if (ioctl(fd, PIO_SCRNMAP, buf))
- bb_perror_msg_and_die("PIO_SCRNMAP ioctl");
- else
- return 0;
- }
- bb_error_msg("Error parsing symbolic map");
- return(1);
-}
-
-
-/*
- * - reads `fp' as a 16-bit ASCII SFM file.
- * - returns -1 on error.
- * - returns it in `unicode' in an E_TABSZ-elements array.
- * - sets `*is_unicode' flagiff there were any non-8-bit
- * (ie. real 16-bit) mapping.
- *
- * FIXME: ignores everything after second word
- */
-static int uni_screen_map_read_ascii(FILE * fp, unicode buf[], int *is_unicode)
-{
- char buffer[256]; /* line buffer reading file */
- char *p, *q; /* 1st + 2nd words in line */
- int in, on; /* the same, as numbers */
- int tmp_is_unicode; /* tmp for is_unicode calculation */
- int i; /* loop index - result holder */
- int ret_code = 0; /* return code */
- sigset_t acmsigset, old_sigset;
-
- assert(is_unicode);
-
- *is_unicode = 0;
-
- /* first 128 codes defaults to ASCII */
- for (i = 0; i < 128; i++)
- buf[i] = i;
- /* remaining defaults to replacement char (usually E_TABSZ = 256) */
- for (; i < E_TABSZ; i++)
- buf[i] = 0xfffd;
-
- /* block SIGCHLD */
- sigemptyset(&acmsigset);
- sigaddset(&acmsigset, SIGCHLD);
- sigprocmask(SIG_BLOCK, &acmsigset, &old_sigset);
-
- do {
- if (NULL == fgets(buffer, sizeof(buffer), fp)) {
- if (feof(fp))
- break;
- else
- bb_perror_msg_and_die("uni_screen_map_read_ascii() can't read line");
- }
-
- /* get "charset-relative charcode", stripping leading spaces */
- p = strtok(buffer, " \t\n");
-
- /* skip empty lines and comments */
- if (!p || *p == '#')
- continue;
-
- /* get unicode mapping */
- q = strtok(NULL, " \t\n");
- if (q) {
- in = ctoi(p, NULL);
- if (in < 0 || in > 255) {
- ret_code = -1;
- break;
- }
-
- on = ctoi(q, &tmp_is_unicode);
- if (in < 0 && on > 65535) {
- ret_code = -1;
- break;
- }
-
- *is_unicode |= tmp_is_unicode;
- buf[in] = on;
- } else {
- ret_code = -1;
- break;
- }
- }
- while (1); /* terminated by break on feof() */
-
- /* restore sig mask */
- sigprocmask(SIG_SETMASK, &old_sigset, NULL);
-
- return ret_code;
-}
-
-
-static int old_screen_map_read_ascii(FILE * fp, unsigned char buf[])
-{
- char buffer[256];
- int in, on;
- char *p, *q;
-
- for (in = 0; in < 256; in++)
- buf[in] = in;
-
- while (fgets(buffer, sizeof(buffer) - 1, fp)) {
- p = strtok(buffer, " \t\n");
-
- if (!p || *p == '#')
- continue;
-
- q = strtok(NULL, " \t\n#");
- if (q) {
- in = ctoi(p, NULL);
- if (in < 0 || in > 255)
- return -1;
-
- on = ctoi(q, NULL);
- if (in < 0 && on > 255)
- return -1;
-
- buf[in] = on;
- } else
- return -1;
- }
-
- return (0);
-}
-
-
-/*
- * - converts a string into an int.
- * - supports dec and hex bytes, hex UCS2, single-quoted byte and UTF8 chars.
- * - returns the converted value
- * - if `is_unicode != NULL', use it to tell whether it was unicode
- *
- * CAVEAT: will report valid UTF mappings using only 1 byte as 8-bit ones.
- */
-static long int ctoi(unsigned char *s, int *is_unicode)
-{
- int i;
- size_t ls;
-
- ls = strlen(s);
- if (is_unicode)
- *is_unicode = 0;
-
- /* hex-specified UCS2 */
- if ((strncmp(s, "U+", 2) == 0) &&
- (strspn(s + 2, "0123456789abcdefABCDEF") == ls - 2)) {
- sscanf(s + 2, "%x", &i);
- if (is_unicode)
- *is_unicode = 1;
- }
-
- /* hex-specified byte */
- else if ((ls <= 4) && (strncmp(s, "0x", 2) == 0) &&
- (strspn(s + 2, "0123456789abcdefABCDEF") == ls - 2))
- sscanf(s + 2, "%x", &i);
-
- /* oct-specified number (byte) */
- else if ((*s == '0') && (strspn(s, "01234567") == ls))
- sscanf(s, "%o", &i);
-
- /* dec-specified number (byte) */
- else if (strspn(s, "0123456789") == ls)
- sscanf(s, "%d", &i);
-
- /* single-byte quoted char */
- else if ((strlen(s) == 3) && (s[0] == '\'') && (s[2] == '\''))
- i = s[1];
-
- /* multi-byte UTF8 quoted char */
- else if ((s[0] == '\'') && (s[ls - 1] == '\'')) {
- s[ls - 1] = 0; /* ensure we'll not "parse UTF too far" */
- i = utf8_to_ucs2(s + 1);
- if (is_unicode)
- *is_unicode = 1;
- } else
- return (-1);
-
- return (i);
-}
-
-
-static unicode utf8_to_ucs2(char *buf)
-{
- int utf_count = 0;
- long utf_char = 0;
- unicode tc = 0;
- unsigned char c;
-
- do {
- c = *buf;
- buf++;
-
- /* if byte should be part of multi-byte sequence */
- if (c & 0x80) {
- /* if we have already started to parse a UTF8 sequence */
- if (utf_count > 0 && (c & 0xc0) == 0x80) {
- utf_char = (utf_char << 6) | (c & 0x3f);
- utf_count--;
- if (utf_count == 0)
- tc = utf_char;
- else
- continue;
- } else { /* Possibly 1st char of a UTF8 sequence */
-
- if ((c & 0xe0) == 0xc0) {
- utf_count = 1;
- utf_char = (c & 0x1f);
- } else if ((c & 0xf0) == 0xe0) {
- utf_count = 2;
- utf_char = (c & 0x0f);
- } else if ((c & 0xf8) == 0xf0) {
- utf_count = 3;
- utf_char = (c & 0x07);
- } else if ((c & 0xfc) == 0xf8) {
- utf_count = 4;
- utf_char = (c & 0x03);
- } else if ((c & 0xfe) == 0xfc) {
- utf_count = 5;
- utf_char = (c & 0x01);
- } else
- utf_count = 0;
- continue;
- }
- } else { /* not part of multi-byte sequence - treat as ASCII
- * this makes incomplete sequences to be ignored
- */
- tc = c;
- utf_count = 0;
- }
- }
- while (utf_count);
-
- return tc;
-}
diff --git a/release/src/router/busybox/console-tools/loadfont.c b/release/src/router/busybox/console-tools/loadfont.c
index 6108151a..33641806 100644
--- a/release/src/router/busybox/console-tools/loadfont.c
+++ b/release/src/router/busybox/console-tools/loadfont.c
@@ -6,68 +6,87 @@
*
* Loads the console font, and possibly the corresponding screen map(s).
* (Adapted for busybox by Matej Vela.)
+ *
+ * Licensed under GPLv2, see file LICENSE in this tarball for details.
*/
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/ioctl.h>
+#include "libbb.h"
#include <sys/kd.h>
-#include <endian.h>
-#include "busybox.h"
-
-static const int PSF_MAGIC1 = 0x36;
-static const int PSF_MAGIC2 = 0x04;
-
-static const int PSF_MODE512 = 0x01;
-static const int PSF_MODEHASTAB = 0x02;
-static const int PSF_MAXMODE = 0x03;
-static const int PSF_SEPARATOR = 0xFFFF;
-struct psf_header {
- unsigned char magic1, magic2; /* Magic number */
- unsigned char mode; /* PSF font mode */
- unsigned char charsize; /* Character size */
+#ifndef KDFONTOP
+#define KDFONTOP 0x4B72
+struct console_font_op {
+ unsigned op; /* KD_FONT_OP_* */
+ unsigned flags; /* KD_FONT_FLAG_* */
+ unsigned width, height;
+ unsigned charcount;
+ unsigned char *data; /* font data with height fixed to 32 */
};
-#define PSF_MAGIC_OK(x) ((x).magic1 == PSF_MAGIC1 && (x).magic2 == PSF_MAGIC2)
+#define KD_FONT_OP_SET 0 /* Set font */
+#define KD_FONT_OP_GET 1 /* Get font */
+#define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default,
+ data points to name / NULL */
+#define KD_FONT_OP_COPY 3 /* Copy from another console */
-static void loadnewfont(int fd);
+#define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface */
+#define KD_FONT_FLAG_DONT_RECALC 1 /* Don't call adjust_height() */
+ /* (Used internally for PIO_FONT support) */
+#endif /* KDFONTOP */
-extern int loadfont_main(int argc, char **argv)
-{
- int fd;
- if (argc != 1)
- bb_show_usage();
+enum {
+ PSF_MAGIC1 = 0x36,
+ PSF_MAGIC2 = 0x04,
- fd = open(CURRENT_VC, O_RDWR);
- if (fd < 0)
- bb_perror_msg_and_die("Error opening " CURRENT_VC);
- loadnewfont(fd);
+ PSF_MODE512 = 0x01,
+ PSF_MODEHASTAB = 0x02,
+ PSF_MAXMODE = 0x03,
+ PSF_SEPARATOR = 0xffff
+};
- return EXIT_SUCCESS;
-}
+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 do_loadfont(int fd, char *inbuf, int unit, int fontsize)
+static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
{
- char buf[16384];
+ char *buf;
int i;
- memset(buf, 0, sizeof(buf));
-
if (unit < 1 || unit > 32)
- bb_error_msg_and_die("Bad character size %d", unit);
+ bb_error_msg_and_die("bad character size %d", unit);
+ buf = xzalloc(16 * 1024);
for (i = 0; i < fontsize; i++)
memcpy(buf + (32 * i), inbuf + (unit * i), unit);
-#if defined( PIO_FONTX ) && !defined( __sparc__ )
+ { /* KDFONTOP */
+ struct console_font_op cfo;
+
+ cfo.op = KD_FONT_OP_SET;
+ cfo.flags = 0;
+ cfo.width = 8;
+ cfo.height = unit;
+ cfo.charcount = fontsize;
+ cfo.data = (void*)buf;
+#if 0
+ if (!ioctl_or_perror(fd, KDFONTOP, &cfo, "KDFONTOP ioctl failed (will try PIO_FONTX)"))
+ goto ret; /* success */
+#else
+ xioctl(fd, KDFONTOP, &cfo);
+#endif
+ }
+
+#if 0
+/* These ones do not honour -C tty (they set font on current tty regardless)
+ * On x86, this distinction is visible on framebuffer consoles
+ * (regular character consoles may have only one shared font anyway)
+ */
+#if defined(PIO_FONTX) && !defined(__sparc__)
{
struct consolefontdesc cfd;
@@ -75,31 +94,31 @@ static void do_loadfont(int fd, char *inbuf, int unit, int 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)");
+ if (!ioctl_or_perror(fd, PIO_FONTX, &cfd, "PIO_FONTX ioctl failed (will try PIO_FONT)"))
+ goto ret; /* success */
}
#endif
- if (ioctl(fd, PIO_FONT, buf))
- bb_perror_msg_and_die("PIO_FONT ioctl error");
+ xioctl(fd, PIO_FONT, buf);
+ ret:
+#endif /* 0 */
+ free(buf);
}
-static void
-do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
+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;
+ uint16_t unicode;
- maxct = tailsz; /* more than enough */
- up = (struct unipair *) xmalloc(maxct * sizeof(struct unipair));
+ maxct = tailsz; /* more than enough */
+ up = xmalloc(maxct * sizeof(struct unipair));
for (glyph = 0; glyph < fontsize; glyph++) {
while (tailsz >= 2) {
- unicode = (((u_short) inbuf[1]) << 8) + inbuf[0];
+ unicode = (((uint16_t) inbuf[1]) << 8) + inbuf[0];
tailsz -= 2;
inbuf += 2;
if (unicode == PSF_SEPARATOR)
@@ -116,94 +135,239 @@ do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
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");
- }
+ xioctl(fd, PIO_UNIMAPCLR, &advice);
ud.entry_ct = ct;
ud.entries = up;
- if (ioctl(fd, PIO_UNIMAP, &ud)) {
-#if 0
- if (errno == ENOMEM) {
- /* change advice parameters */
- }
+ xioctl(fd, PIO_UNIMAP, &ud);
+}
+
+static void do_load(int fd, struct psf_header *psfhdr, size_t len)
+{
+ int unit;
+ int fontsize;
+ int hastable;
+ unsigned head0, head = head;
+
+ /* test for psf first */
+ if (len >= sizeof(struct psf_header) && PSF_MAGIC_OK(psfhdr)) {
+ 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
- bb_perror_msg_and_die("PIO_UNIMAP");
+ hastable = (psfhdr->mode & PSF_MODEHASTAB);
+ unit = psfhdr->charsize;
+ head0 = sizeof(struct psf_header);
+
+ head = head0 + fontsize * unit;
+ if (head > len || (!hastable && head != len))
+ bb_error_msg_and_die("input file: bad length");
+ } else {
+ /* file with three code pages? */
+ if (len == 9780) {
+ head0 = 40;
+ unit = 16;
+ } else {
+ /* bare font */
+ if (len & 0377)
+ bb_error_msg_and_die("input file: bad length");
+ head0 = 0;
+ unit = len / 256;
+ }
+ fontsize = 256;
+ hastable = 0;
}
+
+ do_loadfont(fd, (unsigned char *)psfhdr + head0, unit, fontsize);
+ if (hastable)
+ do_loadtable(fd, (unsigned char *)psfhdr + head, len - head, fontsize);
}
-static void loadnewfont(int fd)
+#if ENABLE_LOADFONT
+int loadfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int loadfont_main(int argc UNUSED_PARAM, char **argv)
{
- int unit;
- char inbuf[32768]; /* primitive */
- unsigned int inputlth, offset;
+ size_t len;
+ struct psf_header *psfhdr;
+
+ // no arguments allowed!
+ opt_complementary = "=0";
+ getopt32(argv, "");
/*
* 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");
+ len = 32*1024; // can't be larger
+ psfhdr = xmalloc_read(STDIN_FILENO, &len);
+ // xmalloc_open_zipped_read_close(filename, &len);
+ if (!psfhdr)
+ bb_perror_msg_and_die("error reading input font");
+ do_load(get_console_fd_or_die(), psfhdr, len);
- /* test for psf first */
- {
- struct psf_header psfhdr;
- int fontsize;
- int hastable;
- unsigned int head0, head;
+ return EXIT_SUCCESS;
+}
+#endif
+
+#if ENABLE_SETFONT
- if (inputlth < sizeof(struct psf_header))
- goto no_psf;
+/*
+kbd-1.12:
- psfhdr = *(struct psf_header *) &inbuf[0];
+setfont [-O font+umap.orig] [-o font.orig] [-om cmap.orig]
+[-ou umap.orig] [-N] [font.new ...] [-m cmap] [-u umap] [-C console]
+[-hNN] [-v] [-V]
- if (!PSF_MAGIC_OK(psfhdr))
- goto no_psf;
+-h NN Override font height
+-o file
+ Save previous font in file
+-O file
+ Save previous font and Unicode map in file
+-om file
+ Store console map in file
+-ou file
+ Save previous Unicode map in file
+-m file
+ Load console map or Unicode console map from file
+-u file
+ Load Unicode table describing the font from file
+ Example:
+ # cp866
+ 0x00-0x7f idem
+ #
+ 0x80 U+0410 # CYRILLIC CAPITAL LETTER A
+ 0x81 U+0411 # CYRILLIC CAPITAL LETTER BE
+ 0x82 U+0412 # CYRILLIC CAPITAL LETTER VE
+-C console
+ Set the font for the indicated console
+-v Verbose
+-V Version
+*/
- 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");
+#if ENABLE_FEATURE_SETFONT_TEXTUAL_MAP
+static int ctoi(char *s)
+{
+ if (s[0] == '\'' && s[1] != '\0' && s[2] == '\'' && s[3] == '\0')
+ return s[1];
+ // U+ means 0x
+ if (s[0] == 'U' && s[1] == '+') {
+ s[0] = '0';
+ s[1] = 'x';
+ }
+ if (!isdigit(s[0]))
+ return -1;
+ return xstrtoul(s, 0);
+}
#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;
+int setfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int setfont_main(int argc UNUSED_PARAM, char **argv)
+{
+ size_t len;
+ unsigned opts;
+ int fd;
+ struct psf_header *psfhdr;
+ char *mapfilename;
+ const char *tty_name = CURRENT_TTY;
+
+ opt_complementary = "=1";
+ opts = getopt32(argv, "m:C:", &mapfilename, &tty_name);
+ argv += optind;
+
+ fd = xopen(tty_name, O_NONBLOCK);
+
+ if (sizeof(CONFIG_DEFAULT_SETFONT_DIR) > 1) { // if not ""
+ if (*argv[0] != '/') {
+ // goto default fonts location. don't die if doesn't exist
+ chdir(CONFIG_DEFAULT_SETFONT_DIR "/consolefonts");
+ }
}
- no_psf:
+ // load font
+ len = 32*1024; // can't be larger
+ psfhdr = xmalloc_open_zipped_read_close(*argv, &len);
+ if (!psfhdr)
+ bb_simple_perror_msg_and_die(*argv);
+ do_load(fd, psfhdr, len);
- /* 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;
+ // load the screen map, if any
+ if (opts & 1) { // -m
+ unsigned mode = PIO_SCRNMAP;
+ void *map;
+
+ if (sizeof(CONFIG_DEFAULT_SETFONT_DIR) > 1) { // if not ""
+ if (mapfilename[0] != '/') {
+ // goto default keymaps location
+ chdir(CONFIG_DEFAULT_SETFONT_DIR "/consoletrans");
+ }
+ }
+ // fetch keymap
+ map = xmalloc_open_zipped_read_close(mapfilename, &len);
+ if (!map)
+ bb_simple_perror_msg_and_die(mapfilename);
+ // file size is 256 or 512 bytes? -> assume binary map
+ if (len == E_TABSZ || len == 2*E_TABSZ) {
+ if (len == 2*E_TABSZ)
+ mode = PIO_UNISCRNMAP;
+ }
+#if ENABLE_FEATURE_SETFONT_TEXTUAL_MAP
+ // assume textual Unicode console maps:
+ // 0x00 U+0000 # NULL (NUL)
+ // 0x01 U+0001 # START OF HEADING (SOH)
+ // 0x02 U+0002 # START OF TEXT (STX)
+ // 0x03 U+0003 # END OF TEXT (ETX)
+ else {
+ int i;
+ char *token[2];
+ parser_t *parser;
+
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(map);
+ map = xmalloc(E_TABSZ * sizeof(unsigned short));
+
+#define unicodes ((unsigned short *)map)
+ // fill vanilla map
+ for (i = 0; i < E_TABSZ; i++)
+ unicodes[i] = 0xf000 + i;
+
+ parser = config_open(mapfilename);
+ while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL | PARSE_MIN_DIE)) {
+ // parse code/value pair
+ int a = ctoi(token[0]);
+ int b = ctoi(token[1]);
+ if (a < 0 || a >= E_TABSZ
+ || b < 0 || b > 65535
+ ) {
+ bb_error_msg_and_die("map format");
+ }
+ // patch map
+ unicodes[a] = b;
+ // unicode character is met?
+ if (b > 255)
+ mode = PIO_UNISCRNMAP;
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ config_close(parser);
+
+ if (mode != PIO_UNISCRNMAP) {
+#define asciis ((unsigned char *)map)
+ for (i = 0; i < E_TABSZ; i++)
+ asciis[i] = unicodes[i];
+#undef asciis
+ }
+#undef unicodes
+ }
+#endif // ENABLE_FEATURE_SETFONT_TEXTUAL_MAP
+
+ // do set screen map
+ xioctl(fd, mode, map);
+
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(map);
}
- do_loadfont(fd, inbuf + offset, unit, 256);
+
+ return EXIT_SUCCESS;
}
+#endif
diff --git a/release/src/router/busybox/console-tools/loadkmap.c b/release/src/router/busybox/console-tools/loadkmap.c
index f4208df6..ac2c0a6e 100644
--- a/release/src/router/busybox/console-tools/loadkmap.c
+++ b/release/src/router/busybox/console-tools/loadkmap.c
@@ -4,30 +4,9 @@
*
* Copyright (C) 1998 Enrique Zanardi <ezanardi@ull.es>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include "busybox.h"
+#include "libbb.h"
#define BINARY_KEYMAP_MAGIC "bkeymap"
@@ -37,43 +16,38 @@ struct kbentry {
unsigned char kb_index;
unsigned short kb_value;
};
-static const int KDSKBENT = 0x4B47; /* sets one entry in translation table */
+/* sets one entry in translation table */
+#define KDSKBENT 0x4B47
/* From <linux/keyboard.h> */
-static const int NR_KEYS = 128;
-static const int MAX_NR_KEYMAPS = 256;
+#define NR_KEYS 128
+#define MAX_NR_KEYMAPS 256
-int loadkmap_main(int argc, char **argv)
+int loadkmap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int loadkmap_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
{
struct kbentry ke;
- u_short *ibuff;
- int i, j, fd, readsz, pos, ibuffsz = NR_KEYS * sizeof(u_short);
- char flags[MAX_NR_KEYMAPS], buff[7];
-
- if (argc != 1)
- bb_show_usage();
+ int i, j, fd;
+ uint16_t ibuff[NR_KEYS];
+/* const char *tty_name = CURRENT_TTY; */
+ RESERVE_CONFIG_BUFFER(flags,MAX_NR_KEYMAPS);
- fd = open(CURRENT_VC, O_RDWR);
- if (fd < 0)
- bb_perror_msg_and_die("Error opening " CURRENT_VC);
+/* bb_warn_ignoring_args(argc >= 2); */
+ fd = get_console_fd_or_die();
+/* or maybe:
+ opt = getopt32(argv, "C:", &tty_name);
+ fd = xopen(tty_name, O_NONBLOCK);
+*/
- read(0, buff, 7);
- if (0 != strncmp(buff, BINARY_KEYMAP_MAGIC, 7))
- bb_error_msg_and_die("This is not a valid binary keymap.");
+ xread(STDIN_FILENO, flags, 7);
+ if (strncmp(flags, BINARY_KEYMAP_MAGIC, 7))
+ bb_error_msg_and_die("not a valid binary keymap");
- if (MAX_NR_KEYMAPS != read(0, flags, MAX_NR_KEYMAPS))
- bb_perror_msg_and_die("Error reading keymap flags");
-
- ibuff = (u_short *) xmalloc(ibuffsz);
+ xread(STDIN_FILENO, flags, MAX_NR_KEYMAPS);
for (i = 0; i < MAX_NR_KEYMAPS; i++) {
if (flags[i] == 1) {
- pos = 0;
- while (pos < ibuffsz) {
- if ((readsz = read(0, (char *) ibuff + pos, ibuffsz - pos)) < 0)
- bb_perror_msg_and_die("Error reading keymap");
- pos += readsz;
- }
+ xread(STDIN_FILENO, ibuff, NR_KEYS * sizeof(uint16_t));
for (j = 0; j < NR_KEYS; j++) {
ke.kb_index = j;
ke.kb_table = i;
@@ -82,8 +56,10 @@ int loadkmap_main(int argc, char **argv)
}
}
}
- /* Don't bother to close files. Exit does that
- * automagically, so we can save a few bytes */
- /* close(fd); */
+
+ if (ENABLE_FEATURE_CLEAN_UP) {
+ close(fd);
+ RELEASE_CONFIG_BUFFER(flags);
+ }
return EXIT_SUCCESS;
}
diff --git a/release/src/router/busybox/console-tools/openvt.c b/release/src/router/busybox/console-tools/openvt.c
index 269dfc01..0906de46 100644
--- a/release/src/router/busybox/console-tools/openvt.c
+++ b/release/src/router/busybox/console-tools/openvt.c
@@ -5,93 +5,177 @@
* busyboxed by Quy Tonthat <quy@signal3.com>
* hacked by Tito <farmatito@tiscali.it>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
-/* getopt not needed */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/types.h>
-#include <ctype.h>
-
-#include "busybox.h"
+#include <linux/vt.h>
+#include "libbb.h"
+
+/* "Standard" openvt's man page (we do not support all of this):
+
+openvt [-c NUM] [-fsulv] [--] [command [args]]
+
+Find the first available VT, and run command on it. Stdio is directed
+to that VT. If no command is specified then $SHELL is used.
+
+-c NUM
+ Use the given VT number, not the first free one.
+-f
+ Force opening a VT: don't try to check if VT is already in use.
+-s
+ Switch to the new VT when starting the command.
+ The VT of the new command will be made the new current VT.
+-u
+ Figure out the owner of the current VT, and run login as that user.
+ Suitable to be called by init. Shouldn't be used with -c or -l.
+-l
+ Make the command a login shell: a "-" is prepended to the argv[0]
+ when command is executed.
+-v
+ Verbose.
+-w
+ Wait for command to complete. If -w and -s are used together,
+ switch back to the controlling terminal when the command completes.
+
+bbox:
+-u: not implemented
+-f: always in effect
+-l: not implemented, ignored
+-v: ignored
+-ws: does NOT switch back
+*/
-#define VTNAME "/dev/tty%d"
+/* Helper: does this fd understand VT_xxx? */
+static int not_vt_fd(int fd)
+{
+ struct vt_stat vtstat;
+ return ioctl(fd, VT_GETSTATE, &vtstat); /* !0: error, it's not VT fd */
+}
-int openvt_main(int argc, char **argv)
+/* Helper: get a fd suitable for VT_xxx */
+static int get_vt_fd(void)
{
- int pid;
int fd;
- int vtno;
- char vtname[sizeof VTNAME + 2];
+ /* Do we, by chance, already have it? */
+ for (fd = 0; fd < 3; fd++)
+ if (!not_vt_fd(fd))
+ return fd;
+ /* _only_ O_NONBLOCK: ask for neither read nor write perms */
+ /*FIXME: use? device_open(DEV_CONSOLE,0); */
+ fd = open(DEV_CONSOLE, O_NONBLOCK);
+ if (fd >= 0 && !not_vt_fd(fd))
+ return fd;
+ bb_error_msg_and_die("can't find open VT");
+}
- if (argc < 3)
- bb_show_usage();
-
- if (!isdigit(argv[1][0]))
- bb_show_usage();
+static int find_free_vtno(void)
+{
+ int vtno;
+ int fd = get_vt_fd();
+
+ errno = 0;
+ /*xfunc_error_retval = 3; - do we need compat? */
+ if (ioctl(fd, VT_OPENQRY, &vtno) != 0 || vtno <= 0)
+ bb_perror_msg_and_die("can't find open VT");
+// Not really needed, grep for DAEMON_ONLY_SANITIZE
+// if (fd > 2)
+// close(fd);
+ return vtno;
+}
- vtno = (int) atol(argv[1]);
+/* vfork scares gcc, it generates bigger code.
+ * Keep it away from main program.
+ * TODO: move to libbb; or adapt existing libbb's spawn().
+ */
+static NOINLINE void vfork_child(char **argv)
+{
+ if (vfork() == 0) {
+ /* CHILD */
+ /* Try to make this VT our controlling tty */
+ setsid(); /* lose old ctty */
+ ioctl(STDIN_FILENO, TIOCSCTTY, 0 /* 0: don't forcibly steal */);
+ //bb_error_msg("our sid %d", getsid(0));
+ //bb_error_msg("our pgrp %d", getpgrp());
+ //bb_error_msg("VT's sid %d", tcgetsid(0));
+ //bb_error_msg("VT's pgrp %d", tcgetpgrp(0));
+ BB_EXECVP(argv[0], argv);
+ bb_perror_msg_and_die("exec %s", argv[0]);
+ }
+}
- /* if (vtno <= 0 || vtno > 63) */
- if (vtno <= 0 || vtno > 12)
- bb_error_msg_and_die("Illegal vt number (%d)", vtno);
+int openvt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int openvt_main(int argc UNUSED_PARAM, char **argv)
+{
+ char vtname[sizeof(VC_FORMAT) + sizeof(int)*3];
+ struct vt_stat vtstat;
+ char *str_c;
+ int vtno;
+ int flags;
+ enum {
+ OPT_c = (1 << 0),
+ OPT_w = (1 << 1),
+ OPT_s = (1 << 2),
+ OPT_l = (1 << 3),
+ OPT_f = (1 << 4),
+ OPT_v = (1 << 5),
+ };
+
+ /* "+" - stop on first non-option */
+ flags = getopt32(argv, "+c:wslfv", &str_c);
+ argv += optind;
+
+ if (flags & OPT_c) {
+ /* Check for illegal vt number: < 1 or > 63 */
+ vtno = xatou_range(str_c, 1, 63);
+ } else {
+ vtno = find_free_vtno();
+ }
- sprintf(vtname, VTNAME, vtno);
+ /* Grab new VT */
+ sprintf(vtname, VC_FORMAT, vtno);
+ /* (Try to) clean up stray open fds above fd 2 */
+ bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS | DAEMON_ONLY_SANITIZE, NULL);
+ close(STDIN_FILENO);
+ /*setsid(); - BAD IDEA: after we exit, child is SIGHUPed... */
+ xopen(vtname, O_RDWR);
+ xioctl(STDIN_FILENO, VT_GETSTATE, &vtstat);
+
+ if (flags & OPT_s) {
+ console_make_active(STDIN_FILENO, vtno);
+ }
- argv+=2;
- argc-=2;
+ if (!argv[0]) {
+ argv--;
+ argv[0] = getenv("SHELL");
+ if (!argv[0])
+ argv[0] = (char *) DEFAULT_SHELL;
+ /*argv[1] = NULL; - already is */
+ }
- if((pid = fork()) == 0) {
- /* leave current vt */
+ xdup2(STDIN_FILENO, STDOUT_FILENO);
+ xdup2(STDIN_FILENO, STDERR_FILENO);
-#ifdef ESIX_5_3_2_D
- if (setpgrp() < 0) {
-#else
- if (setsid() < 0) {
+#ifdef BLOAT
+ {
+ /* Handle -l (login shell) option */
+ const char *prog = argv[0];
+ if (flags & OPT_l)
+ argv[0] = xasprintf("-%s", argv[0]);
+ }
#endif
- bb_perror_msg_and_die("Unable to set new session");
+ vfork_child(argv);
+ if (flags & OPT_w) {
+ /* We have only one child, wait for it */
+ safe_waitpid(-1, NULL, 0); /* loops on EINTR */
+ if (flags & OPT_s) {
+ console_make_active(STDIN_FILENO, vtstat.v_active);
+ // Compat: even with -c N (try to) disallocate:
+ // # /usr/app/kbd-1.12/bin/openvt -f -c 9 -ws sleep 5
+ // openvt: could not deallocate console 9
+ xioctl(STDIN_FILENO, VT_DISALLOCATE, (void*)(ptrdiff_t)vtno);
}
- close(0); /* so that new vt becomes stdin */
-
- /* and grab new one */
- if ((fd = open(vtname, O_RDWR)) == -1)
- bb_perror_msg_and_die("could not open %s", vtname);
-
- /* Reassign stdout and sterr */
- close(1);
- close(2);
- dup(fd);
- dup(fd);
-
- execvp(argv[0], argv);
- _exit(1);
}
return EXIT_SUCCESS;
}
-
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
diff --git a/release/src/router/busybox/console-tools/reset.c b/release/src/router/busybox/console-tools/reset.c
index 69b1e846..6917eda4 100644
--- a/release/src/router/busybox/console-tools/reset.c
+++ b/release/src/router/busybox/console-tools/reset.c
@@ -2,32 +2,46 @@
/*
* Mini reset implementation for busybox
*
- * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
* Written by Erik Andersen and Kent Robotti <robotti@metconnect.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include "busybox.h"
+#include "libbb.h"
+
+/* BTW, which "standard" package has this utility? It doesn't seem
+ * to be ncurses, coreutils, console-tools... then what? */
-extern int reset_main(int argc, char **argv)
+#if ENABLE_STTY
+int stty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+#endif
+
+int reset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int reset_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
{
- printf("\033[?25h\033c\033[J");
- return EXIT_SUCCESS;
-}
+ static const char *const args[] = {
+ "stty", "sane", NULL
+ };
+ /* no options, no getopt */
+
+ if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
+ /* 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");
+ /* http://bugs.busybox.net/view.php?id=1414:
+ * people want it to reset echo etc: */
+#if ENABLE_STTY
+ return stty_main(2, (char**)args);
+#else
+ execvp("stty", (char**)args);
+#endif
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/release/src/router/busybox/console-tools/resize.c b/release/src/router/busybox/console-tools/resize.c
new file mode 100644
index 00000000..4504cc85
--- /dev/null
+++ b/release/src/router/busybox/console-tools/resize.c
@@ -0,0 +1,71 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * resize - set terminal width and height.
+ *
+ * Copyright 2006 Bernhard Reutner-Fischer
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+/* no options, no getopt */
+#include "libbb.h"
+
+#define ESC "\033"
+
+#define old_termios (*(struct termios*)&bb_common_bufsiz1)
+
+static void
+onintr(int sig UNUSED_PARAM)
+{
+ tcsetattr(STDERR_FILENO, TCSANOW, &old_termios);
+ exit(EXIT_FAILURE);
+}
+
+int resize_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int resize_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
+{
+ struct termios new;
+ struct winsize w = { 0, 0, 0, 0 };
+ int ret;
+
+ /* We use _stderr_ in order to make resize usable
+ * in shell backticks (those redirect stdout away from tty).
+ * NB: other versions of resize open "/dev/tty"
+ * and operate on it - should we do the same?
+ */
+
+ tcgetattr(STDERR_FILENO, &old_termios); /* fiddle echo */
+ new = old_termios;
+ new.c_cflag |= (CLOCAL | CREAD);
+ new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ bb_signals(0
+ + (1 << SIGINT)
+ + (1 << SIGQUIT)
+ + (1 << SIGTERM)
+ + (1 << SIGALRM)
+ , onintr);
+ tcsetattr(STDERR_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
+ */
+ fprintf(stderr, ESC"7" ESC"[r" ESC"[999;999H" ESC"[6n");
+ alarm(3); /* Just in case terminal won't answer */
+ scanf(ESC"[%hu;%huR", &w.ws_row, &w.ws_col);
+ fprintf(stderr, ESC"8");
+
+ /* BTW, other versions of resize recalculate w.ws_xpixel, ws.ws_ypixel
+ * by calculating character cell HxW from old values
+ * (gotten via TIOCGWINSZ) and recomputing *pixel values */
+ ret = ioctl(STDERR_FILENO, TIOCSWINSZ, &w);
+
+ tcsetattr(STDERR_FILENO, TCSANOW, &old_termios);
+
+ 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/release/src/router/busybox/console-tools/setconsole.c b/release/src/router/busybox/console-tools/setconsole.c
new file mode 100644
index 00000000..8ad9948d
--- /dev/null
+++ b/release/src/router/busybox/console-tools/setconsole.c
@@ -0,0 +1,39 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * setconsole.c - redirect system console output
+ *
+ * Copyright (C) 2004,2005 Enrik Berkhan <Enrik.Berkhan@inka.de>
+ * Copyright (C) 2008 Bernhard Reutner-Fischer
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "libbb.h"
+
+int setconsole_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int setconsole_main(int argc UNUSED_PARAM, char **argv)
+{
+ const char *device = CURRENT_TTY;
+ bool reset;
+
+#if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS
+ static const char setconsole_longopts[] ALIGN1 =
+ "reset\0" No_argument "r"
+ ;
+ applet_long_options = setconsole_longopts;
+#endif
+ /* at most one non-option argument */
+ opt_complementary = "?1";
+ reset = getopt32(argv, "r");
+
+ argv += 1 + reset;
+ if (*argv) {
+ device = *argv;
+ } else {
+ if (reset)
+ device = DEV_CONSOLE;
+ }
+
+ xioctl(xopen(device, O_RDONLY), TIOCCONS, NULL);
+ return EXIT_SUCCESS;
+}
diff --git a/release/src/router/busybox/console-tools/setkeycodes.c b/release/src/router/busybox/console-tools/setkeycodes.c
index 0a5366be..597272a2 100644
--- a/release/src/router/busybox/console-tools/setkeycodes.c
+++ b/release/src/router/busybox/console-tools/setkeycodes.c
@@ -6,67 +6,44 @@
*
* Adjusted for BusyBox by Erik Andersen <andersen@codepoet.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ * 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"
-
+//#include <sys/ioctl.h>
+#include "libbb.h"
/* From <linux/kd.h> */
struct kbkeycode {
- unsigned int scancode, keycode;
+ unsigned scancode, keycode;
+};
+enum {
+ KDSETKEYCODE = 0x4B4D /* write kernel keycode table entry */
};
-static const int KDSETKEYCODE = 0x4B4D; /* write kernel keycode table entry */
-extern int
-setkeycodes_main(int argc, char** argv)
+int setkeycodes_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int setkeycodes_main(int argc, char **argv)
{
- char *ep;
- int fd, sc;
- struct kbkeycode a;
+ int fd, sc;
+ struct kbkeycode a;
- if (argc % 2 != 1 || argc < 2) {
- bb_show_usage();
+ if (!(argc & 1) /* if even */ || argc < 2) {
+ bb_show_usage();
}
-
- fd = get_console_fd();
- while (argc > 2) {
- a.keycode = atoi(argv[2]);
- a.scancode = sc = strtol(argv[1], &ep, 16);
- if (*ep) {
- bb_error_msg_and_die("error reading SCANCODE: '%s'", argv[1]);
- }
- if (a.scancode > 127) {
- a.scancode -= 0xe000;
- a.scancode += 128;
- }
- if (a.scancode > 255 || a.keycode > 127) {
- bb_error_msg_and_die("SCANCODE or KEYCODE outside bounds");
- }
- if (ioctl(fd,KDSETKEYCODE,&a)) {
- perror("KDSETKEYCODE");
- bb_error_msg_and_die("failed to set SCANCODE %x to KEYCODE %d", sc, a.keycode);
+ fd = get_console_fd_or_die();
+
+ while (argc > 2) {
+ a.keycode = xatou_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;
+ }
+ ioctl_or_perror_and_die(fd, KDSETKEYCODE, &a,
+ "can't set SCANCODE %x to KEYCODE %d",
+ sc, a.keycode);
+ argc -= 2;
+ argv += 2;
}
- argc -= 2;
- argv += 2;
- }
return EXIT_SUCCESS;
}
diff --git a/release/src/router/busybox/console-tools/setlogcons.c b/release/src/router/busybox/console-tools/setlogcons.c
new file mode 100644
index 00000000..dd44591a
--- /dev/null
+++ b/release/src/router/busybox/console-tools/setlogcons.c
@@ -0,0 +1,30 @@
+/* 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 "libbb.h"
+
+int setlogcons_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int setlogcons_main(int argc UNUSED_PARAM, char **argv)
+{
+ struct {
+ char fn;
+ char subarg;
+ } arg = { 11, /* redirect kernel messages */
+ 0 /* to specified console (current as default) */
+ };
+
+ if (argv[1])
+ arg.subarg = xatou_range(argv[1], 0, 63);
+
+ xioctl(xopen(VC_1, O_RDONLY), TIOCLINUX, &arg);
+
+ return EXIT_SUCCESS;
+}
diff --git a/release/src/router/busybox/console-tools/showkey.c b/release/src/router/busybox/console-tools/showkey.c
new file mode 100644
index 00000000..681114df
--- /dev/null
+++ b/release/src/router/busybox/console-tools/showkey.c
@@ -0,0 +1,138 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * shows keys pressed. inspired by kbd package
+ *
+ * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
+ *
+ * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ */
+
+#include "libbb.h"
+#include <linux/kd.h>
+
+// set raw tty mode
+// also used by microcom
+// libbb candidates?
+static void xget1(int fd, struct termios *t, struct termios *oldt)
+{
+ tcgetattr(fd, oldt);
+ *t = *oldt;
+ cfmakeraw(t);
+}
+
+static int xset1(int fd, struct termios *tio, const char *device)
+{
+ int ret = tcsetattr(fd, TCSAFLUSH, tio);
+
+ if (ret) {
+ bb_perror_msg("can't tcsetattr for %s", device);
+ }
+ return ret;
+}
+
+/*
+ * GLOBALS
+ */
+struct globals {
+ int kbmode;
+ struct termios tio, tio0;
+};
+#define G (*ptr_to_globals)
+#define kbmode (G.kbmode)
+#define tio (G.tio)
+#define tio0 (G.tio0)
+#define INIT_G() do { \
+ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
+} while (0)
+
+
+static void signal_handler(int signo)
+{
+ // restore keyboard and console settings
+ xset1(STDIN_FILENO, &tio0, "stdin");
+ xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode);
+ // alarmed? -> exit 0
+ exit(SIGALRM == signo);
+}
+
+int showkey_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int showkey_main(int argc UNUSED_PARAM, char **argv)
+{
+ enum {
+ OPT_a = (1<<0), // display the decimal/octal/hex values of the keys
+ OPT_k = (1<<1), // display only the interpreted keycodes (default)
+ OPT_s = (1<<2), // display only the raw scan-codes
+ };
+
+ // FIXME: aks are all mutually exclusive
+ getopt32(argv, "aks");
+
+ INIT_G();
+
+ // get keyboard settings
+ xioctl(STDIN_FILENO, KDGKBMODE, &kbmode);
+ printf("kb mode was %s\n\nPress any keys. Program terminates %s\n\n",
+ kbmode == K_RAW ? "RAW" :
+ (kbmode == K_XLATE ? "XLATE" :
+ (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" :
+ (kbmode == K_UNICODE ? "UNICODE" : "?UNKNOWN?")))
+ , (option_mask32 & OPT_a) ? "when CTRL+D pressed" : "10s after last keypress"
+ );
+ // prepare for raw mode
+ xget1(STDIN_FILENO, &tio, &tio0);
+ // put stdin in raw mode
+ xset1(STDIN_FILENO, &tio, "stdin");
+
+ if (option_mask32 & OPT_a) {
+ char c;
+ // just read stdin char by char
+ while (1 == safe_read(STDIN_FILENO, &c, 1)) {
+ printf("%3d 0%03o 0x%02x\r\n", c, c, c);
+ if (04 /*CTRL-D*/ == c)
+ break;
+ }
+ } else {
+ // we should exit on any signal
+ bb_signals(BB_FATAL_SIGS, signal_handler);
+ // set raw keyboard mode
+ xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW));
+
+ // read and show scancodes
+ while (1) {
+ char buf[18];
+ int i, n;
+ // setup 10s watchdog
+ alarm(10);
+ // read scancodes
+ n = read(STDIN_FILENO, buf, sizeof(buf));
+ i = 0;
+ while (i < n) {
+ char c = buf[i];
+ // show raw scancodes ordered? ->
+ if (option_mask32 & OPT_s) {
+ printf("0x%02x ", buf[i++]);
+ // show interpreted scancodes (default) ? ->
+ } else {
+ int kc;
+ if (i+2 < n && (c & 0x7f) == 0
+ && (buf[i+1] & 0x80) != 0
+ && (buf[i+2] & 0x80) != 0) {
+ kc = ((buf[i+1] & 0x7f) << 7) | (buf[i+2] & 0x7f);
+ i += 3;
+ } else {
+ kc = (c & 0x7f);
+ i++;
+ }
+ printf("keycode %3d %s", kc, (c & 0x80) ? "release" : "press");
+ }
+ }
+ puts("\r");
+ }
+ }
+
+ // cleanup
+ signal_handler(SIGALRM);
+
+ // should never be here!
+ return EXIT_SUCCESS;
+}