diff options
Diffstat (limited to 'toys/other')
40 files changed, 2098 insertions, 2219 deletions
diff --git a/toys/other/bzcat.c b/toys/other/bzcat.c index c0c2b96a..8266484c 100644 --- a/toys/other/bzcat.c +++ b/toys/other/bzcat.c @@ -1,28 +1,26 @@ -/* vi: set sw=4 ts=4: - * - * bzcat.c - decompress stdin to stdout using bunzip2. +/* bzcat.c - decompress stdin to stdout using bunzip2. * * Copyright 2007 Rob Landley <rob@landley.net> USE_BZCAT(NEWTOY(bzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config BZCAT - bool "bzcat" - default y - help - usage: bzcat [filename...] + bool "bzcat" + default y + help + usage: bzcat [filename...] - Decompress listed files to stdout. Use stdin if no files listed. + Decompress listed files to stdout. Use stdin if no files listed. */ #include "toys.h" static void do_bzcat(int fd, char *name) { - bunzipStream(fd, 1); + bunzipStream(fd, 1); } void bzcat_main(void) { - loopfiles(toys.optargs, do_bzcat); + loopfiles(toys.optargs, do_bzcat); } diff --git a/toys/other/catv.c b/toys/other/catv.c index a0790a9b..62520c41 100644 --- a/toys/other/catv.c +++ b/toys/other/catv.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * cat -v implementation for toybox +/* cat -v implementation for toybox * * Copyright (C) 2006, 2007 Rob Landley <rob@landley.net> * @@ -10,17 +8,17 @@ USE_CATV(NEWTOY(catv, "vte", TOYFLAG_USR|TOYFLAG_BIN)) config CATV - bool "catv" - default y - help - usage: catv [-evt] [filename...] + bool "catv" + default y + help + usage: catv [-evt] [filename...] - Display nonprinting characters as escape sequences. Use M-x for - high ascii characters (>127), and ^x for other nonprinting chars. + Display nonprinting characters as escape sequences. Use M-x for + high ascii characters (>127), and ^x for other nonprinting chars. - -e Mark each newline with $ - -t Show tabs as ^I - -v Don't use ^x or M-x escapes. + -e Mark each newline with $ + -t Show tabs as ^I + -v Don't use ^x or M-x escapes. */ #define FOR_catv @@ -30,40 +28,40 @@ config CATV static void do_catv(int fd, char *name) { - for(;;) { - int i, len; + for(;;) { + int i, len; - len = read(fd, toybuf, sizeof(toybuf)); - if (len < 0) toys.exitval = EXIT_FAILURE; - if (len < 1) break; - for (i=0; i<len; i++) { - char c=toybuf[i]; + len = read(fd, toybuf, sizeof(toybuf)); + if (len < 0) toys.exitval = EXIT_FAILURE; + if (len < 1) break; + for (i=0; i<len; i++) { + char c=toybuf[i]; - if (c > 126 && (toys.optflags & FLAG_v)) { - if (c > 127) { - printf("M-"); - c -= 128; - } - if (c == 127) { - printf("^?"); - continue; - } - } - if (c < 32) { - if (c == 10) { - if (toys.optflags & FLAG_e) xputc('$'); - } else if (toys.optflags & (c==9 ? FLAG_t : FLAG_v)) { - printf("^%c", c+'@'); - continue; - } - } - xputc(c); - } - } + if (c > 126 && (toys.optflags & FLAG_v)) { + if (c > 127) { + printf("M-"); + c -= 128; + } + if (c == 127) { + printf("^?"); + continue; + } + } + if (c < 32) { + if (c == 10) { + if (toys.optflags & FLAG_e) xputc('$'); + } else if (toys.optflags & (c==9 ? FLAG_t : FLAG_v)) { + printf("^%c", c+'@'); + continue; + } + } + xputc(c); + } + } } void catv_main(void) { - toys.optflags ^= FLAG_v; - loopfiles(toys.optargs, do_catv); + toys.optflags ^= FLAG_v; + loopfiles(toys.optargs, do_catv); } diff --git a/toys/other/chroot.c b/toys/other/chroot.c index 003ed072..c9ff10c7 100644 --- a/toys/other/chroot.c +++ b/toys/other/chroot.c @@ -1,26 +1,23 @@ -/* vi: set sw=4 ts=4: - * - * chroot.c - Run command in new root directory. +/* chroot.c - Run command in new root directory. * * Copyright 2007 Rob Landley <rob@landley.net> USE_CHROOT(NEWTOY(chroot, "^<1", TOYFLAG_USR|TOYFLAG_SBIN)) config CHROOT - bool "chroot" - default y - help - usage: chroot NEWPATH [commandline...] + bool "chroot" + default y + help + usage: chroot NEWPATH [commandline...] - Run command within a new root directory. If no command, run /bin/sh. + Run command within a new root directory. If no command, run /bin/sh. */ #include "toys.h" void chroot_main(void) { - char *binsh[] = {"/bin/sh", "-i", 0}; - if (chdir(*toys.optargs) || chroot(".")) - perror_exit("%s", *toys.optargs); - xexec(toys.optargs[1] ? toys.optargs+1 : binsh); + char *binsh[] = {"/bin/sh", "-i", 0}; + if (chdir(*toys.optargs) || chroot(".")) perror_exit("%s", *toys.optargs); + xexec(toys.optargs[1] ? toys.optargs+1 : binsh); } diff --git a/toys/other/chvt.c b/toys/other/chvt.c index 80eeadc4..7a0119c9 100644 --- a/toys/other/chvt.c +++ b/toys/other/chvt.c @@ -1,22 +1,20 @@ -/* vi: set sw=4 ts=4: - * - * chvt.c - switch virtual terminals +/* chvt.c - switch virtual terminals * * Copyright (C) 2008 David Anders <danders@amltd.com> USE_CHVT(NEWTOY(chvt, "<1", TOYFLAG_USR|TOYFLAG_SBIN)) config CHVT - bool "chvt" - default y - help - usage: chvt N + bool "chvt" + default y + help + usage: chvt N - Change to virtual terminal number N. (This only works in text mode.) + Change to virtual terminal number N. (This only works in text mode.) - Virtual terminals are the Linux VGA text mode displays, ordinarily - switched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch - from X to a virtual terminal, and alt-F6 (or F7, or F8) to get back. + Virtual terminals are the Linux VGA text mode displays, ordinarily + switched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch + from X to a virtual terminal, and alt-F6 (or F7, or F8) to get back. */ #include "toys.h" @@ -24,26 +22,26 @@ config CHVT /* Note: get_console_fb() will need to be moved into a seperate lib section */ int get_console_fd() { - int fd; - char *consoles[]={"/dev/console", "/dev/vc/0", "/dev/tty", NULL}, **cc; + int fd; + char *consoles[]={"/dev/console", "/dev/vc/0", "/dev/tty", NULL}, **cc; - cc = consoles; - while (*cc) { - fd = open(*cc++, O_RDWR); - if (fd >= 0) return fd; - } + cc = consoles; + while (*cc) { + fd = open(*cc++, O_RDWR); + if (fd >= 0) return fd; + } - return -1; + return -1; } void chvt_main(void) { - int vtnum, fd; + int vtnum, fd; - vtnum=atoi(*toys.optargs); + vtnum=atoi(*toys.optargs); - fd=get_console_fd(); - // These numbers are VT_ACTIVATE and VT_WAITACTIVE from linux/vt.h - if (fd < 0 || ioctl(fd, 0x5606, vtnum) || ioctl(fd, 0x5607, vtnum)) - perror_exit(NULL); + fd=get_console_fd(); + // These numbers are VT_ACTIVATE and VT_WAITACTIVE from linux/vt.h + if (fd < 0 || ioctl(fd, 0x5606, vtnum) || ioctl(fd, 0x5607, vtnum)) + perror_exit(NULL); } diff --git a/toys/other/clear.c b/toys/other/clear.c index 7647f669..2515f735 100644 --- a/toys/other/clear.c +++ b/toys/other/clear.c @@ -1,21 +1,19 @@ -/* vi: set sw=4 ts=4: - * - * clear.c - clear the screen +/* clear.c - clear the screen * * Copyright 2012 Rob Landley <rob@landley.net> USE_CLEAR(NEWTOY(clear, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config CLEAR - bool "clear" - default y - help - Clear the screen. + bool "clear" + default y + help + Clear the screen. */ #include "toys.h" void clear_main(void) { - write(1, "\e[2J\e[H", 7); + write(1, "\e[2J\e[H", 7); } diff --git a/toys/other/count.c b/toys/other/count.c index 22a06a1c..f3b6f821 100644 --- a/toys/other/count.c +++ b/toys/other/count.c @@ -1,34 +1,32 @@ -/* vi: set sw=4 ts=4: - * - * count.c - Progress indicator from stdin to stdout +/* count.c - Progress indicator from stdin to stdout * * Copyright 2002 Rob Landley <rob@landley.net> USE_COUNT(NEWTOY(count, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config COUNT - bool "count" - default y - help - usage: count + bool "count" + default y + help + usage: count - Copy stdin to stdout, displaying simple progress indicator to stderr. + Copy stdin to stdout, displaying simple progress indicator to stderr. */ #include "toys.h" void count_main(void) { - uint64_t size = 0; - int len; - char buf[32]; + uint64_t size = 0; + int len; + char buf[32]; - for (;;) { - len = xread(0, toybuf, sizeof(toybuf)); - if (!len) break; - size += len; - xwrite(1, toybuf, len); - xwrite(2, buf, sprintf(buf, "%"PRIu64" bytes\r", size)); - } - xwrite(2, "\n", 1); + for (;;) { + len = xread(0, toybuf, sizeof(toybuf)); + if (!len) break; + size += len; + xwrite(1, toybuf, len); + xwrite(2, buf, sprintf(buf, "%"PRIu64" bytes\r", size)); + } + xwrite(2, "\n", 1); } diff --git a/toys/other/dos2unix.c b/toys/other/dos2unix.c index 15cc1706..59cd6a53 100644 --- a/toys/other/dos2unix.c +++ b/toys/other/dos2unix.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * dos2unix.c - convert newline format +/* dos2unix.c - convert newline format * * Copyright 2012 Rob Landley <rob@landley.net> @@ -8,60 +6,60 @@ USE_DOS2UNIX(NEWTOY(dos2unix, NULL, TOYFLAG_BIN)) USE_DOS2UNIX(OLDTOY(unix2dos, dos2unix, NULL, TOYFLAG_BIN)) config DOS2UNIX - bool "dos2unix/unix2dos" - default y - help - usage: dos2unix/unix2dos [file...] + bool "dos2unix/unix2dos" + default y + help + usage: dos2unix/unix2dos [file...] - Convert newline format between dos (\r\n) and unix (just \n) - If no files listed copy from stdin, "-" is a synonym for stdin. + Convert newline format between dos (\r\n) and unix (just \n) + If no files listed copy from stdin, "-" is a synonym for stdin. */ #define FOR_dos2unix #include "toys.h" GLOBALS( - char *tempfile; + char *tempfile; ) static void do_dos2unix(int fd, char *name) { - char c = toys.which->name[0]; - int outfd = 1, catch = 0; + char c = toys.which->name[0]; + int outfd = 1, catch = 0; - if (fd) outfd = copy_tempfile(fd, name, &TT.tempfile); + if (fd) outfd = copy_tempfile(fd, name, &TT.tempfile); - for (;;) { - int len, in, out; + for (;;) { + int len, in, out; - len = read(fd, toybuf+(sizeof(toybuf)/2), sizeof(toybuf)/2); - if (len<0) { - perror_msg("%s",name); - toys.exitval = 1; - } - if (len<1) break; + len = read(fd, toybuf+(sizeof(toybuf)/2), sizeof(toybuf)/2); + if (len<0) { + perror_msg("%s",name); + toys.exitval = 1; + } + if (len<1) break; - for (in = out = 0; in < len; in++) { - char x = toybuf[in+sizeof(toybuf)/2]; + for (in = out = 0; in < len; in++) { + char x = toybuf[in+sizeof(toybuf)/2]; - // Drop \r only if followed by \n in dos2unix mode - if (catch) { - if (c == 'u' || x != '\n') toybuf[out++] = '\r'; - catch = 0; - // Add \r only if \n not after \r in unix2dos mode - } else if (c == 'u' && x == '\n') toybuf[out++] = '\r'; + // Drop \r only if followed by \n in dos2unix mode + if (catch) { + if (c == 'u' || x != '\n') toybuf[out++] = '\r'; + catch = 0; + // Add \r only if \n not after \r in unix2dos mode + } else if (c == 'u' && x == '\n') toybuf[out++] = '\r'; - if (x == '\r') catch++; - else toybuf[out++] = x; - } - xwrite(outfd, toybuf, out); - } - if (catch) xwrite(outfd, "\r", 1); + if (x == '\r') catch++; + else toybuf[out++] = x; + } + xwrite(outfd, toybuf, out); + } + if (catch) xwrite(outfd, "\r", 1); - if (fd) replace_tempfile(-1, outfd, &TT.tempfile); + if (fd) replace_tempfile(-1, outfd, &TT.tempfile); } void dos2unix_main(void) { - loopfiles(toys.optargs, do_dos2unix); + loopfiles(toys.optargs, do_dos2unix); } diff --git a/toys/other/free.c b/toys/other/free.c index aa344928..3281d79b 100644 --- a/toys/other/free.c +++ b/toys/other/free.c @@ -1,59 +1,57 @@ -/* vi: set sw=4 ts=4: - * - * free.c - Display amount of free and used memory in the system. +/* free.c - Display amount of free and used memory in the system. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_FREE(NEWTOY(free, "gmkb", TOYFLAG_USR|TOYFLAG_BIN)) config FREE - bool "free" - default y - help - usage: free [-bkmg] + bool "free" + default y + help + usage: free [-bkmg] - Display the total, free and used amount of physical memory and - swap space. + Display the total, free and used amount of physical memory and + swap space. - -bkmg Output in bytes (default), KB, MB or GB + -bkmg Output in bytes (default), KB, MB or GB */ #define FOR_free #include "toys.h" static unsigned long long convert(unsigned long d, unsigned int iscale, - unsigned int oscale) + unsigned int oscale) { - return ((unsigned long long)d*iscale)>>oscale; + return ((unsigned long long)d*iscale)>>oscale; } void free_main(void) { - struct sysinfo info; - unsigned int iscale = 1; - unsigned int oscale = 0; - - sysinfo(&info); - if (info.mem_unit) iscale = info.mem_unit; - if (toys.optflags & FLAG_b) oscale = 0; - if (toys.optflags & FLAG_k) oscale = 10; - if (toys.optflags & FLAG_m) oscale = 20; - if (toys.optflags & FLAG_g) oscale = 30; - - xprintf("\t\ttotal used free shared buffers\n"); - xprintf("Mem:%17llu%12llu%12llu%12llu%12llu\n", - convert(info.totalram, iscale, oscale), - convert(info.totalram-info.freeram, iscale, oscale), - convert(info.freeram, iscale, oscale), - convert(info.sharedram, iscale, oscale), - convert(info.bufferram, iscale, oscale)); - - xprintf("-/+ buffers/cache:%15llu%12llu\n", - convert(info.totalram - info.freeram - info.bufferram, iscale, oscale), - convert(info.freeram + info.bufferram, iscale, oscale)); - - xprintf("Swap:%16llu%12llu%12llu\n", - convert(info.totalswap, iscale, oscale), - convert(info.totalswap - info.freeswap, iscale, oscale), - convert(info.freeswap, iscale, oscale)); + struct sysinfo info; + unsigned int iscale = 1; + unsigned int oscale = 0; + + sysinfo(&info); + if (info.mem_unit) iscale = info.mem_unit; + if (toys.optflags & FLAG_b) oscale = 0; + if (toys.optflags & FLAG_k) oscale = 10; + if (toys.optflags & FLAG_m) oscale = 20; + if (toys.optflags & FLAG_g) oscale = 30; + + xprintf("\t\ttotal used free shared buffers\n"); + xprintf("Mem:%17llu%12llu%12llu%12llu%12llu\n", + convert(info.totalram, iscale, oscale), + convert(info.totalram-info.freeram, iscale, oscale), + convert(info.freeram, iscale, oscale), + convert(info.sharedram, iscale, oscale), + convert(info.bufferram, iscale, oscale)); + + xprintf("-/+ buffers/cache:%15llu%12llu\n", + convert(info.totalram - info.freeram - info.bufferram, iscale, oscale), + convert(info.freeram + info.bufferram, iscale, oscale)); + + xprintf("Swap:%16llu%12llu%12llu\n", + convert(info.totalswap, iscale, oscale), + convert(info.totalswap - info.freeswap, iscale, oscale), + convert(info.freeswap, iscale, oscale)); } diff --git a/toys/other/hello.c b/toys/other/hello.c index 2b469591..aa256155 100644 --- a/toys/other/hello.c +++ b/toys/other/hello.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * hello.c - A hello world program. (Template for new commands.) +/* hello.c - A hello world program. (Template for new commands.) * * Copyright 2012 Rob Landley <rob@landley.net> * @@ -10,15 +8,15 @@ USE_HELLO(NEWTOY(hello, "e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN)) config HELLO - bool "hello" - default n - help - usage: hello [-a] [-b string] [-c number] [-d list] [-e count] [...] + bool "hello" + default n + help + usage: hello [-a] [-b string] [-c number] [-d list] [-e count] [...] - A hello world program. You don't need this. + A hello world program. You don't need this. - Mostly used as an example/skeleton file for adding new commands, - occasionally nice to test kernel booting via "init=/bin/hello". + Mostly used as an example/skeleton file for adding new commands, + occasionally nice to test kernel booting via "init=/bin/hello". */ #define FOR_hello @@ -27,26 +25,26 @@ config HELLO // Hello doesn't use these globals, they're here for example/skeleton purposes. GLOBALS( - char *b_string; - long c_number; - struct arg_list *d_list; - long e_count; + char *b_string; + long c_number; + struct arg_list *d_list; + long e_count; - int more_globals; + int more_globals; ) void hello_main(void) { - printf("Hello world\n"); - - if (toys.optflags & FLAG_a) printf("Saw a\n"); - if (toys.optflags & FLAG_b) printf("b=%s\n", TT.b_string); - if (toys.optflags & FLAG_c) printf("c=%ld\n", TT.c_number); - while (TT.d_list) { - printf("d=%s\n", TT.d_list->arg); - TT.d_list = TT.d_list->next; - } - if (TT.e_count) printf("e was seen %ld times", TT.e_count); - - while (*toys.optargs) printf("optarg=%s\n", *(toys.optargs++)); + printf("Hello world\n"); + + if (toys.optflags & FLAG_a) printf("Saw a\n"); + if (toys.optflags & FLAG_b) printf("b=%s\n", TT.b_string); + if (toys.optflags & FLAG_c) printf("c=%ld\n", TT.c_number); + while (TT.d_list) { + printf("d=%s\n", TT.d_list->arg); + TT.d_list = TT.d_list->next; + } + if (TT.e_count) printf("e was seen %ld times", TT.e_count); + + while (*toys.optargs) printf("optarg=%s\n", *(toys.optargs++)); } diff --git a/toys/other/help.c b/toys/other/help.c index 2c175552..68bc3aab 100644 --- a/toys/other/help.c +++ b/toys/other/help.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * help.c - Show help for toybox commands +/* help.c - Show help for toybox commands * * Copyright 2007 Rob Landley <rob@landley.net> * @@ -9,15 +7,15 @@ USE_HELP(NEWTOY(help, "<1", TOYFLAG_BIN)) config HELP - bool "help" - default y - help - usage: help [command] + bool "help" + default y + help + usage: help [command] - Show usage information for toybox commands. - Run "toybox" with no arguments for a list of available commands. + Show usage information for toybox commands. + Run "toybox" with no arguments for a list of available commands. */ - + #include "toys.h" #include "generated/help.h" @@ -32,17 +30,17 @@ static char *help_data = void help_main(void) { - struct toy_list *t = toy_find(*toys.optargs); - int i = t-toy_list; - char *s = help_data; - - if (!t) error_exit("Unknown command '%s'", *toys.optargs); - for (;;) { - while (i--) s += strlen(s) + 1; - if (*s != 255) break; - i = toy_find(++s)-toy_list; - s = help_data; - } - - fprintf(toys.exithelp ? stderr : stdout, "%s", s); + struct toy_list *t = toy_find(*toys.optargs); + int i = t-toy_list; + char *s = help_data; + + if (!t) error_exit("Unknown command '%s'", *toys.optargs); + for (;;) { + while (i--) s += strlen(s) + 1; + if (*s != 255) break; + i = toy_find(++s)-toy_list; + s = help_data; + } + + fprintf(toys.exithelp ? stderr : stdout, "%s", s); } diff --git a/toys/other/insmod.c b/toys/other/insmod.c index 3eae538a..8aa959a9 100644 --- a/toys/other/insmod.c +++ b/toys/other/insmod.c @@ -1,18 +1,16 @@ -/* vi: set sw=4 ts=4: - * - * insmod.c - Load a module into the Linux kernel. +/* insmod.c - Load a module into the Linux kernel. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_INSMOD(NEWTOY(insmod, "<1", TOYFLAG_BIN|TOYFLAG_NEEDROOT)) config INSMOD - bool "insmod" - default y - help - usage: insmod MODULE [MODULE_OPTIONS] + bool "insmod" + default y + help + usage: insmod MODULE [MODULE_OPTIONS] - Load the module named MODULE passing options if given. + Load the module named MODULE passing options if given. */ #include "toys.h" @@ -22,24 +20,23 @@ config INSMOD void insmod_main(void) { - char * buf = NULL; - int len, res, i; - int fd = xopen(toys.optargs[0], O_RDONLY); - - len = fdlength(fd); - buf = xmalloc(len); - xreadall(fd, buf, len); - - i = 1; - while(toys.optargs[i] && - strlen(toybuf) + strlen(toys.optargs[i]) + 2 < sizeof(toybuf)) { - strcat(toybuf, toys.optargs[i++]); - strcat(toybuf, " "); - } - - res = init_module(buf, len, toybuf); - if (CFG_TOYBOX_FREE && buf != toybuf) free(buf); - - if (res) - perror_exit("failed to load %s", toys.optargs[0]); + char * buf = NULL; + int len, res, i; + int fd = xopen(toys.optargs[0], O_RDONLY); + + len = fdlength(fd); + buf = xmalloc(len); + xreadall(fd, buf, len); + + i = 1; + while(toys.optargs[i] && + strlen(toybuf) + strlen(toys.optargs[i]) + 2 < sizeof(toybuf)) { + strcat(toybuf, toys.optargs[i++]); + strcat(toybuf, " "); + } + + res = init_module(buf, len, toybuf); + if (CFG_TOYBOX_FREE && buf != toybuf) free(buf); + + if (res) perror_exit("failed to load %s", toys.optargs[0]); } diff --git a/toys/other/login.c b/toys/other/login.c index a9e7562c..72d7063e 100644 --- a/toys/other/login.c +++ b/toys/other/login.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * login.c - Start a session on the system. +/* login.c - Start a session on the system. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> * @@ -10,15 +8,15 @@ USE_LOGIN(NEWTOY(login, ">1fph:", TOYFLAG_BIN)) config LOGIN - bool "login" - default y - help - usage: login [-p] [-h host] [[-f] username] - - Establish a new session with the system. - -p Preserve environment - -h The name of the remote host for this login - -f Do not perform authentication + bool "login" + default y + help + usage: login [-p] [-h host] [[-f] username] + + Establish a new session with the system. + -p Preserve environment + -h The name of the remote host for this login + -f Do not perform authentication */ #define FOR_login @@ -30,215 +28,199 @@ config LOGIN #define HOSTNAME_SIZE 32 GLOBALS( - char *hostname; + char *hostname; ) static void login_timeout_handler(int sig __attribute__((unused))) { - printf("\nLogin timed out after %d seconds.\n", LOGIN_TIMEOUT); - exit(0); + printf("\nLogin timed out after %d seconds.\n", LOGIN_TIMEOUT); + exit(0); } static char *forbid[] = { - "BASH_ENV", - "ENV", - "HOME", - "IFS", - "LD_LIBRARY_PATH", - "LD_PRELOAD", - "LD_TRACE_LOADED_OBJECTS", - "LD_BIND_NOW", - "LD_AOUT_LIBRARY_PATH", - "LD_AOUT_PRELOAD", - "LD_NOWARN", - "LD_KEEPDIR", - "SHELL", - NULL + "BASH_ENV", "ENV", "HOME", "IFS", "LD_LIBRARY_PATH", "LD_PRELOAD", + "LD_TRACE_LOADED_OBJECTS", "LD_BIND_NOW", "LD_AOUT_LIBRARY_PATH", + "LD_AOUT_PRELOAD", "LD_NOWARN", "LD_KEEPDIR", "SHELL", NULL }; int verify_password(char * pwd) { - char *pass; + char *pass; - if (read_password(toybuf, sizeof(toybuf), "Password: ")) return 1; - if (!pwd) return 1; - if (pwd[0] == '!' || pwd[0] == '*') return 1; + if (read_password(toybuf, sizeof(toybuf), "Password: ")) return 1; + if (!pwd) return 1; + if (pwd[0] == '!' || pwd[0] == '*') return 1; - pass = crypt(toybuf, pwd); - if (pass && !strcmp(pass, pwd)) return 0; + pass = crypt(toybuf, pwd); + if (pass && !strcmp(pass, pwd)) return 0; - return 1; + return 1; } void read_user(char * buff, int size) { - char hostname[HOSTNAME_SIZE+1]; - int i = 0; - hostname[HOSTNAME_SIZE] = 0; - if(!gethostname(hostname, HOSTNAME_SIZE)) fputs(hostname, stdout); - - fputs(" login: ", stdout); - fflush(stdout); - - do { - buff[0] = getchar(); - if (buff[0] == EOF) - exit(EXIT_FAILURE); - } while (isblank(buff[0])); - - if (buff[0] != '\n') - if(!fgets(&buff[1], HOSTNAME_SIZE-1, stdin)) - _exit(1); - - while(i<HOSTNAME_SIZE-1 && isgraph(buff[i])) i++; - buff[i] = 0; + char hostname[HOSTNAME_SIZE+1]; + int i = 0; + hostname[HOSTNAME_SIZE] = 0; + if(!gethostname(hostname, HOSTNAME_SIZE)) fputs(hostname, stdout); + + fputs(" login: ", stdout); + fflush(stdout); + + do { + buff[0] = getchar(); + if (buff[0] == EOF) exit(EXIT_FAILURE); + } while (isblank(buff[0])); + + if (buff[0] != '\n') if(!fgets(&buff[1], HOSTNAME_SIZE-1, stdin)) _exit(1); + + while(i<HOSTNAME_SIZE-1 && isgraph(buff[i])) i++; + buff[i] = 0; } void handle_nologin(void) { - int fd = open("/etc/nologin", O_RDONLY); - int size; - if (fd == -1) return; - - size = readall(fd, toybuf,sizeof(toybuf)-1); - toybuf[size] = 0; - if (!size) puts("System closed for routine maintenance\n"); - else puts(toybuf); - - close(fd); - fflush(stdout); - exit(EXIT_FAILURE); + int fd = open("/etc/nologin", O_RDONLY); + int size; + if (fd == -1) return; + + size = readall(fd, toybuf,sizeof(toybuf)-1); + toybuf[size] = 0; + if (!size) puts("System closed for routine maintenance\n"); + else puts(toybuf); + + close(fd); + fflush(stdout); + exit(EXIT_FAILURE); } void handle_motd(void) { - int fd = open("/etc/motd", O_RDONLY); - int size; - if (fd == -1) return; + int fd = open("/etc/motd", O_RDONLY); + int size; + if (fd == -1) return; - size = readall(fd, toybuf,sizeof(toybuf)-1); - toybuf[size] = 0; - puts(toybuf); + size = readall(fd, toybuf,sizeof(toybuf)-1); + toybuf[size] = 0; + puts(toybuf); - close(fd); - fflush(stdout); + close(fd); + fflush(stdout); } int change_identity(const struct passwd *pwd) { - if (initgroups(pwd->pw_name,pwd->pw_gid)) return 1; - if (setgid(pwd->pw_uid)) return 1; - if (setuid(pwd->pw_uid)) return 1; + if (initgroups(pwd->pw_name,pwd->pw_gid)) return 1; + if (setgid(pwd->pw_uid)) return 1; + if (setuid(pwd->pw_uid)) return 1; - return 0; + return 0; } void spawn_shell(const char *shell) { - const char * exec_name = strrchr(shell,'/'); - if (exec_name) exec_name++; - else exec_name = shell; + const char * exec_name = strrchr(shell,'/'); + if (exec_name) exec_name++; + else exec_name = shell; - snprintf(toybuf,sizeof(toybuf)-1, "-%s", shell); - execl(shell, toybuf, NULL); - error_exit("Failed to spawn shell"); + snprintf(toybuf,sizeof(toybuf)-1, "-%s", shell); + execl(shell, toybuf, NULL); + error_exit("Failed to spawn shell"); } void setup_environment(const struct passwd *pwd, int clear_env) { - if (chdir(pwd->pw_dir)) printf("bad home dir: %s\n", pwd->pw_dir); - - if (clear_env) { - const char * term = getenv("TERM"); - clearenv(); - if (term) setenv("TERM", term, 1); - } - - setenv("USER", pwd->pw_name, 1); - setenv("LOGNAME", pwd->pw_name, 1); - setenv("HOME", pwd->pw_dir, 1); - setenv("SHELL", pwd->pw_shell, 1); + if (chdir(pwd->pw_dir)) printf("bad home dir: %s\n", pwd->pw_dir); + + if (clear_env) { + const char * term = getenv("TERM"); + clearenv(); + if (term) setenv("TERM", term, 1); + } + + setenv("USER", pwd->pw_name, 1); + setenv("LOGNAME", pwd->pw_name, 1); + setenv("HOME", pwd->pw_dir, 1); + setenv("SHELL", pwd->pw_shell, 1); } void login_main(void) { - int f_flag = toys.optflags & FLAG_f; - int h_flag = toys.optflags & FLAG_h; - char username[USER_NAME_MAX_SIZE+1], *pass = NULL, **ss; - struct passwd * pwd = NULL; - struct spwd * spwd = NULL; - int auth_fail_cnt = 0; + int f_flag = toys.optflags & FLAG_f; + int h_flag = toys.optflags & FLAG_h; + char username[USER_NAME_MAX_SIZE+1], *pass = NULL, **ss; + struct passwd * pwd = NULL; + struct spwd * spwd = NULL; + int auth_fail_cnt = 0; - if (f_flag && toys.optc != 1) - error_exit("-f requires username"); + if (f_flag && toys.optc != 1) error_exit("-f requires username"); - if (geteuid()) error_exit("not root"); + if (geteuid()) error_exit("not root"); - if (!isatty(0) || !isatty(1) || !isatty(2)) error_exit("no tty"); + if (!isatty(0) || !isatty(1) || !isatty(2)) error_exit("no tty"); - openlog("login", LOG_PID | LOG_CONS, LOG_AUTH); - signal(SIGALRM, login_timeout_handler); - alarm(LOGIN_TIMEOUT); + openlog("login", LOG_PID | LOG_CONS, LOG_AUTH); + signal(SIGALRM, login_timeout_handler); + alarm(LOGIN_TIMEOUT); - for (ss = forbid; *ss; ss++) unsetenv(*ss); + for (ss = forbid; *ss; ss++) unsetenv(*ss); - while (1) { - tcflush(0, TCIFLUSH); + while (1) { + tcflush(0, TCIFLUSH); - username[USER_NAME_MAX_SIZE] = 0; - if (toys.optargs[0]) - strncpy(username, toys.optargs[0], USER_NAME_MAX_SIZE); - else { - read_user(username, USER_NAME_MAX_SIZE+1); - if (username[0] == 0) continue; - } + username[USER_NAME_MAX_SIZE] = 0; + if (toys.optargs[0]) strncpy(username, toys.optargs[0], USER_NAME_MAX_SIZE); + else { + read_user(username, USER_NAME_MAX_SIZE+1); + if (username[0] == 0) continue; + } - pwd = getpwnam(username); - if (!pwd) goto query_pass; // Non-existing user + pwd = getpwnam(username); + if (!pwd) goto query_pass; // Non-existing user - if (pwd->pw_passwd[0] == '!' || pwd->pw_passwd[0] == '*') - goto query_pass; // Locked account + if (pwd->pw_passwd[0] == '!' || pwd->pw_passwd[0] == '*') + goto query_pass; // Locked account - if (f_flag) break; // Pre-authenticated + if (f_flag) break; // Pre-authenticated - if (!pwd->pw_passwd[0]) break; // Password-less account + if (!pwd->pw_passwd[0]) break; // Password-less account - pass = pwd->pw_passwd; - if (pwd->pw_passwd[0] == 'x') { - spwd = getspnam (username); - if (spwd) pass = spwd->sp_pwdp; - } + pass = pwd->pw_passwd; + if (pwd->pw_passwd[0] == 'x') { + spwd = getspnam (username); + if (spwd) pass = spwd->sp_pwdp; + } query_pass: - if (!verify_password(pass)) break; + if (!verify_password(pass)) break; - f_flag = 0; - syslog(LOG_WARNING, "invalid password for '%s' on %s %s %s", username, - ttyname(0), h_flag?"from":"", h_flag?TT.hostname:""); + f_flag = 0; + syslog(LOG_WARNING, "invalid password for '%s' on %s %s %s", username, + ttyname(0), h_flag?"from":"", h_flag?TT.hostname:""); - sleep(LOGIN_FAIL_TIMEOUT); - puts("Login incorrect"); + sleep(LOGIN_FAIL_TIMEOUT); + puts("Login incorrect"); - if (++auth_fail_cnt == 3) - error_exit("Maximum number of tries exceeded (%d)\n", auth_fail_cnt); + if (++auth_fail_cnt == 3) + error_exit("Maximum number of tries exceeded (%d)\n", auth_fail_cnt); - username[0] = 0; - pwd = NULL; - spwd = NULL; - } + username[0] = 0; + pwd = NULL; + spwd = NULL; + } - alarm(0); + alarm(0); - if (pwd->pw_uid) handle_nologin(); + if (pwd->pw_uid) handle_nologin(); - if (change_identity(pwd)) error_exit("Failed to change identity"); + if (change_identity(pwd)) error_exit("Failed to change identity"); - setup_environment(pwd, !(toys.optflags & FLAG_p)); + setup_environment(pwd, !(toys.optflags & FLAG_p)); - handle_motd(); + handle_motd(); - syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name, - ttyname(0), h_flag?"from":"", h_flag?TT.hostname:""); + syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name, + ttyname(0), h_flag?"from":"", h_flag?TT.hostname:""); - spawn_shell(pwd->pw_shell); + spawn_shell(pwd->pw_shell); } diff --git a/toys/other/lsmod.c b/toys/other/lsmod.c index 821243b8..b8f5d820 100644 --- a/toys/other/lsmod.c +++ b/toys/other/lsmod.c @@ -1,40 +1,36 @@ -/* vi: set sw=4 ts=4: - * - * lsmod.c - Show the status of modules in the kernel +/* lsmod.c - Show the status of modules in the kernel * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_LSMOD(NEWTOY(lsmod, NULL, TOYFLAG_BIN)) config LSMOD - bool "lsmod" - default y - help - usage: lsmod + bool "lsmod" + default y + help + usage: lsmod - Display the currently loaded modules, their sizes and their - dependencies. + Display the currently loaded modules, their sizes and their dependencies. */ #include "toys.h" void lsmod_main(void) { - char *modfile = "/proc/modules"; - FILE * file = xfopen(modfile, "r"); - - xprintf("%-23s Size Used by\n", "Module"); - - while (fgets(toybuf, sizeof(toybuf), file)) { - char *name = strtok(toybuf, " "), *size = strtok(NULL, " "), - *refcnt = strtok(NULL, " "), *users = strtok(NULL, " "); - - if(users) { - int len = strlen(users)-1; - if (users[len] == ',' || users[len] == '-') - users[len] = 0; - xprintf("%-19s %8s %s %s\n", name, size, refcnt, users); - } else perror_exit("bad %s", modfile); - } - fclose(file); + char *modfile = "/proc/modules"; + FILE * file = xfopen(modfile, "r"); + + xprintf("%-23s Size Used by\n", "Module"); + + while (fgets(toybuf, sizeof(toybuf), file)) { + char *name = strtok(toybuf, " "), *size = strtok(NULL, " "), + *refcnt = strtok(NULL, " "), *users = strtok(NULL, " "); + + if(users) { + int len = strlen(users)-1; + if (users[len] == ',' || users[len] == '-') users[len] = 0; + xprintf("%-19s %8s %s %s\n", name, size, refcnt, users); + } else perror_exit("bad %s", modfile); + } + fclose(file); } diff --git a/toys/other/mdev.c b/toys/other/mdev.c index 6d030d14..b89ac2ca 100644 --- a/toys/other/mdev.c +++ b/toys/other/mdev.c @@ -1,6 +1,4 @@ -/* vi:set ts=4: - * - * mdev.c - Populate /dev directory and handle hotplug events +/* mdev.c - Populate /dev directory and handle hotplug events * * Copyright 2005, 2008 Rob Landley <rob@landley.net> * Copyright 2005 Frank Sorenson <frank@tuxrocks.com> @@ -8,27 +6,27 @@ USE_MDEV(NEWTOY(mdev, "s", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_UMASK)) config MDEV - bool "mdev" - default n - help - usage: mdev [-s] + bool "mdev" + default n + help + usage: mdev [-s] - Create devices in /dev using information from /sys. + Create devices in /dev using information from /sys. - -s Scan all entries in /sys to populate /dev. + -s Scan all entries in /sys to populate /dev. config MDEV_CONF - bool "Configuration file for mdev" - default y - depends on MDEV - help - The mdev config file (/etc/mdev.conf) contains lines that look like: - hd[a-z][0-9]* 0:3 660 - - Each line must contain three whitespace separated fields. The first - field is a regular expression matching one or more device names, and - the second and third fields are uid:gid and file permissions for - matching devies. + bool "Configuration file for mdev" + default y + depends on MDEV + help + The mdev config file (/etc/mdev.conf) contains lines that look like: + hd[a-z][0-9]* 0:3 660 + + Each line must contain three whitespace separated fields. The first + field is a regular expression matching one or more device names, and + the second and third fields are uid:gid and file permissions for + matching devies. */ #include "toys.h" @@ -39,173 +37,173 @@ config MDEV_CONF // mknod in /dev based on a path like "/sys/block/hda/hda1" static void make_device(char *path) { - char *device_name, *s, *temp; - int major, minor, type, len, fd; - int mode = 0660; - uid_t uid = 0; - gid_t gid = 0; - - // Try to read major/minor string - - temp = strrchr(path, '/'); - fd = open(path, O_RDONLY); - *temp=0; - temp = toybuf; - len = read(fd, temp, 64); - close(fd); - if (len<1) return; - temp[len] = 0; - - // Determine device name, type, major and minor - - device_name = strrchr(path, '/') + 1; - type = path[5]=='c' ? S_IFCHR : S_IFBLK; - major = minor = 0; - sscanf(temp, "%u:%u", &major, &minor); - - // If we have a config file, look up permissions for this device - - if (CFG_MDEV_CONF) { - char *conf, *pos, *end; - - // mmap the config file - if (-1!=(fd = open("/etc/mdev.conf", O_RDONLY))) { - len = fdlength(fd); - conf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); - if (conf) { - int line = 0; - - // Loop through lines in mmaped file - for (pos = conf; pos-conf<len;) { - int field; - char *end2; - - line++; - // find end of this line - for(end = pos; end-conf<len && *end!='\n'; end++); - - // Three fields: regex, uid:gid, mode - for (field = 3; field; field--) { - // Skip whitespace - while (pos<end && isspace(*pos)) pos++; - if (pos==end || *pos=='#') break; - for (end2 = pos; - end2<end && !isspace(*end2) && *end2!='#'; end2++); - switch(field) { - // Regex to match this device - case 3: - { - char *regex = strndup(pos, end2-pos); - regex_t match; - regmatch_t off; - int result; - - // Is this it? - xregcomp(&match, regex, REG_EXTENDED); - result=regexec(&match, device_name, 1, &off, 0); - regfree(&match); - free(regex); - - // If not this device, skip rest of line - if (result || off.rm_so - || off.rm_eo!=strlen(device_name)) - goto end_line; - - break; - } - // uid:gid - case 2: - { - char *s2; - - // Find : - for(s = pos; s<end2 && *s!=':'; s++); - if (s==end2) goto end_line; - - // Parse UID - uid = strtoul(pos,&s2,10); - if (s!=s2) { - struct passwd *pass; - char *str = strndup(pos, s-pos); - pass = getpwnam(str); - free(str); - if (!pass) goto end_line; - uid = pass->pw_uid; - } - s++; - // parse GID - gid = strtoul(s,&s2,10); - if (end2!=s2) { - struct group *grp; - char *str = strndup(s, end2-s); - grp = getgrnam(str); - free(str); - if (!grp) goto end_line; - gid = grp->gr_gid; - } - break; - } - // mode - case 1: - { - mode = strtoul(pos, &pos, 8); - if (pos!=end2) goto end_line; - goto found_device; - } - } - pos=end2; - } + char *device_name, *s, *temp; + int major, minor, type, len, fd; + int mode = 0660; + uid_t uid = 0; + gid_t gid = 0; + + // Try to read major/minor string + + temp = strrchr(path, '/'); + fd = open(path, O_RDONLY); + *temp=0; + temp = toybuf; + len = read(fd, temp, 64); + close(fd); + if (len<1) return; + temp[len] = 0; + + // Determine device name, type, major and minor + + device_name = strrchr(path, '/') + 1; + type = path[5]=='c' ? S_IFCHR : S_IFBLK; + major = minor = 0; + sscanf(temp, "%u:%u", &major, &minor); + + // If we have a config file, look up permissions for this device + + if (CFG_MDEV_CONF) { + char *conf, *pos, *end; + + // mmap the config file + if (-1!=(fd = open("/etc/mdev.conf", O_RDONLY))) { + len = fdlength(fd); + conf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); + if (conf) { + int line = 0; + + // Loop through lines in mmaped file + for (pos = conf; pos-conf<len;) { + int field; + char *end2; + + line++; + // find end of this line + for(end = pos; end-conf<len && *end!='\n'; end++); + + // Three fields: regex, uid:gid, mode + for (field = 3; field; field--) { + // Skip whitespace + while (pos<end && isspace(*pos)) pos++; + if (pos==end || *pos=='#') break; + for (end2 = pos; + end2<end && !isspace(*end2) && *end2!='#'; end2++); + switch(field) { + // Regex to match this device + case 3: + { + char *regex = strndup(pos, end2-pos); + regex_t match; + regmatch_t off; + int result; + + // Is this it? + xregcomp(&match, regex, REG_EXTENDED); + result=regexec(&match, device_name, 1, &off, 0); + regfree(&match); + free(regex); + + // If not this device, skip rest of line + if (result || off.rm_so + || off.rm_eo!=strlen(device_name)) + goto end_line; + + break; + } + // uid:gid + case 2: + { + char *s2; + + // Find : + for(s = pos; s<end2 && *s!=':'; s++); + if (s==end2) goto end_line; + + // Parse UID + uid = strtoul(pos,&s2,10); + if (s!=s2) { + struct passwd *pass; + char *str = strndup(pos, s-pos); + pass = getpwnam(str); + free(str); + if (!pass) goto end_line; + uid = pass->pw_uid; + } + s++; + // parse GID + gid = strtoul(s,&s2,10); + if (end2!=s2) { + struct group *grp; + char *str = strndup(s, end2-s); + grp = getgrnam(str); + free(str); + if (!grp) goto end_line; + gid = grp->gr_gid; + } + break; + } + // mode + case 1: + { + mode = strtoul(pos, &pos, 8); + if (pos!=end2) goto end_line; + goto found_device; + } + } + pos=end2; + } end_line: - // Did everything parse happily? - if (field && field!=3) error_exit("Bad line %d", line); + // Did everything parse happily? + if (field && field!=3) error_exit("Bad line %d", line); - // Next line - pos = ++end; - } + // Next line + pos = ++end; + } found_device: - munmap(conf, len); - } - close(fd); - } - } + munmap(conf, len); + } + close(fd); + } + } - sprintf(temp, "/dev/%s", device_name); - if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST) - perror_exit("mknod %s failed", temp); + sprintf(temp, "/dev/%s", device_name); + if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST) + perror_exit("mknod %s failed", temp); - if (CFG_MDEV_CONF) mode=chown(temp, uid, gid); + if (CFG_MDEV_CONF) mode=chown(temp, uid, gid); } static int callback(struct dirtree *node) { - // Entries in /sys/class/block aren't char devices, so skip 'em. (We'll - // get block devices out of /sys/block.) - if(!strcmp(node->name, "block")) return 0; - - // Does this directory have a "dev" entry in it? - // This is path based because the hotplug callbacks are - if (S_ISDIR(node->st.st_mode) || S_ISLNK(node->st.st_mode)) { - int len=4; - char *dev = dirtree_path(node, &len); - strcpy(dev+len, "/dev"); - if (!access(dev, R_OK)) make_device(dev); - free(dev); - } - - // Circa 2.6.25 the entries more than 2 deep are all either redundant - // (mouse#, event#) or unnamed (every usb_* entry is called "device"). - - return (node->parent && node->parent->parent) ? 0 : DIRTREE_RECURSE; + // Entries in /sys/class/block aren't char devices, so skip 'em. (We'll + // get block devices out of /sys/block.) + if(!strcmp(node->name, "block")) return 0; + + // Does this directory have a "dev" entry in it? + // This is path based because the hotplug callbacks are + if (S_ISDIR(node->st.st_mode) || S_ISLNK(node->st.st_mode)) { + int len=4; + char *dev = dirtree_path(node, &len); + strcpy(dev+len, "/dev"); + if (!access(dev, R_OK)) make_device(dev); + free(dev); + } + + // Circa 2.6.25 the entries more than 2 deep are all either redundant + // (mouse#, event#) or unnamed (every usb_* entry is called "device"). + + return (node->parent && node->parent->parent) ? 0 : DIRTREE_RECURSE; } void mdev_main(void) { - // Handle -s + // Handle -s - if (toys.optflags) { - dirtree_read("/sys/class", callback); - dirtree_read("/sys/block", callback); - } + if (toys.optflags) { + dirtree_read("/sys/class", callback); + dirtree_read("/sys/block", callback); + } - // hotplug support goes here + // hotplug support goes here } diff --git a/toys/other/mke2fs.c b/toys/other/mke2fs.c index 5745d519..1a83e4f6 100644 --- a/toys/other/mke2fs.c +++ b/toys/other/mke2fs.c @@ -1,6 +1,4 @@ -/* vi: set ts=4: - * - * mke2fs.c - Create an ext2 filesystem image. +/* mke2fs.c - Create an ext2 filesystem image. * * Copyright 2006, 2007 Rob Landley <rob@landley.net> @@ -8,155 +6,155 @@ USE_MKE2FS(NEWTOY(mke2fs, "<1>2g:Fnqm#N#i#b#", TOYFLAG_SBIN)) config MKE2FS - bool "mke2fs (unfinished and broken by dirtree changes)" - default n - help - usage: mke2fs [-Fnq] [-b ###] [-N|i ###] [-m ###] device + bool "mke2fs (unfinished and broken by dirtree changes)" + default n + help + usage: mke2fs [-Fnq] [-b ###] [-N|i ###] [-m ###] device - Create an ext2 filesystem on a block device or filesystem image. + Create an ext2 filesystem on a block device or filesystem image. - -F Force to run on a mounted device - -n Don't write to device - -q Quiet (no output) - -b size Block size (1024, 2048, or 4096) - -N inodes Allocate this many inodes - -i bytes Allocate one inode for every XXX bytes of device - -m percent Reserve this percent of filesystem space for root user + -F Force to run on a mounted device + -n Don't write to device + -q Quiet (no output) + -b size Block size (1024, 2048, or 4096) + -N inodes Allocate this many inodes + -i bytes Allocate one inode for every XXX bytes of device + -m percent Reserve this percent of filesystem space for root user config MKE2FS_JOURNAL - bool "Journaling support (ext3)" - default n - depends on MKE2FS - help - usage: [-j] [-J size=###,device=XXX] + bool "Journaling support (ext3)" + default n + depends on MKE2FS + help + usage: [-j] [-J size=###,device=XXX] - -j Create journal (ext3) - -J Journal options - size: Number of blocks (1024-102400) - device: Specify an external journal + -j Create journal (ext3) + -J Journal options + size: Number of blocks (1024-102400) + device: Specify an external journal config MKE2FS_GEN - bool "Generate (gene2fs)" - default n - depends on MKE2FS - help - usage: gene2fs [options] device filename + bool "Generate (gene2fs)" + default n + depends on MKE2FS + help + usage: gene2fs [options] device filename - The [options] are the same as mke2fs. + The [options] are the same as mke2fs. config MKE2FS_LABEL - bool "Label support" - default n - depends on MKE2FS - help - usage: mke2fs [-L label] [-M path] [-o string] + bool "Label support" + default n + depends on MKE2FS + help + usage: mke2fs [-L label] [-M path] [-o string] - -L Volume label - -M Path to mount point - -o Created by + -L Volume label + -M Path to mount point + -o Created by config MKE2FS_EXTENDED - bool "Extended options" - default n - depends on MKE2FS - help - usage: mke2fs [-E stride=###] [-O option[,option]] - - -E stride= Set RAID stripe size (in blocks) - -O [opts] Specify fewer ext2 option flags (for old kernels) - All of these are on by default (as appropriate) - none Clear default options (all but journaling) - dir_index Use htree indexes for large directories - filetype Store file type info in directory entry - has_journal Set by -j - journal_dev Set by -J device=XXX - sparse_super Don't allocate huge numbers of redundant superblocks + bool "Extended options" + default n + depends on MKE2FS + help + usage: mke2fs [-E stride=###] [-O option[,option]] + + -E stride= Set RAID stripe size (in blocks) + -O [opts] Specify fewer ext2 option flags (for old kernels) + All of these are on by default (as appropriate) + none Clear default options (all but journaling) + dir_index Use htree indexes for large directories + filetype Store file type info in directory entry + has_journal Set by -j + journal_dev Set by -J device=XXX + sparse_super Don't allocate huge numbers of redundant superblocks */ #define FOR_mke2fs #include "toys.h" GLOBALS( - // Command line arguments. - long blocksize; - long bytes_per_inode; - long inodes; // Total inodes in filesystem. - long reserved_percent; // Integer precent of space to reserve for root. - char *gendir; // Where to read dirtree from. - - // Internal data. - struct dirtree *dt; // Tree of files to copy into the new filesystem. - unsigned treeblocks; // Blocks used by dt - unsigned treeinodes; // Inodes used by dt - - unsigned blocks; // Total blocks in the filesystem. - unsigned freeblocks; // Free blocks in the filesystem. - unsigned inodespg; // Inodes per group - unsigned groups; // Total number of block groups. - unsigned blockbits; // Bits per block. (Also blocks per group.) - - // For gene2fs - unsigned nextblock; // Next data block to allocate - unsigned nextgroup; // Next group we'll be allocating from - int fsfd; // File descriptor of filesystem (to output to). - - struct ext2_superblock sb; + // Command line arguments. + long blocksize; + long bytes_per_inode; + long inodes; // Total inodes in filesystem. + long reserved_percent; // Integer precent of space to reserve for root. + char *gendir; // Where to read dirtree from. + + // Internal data. + struct dirtree *dt; // Tree of files to copy into the new filesystem. + unsigned treeblocks; // Blocks used by dt + unsigned treeinodes; // Inodes used by dt + + unsigned blocks; // Total blocks in the filesystem. + unsigned freeblocks; // Free blocks in the filesystem. + unsigned inodespg; // Inodes per group + unsigned groups; // Total number of block groups. + unsigned blockbits; // Bits per block. (Also blocks per group.) + + // For gene2fs + unsigned nextblock; // Next data block to allocate + unsigned nextgroup; // Next group we'll be allocating from + int fsfd; // File descriptor of filesystem (to output to). + + struct ext2_superblock sb; ) #define INODES_RESERVED 10 static uint32_t div_round_up(uint32_t a, uint32_t b) { - uint32_t c = a/b; + uint32_t c = a/b; - if (a%b) c++; - return c; + if (a%b) c++; + return c; } // Calculate data blocks plus index blocks needed to hold a file. static uint32_t file_blocks_used(uint64_t size, uint32_t *blocklist) { - uint32_t dblocks = (uint32_t)((size+(TT.blocksize-1))/TT.blocksize); - uint32_t idx=TT.blocksize/4, iblocks=0, diblocks=0, tiblocks=0; + uint32_t dblocks = (uint32_t)((size+(TT.blocksize-1))/TT.blocksize); + uint32_t idx=TT.blocksize/4, iblocks=0, diblocks=0, tiblocks=0; - // Fill out index blocks in inode. + // Fill out index blocks in inode. - if (blocklist) { - int i; + if (blocklist) { + int i; - // Direct index blocks - for (i=0; i<13 && i<dblocks; i++) blocklist[i] = i; - // Singly indirect index blocks - if (dblocks > 13+idx) blocklist[13] = 13+idx; - // Doubly indirect index blocks - idx = 13 + idx + (idx*idx); - if (dblocks > idx) blocklist[14] = idx; + // Direct index blocks + for (i=0; i<13 && i<dblocks; i++) blocklist[i] = i; + // Singly indirect index blocks + if (dblocks > 13+idx) blocklist[13] = 13+idx; + // Doubly indirect index blocks + idx = 13 + idx + (idx*idx); + if (dblocks > idx) blocklist[14] = idx; - return 0; - } + return 0; + } - // Account for direct, singly, doubly, and triply indirect index blocks + // Account for direct, singly, doubly, and triply indirect index blocks - if (dblocks > 12) { - iblocks = ((dblocks-13)/idx)+1; - if (iblocks > 1) { - diblocks = ((iblocks-2)/idx)+1; - if (diblocks > 1) - tiblocks = ((diblocks-2)/idx)+1; - } - } + if (dblocks > 12) { + iblocks = ((dblocks-13)/idx)+1; + if (iblocks > 1) { + diblocks = ((iblocks-2)/idx)+1; + if (diblocks > 1) + tiblocks = ((diblocks-2)/idx)+1; + } + } - return dblocks + iblocks + diblocks + tiblocks; + return dblocks + iblocks + diblocks + tiblocks; } // Use the parent pointer to iterate through the tree non-recursively. static struct dirtree *treenext(struct dirtree *this) { - while (this && !this->next) this = this->parent; - if (this) this = this->next; + while (this && !this->next) this = this->parent; + if (this) this = this->next; - return this; + return this; } // Recursively calculate the number of blocks used by each inode in the tree. @@ -165,27 +163,27 @@ static struct dirtree *treenext(struct dirtree *this) static long check_treesize(struct dirtree *that, off_t *size) { - long blocks; - - while (that) { - *size += sizeof(struct ext2_dentry) + strlen(that->name); - - if (that->child) - that->st.st_blocks = check_treesize(that->child, &that->st.st_size); - else if (S_ISREG(that->st.st_mode)) { - that->st.st_blocks = file_blocks_used(that->st.st_size, 0); - TT.treeblocks += that->st.st_blocks; - } - that = that->next; - } - TT.treeblocks += blocks = file_blocks_used(*size, 0); - TT.treeinodes++; - - return blocks; + long blocks; + + while (that) { + *size += sizeof(struct ext2_dentry) + strlen(that->name); + + if (that->child) + that->st.st_blocks = check_treesize(that->child, &that->st.st_size); + else if (S_ISREG(that->st.st_mode)) { + that->st.st_blocks = file_blocks_used(that->st.st_size, 0); + TT.treeblocks += that->st.st_blocks; + } + that = that->next; + } + TT.treeblocks += blocks = file_blocks_used(*size, 0); + TT.treeinodes++; + + return blocks; } // Calculate inode numbers and link counts. -// +// // To do this right I need to copy the tree and sort it, but here's a really // ugly n^2 way of dealing with the problem that doesn't scale well to large // numbers of files (> 100,000) but can be done in very little code. @@ -193,32 +191,32 @@ static long check_treesize(struct dirtree *that, off_t *size) static void check_treelinks(struct dirtree *tree) { - struct dirtree *current=tree, *that; - long inode = INODES_RESERVED; - - while (current) { - ++inode; - // Since we can't hardlink to directories, we know their link count. - if (S_ISDIR(current->st.st_mode)) current->st.st_nlink = 2; - else { - dev_t new = current->st.st_dev; - - if (!new) continue; - - // Look for other copies of current node - current->st.st_nlink = 0; - for (that = tree; that; that = treenext(that)) { - if (current->st.st_ino == that->st.st_ino && - current->st.st_dev == that->st.st_dev) - { - current->st.st_nlink++; - current->st.st_ino = inode; - } - } - } - current->st.st_ino = inode; - current = treenext(current); - } + struct dirtree *current=tree, *that; + long inode = INODES_RESERVED; + + while (current) { + ++inode; + // Since we can't hardlink to directories, we know their link count. + if (S_ISDIR(current->st.st_mode)) current->st.st_nlink = 2; + else { + dev_t new = current->st.st_dev; + + if (!new) continue; + + // Look for other copies of current node + current->st.st_nlink = 0; + for (that = tree; that; that = treenext(that)) { + if (current->st.st_ino == that->st.st_ino && + current->st.st_dev == that->st.st_dev) + { + current->st.st_nlink++; + current->st.st_ino = inode; + } + } + } + current->st.st_ino = inode; + current = treenext(current); + } } // According to http://www.opengroup.org/onlinepubs/9629399/apdxa.htm @@ -231,202 +229,202 @@ static void check_treelinks(struct dirtree *tree) static void create_uuid(char *uuid) { - // Read 128 random bits - int fd = xopen("/dev/urandom", O_RDONLY); - xreadall(fd, uuid, 16); - close(fd); - - // Claim to be a DCE format UUID. - uuid[6] = (uuid[6] & 0x0F) | 0x40; - uuid[8] = (uuid[8] & 0x3F) | 0x80; - - // rfc2518 section 6.4.1 suggests if we're not using a macaddr, we should - // set bit 1 of the node ID, which is the mac multicast bit. This means we - // should never collide with anybody actually using a macaddr. - uuid[11] = uuid[11] | 128; + // Read 128 random bits + int fd = xopen("/dev/urandom", O_RDONLY); + xreadall(fd, uuid, 16); + close(fd); + + // Claim to be a DCE format UUID. + uuid[6] = (uuid[6] & 0x0F) | 0x40; + uuid[8] = (uuid[8] & 0x3F) | 0x80; + + // rfc2518 section 6.4.1 suggests if we're not using a macaddr, we should + // set bit 1 of the node ID, which is the mac multicast bit. This means we + // should never collide with anybody actually using a macaddr. + uuid[11] = uuid[11] | 128; } // Calculate inodes per group from total inodes. static uint32_t get_inodespg(uint32_t inodes) { - uint32_t temp; + uint32_t temp; - // Round up to fill complete inode blocks. - temp = (inodes + TT.groups - 1) / TT.groups; - inodes = TT.blocksize/sizeof(struct ext2_inode); - return ((temp + inodes - 1)/inodes)*inodes; + // Round up to fill complete inode blocks. + temp = (inodes + TT.groups - 1) / TT.groups; + inodes = TT.blocksize/sizeof(struct ext2_inode); + return ((temp + inodes - 1)/inodes)*inodes; } // Fill out superblock and TT structures. static void init_superblock(struct ext2_superblock *sb) { - uint32_t temp; + uint32_t temp; - // Set log_block_size and log_frag_size. + // Set log_block_size and log_frag_size. - for (temp = 0; temp < 4; temp++) if (TT.blocksize == 1024<<temp) break; - if (temp==4) error_exit("bad blocksize"); - sb->log_block_size = sb->log_frag_size = SWAP_LE32(temp); + for (temp = 0; temp < 4; temp++) if (TT.blocksize == 1024<<temp) break; + if (temp==4) error_exit("bad blocksize"); + sb->log_block_size = sb->log_frag_size = SWAP_LE32(temp); - // Fill out blocks_count, r_blocks_count, first_data_block + // Fill out blocks_count, r_blocks_count, first_data_block - sb->blocks_count = SWAP_LE32(TT.blocks); - sb->free_blocks_count = SWAP_LE32(TT.freeblocks); - temp = (TT.blocks * (uint64_t)TT.reserved_percent) / 100; - sb->r_blocks_count = SWAP_LE32(temp); + sb->blocks_count = SWAP_LE32(TT.blocks); + sb->free_blocks_count = SWAP_LE32(TT.freeblocks); + temp = (TT.blocks * (uint64_t)TT.reserved_percent) / 100; + sb->r_blocks_count = SWAP_LE32(temp); - sb->first_data_block = SWAP_LE32(TT.blocksize == 1024 ? 1 : 0); + sb->first_data_block = SWAP_LE32(TT.blocksize == 1024 ? 1 : 0); - // Set blocks_per_group and frags_per_group, which is the size of an - // allocation bitmap that fits in one block (I.E. how many bits per block)? + // Set blocks_per_group and frags_per_group, which is the size of an + // allocation bitmap that fits in one block (I.E. how many bits per block)? - sb->blocks_per_group = sb->frags_per_group = SWAP_LE32(TT.blockbits); + sb->blocks_per_group = sb->frags_per_group = SWAP_LE32(TT.blockbits); - // Set inodes_per_group and total inodes_count - sb->inodes_per_group = SWAP_LE32(TT.inodespg); - sb->inodes_count = SWAP_LE32(TT.inodespg * TT.groups); + // Set inodes_per_group and total inodes_count + sb->inodes_per_group = SWAP_LE32(TT.inodespg); + sb->inodes_count = SWAP_LE32(TT.inodespg * TT.groups); - // Determine free inodes. - temp = TT.inodespg*TT.groups - INODES_RESERVED; - if (temp < TT.treeinodes) error_exit("Not enough inodes.\n"); - sb->free_inodes_count = SWAP_LE32(temp - TT.treeinodes); + // Determine free inodes. + temp = TT.inodespg*TT.groups - INODES_RESERVED; + if (temp < TT.treeinodes) error_exit("Not enough inodes.\n"); + sb->free_inodes_count = SWAP_LE32(temp - TT.treeinodes); - // Fill out the rest of the superblock. - sb->max_mnt_count=0xFFFF; - sb->wtime = sb->lastcheck = sb->mkfs_time = SWAP_LE32(time(NULL)); - sb->magic = SWAP_LE32(0xEF53); - sb->state = sb->errors = SWAP_LE16(1); + // Fill out the rest of the superblock. + sb->max_mnt_count=0xFFFF; + sb->wtime = sb->lastcheck = sb->mkfs_time = SWAP_LE32(time(NULL)); + sb->magic = SWAP_LE32(0xEF53); + sb->state = sb->errors = SWAP_LE16(1); - sb->rev_level = SWAP_LE32(1); - sb->first_ino = SWAP_LE32(INODES_RESERVED+1); - sb->inode_size = SWAP_LE16(sizeof(struct ext2_inode)); - sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE); - sb->feature_ro_compat = SWAP_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER); + sb->rev_level = SWAP_LE32(1); + sb->first_ino = SWAP_LE32(INODES_RESERVED+1); + sb->inode_size = SWAP_LE16(sizeof(struct ext2_inode)); + sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE); + sb->feature_ro_compat = SWAP_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER); - create_uuid(sb->uuid); - - // TODO If we're called as mke3fs or mkfs.ext3, do a journal. + create_uuid(sb->uuid); - //if (strchr(toys.which->name,'3')) - // sb->feature_compat |= SWAP_LE32(EXT3_FEATURE_COMPAT_HAS_JOURNAL); + // TODO If we're called as mke3fs or mkfs.ext3, do a journal. + + //if (strchr(toys.which->name,'3')) + // sb->feature_compat |= SWAP_LE32(EXT3_FEATURE_COMPAT_HAS_JOURNAL); } // Does this group contain a superblock backup (and group descriptor table)? static int is_sb_group(uint32_t group) { - int i; - - // Superblock backups are on groups 0, 1, and powers of 3, 5, and 7. - if(!group || group==1) return 1; - for (i=3; i<9; i+=2) { - int j = i; - while (j<group) j*=i; - if (j==group) return 1; - } - return 0; + int i; + + // Superblock backups are on groups 0, 1, and powers of 3, 5, and 7. + if(!group || group==1) return 1; + for (i=3; i<9; i+=2) { + int j = i; + while (j<group) j*=i; + if (j==group) return 1; + } + return 0; } - + // Number of blocks used in group by optional superblock/group list backup. static int group_superblock_overhead(uint32_t group) { - int used; + int used; - if (!is_sb_group(group)) return 0; + if (!is_sb_group(group)) return 0; - // How many blocks does the group descriptor table take up? - used = TT.groups * sizeof(struct ext2_group); - used += TT.blocksize - 1; - used /= TT.blocksize; - // Plus the superblock itself. - used++; - // And a corner case. - if (!group && TT.blocksize == 1024) used++; + // How many blocks does the group descriptor table take up? + used = TT.groups * sizeof(struct ext2_group); + used += TT.blocksize - 1; + used /= TT.blocksize; + // Plus the superblock itself. + used++; + // And a corner case. + if (!group && TT.blocksize == 1024) used++; - return used; + return used; } // Number of blocks used in group to store superblock/group/inode list static int group_overhead(uint32_t group) { - // Return superblock backup overhead (if any), plus block/inode - // allocation bitmaps, plus inode tables. - return group_superblock_overhead(group) + 2 + get_inodespg(TT.inodespg) - / (TT.blocksize/sizeof(struct ext2_inode)); + // Return superblock backup overhead (if any), plus block/inode + // allocation bitmaps, plus inode tables. + return group_superblock_overhead(group) + 2 + get_inodespg(TT.inodespg) + / (TT.blocksize/sizeof(struct ext2_inode)); } // In bitmap "array" set "len" bits starting at position "start" (from 0). static void bits_set(char *array, int start, int len) { - while(len) { - if ((start&7) || len<8) { - array[start/8]|=(1<<(start&7)); - start++; - len--; - } else { - array[start/8]=255; - start+=8; - len-=8; - } - } + while(len) { + if ((start&7) || len<8) { + array[start/8]|=(1<<(start&7)); + start++; + len--; + } else { + array[start/8]=255; + start+=8; + len-=8; + } + } } // Seek past len bytes (to maintain sparse file), or write zeroes if output // not seekable static void put_zeroes(int len) { - if(-1 == lseek(TT.fsfd, len, SEEK_SET)) { - memset(toybuf, 0, sizeof(toybuf)); - while (len) { - int out = len > sizeof(toybuf) ? sizeof(toybuf) : len; - xwrite(TT.fsfd, toybuf, out); - len -= out; - } - } + if(-1 == lseek(TT.fsfd, len, SEEK_SET)) { + memset(toybuf, 0, sizeof(toybuf)); + while (len) { + int out = len > sizeof(toybuf) ? sizeof(toybuf) : len; + xwrite(TT.fsfd, toybuf, out); + len -= out; + } + } } // Fill out an inode structure from struct stat info in dirtree. static void fill_inode(struct ext2_inode *in, struct dirtree *that) { - uint32_t fbu[15]; - int temp; - - file_blocks_used(that->st.st_size, fbu); - - // If that inode needs data blocks allocated to it. - if (that->st.st_size) { - int i, group = TT.nextblock/TT.blockbits; - - // TODO: teach this about indirect blocks. - for (i=0; i<15; i++) { - // If we just jumped into a new group, skip group overhead blocks. - while (group >= TT.nextgroup) - TT.nextblock += group_overhead(TT.nextgroup++); - } - } - // TODO : S_ISREG/DIR/CHR/BLK/FIFO/LNK/SOCK(m) - in->mode = SWAP_LE32(that->st.st_mode); - - in->uid = SWAP_LE16(that->st.st_uid & 0xFFFF); - in->uid_high = SWAP_LE16(that->st.st_uid >> 16); - in->gid = SWAP_LE16(that->st.st_gid & 0xFFFF); - in->gid_high = SWAP_LE16(that->st.st_gid >> 16); - in->size = SWAP_LE32(that->st.st_size & 0xFFFFFFFF); - - // Contortions to make the compiler not generate a warning for x>>32 - // when x is 32 bits. The optimizer should clean this up. - if (sizeof(that->st.st_size) > 4) temp = 32; - else temp = 0; - if (temp) in->dir_acl = SWAP_LE32(that->st.st_size >> temp); - - in->atime = SWAP_LE32(that->st.st_atime); - in->ctime = SWAP_LE32(that->st.st_ctime); - in->mtime = SWAP_LE32(that->st.st_mtime); - - in->links_count = SWAP_LE16(that->st.st_nlink); - in->blocks = SWAP_LE32(that->st.st_blocks); - // in->faddr + uint32_t fbu[15]; + int temp; + + file_blocks_used(that->st.st_size, fbu); + + // If that inode needs data blocks allocated to it. + if (that->st.st_size) { + int i, group = TT.nextblock/TT.blockbits; + + // TODO: teach this about indirect blocks. + for (i=0; i<15; i++) { + // If we just jumped into a new group, skip group overhead blocks. + while (group >= TT.nextgroup) + TT.nextblock += group_overhead(TT.nextgroup++); + } + } + // TODO : S_ISREG/DIR/CHR/BLK/FIFO/LNK/SOCK(m) + in->mode = SWAP_LE32(that->st.st_mode); + + in->uid = SWAP_LE16(that->st.st_uid & 0xFFFF); + in->uid_high = SWAP_LE16(that->st.st_uid >> 16); + in->gid = SWAP_LE16(that->st.st_gid & 0xFFFF); + in->gid_high = SWAP_LE16(that->st.st_gid >> 16); + in->size = SWAP_LE32(that->st.st_size & 0xFFFFFFFF); + + // Contortions to make the compiler not generate a warning for x>>32 + // when x is 32 bits. The optimizer should clean this up. + if (sizeof(that->st.st_size) > 4) temp = 32; + else temp = 0; + if (temp) in->dir_acl = SWAP_LE32(that->st.st_size >> temp); + + in->atime = SWAP_LE32(that->st.st_atime); + in->ctime = SWAP_LE32(that->st.st_ctime); + in->mtime = SWAP_LE32(that->st.st_mtime); + + in->links_count = SWAP_LE16(that->st.st_nlink); + in->blocks = SWAP_LE32(that->st.st_blocks); + // in->faddr } // Works like an archiver. @@ -435,224 +433,224 @@ static void fill_inode(struct ext2_inode *in, struct dirtree *that) void mke2fs_main(void) { - int i, temp; - off_t length; - uint32_t usedblocks, usedinodes, dtiblk, dtbblk; - struct dirtree *dti, *dtb; - - // Handle command line arguments. - - if (toys.optargs[1]) { - sscanf(toys.optargs[1], "%u", &TT.blocks); - temp = O_RDWR|O_CREAT; - } else temp = O_RDWR; - if (!TT.reserved_percent) TT.reserved_percent = 5; - - // TODO: Check if filesystem is mounted here - - // For mke?fs, open file. For gene?fs, create file. - TT.fsfd = xcreate(*toys.optargs, temp, 0777); - - // Determine appropriate block size and block count from file length. - // (If no length, default to 4k. They can override it on the cmdline.) - - length = fdlength(TT.fsfd); - if (!TT.blocksize) TT.blocksize = (length && length < 1<<29) ? 1024 : 4096; - TT.blockbits = 8*TT.blocksize; - if (!TT.blocks) TT.blocks = length/TT.blocksize; - - // Collect gene2fs list or lost+found, calculate requirements. - - if (TT.gendir) { - strncpy(toybuf, TT.gendir, sizeof(toybuf)); - dti = dirtree_read(toybuf, NULL, NULL); - } else { - dti = xzalloc(sizeof(struct dirtree)+11); - strcpy(dti->name, "lost+found"); - dti->st.st_mode = S_IFDIR|0755; - dti->st.st_ctime = dti->st.st_mtime = time(NULL); - } - - // Add root directory inode. This is iterated through for when finding - // blocks, but not when finding inodes. The tree's parent pointers don't - // point back into this. - - dtb = xzalloc(sizeof(struct dirtree)+1); - dtb->st.st_mode = S_IFDIR|0755; - dtb->st.st_ctime = dtb->st.st_mtime = time(NULL); - dtb->child = dti; - - // Figure out how much space is used by preset files - length = check_treesize(dtb, &(dtb->st.st_size)); - check_treelinks(dtb); - - // Figure out how many total inodes we need. - - if (!TT.inodes) { - if (!TT.bytes_per_inode) TT.bytes_per_inode = 8192; - TT.inodes = (TT.blocks * (uint64_t)TT.blocksize) / TT.bytes_per_inode; - } - - // If we're generating a filesystem and have no idea how many blocks it - // needs, start with a minimal guess, find the overhead of that many - // groups, and loop until this is enough groups to store this many blocks. - if (!TT.blocks) TT.groups = (TT.treeblocks/TT.blockbits)+1; - else TT.groups = div_round_up(TT.blocks, TT.blockbits); - - for (;;) { - temp = TT.treeblocks; - - for (i = 0; i<TT.groups; i++) temp += group_overhead(i); - - if (TT.blocks) { - if (TT.blocks < temp) error_exit("Not enough space.\n"); - break; - } - if (temp <= TT.groups * TT.blockbits) { - TT.blocks = temp; - break; - } - TT.groups++; - } - TT.freeblocks = TT.blocks - temp; - - // Now we know all the TT data, initialize superblock structure. - - init_superblock(&TT.sb); - - // Start writing. Skip the first 1k to avoid the boot sector (if any). - put_zeroes(1024); - - // Loop through block groups, write out each one. - dtiblk = dtbblk = usedblocks = usedinodes = 0; - for (i=0; i<TT.groups; i++) { - struct ext2_inode *in = (struct ext2_inode *)toybuf; - uint32_t start, itable, used, end; - int j, slot; - - // Where does this group end? - end = TT.blockbits; - if ((i+1)*TT.blockbits > TT.blocks) end = TT.blocks & (TT.blockbits-1); - - // Blocks used by inode table - itable = (TT.inodespg*sizeof(struct ext2_inode))/TT.blocksize; - - // If a superblock goes here, write it out. - start = group_superblock_overhead(i); - if (start) { - struct ext2_group *bg = (struct ext2_group *)toybuf; - int treeblocks = TT.treeblocks, treeinodes = TT.treeinodes; - - TT.sb.block_group_nr = SWAP_LE16(i); - - // Write superblock and pad it up to block size - xwrite(TT.fsfd, &TT.sb, sizeof(struct ext2_superblock)); - temp = TT.blocksize - sizeof(struct ext2_superblock); - if (!i && TT.blocksize > 1024) temp -= 1024; - memset(toybuf, 0, TT.blocksize); - xwrite(TT.fsfd, toybuf, temp); - - // Loop through groups to write group descriptor table. - for(j=0; j<TT.groups; j++) { - - // Figure out what sector this group starts in. - used = group_superblock_overhead(j); - - // Find next array slot in this block (flush block if full). - slot = j % (TT.blocksize/sizeof(struct ext2_group)); - if (!slot) { - if (j) xwrite(TT.fsfd, bg, TT.blocksize); - memset(bg, 0, TT.blocksize); - } - - // How many free inodes in this group? - temp = TT.inodespg; - if (!i) temp -= INODES_RESERVED; - if (temp > treeinodes) { - treeinodes -= temp; - temp = 0; - } else { - temp -= treeinodes; - treeinodes = 0; - } - bg[slot].free_inodes_count = SWAP_LE16(temp); - - // How many free blocks in this group? - temp = TT.inodespg/(TT.blocksize/sizeof(struct ext2_inode)) + 2; - temp = end-used-temp; - if (temp > treeblocks) { - treeblocks -= temp; - temp = 0; - } else { - temp -= treeblocks; - treeblocks = 0; - } - bg[slot].free_blocks_count = SWAP_LE32(temp); - - // Fill out rest of group structure - used += j*TT.blockbits; - bg[slot].block_bitmap = SWAP_LE32(used++); - bg[slot].inode_bitmap = SWAP_LE32(used++); - bg[slot].inode_table = SWAP_LE32(used); - bg[slot].used_dirs_count = 0; // (TODO) - } - xwrite(TT.fsfd, bg, TT.blocksize); - } - - // Now write out stuff that every block group has. - - // Write block usage bitmap - - start += 2 + itable; - memset(toybuf, 0, TT.blocksize); - bits_set(toybuf, 0, start); - bits_set(toybuf, end, TT.blockbits-end); - temp = TT.treeblocks - usedblocks; - if (temp) { - if (end-start > temp) temp = end-start; - bits_set(toybuf, start, temp); - } - xwrite(TT.fsfd, toybuf, TT.blocksize); - - // Write inode bitmap - memset(toybuf, 0, TT.blocksize); - j = 0; - if (!i) bits_set(toybuf, 0, j = INODES_RESERVED); - bits_set(toybuf, TT.inodespg, slot = TT.blockbits-TT.inodespg); - temp = TT.treeinodes - usedinodes; - if (temp) { - if (slot-j > temp) temp = slot-j; - bits_set(toybuf, j, temp); - } - xwrite(TT.fsfd, toybuf, TT.blocksize); - - // Write inode table for this group (TODO) - for (j = 0; j<TT.inodespg; j++) { - slot = j % (TT.blocksize/sizeof(struct ext2_inode)); - if (!slot) { - if (j) xwrite(TT.fsfd, in, TT.blocksize); - memset(in, 0, TT.blocksize); - } - if (!i && j<INODES_RESERVED) { - // Write root inode - if (j == 2) fill_inode(in+slot, dtb); - } else if (dti) { - fill_inode(in+slot, dti); - dti = treenext(dti); - } - } - xwrite(TT.fsfd, in, TT.blocksize); - - while (dtb) { - // TODO write index data block - // TODO write root directory data block - // TODO write directory data block - // TODO write file data block - put_zeroes(TT.blocksize); - start++; - if (start == end) break; - } - // Write data blocks (TODO) - put_zeroes((end-start) * TT.blocksize); - } + int i, temp; + off_t length; + uint32_t usedblocks, usedinodes, dtiblk, dtbblk; + struct dirtree *dti, *dtb; + + // Handle command line arguments. + + if (toys.optargs[1]) { + sscanf(toys.optargs[1], "%u", &TT.blocks); + temp = O_RDWR|O_CREAT; + } else temp = O_RDWR; + if (!TT.reserved_percent) TT.reserved_percent = 5; + + // TODO: Check if filesystem is mounted here + + // For mke?fs, open file. For gene?fs, create file. + TT.fsfd = xcreate(*toys.optargs, temp, 0777); + + // Determine appropriate block size and block count from file length. + // (If no length, default to 4k. They can override it on the cmdline.) + + length = fdlength(TT.fsfd); + if (!TT.blocksize) TT.blocksize = (length && length < 1<<29) ? 1024 : 4096; + TT.blockbits = 8*TT.blocksize; + if (!TT.blocks) TT.blocks = length/TT.blocksize; + + // Collect gene2fs list or lost+found, calculate requirements. + + if (TT.gendir) { + strncpy(toybuf, TT.gendir, sizeof(toybuf)); + dti = dirtree_read(toybuf, NULL, NULL); + } else { + dti = xzalloc(sizeof(struct dirtree)+11); + strcpy(dti->name, "lost+found"); + dti->st.st_mode = S_IFDIR|0755; + dti->st.st_ctime = dti->st.st_mtime = time(NULL); + } + + // Add root directory inode. This is iterated through for when finding + // blocks, but not when finding inodes. The tree's parent pointers don't + // point back into this. + + dtb = xzalloc(sizeof(struct dirtree)+1); + dtb->st.st_mode = S_IFDIR|0755; + dtb->st.st_ctime = dtb->st.st_mtime = time(NULL); + dtb->child = dti; + + // Figure out how much space is used by preset files + length = check_treesize(dtb, &(dtb->st.st_size)); + check_treelinks(dtb); + + // Figure out how many total inodes we need. + + if (!TT.inodes) { + if (!TT.bytes_per_inode) TT.bytes_per_inode = 8192; + TT.inodes = (TT.blocks * (uint64_t)TT.blocksize) / TT.bytes_per_inode; + } + + // If we're generating a filesystem and have no idea how many blocks it + // needs, start with a minimal guess, find the overhead of that many + // groups, and loop until this is enough groups to store this many blocks. + if (!TT.blocks) TT.groups = (TT.treeblocks/TT.blockbits)+1; + else TT.groups = div_round_up(TT.blocks, TT.blockbits); + + for (;;) { + temp = TT.treeblocks; + + for (i = 0; i<TT.groups; i++) temp += group_overhead(i); + + if (TT.blocks) { + if (TT.blocks < temp) error_exit("Not enough space.\n"); + break; + } + if (temp <= TT.groups * TT.blockbits) { + TT.blocks = temp; + break; + } + TT.groups++; + } + TT.freeblocks = TT.blocks - temp; + + // Now we know all the TT data, initialize superblock structure. + + init_superblock(&TT.sb); + + // Start writing. Skip the first 1k to avoid the boot sector (if any). + put_zeroes(1024); + + // Loop through block groups, write out each one. + dtiblk = dtbblk = usedblocks = usedinodes = 0; + for (i=0; i<TT.groups; i++) { + struct ext2_inode *in = (struct ext2_inode *)toybuf; + uint32_t start, itable, used, end; + int j, slot; + + // Where does this group end? + end = TT.blockbits; + if ((i+1)*TT.blockbits > TT.blocks) end = TT.blocks & (TT.blockbits-1); + + // Blocks used by inode table + itable = (TT.inodespg*sizeof(struct ext2_inode))/TT.blocksize; + + // If a superblock goes here, write it out. + start = group_superblock_overhead(i); + if (start) { + struct ext2_group *bg = (struct ext2_group *)toybuf; + int treeblocks = TT.treeblocks, treeinodes = TT.treeinodes; + + TT.sb.block_group_nr = SWAP_LE16(i); + + // Write superblock and pad it up to block size + xwrite(TT.fsfd, &TT.sb, sizeof(struct ext2_superblock)); + temp = TT.blocksize - sizeof(struct ext2_superblock); + if (!i && TT.blocksize > 1024) temp -= 1024; + memset(toybuf, 0, TT.blocksize); + xwrite(TT.fsfd, toybuf, temp); + + // Loop through groups to write group descriptor table. + for(j=0; j<TT.groups; j++) { + + // Figure out what sector this group starts in. + used = group_superblock_overhead(j); + + // Find next array slot in this block (flush block if full). + slot = j % (TT.blocksize/sizeof(struct ext2_group)); + if (!slot) { + if (j) xwrite(TT.fsfd, bg, TT.blocksize); + memset(bg, 0, TT.blocksize); + } + + // How many free inodes in this group? + temp = TT.inodespg; + if (!i) temp -= INODES_RESERVED; + if (temp > treeinodes) { + treeinodes -= temp; + temp = 0; + } else { + temp -= treeinodes; + treeinodes = 0; + } + bg[slot].free_inodes_count = SWAP_LE16(temp); + + // How many free blocks in this group? + temp = TT.inodespg/(TT.blocksize/sizeof(struct ext2_inode)) + 2; + temp = end-used-temp; + if (temp > treeblocks) { + treeblocks -= temp; + temp = 0; + } else { + temp -= treeblocks; + treeblocks = 0; + } + bg[slot].free_blocks_count = SWAP_LE32(temp); + + // Fill out rest of group structure + used += j*TT.blockbits; + bg[slot].block_bitmap = SWAP_LE32(used++); + bg[slot].inode_bitmap = SWAP_LE32(used++); + bg[slot].inode_table = SWAP_LE32(used); + bg[slot].used_dirs_count = 0; // (TODO) + } + xwrite(TT.fsfd, bg, TT.blocksize); + } + + // Now write out stuff that every block group has. + + // Write block usage bitmap + + start += 2 + itable; + memset(toybuf, 0, TT.blocksize); + bits_set(toybuf, 0, start); + bits_set(toybuf, end, TT.blockbits-end); + temp = TT.treeblocks - usedblocks; + if (temp) { + if (end-start > temp) temp = end-start; + bits_set(toybuf, start, temp); + } + xwrite(TT.fsfd, toybuf, TT.blocksize); + + // Write inode bitmap + memset(toybuf, 0, TT.blocksize); + j = 0; + if (!i) bits_set(toybuf, 0, j = INODES_RESERVED); + bits_set(toybuf, TT.inodespg, slot = TT.blockbits-TT.inodespg); + temp = TT.treeinodes - usedinodes; + if (temp) { + if (slot-j > temp) temp = slot-j; + bits_set(toybuf, j, temp); + } + xwrite(TT.fsfd, toybuf, TT.blocksize); + + // Write inode table for this group (TODO) + for (j = 0; j<TT.inodespg; j++) { + slot = j % (TT.blocksize/sizeof(struct ext2_inode)); + if (!slot) { + if (j) xwrite(TT.fsfd, in, TT.blocksize); + memset(in, 0, TT.blocksize); + } + if (!i && j<INODES_RESERVED) { + // Write root inode + if (j == 2) fill_inode(in+slot, dtb); + } else if (dti) { + fill_inode(in+slot, dti); + dti = treenext(dti); + } + } + xwrite(TT.fsfd, in, TT.blocksize); + + while (dtb) { + // TODO write index data block + // TODO write root directory data block + // TODO write directory data block + // TODO write file data block + put_zeroes(TT.blocksize); + start++; + if (start == end) break; + } + // Write data blocks (TODO) + put_zeroes((end-start) * TT.blocksize); + } } diff --git a/toys/other/mkswap.c b/toys/other/mkswap.c index 1e96c196..ff864244 100644 --- a/toys/other/mkswap.c +++ b/toys/other/mkswap.c @@ -1,40 +1,38 @@ -/* vi: set sw=4 ts=4: - * - * mkswap.c - Format swap device. +/* mkswap.c - Format swap device. * * Copyright 2009 Rob Landley <rob@landley.net> USE_MKSWAP(NEWTOY(mkswap, "<1>1", TOYFLAG_SBIN)) config MKSWAP - bool "mkswap" - default y - help - usage: mkswap DEVICE + bool "mkswap" + default y + help + usage: mkswap DEVICE - Sets up a Linux swap area on a device or file. + Sets up a Linux swap area on a device or file. */ #include "toys.h" void mkswap_main(void) { - int fd = xopen(*toys.optargs, O_RDWR), pagesize = sysconf(_SC_PAGE_SIZE); - off_t len = fdlength(fd); - unsigned int pages = (len/pagesize)-1, *swap = (unsigned int *)toybuf; + int fd = xopen(*toys.optargs, O_RDWR), pagesize = sysconf(_SC_PAGE_SIZE); + off_t len = fdlength(fd); + unsigned int pages = (len/pagesize)-1, *swap = (unsigned int *)toybuf; - // Write header. Note that older kernel versions checked signature - // on disk (not in cache) during swapon, so sync after writing. + // Write header. Note that older kernel versions checked signature + // on disk (not in cache) during swapon, so sync after writing. - swap[0] = 1; - swap[1] = pages; - xlseek(fd, 1024, SEEK_SET); - xwrite(fd, swap, 129*sizeof(unsigned int)); - xlseek(fd, pagesize-10, SEEK_SET); - xwrite(fd, "SWAPSPACE2", 10); - fsync(fd); + swap[0] = 1; + swap[1] = pages; + xlseek(fd, 1024, SEEK_SET); + xwrite(fd, swap, 129*sizeof(unsigned int)); + xlseek(fd, pagesize-10, SEEK_SET); + xwrite(fd, "SWAPSPACE2", 10); + fsync(fd); - if (CFG_TOYBOX_FREE) close(fd); + if (CFG_TOYBOX_FREE) close(fd); - printf("Swapspace size: %luk\n", pages*(unsigned long)(pagesize/1024)); + printf("Swapspace size: %luk\n", pages*(unsigned long)(pagesize/1024)); } diff --git a/toys/other/modinfo.c b/toys/other/modinfo.c index 0c5f177f..36a38382 100644 --- a/toys/other/modinfo.c +++ b/toys/other/modinfo.c @@ -1,101 +1,92 @@ -/* vi: set sw=4 ts=4: - * - * modinfo.c - Display module info +/* modinfo.c - Display module info * * Copyright 2012 Andre Renaud <andre@bluewatersys.com> - * USE_MODINFO(NEWTOY(modinfo, "<1F:0", TOYFLAG_BIN)) config MODINFO - bool "modinfo" - default y - help - usage: modinfo [-0] [-F field] [modulename...] + bool "modinfo" + default y + help + usage: modinfo [-0] [-F field] [modulename...] */ #define FOR_modinfo #include "toys.h" GLOBALS( - char *field; + char *field; ) static const char *modinfo_tags[] = { - "alias", "license", "description", "author", "vermagic", - "srcversion", "intree", "parm", "depends", + "alias", "license", "description", "author", "vermagic", + "srcversion", "intree", "parm", "depends", }; static void output_field(const char *field, const char *value) { - int len; - - if (TT.field && strcmp(TT.field, field) != 0) - return; - - len = strlen(field); - - if (TT.field) - xprintf("%s", value); - else - xprintf("%s:%*s%s", - field, 15 - len, "", value); - if (toys.optflags & FLAG_0) - xwrite(fileno(stdout), "\0", 1); - else - xputs(""); + int len; + + if (TT.field && strcmp(TT.field, field) != 0) return; + + len = strlen(field); + + if (TT.field) xprintf("%s", value); + else xprintf("%s:%*s%s", field, 15 - len, "", value); + if (toys.optflags & FLAG_0) xwrite(fileno(stdout), "\0", 1); + else xputs(""); } static void modinfo_file(struct dirtree *dir) { - int fd, len, i; - char *buf, *pos; - char *full_name; - - full_name = dirtree_path(dir, NULL); - - output_field("filename", full_name); - fd = xopen(full_name, O_RDONLY); - len = fdlength(fd); - buf = xmalloc(len); - xreadall(fd, buf, len); - - for (pos = buf; pos < buf + len + 10; pos++) { - if (*pos) - continue; - - for (i = 0; i < sizeof(modinfo_tags) / sizeof(modinfo_tags[0]); i++) { - const char *str = modinfo_tags[i]; - int len = strlen(str); - if (strncmp(pos + 1, str, len) == 0 && pos[len + 1] == '=') - output_field(str, &pos[len + 2]); - } + int fd, len, i; + char *buf, *pos; + char *full_name; + + full_name = dirtree_path(dir, NULL); + + output_field("filename", full_name); + fd = xopen(full_name, O_RDONLY); + len = fdlength(fd); + buf = xmalloc(len); + xreadall(fd, buf, len); + + for (pos = buf; pos < buf + len + 10; pos++) { + if (*pos) continue; + + for (i = 0; i < sizeof(modinfo_tags) / sizeof(modinfo_tags[0]); i++) { + const char *str = modinfo_tags[i]; + int len = strlen(str); + if (strncmp(pos + 1, str, len) == 0 && pos[len + 1] == '=') + output_field(str, &pos[len + 2]); } + } - free(full_name); - free(buf); - close(fd); + free(full_name); + free(buf); + close(fd); } static int check_module(struct dirtree *new) { - if (S_ISREG(new->st.st_mode)) { - char **s; - for (s = toys.optargs; *s; s++) { - int len = strlen(*s); - if (!strncmp(*s, new->name, len) && !strcmp(new->name+len, ".ko")) - modinfo_file(new); - } + if (S_ISREG(new->st.st_mode)) { + char **s; + for (s = toys.optargs; *s; s++) { + int len = strlen(*s); + if (!strncmp(*s, new->name, len) && !strcmp(new->name+len, ".ko")) + modinfo_file(new); } + } - return dirtree_notdotdot(new); + return dirtree_notdotdot(new); } void modinfo_main(void) { - struct utsname uts; - if (uname(&uts) < 0) perror_exit("bad uname"); - sprintf(toybuf, "/lib/modules/%s", uts.release); - dirtree_read(toybuf, check_module); + struct utsname uts; + + if (uname(&uts) < 0) perror_exit("bad uname"); + sprintf(toybuf, "/lib/modules/%s", uts.release); + dirtree_read(toybuf, check_module); } diff --git a/toys/other/mountpoint.c b/toys/other/mountpoint.c index fe63b725..29b8ae67 100644 --- a/toys/other/mountpoint.c +++ b/toys/other/mountpoint.c @@ -1,20 +1,19 @@ -/* vi: set sw=4 ts=4: - * - * mountpoint.c - Check if a directory is a mountpoint. +/* mountpoint.c - Check if a directory is a mountpoint. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_MOUNTPOINT(NEWTOY(mountpoint, "<1qdx", TOYFLAG_BIN)) config MOUNTPOINT - bool "mountpoint" - default y - help - usage: mountpoint [-q] [-d] directory - mountpoint [-q] [-x] device - -q Be quiet, return zero if directory is a mountpoint - -d Print major/minor device number of the directory - -x Print major/minor device number of the block device + bool "mountpoint" + default y + help + usage: mountpoint [-q] [-d] directory + mountpoint [-q] [-x] device + + -q Be quiet, return zero if directory is a mountpoint + -d Print major/minor device number of the directory + -x Print major/minor device number of the block device */ #define FOR_mountpoint @@ -22,34 +21,34 @@ config MOUNTPOINT void mountpoint_main(void) { - struct stat st1, st2; - int res = 0; - int quiet = toys.optflags & FLAG_q; - toys.exitval = 1; // be pessimistic - strncpy(toybuf, toys.optargs[0], sizeof(toybuf)); - if (((toys.optflags & FLAG_x) && lstat(toybuf, &st1)) || stat(toybuf, &st1)) - perror_exit("%s", toybuf); + struct stat st1, st2; + int res = 0; + int quiet = toys.optflags & FLAG_q; + toys.exitval = 1; // be pessimistic + strncpy(toybuf, toys.optargs[0], sizeof(toybuf)); + if (((toys.optflags & FLAG_x) && lstat(toybuf, &st1)) || stat(toybuf, &st1)) + perror_exit("%s", toybuf); - if (toys.optflags & FLAG_x){ - if (S_ISBLK(st1.st_mode)) { - if (!quiet) printf("%u:%u\n", major(st1.st_rdev), minor(st1.st_rdev)); - toys.exitval = 0; - return; - } - if (!quiet) printf("%s: not a block device\n", toybuf); - return; - } + if (toys.optflags & FLAG_x){ + if (S_ISBLK(st1.st_mode)) { + if (!quiet) printf("%u:%u\n", major(st1.st_rdev), minor(st1.st_rdev)); + toys.exitval = 0; + return; + } + if (!quiet) printf("%s: not a block device\n", toybuf); + return; + } - if(!S_ISDIR(st1.st_mode)){ - if (!quiet) printf("%s: not a directory\n", toybuf); - return; - } - strncat(toybuf, "/..", sizeof(toybuf)); - stat(toybuf, &st2); - res = (st1.st_dev != st2.st_dev) || - (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); - if (!quiet) printf("%s is %sa mountpoint\n", toys.optargs[0], res ? "" : "not "); - if (toys.optflags & FLAG_d) - printf("%u:%u\n", major(st1.st_dev), minor(st1.st_dev)); - toys.exitval = res ? 0 : 1; + if(!S_ISDIR(st1.st_mode)){ + if (!quiet) printf("%s: not a directory\n", toybuf); + return; + } + strncat(toybuf, "/..", sizeof(toybuf)); + stat(toybuf, &st2); + res = (st1.st_dev != st2.st_dev) || + (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); + if (!quiet) printf("%s is %sa mountpoint\n", toys.optargs[0], res ? "" : "not "); + if (toys.optflags & FLAG_d) + printf("%u:%u\n", major(st1.st_dev), minor(st1.st_dev)); + toys.exitval = res ? 0 : 1; } diff --git a/toys/other/netcat.c b/toys/other/netcat.c index 2e90737d..0173e6db 100644 --- a/toys/other/netcat.c +++ b/toys/other/netcat.c @@ -1,46 +1,42 @@ -/* vi: set sw=4 ts=4: - * - * netcat.c - Forward stdin/stdout to a file or network connection. +/* netcat.c - Forward stdin/stdout to a file or network connection. * * Copyright 2007 Rob Landley <rob@landley.net> * * TODO: udp, ipv6, genericize for telnet/microcom/tail-f - USE_NETCAT(OLDTOY(nc, netcat, USE_NETCAT_LISTEN("tl^L^")"w#p#s:q#f:", TOYFLAG_BIN)) USE_NETCAT(NEWTOY(netcat, USE_NETCAT_LISTEN("tl^L^")"w#p#s:q#f:", TOYFLAG_BIN)) config NETCAT - bool "netcat" - default y - help - usage: netcat [-wpq #] [-s addr] {IPADDR PORTNUM|-f FILENAME|-let} [-e COMMAND] - - -w SECONDS timeout for connection - -p local port number - -s local ipv4 address - -q SECONDS quit this many seconds after EOF on stdin. - -f use FILENAME (ala /dev/ttyS0) instead of network + bool "netcat" + default y + help + usage: netcat [-wpq #] [-s addr] {IPADDR PORTNUM|-f FILENAME|-let} [-e COMMAND] - Use "stty 115200 -F /dev/ttyS0 && stty raw -echo -ctlecho" with - netcat -f to connect to a serial port. + -w SECONDS timeout for connection + -p local port number + -s local ipv4 address + -q SECONDS quit this many seconds after EOF on stdin. + -f use FILENAME (ala /dev/ttyS0) instead of network + Use "stty 115200 -F /dev/ttyS0 && stty raw -echo -ctlecho" with + netcat -f to connect to a serial port. config NETCAT_LISTEN - bool "netcat server options (-let)" - default y - depends on NETCAT - help - -t allocate tty (must come before -l or -L) - -l listen for one incoming connection. - -L listen for multiple incoming connections (server mode). - - Any additional command line arguments after -l or -L are executed - to handle each incoming connection. If none, the connection is - forwarded to stdin/stdout. - - For a quick-and-dirty server, try something like: - netcat -s 127.0.0.1 -p 1234 -tL /bin/bash -l + bool "netcat server options (-let)" + default y + depends on NETCAT + help + -t allocate tty (must come before -l or -L) + -l listen for one incoming connection. + -L listen for multiple incoming connections (server mode). + + Any additional command line arguments after -l or -L are executed + to handle each incoming connection. If none, the connection is + forwarded to stdin/stdout. + + For a quick-and-dirty server, try something like: + netcat -s 127.0.0.1 -p 1234 -tL /bin/bash -l */ #define FOR_netcat @@ -48,33 +44,33 @@ config NETCAT_LISTEN #include "toynet.h" GLOBALS( - char *filename; // -f read from filename instead of network - long quit_delay; // -q Exit after EOF from stdin after # seconds. - char *source_address; // -s Bind to a specific source address. - long port; // -p Bind to a specific source port. - long wait; // -w Wait # seconds for a connection. + char *filename; // -f read from filename instead of network + long quit_delay; // -q Exit after EOF from stdin after # seconds. + char *source_address; // -s Bind to a specific source address. + long port; // -p Bind to a specific source port. + long wait; // -w Wait # seconds for a connection. ) static void timeout(int signum) { - if (TT.wait) error_exit("Timeout"); - exit(0); + if (TT.wait) error_exit("Timeout"); + exit(0); } static void set_alarm(int seconds) { - signal(SIGALRM, seconds ? timeout : SIG_DFL); - alarm(seconds); + signal(SIGALRM, seconds ? timeout : SIG_DFL); + alarm(seconds); } // Translate x.x.x.x numeric IPv4 address, or else DNS lookup an IPv4 name. static void lookup_name(char *name, uint32_t *result) { - struct hostent *hostbyname; + struct hostent *hostbyname; - hostbyname = gethostbyname(name); - if (!hostbyname) error_exit("no host '%s'", name); - *result = *(uint32_t *)*hostbyname->h_addr_list; + hostbyname = gethostbyname(name); + if (!hostbyname) error_exit("no host '%s'", name); + *result = *(uint32_t *)*hostbyname->h_addr_list; } // Worry about a fancy lookup later. @@ -85,143 +81,142 @@ static void lookup_port(char *str, uint16_t *port) void netcat_main(void) { - int sockfd=-1, pollcount=2; - struct pollfd pollfds[2]; - - memset(pollfds, 0, 2*sizeof(struct pollfd)); - pollfds[0].events = pollfds[1].events = POLLIN; - set_alarm(TT.wait); - - // The argument parsing logic can't make "<2" conditional on other - // arguments like -f and -l, so we do it by hand here. - if (toys.optflags&FLAG_f) { - if (toys.optc) toys.exithelp++; - } else if (!(toys.optflags&(FLAG_l|FLAG_L)) && toys.optc!=2) toys.exithelp++; - - if (toys.exithelp) error_exit("Argument count wrong"); - - if (TT.filename) pollfds[0].fd = xopen(TT.filename, O_RDWR); - else { - int temp; - struct sockaddr_in address; - - // Setup socket - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (-1 == sockfd) perror_exit("socket"); - fcntl(sockfd, F_SETFD, FD_CLOEXEC); - temp = 1; - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(temp)); - memset(&address, 0, sizeof(address)); - address.sin_family = AF_INET; - if (TT.source_address || TT.port) { - address.sin_port = SWAP_BE16(TT.port); - if (TT.source_address) - lookup_name(TT.source_address, (uint32_t *)&address.sin_addr); - if (bind(sockfd, (struct sockaddr *)&address, sizeof(address))) - perror_exit("bind"); - } - - // Dial out - - if (!CFG_NETCAT_LISTEN || !(toys.optflags&(FLAG_L|FLAG_l))) { - // Figure out where to dial out to. - lookup_name(*toys.optargs, (uint32_t *)&address.sin_addr); - lookup_port(toys.optargs[1], &address.sin_port); - temp = connect(sockfd, (struct sockaddr *)&address, sizeof(address)); - if (temp<0) perror_exit("connect"); - pollfds[0].fd = sockfd; - - // Listen for incoming connections - - } else { - socklen_t len = sizeof(address); - - if (listen(sockfd, 5)) error_exit("listen"); - if (!TT.port) { - getsockname(sockfd, (struct sockaddr *)&address, &len); - printf("%d\n", SWAP_BE16(address.sin_port)); - fflush(stdout); - } - // Do we need to return immediately because -l has arguments? - - if ((toys.optflags&FLAG_l) && toys.optc) { - if (fork()) goto cleanup; - close(0); - close(1); - close(2); - } - - for (;;) { - pid_t child = 0; - - // For -l, call accept from the _new_ thread. - - pollfds[0].fd = accept(sockfd, (struct sockaddr *)&address, - &len); - if (pollfds[0].fd<0) perror_exit("accept"); - - // Do we need a tty? - - if (toys.optflags&FLAG_t) - child = forkpty(&(pollfds[1].fd), NULL, NULL, NULL); - - // Do we need to fork and/or redirect for exec? - - else { - if (toys.optflags&FLAG_L) child = fork(); - if (!child && toys.optc) { - int fd = pollfds[0].fd; - - if (!temp) close(sockfd); - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd>2) close(fd); - } - } - - if (child<0) error_msg("Fork failed\n"); - if (child<1) break; - close(pollfds[0].fd); - } - } - } - - // We have a connection. Disarm timeout. - // (Does not play well with -L, but what _should_ that do?) - set_alarm(0); - - if (CFG_NETCAT_LISTEN && (toys.optflags&(FLAG_L|FLAG_l) && toys.optc)) { - execvp(*toys.optargs, toys.optargs); - error_exit("Exec failed"); - } - - // Poll loop copying stdin->socket and socket->stdout. - for (;;) { - int i; - - if (0>poll(pollfds, pollcount, -1)) perror_exit("poll"); - - for (i=0; i<pollcount; i++) { - if (pollfds[i].revents & POLLIN) { - int len = read(pollfds[i].fd, toybuf, sizeof(toybuf)); - if (len<1) goto dohupnow; - xwrite(i ? pollfds[0].fd : 1, toybuf, len); - } else if (pollfds[i].revents & POLLHUP) { + int sockfd=-1, pollcount=2; + struct pollfd pollfds[2]; + + memset(pollfds, 0, 2*sizeof(struct pollfd)); + pollfds[0].events = pollfds[1].events = POLLIN; + set_alarm(TT.wait); + + // The argument parsing logic can't make "<2" conditional on other + // arguments like -f and -l, so we do it by hand here. + if (toys.optflags&FLAG_f) { + if (toys.optc) toys.exithelp++; + } else if (!(toys.optflags&(FLAG_l|FLAG_L)) && toys.optc!=2) toys.exithelp++; + + if (toys.exithelp) error_exit("Argument count wrong"); + + if (TT.filename) pollfds[0].fd = xopen(TT.filename, O_RDWR); + else { + int temp; + struct sockaddr_in address; + + // Setup socket + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (-1 == sockfd) perror_exit("socket"); + fcntl(sockfd, F_SETFD, FD_CLOEXEC); + temp = 1; + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(temp)); + memset(&address, 0, sizeof(address)); + address.sin_family = AF_INET; + if (TT.source_address || TT.port) { + address.sin_port = SWAP_BE16(TT.port); + if (TT.source_address) + lookup_name(TT.source_address, (uint32_t *)&address.sin_addr); + if (bind(sockfd, (struct sockaddr *)&address, sizeof(address))) + perror_exit("bind"); + } + + // Dial out + + if (!CFG_NETCAT_LISTEN || !(toys.optflags&(FLAG_L|FLAG_l))) { + // Figure out where to dial out to. + lookup_name(*toys.optargs, (uint32_t *)&address.sin_addr); + lookup_port(toys.optargs[1], &address.sin_port); + temp = connect(sockfd, (struct sockaddr *)&address, sizeof(address)); + if (temp<0) perror_exit("connect"); + pollfds[0].fd = sockfd; + + // Listen for incoming connections + + } else { + socklen_t len = sizeof(address); + + if (listen(sockfd, 5)) error_exit("listen"); + if (!TT.port) { + getsockname(sockfd, (struct sockaddr *)&address, &len); + printf("%d\n", SWAP_BE16(address.sin_port)); + fflush(stdout); + } + // Do we need to return immediately because -l has arguments? + + if ((toys.optflags&FLAG_l) && toys.optc) { + if (fork()) goto cleanup; + close(0); + close(1); + close(2); + } + + for (;;) { + pid_t child = 0; + + // For -l, call accept from the _new_ thread. + + pollfds[0].fd = accept(sockfd, (struct sockaddr *)&address, &len); + if (pollfds[0].fd<0) perror_exit("accept"); + + // Do we need a tty? + + if (toys.optflags&FLAG_t) + child = forkpty(&(pollfds[1].fd), NULL, NULL, NULL); + + // Do we need to fork and/or redirect for exec? + + else { + if (toys.optflags&FLAG_L) child = fork(); + if (!child && toys.optc) { + int fd = pollfds[0].fd; + + if (!temp) close(sockfd); + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + if (fd>2) close(fd); + } + } + + if (child<0) error_msg("Fork failed\n"); + if (child<1) break; + close(pollfds[0].fd); + } + } + } + + // We have a connection. Disarm timeout. + // (Does not play well with -L, but what _should_ that do?) + set_alarm(0); + + if (CFG_NETCAT_LISTEN && (toys.optflags&(FLAG_L|FLAG_l) && toys.optc)) { + execvp(*toys.optargs, toys.optargs); + error_exit("Exec failed"); + } + + // Poll loop copying stdin->socket and socket->stdout. + for (;;) { + int i; + + if (0>poll(pollfds, pollcount, -1)) perror_exit("poll"); + + for (i=0; i<pollcount; i++) { + if (pollfds[i].revents & POLLIN) { + int len = read(pollfds[i].fd, toybuf, sizeof(toybuf)); + if (len<1) goto dohupnow; + xwrite(i ? pollfds[0].fd : 1, toybuf, len); + } else if (pollfds[i].revents & POLLHUP) { dohupnow: - // Close half-connection. This is needed for things like - // "echo GET / | netcat landley.net 80" - if (i) { - shutdown(pollfds[0].fd, SHUT_WR); - pollcount--; - set_alarm(TT.quit_delay); - } else goto cleanup; - } - } - } + // Close half-connection. This is needed for things like + // "echo GET / | netcat landley.net 80" + if (i) { + shutdown(pollfds[0].fd, SHUT_WR); + pollcount--; + set_alarm(TT.quit_delay); + } else goto cleanup; + } + } + } cleanup: - if (CFG_TOYBOX_FREE) { - close(pollfds[0].fd); - close(sockfd); - } + if (CFG_TOYBOX_FREE) { + close(pollfds[0].fd); + close(sockfd); + } } diff --git a/toys/other/oneit.c b/toys/other/oneit.c index 8bb482da..5bf4e941 100644 --- a/toys/other/oneit.c +++ b/toys/other/oneit.c @@ -1,27 +1,25 @@ -/* vi: set sw=4 ts=4: - * - * oneit.c - tiny init replacement to launch a single child process. +/* oneit.c - tiny init replacement to launch a single child process. * * Copyright 2005, 2007 by Rob Landley <rob@landley.net>. USE_ONEIT(NEWTOY(oneit, "^<1c:p", TOYFLAG_SBIN)) config ONEIT - bool "oneit" - default y - help - usage: oneit [-p] [-c /dev/tty0] command [...] + bool "oneit" + default y + help + usage: oneit [-p] [-c /dev/tty0] command [...] - A simple init program that runs a single supplied command line with a - controlling tty (so CTRL-C can kill it). + A simple init program that runs a single supplied command line with a + controlling tty (so CTRL-C can kill it). - -p Power off instead of rebooting when command exits. - -c Which console device to use. + -p Power off instead of rebooting when command exits. + -c Which console device to use. - The oneit command runs the supplied command line as a child process - (because PID 1 has signals blocked), attached to /dev/tty0, in its - own session. Then oneit reaps zombies until the child exits, at - which point it reboots (or with -p, powers off) the system. + The oneit command runs the supplied command line as a child process + (because PID 1 has signals blocked), attached to /dev/tty0, in its + own session. Then oneit reaps zombies until the child exits, at + which point it reboots (or with -p, powers off) the system. */ #define FOR_oneit @@ -29,7 +27,7 @@ config ONEIT #include <sys/reboot.h> GLOBALS( - char *console; + char *console; ) // The minimum amount of work necessary to get ctrl-c and such to work is: @@ -53,22 +51,21 @@ void oneit_main(void) if (pid) { // pid 1 just reaps zombies until it gets its child, then halts the system. - while (pid!=wait(&i)); + while (pid != wait(&i)); sync(); - // PID 1 can't call reboot() because it kills the task that calls it, - // which causes the kernel to panic before the actual reboot happens. - if (!vfork()) - reboot((toys.optflags & FLAG_p) ? RB_POWER_OFF : RB_AUTOBOOT); - sleep(5); - _exit(1); + // PID 1 can't call reboot() because it kills the task that calls it, + // which causes the kernel to panic before the actual reboot happens. + if (!vfork()) reboot((toys.optflags & FLAG_p) ? RB_POWER_OFF : RB_AUTOBOOT); + sleep(5); + _exit(1); } // Redirect stdio to /dev/tty0, with new session ID, so ctrl-c works. setsid(); for (i=0; i<3; i++) { close(i); - xopen(TT.console ? TT.console : "/dev/tty0",O_RDWR); + xopen(TT.console ? TT.console : "/dev/tty0", O_RDWR); } // Can't xexec() here, because we vforked so we don't want to error_exit(). diff --git a/toys/other/printenv.c b/toys/other/printenv.c index d5177468..e8bcf29b 100644 --- a/toys/other/printenv.c +++ b/toys/other/printenv.c @@ -1,20 +1,18 @@ -/* vi: set sw=4 ts=4: - * - * printenv.c - Print environment variables. +/* printenv.c - Print environment variables. * * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org> USE_PRINTENV(NEWTOY(printenv, "0(null)", TOYFLAG_USR|TOYFLAG_BIN)) config PRINTENV - bool "printenv" - default y - help - usage: printenv [-0] [env_var...] + bool "printenv" + default y + help + usage: printenv [-0] [env_var...] - Print environment variables. + Print environment variables. - -0 Use \0 as delimiter instead of \n + -0 Use \0 as delimiter instead of \n */ #include "toys.h" @@ -23,24 +21,23 @@ extern char **environ; void printenv_main(void) { - char **env, **var = toys.optargs; - char delim = '\n'; - - if (toys.optflags) delim = 0; - - do { - int catch = 0, len = *var ? strlen(*var) : 0; - - for (env = environ; *env; env++) { - char *out = *env; - if (*var) { - if (!strncmp(out, *var, len) && out[len] == '=') - out += len +1; - else continue; - } - xprintf("%s%c", out, delim); - catch++; - } - if (*var && !catch) toys.exitval = 1; - } while (*var && *(++var)); + char **env, **var = toys.optargs; + char delim = '\n'; + + if (toys.optflags) delim = 0; + + do { + int catch = 0, len = *var ? strlen(*var) : 0; + + for (env = environ; *env; env++) { + char *out = *env; + if (*var) { + if (!strncmp(out, *var, len) && out[len] == '=') out += len +1; + else continue; + } + xprintf("%s%c", out, delim); + catch++; + } + if (*var && !catch) toys.exitval = 1; + } while (*var && *(++var)); } diff --git a/toys/other/readlink.c b/toys/other/readlink.c index c579635c..b7f77f91 100644 --- a/toys/other/readlink.c +++ b/toys/other/readlink.c @@ -1,43 +1,41 @@ -/* vi: set sw=4 ts=4: - * - * readlink.c - Return string representation of a symbolic link. +/* readlink.c - Return string representation of a symbolic link. * * Copyright 2007 Rob Landley <rob@landley.net> USE_READLINK(NEWTOY(readlink, "<1f", TOYFLAG_BIN)) config READLINK - bool "readlink" - default n - help - usage: readlink + bool "readlink" + default n + help + usage: readlink - Show what a symbolic link points to. + Show what a symbolic link points to. config READLINK_F - bool "readlink -f" - default n - depends on READLINK - help - usage: readlink [-f] - - -f Show full cannonical path, with no symlinks in it. Returns - nonzero if nothing could currently exist at this location. + bool "readlink -f" + default n + depends on READLINK + help + usage: readlink [-f] + + -f Show full cannonical path, with no symlinks in it. Returns + nonzero if nothing could currently exist at this location. */ #include "toys.h" void readlink_main(void) { - char *s; + char *s; - // Calculating full cannonical path? + // Calculating full cannonical path? - if (CFG_READLINK_F && toys.optflags) s = xrealpath(*toys.optargs); - else s = xreadlink(*toys.optargs); + if (CFG_READLINK_F && toys.optflags) s = xrealpath(*toys.optargs); + else s = xreadlink(*toys.optargs); - if (s) { - xputs(s); - if (CFG_TOYBOX_FREE) free(s); - } else toys.exitval = 1; + if (s) { + xputs(s); + if (CFG_TOYBOX_FREE) free(s); + } else toys.exitval = 1; } diff --git a/toys/other/realpath.c b/toys/other/realpath.c index 1503c455..dc75840b 100644 --- a/toys/other/realpath.c +++ b/toys/other/realpath.c @@ -1,29 +1,28 @@ -/* vi: set sw=4 ts=4: - * - * realpath.c - Return the canonical version of a pathname +/* realpath.c - Return the canonical version of a pathname * * Copyright 2012 Andre Renaud <andre@bluewatersys.com> USE_REALPATH(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN)) config REALPATH - bool "realpath" - default y - help - usage: realpath FILE... + bool "realpath" + default y + help + usage: realpath FILE... - Display the canonical absolute pathname + Display the canonical absolute pathname */ #include "toys.h" void realpath_main(void) { - char **s = toys.optargs; - for (s = toys.optargs; *s; s++) { - if (!realpath(*s, toybuf)) { - perror_msg("cannot access '%s'", *s); - toys.exitval = 1; - } else xputs(toybuf); - } + char **s = toys.optargs; + + for (s = toys.optargs; *s; s++) { + if (!realpath(*s, toybuf)) { + perror_msg("cannot access '%s'", *s); + toys.exitval = 1; + } else xputs(toybuf); + } } diff --git a/toys/other/rmmod.c b/toys/other/rmmod.c index 18ace3fa..093eb8a1 100644 --- a/toys/other/rmmod.c +++ b/toys/other/rmmod.c @@ -1,20 +1,18 @@ -/* vi: set sw=4 ts=4: - * - * rmmod.c - Remove a module from the Linux kernel. +/* rmmod.c - Remove a module from the Linux kernel. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_RMMOD(NEWTOY(rmmod, "<1wf", TOYFLAG_BIN|TOYFLAG_NEEDROOT)) config RMMOD - bool "rmmod" - default y - help - usage: rmmod [-wf] [MODULE] + bool "rmmod" + default y + help + usage: rmmod [-wf] [MODULE] - Unload the module named MODULE from the Linux kernel. - -f Force unload of a module - -w Wait until the module is no longer used. + Unload the module named MODULE from the Linux kernel. + -f Force unload of a module + -w Wait until the module is no longer used. */ @@ -26,25 +24,22 @@ config RMMOD void rmmod_main(void) { - unsigned int flags = O_NONBLOCK|O_EXCL; - char * mod_name; - int len; - - // Basename - mod_name = strrchr(toys.optargs[0],'/'); - if (mod_name) - mod_name++; - else - mod_name = toys.optargs[0]; - - // Remove .ko if present - len = strlen(mod_name); - if (len > 3 && !strcmp(&mod_name[len-3], ".ko" )) - mod_name[len-3] = 0; - - if (toys.optflags & FLAG_f) flags |= O_TRUNC; - if (toys.optflags & FLAG_w) flags &= ~O_NONBLOCK; - - if (delete_module(mod_name, flags)) - perror_exit("failed to unload %s", mod_name); + unsigned int flags = O_NONBLOCK|O_EXCL; + char * mod_name; + int len; + + // Basename + mod_name = strrchr(toys.optargs[0],'/'); + if (mod_name) mod_name++; + else mod_name = toys.optargs[0]; + + // Remove .ko if present + len = strlen(mod_name); + if (len > 3 && !strcmp(&mod_name[len-3], ".ko" )) mod_name[len-3] = 0; + + if (toys.optflags & FLAG_f) flags |= O_TRUNC; + if (toys.optflags & FLAG_w) flags &= ~O_NONBLOCK; + + if (delete_module(mod_name, flags)) + perror_exit("failed to unload %s", mod_name); } diff --git a/toys/other/setsid.c b/toys/other/setsid.c index 0f08cc03..59a1d78f 100644 --- a/toys/other/setsid.c +++ b/toys/other/setsid.c @@ -1,31 +1,28 @@ -/* vi: set sw=4 ts=4: - * - * setsid.c - Run program in a new session ID. +/* setsid.c - Run program in a new session ID. * * Copyright 2006 Rob Landley <rob@landley.net> USE_SETSID(NEWTOY(setsid, "^<1t", TOYFLAG_USR|TOYFLAG_BIN)) config SETSID - bool "setsid" - default y - help - usage: setsid [-t] command [args...] + bool "setsid" + default y + help + usage: setsid [-t] command [args...] - Run process in a new session. + Run process in a new session. - -t Grab tty (become foreground process, receiving keyboard signals) + -t Grab tty (become foreground process, receiving keyboard signals) */ #include "toys.h" void setsid_main(void) { - while (setsid()<0) - if (vfork()) _exit(0); - if (toys.optflags) { - setpgid(0,0); - tcsetpgrp(0, getpid()); - } - xexec(toys.optargs); + while (setsid()<0) if (vfork()) _exit(0); + if (toys.optflags) { + setpgid(0,0); + tcsetpgrp(0, getpid()); + } + xexec(toys.optargs); } diff --git a/toys/other/swapoff.c b/toys/other/swapoff.c index cac15732..b89e915c 100644 --- a/toys/other/swapoff.c +++ b/toys/other/swapoff.c @@ -1,24 +1,21 @@ -/* vi: set sw=4 ts=4: - * - * swapoff.c - Disable region for swapping +/* swapoff.c - Disable region for swapping * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_SWAPOFF(NEWTOY(swapoff, "<1>1", TOYFLAG_BIN|TOYFLAG_NEEDROOT)) config SWAPOFF - bool "swapoff" - default y - help - usage: swapoff swapregion + bool "swapoff" + default y + help + usage: swapoff swapregion - Disable swapping on a given swapregion. + Disable swapping on a given swapregion. */ #include "toys.h" void swapoff_main(void) { - if (swapoff(toys.optargs[0])) - perror_exit("failed to remove swaparea"); + if (swapoff(toys.optargs[0])) perror_exit("failed to remove swaparea"); } diff --git a/toys/other/swapon.c b/toys/other/swapon.c index db7c45b0..49f12499 100644 --- a/toys/other/swapon.c +++ b/toys/other/swapon.c @@ -1,34 +1,32 @@ -/* vi: set sw=4 ts=4: - * - * swapon.c - Enable region for swapping +/* swapon.c - Enable region for swapping * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_SWAPON(NEWTOY(swapon, "<1>1p#<0>32767", TOYFLAG_BIN|TOYFLAG_NEEDROOT)) config SWAPON - bool "swapon" - default y - help - usage: swapon [-p priority] filename + bool "swapon" + default y + help + usage: swapon [-p priority] filename - Enable swapping on a given device/file. + Enable swapping on a given device/file. */ #define FOR_swapon #include "toys.h" GLOBALS( - long priority; + long priority; ) void swapon_main(void) { - int flags = 0; + int flags = 0; - if (toys.optflags) - flags = SWAP_FLAG_PREFER | (TT.priority << SWAP_FLAG_PRIO_SHIFT); + if (toys.optflags) + flags = SWAP_FLAG_PREFER | (TT.priority << SWAP_FLAG_PRIO_SHIFT); - if (swapon(*toys.optargs, flags)) - perror_exit("Couldn't swapon '%s'", *toys.optargs); + if (swapon(*toys.optargs, flags)) + perror_exit("Couldn't swapon '%s'", *toys.optargs); } diff --git a/toys/other/switch_root.c b/toys/other/switch_root.c index 6451ec15..1dfa20de 100644 --- a/toys/other/switch_root.c +++ b/toys/other/switch_root.c @@ -5,16 +5,16 @@ USE_SWITCH_ROOT(NEWTOY(switch_root, "<2c:h", TOYFLAG_SBIN)) config SWITCH_ROOT - bool "switch_root" - default y - help - usage: switch_root [-c /dev/console] NEW_ROOT NEW_INIT... + bool "switch_root" + default y + help + usage: switch_root [-c /dev/console] NEW_ROOT NEW_INIT... - Use from PID 1 under initramfs to free initramfs, chroot to NEW_ROOT, - and exec NEW_INIT. + Use from PID 1 under initramfs to free initramfs, chroot to NEW_ROOT, + and exec NEW_INIT. - -c Redirect console to device in NEW_ROOT - -h Hang instead of exiting on failure (avoids kernel panic) + -c Redirect console to device in NEW_ROOT + -h Hang instead of exiting on failure (avoids kernel panic) */ #define FOR_switch_root @@ -22,72 +22,72 @@ config SWITCH_ROOT #include <sys/vfs.h> GLOBALS( - char *console; + char *console; - dev_t rootdev; + dev_t rootdev; ) static int del_node(struct dirtree *node) { - if (node->st.st_dev == TT.rootdev && dirtree_notdotdot(node)) { - int flag = 0; - if (S_ISDIR(node->st.st_mode)) { - if (node->data != -1) return DIRTREE_COMEAGAIN; - flag = AT_REMOVEDIR; - } - unlinkat(dirtree_parentfd(node), node->name, flag); - } - - return 0; + if (node->st.st_dev == TT.rootdev && dirtree_notdotdot(node)) { + int flag = 0; + if (S_ISDIR(node->st.st_mode)) { + if (node->data != -1) return DIRTREE_COMEAGAIN; + flag = AT_REMOVEDIR; + } + unlinkat(dirtree_parentfd(node), node->name, flag); + } + + return 0; } void switch_root_main(void) { - char *newroot = *toys.optargs, **cmdline = toys.optargs+1; - struct stat st1, st2; - struct statfs stfs; - int console = console; // gcc's "may be used" warnings are broken. - - if (getpid() != 1) error_exit("not pid 1"); - - // Root filesystem we're leaving must be ramfs or tmpfs - if (statfs("/", &stfs) || - (stfs.f_type != 0x858458f6 && stfs.f_type != 0x01021994)) - { - error_msg("not ramfs"); - goto panic; - } - - // New directory must be different filesystem instance - if (chdir(newroot) || stat(".", &st1) || stat("/", &st2) || - st1.st_dev == st2.st_dev) - { - error_msg("bad newroot '%s'", newroot); - goto panic; - } - TT.rootdev=st2.st_dev; - - // init program must exist and be an executable file - if (stat("init", &st1) || !S_ISREG(st1.st_mode) || !(st1.st_mode&0100)) { - error_msg("bad init"); - goto panic; - } - - if (TT.console && -1 == (console = open(TT.console, O_RDWR))) { - perror_msg("bad console '%s'", TT.console); - goto panic; - } + char *newroot = *toys.optargs, **cmdline = toys.optargs+1; + struct stat st1, st2; + struct statfs stfs; + int console = console; // gcc's "may be used" warnings are broken. + + if (getpid() != 1) error_exit("not pid 1"); + + // Root filesystem we're leaving must be ramfs or tmpfs + if (statfs("/", &stfs) || + (stfs.f_type != 0x858458f6 && stfs.f_type != 0x01021994)) + { + error_msg("not ramfs"); + goto panic; + } + + // New directory must be different filesystem instance + if (chdir(newroot) || stat(".", &st1) || stat("/", &st2) || + st1.st_dev == st2.st_dev) + { + error_msg("bad newroot '%s'", newroot); + goto panic; + } + TT.rootdev=st2.st_dev; + + // init program must exist and be an executable file + if (stat("init", &st1) || !S_ISREG(st1.st_mode) || !(st1.st_mode&0100)) { + error_msg("bad init"); + goto panic; + } + + if (TT.console && -1 == (console = open(TT.console, O_RDWR))) { + perror_msg("bad console '%s'", TT.console); + goto panic; + } - // Ok, enough safety checks: wipe root partition. - dirtree_read("/", del_node); - - if (TT.console) { - int i; - for (i=0; i<3; i++) if (console != i) dup2(console, i); - if (console>2) close(console); - } - execv(*cmdline, cmdline); - perror_msg("Failed to exec '%s'", *cmdline); + // Ok, enough safety checks: wipe root partition. + dirtree_read("/", del_node); + + if (TT.console) { + int i; + for (i=0; i<3; i++) if (console != i) dup2(console, i); + if (console>2) close(console); + } + execv(*cmdline, cmdline); + perror_msg("Failed to exec '%s'", *cmdline); panic: - if (toys.optflags & FLAG_h) for (;;) wait(NULL); + if (toys.optflags & FLAG_h) for (;;) wait(NULL); } diff --git a/toys/other/tac.c b/toys/other/tac.c index 7a8bb4ae..78b22866 100644 --- a/toys/other/tac.c +++ b/toys/other/tac.c @@ -1,53 +1,51 @@ -/* vi: set sw=4 ts=4: - * - * tac.c - output lines in reverse order +/* tac.c - output lines in reverse order * * Copyright 2012 Rob Landley <rob@landley.net> USE_TAC(NEWTOY(tac, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config TAC - bool "tac" - default y - help - usage: tac [FILE...] + bool "tac" + default y + help + usage: tac [FILE...] - Output lines in reverse order. + Output lines in reverse order. */ #include "toys.h" void do_tac(int fd, char *name) { - struct arg_list *list = NULL; - char *c; - - // Read in lines - for (;;) { - struct arg_list *temp; - int len; - - if (!(c = get_line(fd))) break; - - len = strlen(c); - if (len && c[len-1]=='\n') c[len-1] = 0; - temp = xmalloc(sizeof(struct arg_list)); - temp->next = list; - temp->arg = c; - list = temp; - } - - // Play them back. - while (list) { - struct arg_list *temp = list->next; - xputs(list->arg); - free(list->arg); - free(list); - list = temp; - } + struct arg_list *list = NULL; + char *c; + + // Read in lines + for (;;) { + struct arg_list *temp; + int len; + + if (!(c = get_line(fd))) break; + + len = strlen(c); + if (len && c[len-1]=='\n') c[len-1] = 0; + temp = xmalloc(sizeof(struct arg_list)); + temp->next = list; + temp->arg = c; + list = temp; + } + + // Play them back. + while (list) { + struct arg_list *temp = list->next; + xputs(list->arg); + free(list->arg); + free(list); + list = temp; + } } void tac_main(void) { - loopfiles(toys.optargs, do_tac); + loopfiles(toys.optargs, do_tac); } diff --git a/toys/other/taskset.c b/toys/other/taskset.c index 74cbfffa..967bf70f 100644 --- a/toys/other/taskset.c +++ b/toys/other/taskset.c @@ -1,25 +1,23 @@ -/* vi: set sw=4 ts=4: - * - * taskset.c - Retrieve or set the CPU affinity of a process. +/* taskset.c - Retrieve or set the CPU affinity of a process. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_TASKSET(NEWTOY(taskset, "<1^pa", TOYFLAG_BIN|TOYFLAG_STAYROOT)) config TASKSET - bool "taskset" - default y - help - usage: taskset [-ap] [mask] [PID | cmd [args...]] + bool "taskset" + default y + help + usage: taskset [-ap] [mask] [PID | cmd [args...]] - Launch a new task which may only run on certain processors, or change - the processor affinity of an exisitng PID. + Launch a new task which may only run on certain processors, or change + the processor affinity of an exisitng PID. - Mask is a hex string where each bit represents a processor the process - is allowed to run on. PID without a mask displays existing affinity. + Mask is a hex string where each bit represents a processor the process + is allowed to run on. PID without a mask displays existing affinity. - -p Set/get the affinity of given PID instead of a new command. - -a Set/get the affinity of all threads of the PID. + -p Set/get the affinity of given PID instead of a new command. + -a Set/get the affinity of all threads of the PID. */ #define FOR_taskset @@ -34,73 +32,73 @@ int sched_getaffinity(pid_t pid, size_t size, void *cpuset); static void do_taskset(pid_t pid, int quiet) { - unsigned long *mask = (unsigned long *)toybuf; - char *s = *toys.optargs, *failed = "failed to %s %d's affinity"; - int i, j, k; - - for (i=0; ; i++) { - if (!quiet) { - int j = sizeof(toybuf), flag = 0; - - if (sched_getaffinity(pid, sizeof(toybuf), (void *)mask)) - perror_exit(failed, "get", pid); - - printf("pid %d's %s affinity mask: ", pid, i ? "new" : "current"); - - while (j--) { - int x = 255 & (mask[j/sizeof(long)] >> (8*(j&(sizeof(long)-1)))); - - if (flag) printf("%02x", x); - else if (x) { - flag++; - printf("%x", x); - } - } - putchar('\n'); - } - - if (i || toys.optc < 2) return; - - memset(toybuf, 0, sizeof(toybuf)); - k = strlen(s = *toys.optargs); - s += k; - for (j = 0; j<k; j++) { - unsigned long digit = *(--s) - '0'; - - if (digit > 9) digit = 10 + tolower(*s)-'a'; - if (digit > 15) error_exit("bad mask '%s'", *toys.optargs); - mask[j/(2*sizeof(long))] |= digit << 4*(j&((2*sizeof(long))-1)); - } - - if (sched_setaffinity(pid, sizeof(toybuf), (void *)mask)) - perror_exit(failed, "set", pid); - } + unsigned long *mask = (unsigned long *)toybuf; + char *s = *toys.optargs, *failed = "failed to %s %d's affinity"; + int i, j, k; + + for (i=0; ; i++) { + if (!quiet) { + int j = sizeof(toybuf), flag = 0; + + if (sched_getaffinity(pid, sizeof(toybuf), (void *)mask)) + perror_exit(failed, "get", pid); + + printf("pid %d's %s affinity mask: ", pid, i ? "new" : "current"); + + while (j--) { + int x = 255 & (mask[j/sizeof(long)] >> (8*(j&(sizeof(long)-1)))); + + if (flag) printf("%02x", x); + else if (x) { + flag++; + printf("%x", x); + } + } + putchar('\n'); + } + + if (i || toys.optc < 2) return; + + memset(toybuf, 0, sizeof(toybuf)); + k = strlen(s = *toys.optargs); + s += k; + for (j = 0; j<k; j++) { + unsigned long digit = *(--s) - '0'; + + if (digit > 9) digit = 10 + tolower(*s)-'a'; + if (digit > 15) error_exit("bad mask '%s'", *toys.optargs); + mask[j/(2*sizeof(long))] |= digit << 4*(j&((2*sizeof(long))-1)); + } + + if (sched_setaffinity(pid, sizeof(toybuf), (void *)mask)) + perror_exit(failed, "set", pid); + } } static int task_callback(struct dirtree *new) { - if (!new->parent) return DIRTREE_RECURSE; - if (isdigit(*new->name)) do_taskset(atoi(new->name), 0); + if (!new->parent) return DIRTREE_RECURSE; + if (isdigit(*new->name)) do_taskset(atoi(new->name), 0); - return 0; + return 0; } void taskset_main(void) { - if (!(toys.optflags & FLAG_p)) { - if (toys.optc < 2) error_exit("Needs 2 args"); - do_taskset(getpid(), 1); - xexec(toys.optargs+1); - } else { - char *c; - pid_t pid = strtol(toys.optargs[toys.optc-1], &c, 10); - - if (*c) error_exit("Not int %s", toys.optargs[1]); - - if (toys.optflags & FLAG_a) { - char buf[33]; - sprintf(buf, "/proc/%ld/task/", (long)pid); - dirtree_read(buf, task_callback); - } else do_taskset(pid, 0); - } + if (!(toys.optflags & FLAG_p)) { + if (toys.optc < 2) error_exit("Needs 2 args"); + do_taskset(getpid(), 1); + xexec(toys.optargs+1); + } else { + char *c; + pid_t pid = strtol(toys.optargs[toys.optc-1], &c, 10); + + if (*c) error_exit("Not int %s", toys.optargs[1]); + + if (toys.optflags & FLAG_a) { + char buf[33]; + sprintf(buf, "/proc/%ld/task/", (long)pid); + dirtree_read(buf, task_callback); + } else do_taskset(pid, 0); + } } diff --git a/toys/other/truncate.c b/toys/other/truncate.c index 47b07583..5ed9f61b 100644 --- a/toys/other/truncate.c +++ b/toys/other/truncate.c @@ -1,44 +1,43 @@ -/* vi: set sw=4 ts=4: - * - * truncate.c - set file length, extending sparsely if necessary +/* truncate.c - set file length, extending sparsely if necessary * * Copyright 2011 Rob Landley <rob@landley.net> USE_TRUNCATE(NEWTOY(truncate, "<1s#|c", TOYFLAG_BIN)) config TRUNCATE - bool "truncate" - default y - help - usage: truncate [-c] -s file... - Set length of file(s), extending sparsely if necessary. - - -c Don't create file if it doesn't exist. - -s New size + bool "truncate" + default y + help + usage: truncate [-c] -s file... + + Set length of file(s), extending sparsely if necessary. + + -c Don't create file if it doesn't exist. + -s New size */ #define FOR_truncate #include "toys.h" GLOBALS( - long size; + long size; ) static void do_truncate(int fd, char *name) { - if (fd<0) return; - if (ftruncate(fd, TT.size)) { - perror_msg("failed to set '%s' to '%ld'", name, TT.size); - toys.exitval = EXIT_FAILURE; - } + if (fd<0) return; + if (ftruncate(fd, TT.size)) { + perror_msg("failed to set '%s' to '%ld'", name, TT.size); + toys.exitval = EXIT_FAILURE; + } } void truncate_main(void) { - int cr = !(toys.optflags&1); + int cr = !(toys.optflags&1); - // Create files with mask rwrwrw. - // Nonexistent files are only an error if we're supposed to create them. - loopfiles_rw(toys.optargs, O_WRONLY|(cr ? O_CREAT : 0), 0666, cr, - do_truncate); + // Create files with mask rwrwrw. + // Nonexistent files are only an error if we're supposed to create them. + loopfiles_rw(toys.optargs, O_WRONLY|(cr ? O_CREAT : 0), 0666, cr, + do_truncate); } diff --git a/toys/other/unshare.c b/toys/other/unshare.c index bdee66bc..9a938186 100644 --- a/toys/other/unshare.c +++ b/toys/other/unshare.c @@ -1,26 +1,24 @@ -/* vi: set sw=4 ts=4: - * - * unshare.c - run command in new context +/* unshare.c - run command in new context * * Copyright 2011 Rob Landley <rob@landley.net> USE_UNSHARE(NEWTOY(unshare, "<1^nium", TOYFLAG_USR|TOYFLAG_BIN)) config UNSHARE - bool "unshare" - default y - depends on TOYBOX_CONTAINER - help - usage: unshare [-muin] COMMAND... - - Create new namespace(s) for this process and its children, so some - attribute is not shared with the parent process. This is part of - Linux Containers. Each process can have its own: - - -m Mount/unmount tree - -u Host and domain names - -i SysV IPC (message queues, semaphores, shared memory) - -n Network address, sockets, routing, iptables + bool "unshare" + default y + depends on TOYBOX_CONTAINER + help + usage: unshare [-muin] COMMAND... + + Create new namespace(s) for this process and its children, so some + attribute is not shared with the parent process. This is part of + Linux Containers. Each process can have its own: + + -m Mount/unmount tree + -u Host and domain names + -i SysV IPC (message queues, semaphores, shared memory) + -n Network address, sockets, routing, iptables */ #include "toys.h" @@ -29,15 +27,13 @@ extern int unshare (int __flags); void unshare_main(void) { - unsigned flags[]={CLONE_NEWNS, CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWNET,0}; - unsigned f=0; - int i; + unsigned flags[]={CLONE_NEWNS, CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWNET, 0}; + unsigned f=0; + int i; - for (i=0; flags[i]; i++) - if (toys.optflags & (1<<i)) - f |= flags[i]; + for (i=0; flags[i]; i++) if (toys.optflags & (1<<i)) f |= flags[i]; - if(unshare(f)) perror_exit("failed"); + if(unshare(f)) perror_exit("failed"); - xexec(toys.optargs); + xexec(toys.optargs); } diff --git a/toys/other/uptime.c b/toys/other/uptime.c index dfd62b6c..f4ce5e46 100644 --- a/toys/other/uptime.c +++ b/toys/other/uptime.c @@ -1,50 +1,45 @@ -/* vi: set sw=4 ts=4: - * - * uptime.c - Tell how long the system has been running. +/* uptime.c - Tell how long the system has been running. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_UPTIME(NEWTOY(uptime, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config UPTIME - bool "uptime" - default y - help - usage: uptime + bool "uptime" + default y + help + usage: uptime - Tell how long the system has been running and the system load - averages for the past 1, 5 and 15 minutes. + Tell how long the system has been running and the system load + averages for the past 1, 5 and 15 minutes. */ #include "toys.h" void uptime_main(void) { - struct sysinfo info; - time_t tmptime; - struct tm * now; - unsigned int days, hours, minutes; - - // Obtain the data we need. - sysinfo(&info); - time(&tmptime); - now = localtime(&tmptime); - - // Time - xprintf(" %02d:%02d:%02d up ", now->tm_hour, now->tm_min, now->tm_sec); - // Uptime - info.uptime /= 60; - minutes = info.uptime%60; - info.uptime /= 60; - hours = info.uptime%24; - days = info.uptime/24; - if (days) xprintf("%d day%s, ", days, (days!=1)?"s":""); - if (hours) - xprintf("%2d:%02d, ", hours, minutes); - else - printf("%d min, ", minutes); - - printf(" load average: %.02f %.02f %.02f\n", info.loads[0]/65536.0, - info.loads[1]/65536.0, info.loads[2]/65536.0); - + struct sysinfo info; + time_t tmptime; + struct tm * now; + unsigned int days, hours, minutes; + + // Obtain the data we need. + sysinfo(&info); + time(&tmptime); + now = localtime(&tmptime); + + // Time + xprintf(" %02d:%02d:%02d up ", now->tm_hour, now->tm_min, now->tm_sec); + // Uptime + info.uptime /= 60; + minutes = info.uptime%60; + info.uptime /= 60; + hours = info.uptime%24; + days = info.uptime/24; + if (days) xprintf("%d day%s, ", days, (days!=1)?"s":""); + if (hours) xprintf("%2d:%02d, ", hours, minutes); + else printf("%d min, ", minutes); + + printf(" load average: %.02f %.02f %.02f\n", info.loads[0]/65536.0, + info.loads[1]/65536.0, info.loads[2]/65536.0); } diff --git a/toys/other/usleep.c b/toys/other/usleep.c index ff7fe88b..6040cc06 100644 --- a/toys/other/usleep.c +++ b/toys/other/usleep.c @@ -1,30 +1,26 @@ -/* vi: set sw=4 ts=4: - * - * usleep.c - Wait for a number of microseconds. +/* usleep.c - Wait for a number of microseconds. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_USLEEP(NEWTOY(usleep, "<1", TOYFLAG_BIN)) config USLEEP - bool "usleep" - default y - help - usage: usleep MICROSECONDS - - Pause for MICROSECONDS microseconds. + bool "usleep" + default y + help + usage: usleep MICROSECONDS + Pause for MICROSECONDS microseconds. */ #include "toys.h" void usleep_main(void) { - struct timespec tv; - long delay = atol(*toys.optargs); - - tv.tv_sec = delay/1000000; - tv.tv_nsec = (delay%1000000) * 1000; - toys.exitval = !!nanosleep(&tv, NULL); + struct timespec tv; + long delay = atol(*toys.optargs); + tv.tv_sec = delay/1000000; + tv.tv_nsec = (delay%1000000) * 1000; + toys.exitval = !!nanosleep(&tv, NULL); } diff --git a/toys/other/vconfig.c b/toys/other/vconfig.c index 92d9d7f0..18225fc4 100644 --- a/toys/other/vconfig.c +++ b/toys/other/vconfig.c @@ -1,6 +1,4 @@ -/* vi: set sw=4 ts=4: - * - * vconfig.c - Creates virtual ethernet devices. +/* vconfig.c - Creates virtual ethernet devices. * * Copyright 2012 Sandeep Sharma <sandeep.jack2756@gmail.com>, Kyungwan Han <asura321@gmail.com> * @@ -9,20 +7,19 @@ USE_VCONFIG(NEWTOY(vconfig, "<2>4", TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) config VCONFIG - bool "vconfig" - default y - help - usage: vconfig COMMAND [OPTIONS] + bool "vconfig" + default y + help + usage: vconfig COMMAND [OPTIONS] - add [interface-name] [vlan_id] - rem [vlan-name] - set_flag [interface-name] [flag-num] [0 | 1] - set_egress_map [vlan-name] [skb_priority] [vlan_qos] - set_ingress_map [vlan-name] [skb_priority] [vlan_qos] - set_name_type [name-type] - - Create and remove virtual ethernet devices + add [interface-name] [vlan_id] + rem [vlan-name] + set_flag [interface-name] [flag-num] [0 | 1] + set_egress_map [vlan-name] [skb_priority] [vlan_qos] + set_ingress_map [vlan-name] [skb_priority] [vlan_qos] + set_name_type [name-type] + Create and remove virtual ethernet devices */ #include "toys.h" @@ -34,16 +31,15 @@ config VCONFIG */ static int strtol_range(char *str, int min, int max) { - char *endptr = NULL; - errno = 0; - long ret_value = strtol(str, &endptr, 10); - if(errno) perror_exit("Invalid num %s", str); - else { - if(endptr && (*endptr != '\0' || endptr == str)) - perror_exit("Not a valid num %s", str); - } - if(ret_value >= min && ret_value <= max) return ret_value; - else perror_exit("Number %s is not in valid [%d-%d] Range\n", str, min, max); + char *endptr = NULL; + errno = 0; + long ret_value = strtol(str, &endptr, 10); + + if(errno) perror_exit("Invalid num %s", str); + else if(endptr && (*endptr != '\0' || endptr == str)) + perror_exit("Not a valid num %s", str); + if(ret_value >= min && ret_value <= max) return ret_value; + else perror_exit("Number %s is not in valid [%d-%d] Range\n", str, min, max); } /* * vconfig main function. @@ -51,83 +47,84 @@ static int strtol_range(char *str, int min, int max) void vconfig_main(void) { #define MAX_VLAN_ID 4094 - struct vlan_ioctl_args request; - char *interface_name = NULL; - unsigned int name_type = VLAN_NAME_TYPE_PLUS_VID; - char *cmd; - int fd = 0; - int vlan_id = 0; - - if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror_exit("Can't open socket"); //Use socket instead of open - memset(&request, 0, sizeof(struct vlan_ioctl_args)); // Null set all the VLAN info's. - cmd = toys.optargs[0]; // Fetch cmd and proceed. - if(strcmp(cmd, "set_name_type") == 0) { - if(strcmp(toys.optargs[1], "VLAN_PLUS_VID") == 0) { - name_type = VLAN_NAME_TYPE_PLUS_VID; - } - else if(strcmp(toys.optargs[1], "VLAN_PLUS_VID_NO_PAD") == 0) { - name_type = VLAN_NAME_TYPE_PLUS_VID_NO_PAD; - } - else if(strcmp(toys.optargs[1], "DEV_PLUS_VID") == 0) { - name_type = VLAN_NAME_TYPE_RAW_PLUS_VID; - } - else if(strcmp(toys.optargs[1], "DEV_PLUS_VID_NO_PAD") == 0) { - name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD; - } - else perror_exit("ERROR: Invalid name type"); - - request.u.name_type = name_type; - request.cmd = SET_VLAN_NAME_TYPE_CMD; - if(ioctl(fd, SIOCSIFVLAN, &request) == 0) { - xprintf("Successful set_name_type for VLAN subsystem\n"); - exit(EXIT_SUCCESS); - } - else perror_exit("Failed to set set_name_type:"); - } - else { - interface_name = toys.optargs[1]; // Store interface name. - if(strlen(interface_name) > 15) perror_exit("ERROR:if_name length can not be greater than 15"); - strcpy(request.device1, interface_name); //we had exited if interface_name length greater than 15, so here it never overflows. - } + struct vlan_ioctl_args request; + char *interface_name = NULL; + unsigned int name_type = VLAN_NAME_TYPE_PLUS_VID; + char *cmd; + int fd = 0; + int vlan_id = 0; - if(strcmp(cmd, "add") == 0) { - request.cmd = ADD_VLAN_CMD; - if(toys.optargs[2]) vlan_id = strtol_range(toys.optargs[2], 0, MAX_VLAN_ID); - else vlan_id = 0; - request.u.VID = vlan_id; - } - else if(strcmp(cmd, "rem") == 0) { - request.cmd = DEL_VLAN_CMD; - } - else if(strcmp(cmd, "set_flag") == 0) { - request.cmd = SET_VLAN_FLAG_CMD; - if(toys.optargs[2]) request.u.flag = strtol_range(toys.optargs[2], 0, 1); - else request.u.flag = 0; - if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7); - else request.vlan_qos = 0; + if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror_exit("Can't open socket"); //Use socket instead of open + memset(&request, 0, sizeof(struct vlan_ioctl_args)); // Null set all the VLAN info's. + cmd = toys.optargs[0]; // Fetch cmd and proceed. + if(strcmp(cmd, "set_name_type") == 0) { + if(strcmp(toys.optargs[1], "VLAN_PLUS_VID") == 0) { + name_type = VLAN_NAME_TYPE_PLUS_VID; } - else if(strcmp(cmd, "set_egress_map") == 0) { - request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD; - if(toys.optargs[2]) request.u.skb_priority = strtol_range(toys.optargs[2], 0, INT_MAX); - else request.u.skb_priority = 0; - if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7); - else request.vlan_qos = 0; + else if(strcmp(toys.optargs[1], "VLAN_PLUS_VID_NO_PAD") == 0) { + name_type = VLAN_NAME_TYPE_PLUS_VID_NO_PAD; } - else if(strcmp(cmd, "set_ingress_map") == 0) { - request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD; - if(toys.optargs[2]) request.u.skb_priority = strtol_range(toys.optargs[2], 0, INT_MAX); - else request.u.skb_priority = 0; - if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7); //To set flag we must have to set vlan_qos - else request.vlan_qos = 0; + else if(strcmp(toys.optargs[1], "DEV_PLUS_VID") == 0) { + name_type = VLAN_NAME_TYPE_RAW_PLUS_VID; } - else { - xclose(fd); - perror_exit("Unknown command %s", cmd); + else if(strcmp(toys.optargs[1], "DEV_PLUS_VID_NO_PAD") == 0) { + name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD; } + else perror_exit("ERROR: Invalid name type"); + + request.u.name_type = name_type; + request.cmd = SET_VLAN_NAME_TYPE_CMD; if(ioctl(fd, SIOCSIFVLAN, &request) == 0) { - if(strcmp(cmd, "add") == 0 && vlan_id == 1) - xprintf("WARNING: VLAN 1 does not work with many switches,consider another number if you have problems.\n"); - xprintf("Successful %s on device %s\n", cmd, interface_name); + xprintf("Successful set_name_type for VLAN subsystem\n"); + exit(EXIT_SUCCESS); } - else perror_exit("Failed to %s, on vlan subsystem %s.", cmd, interface_name); -} + else perror_exit("Failed to set set_name_type:"); + } + else { + interface_name = toys.optargs[1]; // Store interface name. + if(strlen(interface_name) > 15) perror_exit("ERROR:if_name length can not be greater than 15"); + strcpy(request.device1, interface_name); //we had exited if interface_name length greater than 15, so here it never overflows. + } + + if(strcmp(cmd, "add") == 0) { + request.cmd = ADD_VLAN_CMD; + if(toys.optargs[2]) vlan_id = strtol_range(toys.optargs[2], 0, MAX_VLAN_ID); + else vlan_id = 0; + request.u.VID = vlan_id; + } + else if(strcmp(cmd, "rem") == 0) { + request.cmd = DEL_VLAN_CMD; + } + else if(strcmp(cmd, "set_flag") == 0) { + request.cmd = SET_VLAN_FLAG_CMD; + if(toys.optargs[2]) request.u.flag = strtol_range(toys.optargs[2], 0, 1); + else request.u.flag = 0; + if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7); + else request.vlan_qos = 0; + } + else if(strcmp(cmd, "set_egress_map") == 0) { + request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD; + if(toys.optargs[2]) request.u.skb_priority = strtol_range(toys.optargs[2], 0, INT_MAX); + else request.u.skb_priority = 0; + if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7); + else request.vlan_qos = 0; + } + else if(strcmp(cmd, "set_ingress_map") == 0) { + request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD; + if(toys.optargs[2]) request.u.skb_priority = strtol_range(toys.optargs[2], 0, INT_MAX); + else request.u.skb_priority = 0; + //To set flag we must have to set vlan_qos + if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7); + else request.vlan_qos = 0; + } + else { + xclose(fd); + perror_exit("Unknown command %s", cmd); + } + if(ioctl(fd, SIOCSIFVLAN, &request) == 0) { + if(strcmp(cmd, "add") == 0 && vlan_id == 1) + xprintf("WARNING: VLAN 1 does not work with many switches,consider another number if you have problems.\n"); + xprintf("Successful %s on device %s\n", cmd, interface_name); + } + else perror_exit("Failed to %s, on vlan subsystem %s.", cmd, interface_name); +} diff --git a/toys/other/vmstat.c b/toys/other/vmstat.c index 1c348f2a..16d45f2a 100644 --- a/toys/other/vmstat.c +++ b/toys/other/vmstat.c @@ -1,189 +1,184 @@ -/* vi: set sw=4 ts=4: - * - * vmstat.c - Report virtual memory statistics. +/* vmstat.c - Report virtual memory statistics. * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> USE_VMSTAT(NEWTOY(vmstat, ">2n", TOYFLAG_BIN)) config VMSTAT - bool "vmstat" - default y - help - usage: vmstat [-n] [delay [count]] - -n Display the header only once - delay The delay between updates in seconds, when not specified - the average since boot is displayed. - count Number of updates to display, the default is inifinite. + bool "vmstat" + default y + help + usage: vmstat [-n] [delay [count]] + -n Display the header only once + delay The delay between updates in seconds, when not specified + the average since boot is displayed. + count Number of updates to display, the default is inifinite. */ #include "toys.h" -void read_proc_stat(unsigned int * proc_running, unsigned int * proc_blocked, - uint64_t * sys_irq, uint64_t * sys_ctxt, - uint64_t * cpu_user, uint64_t * cpu_sys, uint64_t * cpu_idle, uint64_t * cpu_wait) +void read_proc_stat(unsigned int *proc_running, unsigned int *proc_blocked, + uint64_t *sys_irq, uint64_t *sys_ctxt, uint64_t *cpu_user, uint64_t *cpu_sys, + uint64_t *cpu_idle, uint64_t *cpu_wait) { - char * off; - uint64_t c_user, c_nice, c_sys, c_irq, c_sirq; - int fd = xopen("/proc/stat", O_RDONLY); - size_t s = xread(fd, toybuf, sizeof(toybuf)-1); - toybuf[s] = 0; - if ( s == sizeof(toybuf)-1) - error_exit("/proc/stat is too large"); - - off = strstr(toybuf, "cpu "); - // Ignoring steal and guest fields for now. - if (off) sscanf(off, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64 \ - " %"PRIu64" %"PRIu64" %"PRIu64, &c_user, &c_nice, &c_sys, cpu_idle, - cpu_wait, &c_irq, &c_sirq); - *cpu_user = c_user + c_nice; - *cpu_sys = c_sys + c_irq + c_sirq; - off = strstr(toybuf, "intr"); - if (off) sscanf(off, "intr %"PRIu64, sys_irq); - - off = strstr(toybuf, "ctxt"); - if (off) sscanf(off, "ctxt %"PRIu64, sys_ctxt); - - off = strstr(toybuf, "procs_running"); - if (off) sscanf(off, "procs_running %u", proc_running); - (*proc_running)--; // look, i'm invisible. - - off = strstr(toybuf, "procs_blocked"); - if (off) sscanf(off, "procs_blocked %u", proc_blocked); - - close(fd); + char * off; + uint64_t c_user, c_nice, c_sys, c_irq, c_sirq; + int fd = xopen("/proc/stat", O_RDONLY); + size_t s = xread(fd, toybuf, sizeof(toybuf)-1); + + toybuf[s] = 0; + if (s == sizeof(toybuf)-1) error_exit("/proc/stat is too large"); + + off = strstr(toybuf, "cpu "); + // Ignoring steal and guest fields for now. + if (off) sscanf(off, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64 \ + " %"PRIu64" %"PRIu64" %"PRIu64, &c_user, &c_nice, &c_sys, cpu_idle, + cpu_wait, &c_irq, &c_sirq); + *cpu_user = c_user + c_nice; + *cpu_sys = c_sys + c_irq + c_sirq; + off = strstr(toybuf, "intr"); + if (off) sscanf(off, "intr %"PRIu64, sys_irq); + + off = strstr(toybuf, "ctxt"); + if (off) sscanf(off, "ctxt %"PRIu64, sys_ctxt); + + off = strstr(toybuf, "procs_running"); + if (off) sscanf(off, "procs_running %u", proc_running); + (*proc_running)--; // look, i'm invisible. + + off = strstr(toybuf, "procs_blocked"); + if (off) sscanf(off, "procs_blocked %u", proc_blocked); + + close(fd); } -void read_proc_meminfo(unsigned long * mem_swapped, unsigned long * mem_free, - unsigned long * mem_buff, unsigned long * mem_cache) +void read_proc_meminfo(unsigned long *mem_swapped, unsigned long *mem_free, + unsigned long *mem_buff, unsigned long *mem_cache) { - char * off; - unsigned long swap_total, swap_free; - int fd = xopen("/proc/meminfo", O_RDONLY); - size_t s = xread(fd, toybuf, sizeof(toybuf)-1); - toybuf[s] = 0; - if ( s == sizeof(toybuf)-1) - error_exit("/proc/meminfo is too large"); + char * off; + unsigned long swap_total, swap_free; + int fd = xopen("/proc/meminfo", O_RDONLY); + size_t s = xread(fd, toybuf, sizeof(toybuf)-1); + + toybuf[s] = 0; + if (s == sizeof(toybuf)-1) error_exit("/proc/meminfo is too large"); - off = strstr(toybuf, "MemFree"); - if (off) sscanf(off, "MemFree: %lu kB", mem_free); + off = strstr(toybuf, "MemFree"); + if (off) sscanf(off, "MemFree: %lu kB", mem_free); - off = strstr(toybuf, "Buffers"); - if (off) sscanf(off, "Buffers: %lu kB", mem_buff); + off = strstr(toybuf, "Buffers"); + if (off) sscanf(off, "Buffers: %lu kB", mem_buff); - off = strstr(toybuf, "Cached"); - if (off) sscanf(off, "Cached: %lu kB", mem_cache); + off = strstr(toybuf, "Cached"); + if (off) sscanf(off, "Cached: %lu kB", mem_cache); - off = strstr(toybuf, "SwapFree"); - if (off) sscanf(off, "SwapFree: %lu kB", &swap_free); + off = strstr(toybuf, "SwapFree"); + if (off) sscanf(off, "SwapFree: %lu kB", &swap_free); - off = strstr(toybuf, "SwapTotal"); - if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total); - *mem_swapped = swap_total - swap_free; + off = strstr(toybuf, "SwapTotal"); + if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total); + *mem_swapped = swap_total - swap_free; - close(fd); + close(fd); } -void read_proc_vmstat(unsigned long * io_pages_in, unsigned long * io_pages_out, - unsigned long * swap_bytes_in, unsigned long * swap_bytes_out) +void read_proc_vmstat(unsigned long *io_pages_in, unsigned long *io_pages_out, + unsigned long *swap_bytes_in, unsigned long *swap_bytes_out) { - char * off; - unsigned long s_pages_in, s_pages_out; - unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L; - int fd = xopen("/proc/vmstat", O_RDONLY); - size_t s = xread(fd, toybuf, sizeof(toybuf)-1); - toybuf[s] = 0; - if ( s == sizeof(toybuf)-1) - error_exit("/proc/vmstat is too large"); - - off = strstr(toybuf, "pgpgin"); - if (off) sscanf(off, "pgpgin %lu", io_pages_in); - - off = strstr(toybuf, "pgpgout"); - if (off) sscanf(off, "pgpgout %lu", io_pages_out); - - off = strstr(toybuf, "pswpin"); - if (off) sscanf(off, "pswpin %lu", &s_pages_in); - *swap_bytes_in = s_pages_in * pagesize_kb; - - off = strstr(toybuf, "pswpout"); - if (off) sscanf(off, "pswpout %lu", &s_pages_out); - *swap_bytes_out = s_pages_out * pagesize_kb; - - close(fd); + char *off; + unsigned long s_pages_in, s_pages_out; + unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L; + int fd = xopen("/proc/vmstat", O_RDONLY); + size_t s = xread(fd, toybuf, sizeof(toybuf)-1); + + toybuf[s] = 0; + if (s == sizeof(toybuf)-1) error_exit("/proc/vmstat is too large"); + + off = strstr(toybuf, "pgpgin"); + if (off) sscanf(off, "pgpgin %lu", io_pages_in); + + off = strstr(toybuf, "pgpgout"); + if (off) sscanf(off, "pgpgout %lu", io_pages_out); + + off = strstr(toybuf, "pswpin"); + if (off) sscanf(off, "pswpin %lu", &s_pages_in); + *swap_bytes_in = s_pages_in * pagesize_kb; + + off = strstr(toybuf, "pswpout"); + if (off) sscanf(off, "pswpout %lu", &s_pages_out); + *swap_bytes_out = s_pages_out * pagesize_kb; + + close(fd); } void vmstat_main(void) { - const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n"; - unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0; - unsigned int running = 0, blocked = 0; - unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0; - unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2]; - uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2]; - int first_run = 1; - int no_header = toys.optflags; - unsigned num_rows = 22; - - if (toys.optc >= 1) - loop_delay = atoi(toys.optargs[0]); - if (toys.optc >= 2) - loop_max_num = atoi(toys.optargs[1]); - - if (loop_max_num < 0 || loop_delay < 0) - error_exit("Invalid arguments"); - - while(1) { - uint64_t total_jif; - int idx = loop_num%2; - - if(first_run || (!(loop_num % num_rows) && !no_header)) { - unsigned rows = 0, cols = 0; - terminal_size(&cols, &rows); - num_rows = (rows > 3)? rows - 3 : 22; - printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n"); - printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n"); - } - - read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx], - &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]); - read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache); - read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]); - - if (first_run) { - struct sysinfo inf; - sysinfo(&inf); - first_run = 0; - total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx]; - printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, - (unsigned) (swap_bytes_in[idx]/inf.uptime), - (unsigned) (swap_bytes_out[idx]/inf.uptime), - (unsigned) (io_pages_in[idx]/inf.uptime), - (unsigned) (io_pages_out[idx]/inf.uptime), - (unsigned) (sys_irq[idx]/inf.uptime), - (unsigned) (sys_ctxt[idx]/inf.uptime), - (unsigned) (100*cpu_user[idx]/total_jif), - (unsigned) (100*cpu_sys[idx]/total_jif), - (unsigned) (100*cpu_idle[idx]/total_jif), - (unsigned) (100*cpu_wait[idx]/total_jif)); - }else{ - total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx]; - printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, - (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay), - (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay), - (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay), - (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay), - (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay), - (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay), - (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif), - (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif), - (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif), - (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif)); - } - - loop_num++; - if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num)) - break; - sleep(loop_delay); - } + const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n"; + unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0; + unsigned int running = 0, blocked = 0; + unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0; + unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2]; + uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2]; + int first_run = 1; + int no_header = toys.optflags; + unsigned num_rows = 22; + + if (toys.optc >= 1) loop_delay = atoi(toys.optargs[0]); + if (toys.optc >= 2) loop_max_num = atoi(toys.optargs[1]); + + if (loop_max_num < 0 || loop_delay < 0) error_exit("Invalid arguments"); + + while(1) { + uint64_t total_jif; + int idx = loop_num%2; + + if(first_run || (!(loop_num % num_rows) && !no_header)) { + unsigned rows = 0, cols = 0; + terminal_size(&cols, &rows); + num_rows = (rows > 3)? rows - 3 : 22; + printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n"); + printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n"); + } + + read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx], + &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]); + read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache); + read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]); + + if (first_run) { + struct sysinfo inf; + sysinfo(&inf); + first_run = 0; + total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx]; + printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, + (unsigned) (swap_bytes_in[idx]/inf.uptime), + (unsigned) (swap_bytes_out[idx]/inf.uptime), + (unsigned) (io_pages_in[idx]/inf.uptime), + (unsigned) (io_pages_out[idx]/inf.uptime), + (unsigned) (sys_irq[idx]/inf.uptime), + (unsigned) (sys_ctxt[idx]/inf.uptime), + (unsigned) (100*cpu_user[idx]/total_jif), + (unsigned) (100*cpu_sys[idx]/total_jif), + (unsigned) (100*cpu_idle[idx]/total_jif), + (unsigned) (100*cpu_wait[idx]/total_jif)); + }else{ + total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx]; + printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, + (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay), + (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay), + (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay), + (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay), + (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay), + (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay), + (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif), + (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif), + (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif), + (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif)); + } + + loop_num++; + if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num)) + break; + sleep(loop_delay); + } } diff --git a/toys/other/w.c b/toys/other/w.c index 097a4386..c271e8bd 100644 --- a/toys/other/w.c +++ b/toys/other/w.c @@ -1,34 +1,33 @@ -/* vi: set sw=4 ts=4: - * - * w.c - shows logged in users +/* w.c - shows logged in users * * Copyright 2012 Gaurang Shastri <gmshastri@gmail.com> USE_W(NEWTOY(w, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config W - bool "w" - default y - help - usage: w + bool "w" + default y + help + usage: w - Show who is logged on and since how long they logged in. + Show who is logged on and since how long they logged in. */ #include "toys.h" void w_main(void) { - struct utmpx *x; + struct utmpx *x; - xprintf("USER TTY LOGIN@ FROM"); - setutxent(); - while ((x=getutxent()) != NULL) - if (x->ut_type==7) { - time_t tt = x->ut_tv.tv_sec; + xprintf("USER TTY LOGIN@ FROM"); + setutxent(); + while ((x=getutxent()) != NULL) { + if (x->ut_type==7) { + time_t tt = x->ut_tv.tv_sec; - xprintf("\n%-9.8s%-9.8s %-4.24s (%-1.12s)", x->ut_user, x->ut_line, - ctime(&tt), x->ut_host); - } - xputc('\n'); + xprintf("\n%-9.8s%-9.8s %-4.24s (%-1.12s)", x->ut_user, x->ut_line, + ctime(&tt), x->ut_host); + } + } + xputc('\n'); } diff --git a/toys/other/which.c b/toys/other/which.c index 44b1f568..fc65fe8a 100644 --- a/toys/other/which.c +++ b/toys/other/which.c @@ -1,20 +1,18 @@ -/* vi: set sw=4 ts=4: - * - * which.c - Find executable files in $PATH. +/* which.c - Find executable files in $PATH. * * Copyright 2006 Rob landley <rob@landley.net> USE_WHICH(NEWTOY(which, "<1a", TOYFLAG_USR|TOYFLAG_BIN)) config WHICH - bool "which" - default y - help - usage: which [-a] filename ... + bool "which" + default y + help + usage: which [-a] filename ... - Search $PATH for executable files matching filename(s). + Search $PATH for executable files matching filename(s). - -a Show all matches + -a Show all matches */ #include "toys.h" @@ -24,46 +22,47 @@ config WHICH static int which_in_path(char *filename) { - struct string_list *list; + struct string_list *list; - // If they gave us a path, don't worry about $PATH or -a + // If they gave us a path, don't worry about $PATH or -a - if (strchr(filename, '/')) { - // Confirm it has the executable bit set, and it's not a directory. - if (!access(filename, X_OK)) { - struct stat st; + if (strchr(filename, '/')) { + // Confirm it has the executable bit set, and it's not a directory. + if (!access(filename, X_OK)) { + struct stat st; - if (!stat(filename, &st) && S_ISREG(st.st_mode)) { - puts(filename); - return 0; - } - return 1; - } - } + if (!stat(filename, &st) && S_ISREG(st.st_mode)) { + puts(filename); + return 0; + } + return 1; + } + } - // Search $PATH for matches. - list = find_in_path(getenv("PATH"), filename); - if (!list) return 1; + // Search $PATH for matches. + list = find_in_path(getenv("PATH"), filename); + if (!list) return 1; - // Print out matches - while (list) { - if (!access(list->str, X_OK)) { - puts(list->str); - // If we should stop at one match, do so - if (!toys.optflags) { - llist_traverse(list, free); - break; - } - } - free(llist_pop(&list)); - } + // Print out matches + while (list) { + if (!access(list->str, X_OK)) { + puts(list->str); + // If we should stop at one match, do so + if (!toys.optflags) { + llist_traverse(list, free); + break; + } + } + free(llist_pop(&list)); + } - return 0; + return 0; } void which_main(void) { - int i; - for (i=0; toys.optargs[i]; i++) - toys.exitval |= which_in_path(toys.optargs[i]); + int i; + + for (i=0; toys.optargs[i]; i++) + toys.exitval |= which_in_path(toys.optargs[i]); } diff --git a/toys/other/whoami.c b/toys/other/whoami.c index e6131498..a7ed047a 100644 --- a/toys/other/whoami.c +++ b/toys/other/whoami.c @@ -1,31 +1,29 @@ -/* vi: set sw=4 ts=4: - * - * whoami.c - Print effective user name +/* whoami.c - Print effective user name * * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org> USE_WHOAMI(NEWTOY(whoami, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config WHOAMI - bool "whoami" - default y - help - usage: whoami + bool "whoami" + default y + help + usage: whoami - Print effective user name. + Print effective user name. */ #include "toys.h" void whoami_main(void) { - struct passwd *pw = getpwuid(geteuid()); + struct passwd *pw = getpwuid(geteuid()); - if (!pw) { - perror("getpwuid"); - toys.exitval = 1; - return; - } + if (!pw) { + perror("getpwuid"); + toys.exitval = 1; + return; + } - xputs(pw->pw_name); + xputs(pw->pw_name); } diff --git a/toys/other/yes.c b/toys/other/yes.c index 90bf522d..773a5a88 100644 --- a/toys/other/yes.c +++ b/toys/other/yes.c @@ -1,31 +1,29 @@ -/* vi: set sw=4 ts=4: - * - * yes.c - Repeatedly output a string. +/* yes.c - Repeatedly output a string. * * Copyright 2007 Rob Landley <rob@landley.net> USE_YES(NEWTOY(yes, NULL, TOYFLAG_USR|TOYFLAG_BIN)) config YES - bool "yes" - default y - help - usage: yes [args...] + bool "yes" + default y + help + usage: yes [args...] - Repeatedly output line until killed. If no args, output 'y'. + Repeatedly output line until killed. If no args, output 'y'. */ #include "toys.h" void yes_main(void) { - for (;;) { - int i; - for (i=0; toys.optargs[i]; i++) { - if (i) xputc(' '); - xprintf("%s", toys.optargs[i]); - } - if (!i) xputc('y'); - xputc('\n'); - } + for (;;) { + int i; + for (i=0; toys.optargs[i]; i++) { + if (i) xputc(' '); + xprintf("%s", toys.optargs[i]); + } + if (!i) xputc('y'); + xputc('\n'); + } } |