From 73b16af8feec390afbabd9356d6e5e83c0390838 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 15 May 2015 10:20:47 +0200 Subject: busybox: imported from http://www.busybox.net/downloads/busybox-1.13.3.tar.bz2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- console-tools/Config.in | 138 ++++++++++++++++ console-tools/Kbuild | 22 +++ console-tools/chvt.c | 24 +++ console-tools/clear.c | 19 +++ console-tools/deallocvt.c | 33 ++++ console-tools/dumpkmap.c | 69 ++++++++ console-tools/kbd_mode.c | 55 +++++++ console-tools/loadfont.c | 371 ++++++++++++++++++++++++++++++++++++++++++++ console-tools/loadkmap.c | 65 ++++++++ console-tools/openvt.c | 181 +++++++++++++++++++++ console-tools/reset.c | 47 ++++++ console-tools/resize.c | 71 +++++++++ console-tools/setconsole.c | 39 +++++ console-tools/setkeycodes.c | 49 ++++++ console-tools/setlogcons.c | 30 ++++ console-tools/showkey.c | 138 ++++++++++++++++ 16 files changed, 1351 insertions(+) create mode 100644 console-tools/Config.in create mode 100644 console-tools/Kbuild create mode 100644 console-tools/chvt.c create mode 100644 console-tools/clear.c create mode 100644 console-tools/deallocvt.c create mode 100644 console-tools/dumpkmap.c create mode 100644 console-tools/kbd_mode.c create mode 100644 console-tools/loadfont.c create mode 100644 console-tools/loadkmap.c create mode 100644 console-tools/openvt.c create mode 100644 console-tools/reset.c create mode 100644 console-tools/resize.c create mode 100644 console-tools/setconsole.c create mode 100644 console-tools/setkeycodes.c create mode 100644 console-tools/setlogcons.c create mode 100644 console-tools/showkey.c (limited to 'console-tools') diff --git a/console-tools/Config.in b/console-tools/Config.in new file mode 100644 index 0000000..994140b --- /dev/null +++ b/console-tools/Config.in @@ -0,0 +1,138 @@ +# +# 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 KBD_MODE + bool "kbd_mode" + default n + help + This program reports and sets keyboard mode. + +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 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/console-tools/Kbuild b/console-tools/Kbuild new file mode 100644 index 0000000..df5ffdb --- /dev/null +++ b/console-tools/Kbuild @@ -0,0 +1,22 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# 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/console-tools/chvt.c b/console-tools/chvt.c new file mode 100644 index 0000000..302ffb4 --- /dev/null +++ b/console-tools/chvt.c @@ -0,0 +1,24 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini chvt implementation for busybox + * + * Copyright (C) 1999-2004 by Erik Andersen + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" + +int chvt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int chvt_main(int argc, char **argv) +{ + int num; + + if (argc != 2) { + bb_show_usage(); + } + + num = xatou_range(argv[1], 1, 63); + console_make_active(get_console_fd_or_die(), num); + return EXIT_SUCCESS; +} diff --git a/console-tools/clear.c b/console-tools/clear.c new file mode 100644 index 0000000..8b727b3 --- /dev/null +++ b/console-tools/clear.c @@ -0,0 +1,19 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini clear implementation for busybox + * + * Copyright (C) 1999-2004 by Erik Andersen + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * + */ + +/* no options, no getopt */ + +#include "libbb.h" + +int clear_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int clear_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) +{ + return printf("\033[H\033[J") != 6; +} diff --git a/console-tools/deallocvt.c b/console-tools/deallocvt.c new file mode 100644 index 0000000..0974883 --- /dev/null +++ b/console-tools/deallocvt.c @@ -0,0 +1,33 @@ +/* vi: set sw=4 ts=4: */ +/* + * Disallocate virtual terminal(s) + * + * Copyright (C) 2003 by Tito Ragusa + * Copyright (C) 1999-2004 by Erik Andersen + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +/* no options, no getopt */ + +#include "libbb.h" + +/* From */ +enum { VT_DISALLOCATE = 0x5608 }; /* free memory associated to vt */ + +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; + + if (argv[1]) { + if (argv[2]) + bb_show_usage(); + num = xatou_range(argv[1], 1, 63); + } + + /* 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/console-tools/dumpkmap.c b/console-tools/dumpkmap.c new file mode 100644 index 0000000..c382b5a --- /dev/null +++ b/console-tools/dumpkmap.c @@ -0,0 +1,69 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini dumpkmap implementation for busybox + * + * Copyright (C) Arne Bernin + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * + */ +/* no options, no getopt */ + +#include "libbb.h" + +/* From */ +struct kbentry { + unsigned char kb_table; + unsigned char kb_index; + unsigned short kb_value; +}; +#define KDGKBENT 0x4B46 /* gets one entry in translation table */ + +/* From */ +#define NR_KEYS 128 +#define MAX_NR_KEYMAPS 256 + +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; + RESERVE_CONFIG_BUFFER(flags,MAX_NR_KEYMAPS); + +/* bb_warn_ignoring_args(argc>=2);*/ + + fd = get_console_fd_or_die(); + + write(STDOUT_FILENO, "bkeymap", 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(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_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); + } + } + } + } + if (ENABLE_FEATURE_CLEAN_UP) { + close(fd); + RELEASE_CONFIG_BUFFER(flags); + } + return EXIT_SUCCESS; +} diff --git a/console-tools/kbd_mode.c b/console-tools/kbd_mode.c new file mode 100644 index 0000000..544bbb7 --- /dev/null +++ b/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 + * written using Andries Brouwer '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 + +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/console-tools/loadfont.c b/console-tools/loadfont.c new file mode 100644 index 0000000..863c6ef --- /dev/null +++ b/console-tools/loadfont.c @@ -0,0 +1,371 @@ +/* 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 "libbb.h" +#include + +#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 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 */ + +#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 */ + + +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 do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize) +{ + char *buf; + int i; + + if (unit < 1 || unit > 32) + 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); + + { /* 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; + + cfd.charcount = fontsize; + cfd.charheight = unit; + cfd.chardata = buf; + + if (!ioctl_or_perror(fd, PIO_FONTX, &cfd, "PIO_FONTX ioctl failed (will try PIO_FONT)")) + goto ret; /* success */ + } +#endif + xioctl(fd, PIO_FONT, buf); + ret: +#endif /* 0 */ + free(buf); +} + +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; + uint16_t unicode; + + maxct = tailsz; /* more than enough */ + up = xmalloc(maxct * sizeof(struct unipair)); + + for (glyph = 0; glyph < fontsize; glyph++) { + while (tailsz >= 2) { + unicode = (((uint16_t) 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; + xioctl(fd, PIO_UNIMAPCLR, &advice); + ud.entry_ct = ct; + ud.entries = up; + 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 + 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); +} + +#if ENABLE_LOADFONT +int loadfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int loadfont_main(int argc UNUSED_PARAM, char **argv) +{ + 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. + */ + 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); + + return EXIT_SUCCESS; +} +#endif + +#if ENABLE_SETFONT + +/* +kbd-1.12: + +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] + +-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 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 + +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"); + } + } + // 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); + + // 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); + } + + return EXIT_SUCCESS; +} +#endif diff --git a/console-tools/loadkmap.c b/console-tools/loadkmap.c new file mode 100644 index 0000000..ac2c0a6 --- /dev/null +++ b/console-tools/loadkmap.c @@ -0,0 +1,65 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini loadkmap implementation for busybox + * + * Copyright (C) 1998 Enrique Zanardi + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ +#include "libbb.h" + +#define BINARY_KEYMAP_MAGIC "bkeymap" + +/* From */ +struct kbentry { + unsigned char kb_table; + unsigned char kb_index; + unsigned short kb_value; +}; +/* sets one entry in translation table */ +#define KDSKBENT 0x4B47 + +/* From */ +#define NR_KEYS 128 +#define MAX_NR_KEYMAPS 256 + +int loadkmap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int loadkmap_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) +{ + struct kbentry ke; + int i, j, fd; + uint16_t ibuff[NR_KEYS]; +/* const char *tty_name = CURRENT_TTY; */ + RESERVE_CONFIG_BUFFER(flags,MAX_NR_KEYMAPS); + +/* 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); +*/ + + xread(STDIN_FILENO, flags, 7); + if (strncmp(flags, BINARY_KEYMAP_MAGIC, 7)) + bb_error_msg_and_die("not a valid binary keymap"); + + xread(STDIN_FILENO, flags, MAX_NR_KEYMAPS); + + for (i = 0; i < MAX_NR_KEYMAPS; i++) { + if (flags[i] == 1) { + xread(STDIN_FILENO, ibuff, NR_KEYS * sizeof(uint16_t)); + 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); + RELEASE_CONFIG_BUFFER(flags); + } + return EXIT_SUCCESS; +} diff --git a/console-tools/openvt.c b/console-tools/openvt.c new file mode 100644 index 0000000..0906de4 --- /dev/null +++ b/console-tools/openvt.c @@ -0,0 +1,181 @@ +/* vi: set sw=4 ts=4: */ +/* + * openvt.c - open a vt to run a command. + * + * busyboxed by Quy Tonthat + * hacked by Tito + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include +#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 +*/ + +/* 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 */ +} + +/* Helper: get a fd suitable for VT_xxx */ +static int get_vt_fd(void) +{ + int fd; + + /* 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"); +} + +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; +} + +/* 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]); + } +} + +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(); + } + + /* 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); + } + + if (!argv[0]) { + argv--; + argv[0] = getenv("SHELL"); + if (!argv[0]) + argv[0] = (char *) DEFAULT_SHELL; + /*argv[1] = NULL; - already is */ + } + + xdup2(STDIN_FILENO, STDOUT_FILENO); + xdup2(STDIN_FILENO, STDERR_FILENO); + +#ifdef BLOAT + { + /* Handle -l (login shell) option */ + const char *prog = argv[0]; + if (flags & OPT_l) + argv[0] = xasprintf("-%s", argv[0]); + } +#endif + + 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); + } + } + return EXIT_SUCCESS; +} diff --git a/console-tools/reset.c b/console-tools/reset.c new file mode 100644 index 0000000..6917eda --- /dev/null +++ b/console-tools/reset.c @@ -0,0 +1,47 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini reset implementation for busybox + * + * Copyright (C) 1999-2004 by Erik Andersen + * Written by Erik Andersen and Kent Robotti + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" + +/* BTW, which "standard" package has this utility? It doesn't seem + * to be ncurses, coreutils, console-tools... then what? */ + +#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) +{ + 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/console-tools/resize.c b/console-tools/resize.c new file mode 100644 index 0000000..4504cc8 --- /dev/null +++ b/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/console-tools/setconsole.c b/console-tools/setconsole.c new file mode 100644 index 0000000..8ad9948 --- /dev/null +++ b/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 + * 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/console-tools/setkeycodes.c b/console-tools/setkeycodes.c new file mode 100644 index 0000000..597272a --- /dev/null +++ b/console-tools/setkeycodes.c @@ -0,0 +1,49 @@ +/* vi: set sw=4 ts=4: */ +/* + * setkeycodes + * + * Copyright (C) 1994-1998 Andries E. Brouwer + * + * Adjusted for BusyBox by Erik Andersen + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +//#include +#include "libbb.h" + +/* From */ +struct kbkeycode { + unsigned scancode, keycode; +}; +enum { + KDSETKEYCODE = 0x4B4D /* write kernel keycode table entry */ +}; + +int setkeycodes_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int setkeycodes_main(int argc, char **argv) +{ + int fd, sc; + struct kbkeycode a; + + if (!(argc & 1) /* if even */ || argc < 2) { + bb_show_usage(); + } + + 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; + } + return EXIT_SUCCESS; +} diff --git a/console-tools/setlogcons.c b/console-tools/setlogcons.c new file mode 100644 index 0000000..dd44591 --- /dev/null +++ b/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 + * + * 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/console-tools/showkey.c b/console-tools/showkey.c new file mode 100644 index 0000000..681114d --- /dev/null +++ b/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 + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" +#include + +// 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; +} -- cgit v1.2.3