diff options
Diffstat (limited to 'toys/other')
-rw-r--r-- | toys/other/blkid.c | 76 | ||||
-rw-r--r-- | toys/other/help.c | 4 | ||||
-rw-r--r-- | toys/other/hexedit.c | 7 | ||||
-rw-r--r-- | toys/other/losetup.c | 63 | ||||
-rw-r--r-- | toys/other/lsattr.c | 10 | ||||
-rw-r--r-- | toys/other/makedevs.c | 10 | ||||
-rw-r--r-- | toys/other/modinfo.c | 43 | ||||
-rw-r--r-- | toys/other/nbd_client.c | 2 | ||||
-rw-r--r-- | toys/other/printenv.c | 2 | ||||
-rw-r--r-- | toys/other/readlink.c | 31 | ||||
-rw-r--r-- | toys/other/rev.c | 26 | ||||
-rw-r--r-- | toys/other/stat.c | 73 | ||||
-rw-r--r-- | toys/other/tac.c | 41 | ||||
-rw-r--r-- | toys/other/timeout.c | 12 |
14 files changed, 167 insertions, 233 deletions
diff --git a/toys/other/blkid.c b/toys/other/blkid.c index 40391de4..38559981 100644 --- a/toys/other/blkid.c +++ b/toys/other/blkid.c @@ -3,22 +3,20 @@ * Copyright 2013 Brad Conroy <bconroy@uis.edu> * * See ftp://ftp.kernel.org/pub/linux/utils/util-linux/v2.24/libblkid-docs/api-index-full.html - * TODO: -U and -L should require arguments -USE_BLKID(NEWTOY(blkid, "ULs*[!LU]", TOYFLAG_BIN)) +USE_BLKID(NEWTOY(blkid, "UL[!LU]", TOYFLAG_BIN)) USE_FSTYPE(NEWTOY(fstype, "<1", TOYFLAG_BIN)) config BLKID bool "blkid" default y help - usage: blkid [-s TAG] [-UL] DEV... + usage: blkid [-UL] DEV... Print type, label and UUID of filesystem on a block device or image. -U Show UUID only (or device with that UUID) -L Show LABEL only (or device with that LABEL) - -s TAG Only show matching tags (default all) config FSTYPE bool "fstype" @@ -32,10 +30,6 @@ config FSTYPE #define FOR_blkid #include "toys.h" -GLOBALS( - struct arg_list *s; -) - struct fstype { char *name; uint64_t magic; @@ -45,13 +39,13 @@ struct fstype { {"swap", 0x4341505350415753LL, 8, 4086, 1036, 15, 1052}, // NTFS label actually 8/16 0x4d80 but horrible: 16 bit wide characters via // codepage, something called a uuid that's only 8 bytes long... - {"ntfs", 0x5346544e, 4, 3, 0x48, 0, 0}, + {"ntfs", 0x5346544e, 4, 3, 0x48+(8<<24), 0, 0}, {"adfs", 0xadf5, 2, 0xc00, 0,0,0}, {"bfs", 0x1badface, 4, 0, 0,0,0}, {"btrfs", 0x4D5F53665248425FULL, 8, 65600, 65803, 256, 65819}, {"cramfs", 0x28cd3d45, 4, 0, 0, 16, 48}, - {"f2fs", 0xF2F52010, 4, 1024, 1132, 512, 0x47c}, + {"f2fs", 0xF2F52010, 4, 1024, 1132, 16, 1110}, {"jfs", 0x3153464a, 4, 32768, 32920, 16, 32904}, {"nilfs", 0x3434, 2, 1030, 1176, 80, 1192}, {"reiserfs", 0x724573496552ULL, 6, 8244, 8276, 16, 8292}, @@ -60,22 +54,10 @@ struct fstype { {"squashfs", 0x73717368, 4, 0, 0,0,0}, {"xiafs", 0x012fd16d, 4, 572, 0,0,0}, {"xfs", 0x42534658, 4, 0, 32, 12, 108}, - {"vfat", 0x3233544146ULL, 5, 82, 67, 11, 71}, // fat32 - {"vfat", 0x31544146, 4, 54, 39, 11, 43} // fat1 + {"vfat", 0x3233544146ULL, 5, 82, 67+(4<<24), 11, 71}, // fat32 + {"vfat", 0x31544146, 4, 54, 39+(4<<24), 11, 43} // fat1 }; -static void show_tag(char *key, char *value) -{ - int show = 0; - struct arg_list *al; - - if (TT.s) { - for (al = TT.s; al; al = al->next) if (!strcmp(key, al->arg)) show = 1; - } else show = 1; - - if (show) printf(" %s=\"%s\"", key, value); -} - static void flagshow(char *s, char *name) { if (*toys.optargs && strcmp(s, *toys.optargs)) return; @@ -130,6 +112,8 @@ static void do_blkid(int fd, char *name) if (toybuf[1120]&64) type = "ext4"; } + // Could special case NTFS here... + // Output for fstype if (*toys.which->name == 'f') { puts(type); @@ -137,59 +121,39 @@ static void do_blkid(int fd, char *name) } // output for blkid - if (!FLAG(L) && !FLAG(U)) printf("%s:",name); + if (!toys.optflags) printf("%s:",name); len = fstypes[i].label_len; if (!FLAG(U) && len) { s = toybuf+fstypes[i].label_off-off; if (!strcmp(type, "vfat")) { - show_tag("SEC_TYPE", "msdos"); while (len && s[len-1]==' ') len--; if (strstart(&s, "NO NAME")) len=0; } - // TODO: special case NTFS $VOLUME_NAME here... - if (len) { - if (!strcmp(type, "f2fs")) { - // Convert UTF16LE to ASCII by replacing non-ASCII with '?'. - // TODO: support non-ASCII. - for (j=0; j<len; j++) { - buf[j] = s[2*j]; - if (s[2*j+1]) buf[j]='?'; - if (!buf[j]) break; - } - } else sprintf(buf, "%.*s", len, s); + if (len && *s) { + sprintf(buf, "%.*s", len, s); if (FLAG(L)) return flagshow(buf, name); - show_tag("LABEL", buf); + printf(" LABEL=\"%s\"", buf); } } len = fstypes[i].uuid_off; if (!FLAG(L) && len) { - int uoff = len-off; + int bits = 0x550, size = len >> 24, uoff = (len&((1<<24)-1))-off; // Assemble UUID with whatever size and set of dashes this filesystem uses - s = buf; - if (!strcmp(type, "ntfs")) { - for (j = 7; j >= 0; --j) s += sprintf(s, "%02X", toybuf[uoff+j]); - } else if (!strcmp(type, "vfat")) { - s += sprintf(s, "%02X%02X-%02X%02X", toybuf[uoff+3], toybuf[uoff+2], - toybuf[uoff+1], toybuf[uoff]); - } else { - for (j = 0; j < 16; j++) - s += sprintf(s, "-%02x"+!(0x550 & (1<<j)), toybuf[uoff+j]); - } + if (size) bits = 4*(size == 4); + else size = 16; + for (j = 0, s = buf; j < size; j++) + s += sprintf(s, "-%02x"+!(bits & (1<<j)), toybuf[uoff+j]); if (FLAG(U)) return flagshow(buf, name); - show_tag("UUID", buf); + printf(" UUID=\"%s\"", buf); } - if ((!strcmp(type, "ext3")||!strcmp(type,"ext4")) && !(toybuf[1120]&~0x12)) - show_tag("SEC_TYPE", "ext2"); - - if (FLAG(U) || FLAG(L)) return; + if (toys.optflags) return; - show_tag("TYPE", type); - xputc('\n'); + printf(" TYPE=\"%s\"\n", type); } void blkid_main(void) diff --git a/toys/other/help.c b/toys/other/help.c index 6ce1b02e..f7d84817 100644 --- a/toys/other/help.c +++ b/toys/other/help.c @@ -61,7 +61,7 @@ void help_main(void) if (toys.optflags & FLAG_h) { xprintf("<html>\n<title>Toybox command list</title>\n<body>\n<p>\n"); for (i=0; i < toys.toycount; i++) - xprintf("<a href=\"#%s\">%s\n</a>\n", toy_list[i].name, + xprintf("<a href=\"#%s\">%s</a>\n", toy_list[i].name, toy_list[i].name); xprintf("</p>\n"); } @@ -71,7 +71,7 @@ void help_main(void) else { memset(toybuf, '-', 78); memcpy(toybuf+3, toy_list[i].name, strlen(toy_list[i].name)); - printf("\n%s\n\n", toybuf); + printf("%s\n\n", toybuf); } do_help(toy_list+i); if (toys.optflags & FLAG_h) xprintf("</pre>\n"); diff --git a/toys/other/hexedit.c b/toys/other/hexedit.c index 4b628463..06a96a22 100644 --- a/toys/other/hexedit.c +++ b/toys/other/hexedit.c @@ -158,8 +158,8 @@ void hexedit_main(void) } else { TT.base--; i++; + tty_esc("1T"); tty_jump(0, 0); - tty_esc("1L"); draw_line(0); } } @@ -170,8 +170,7 @@ void hexedit_main(void) } else { TT.base++; i++; - tty_jump(0, 0); - tty_esc("1M"); + tty_esc("1S"); tty_jump(0, TT.height-1); draw_line(TT.height-1); } @@ -181,7 +180,7 @@ void hexedit_main(void) // Display cursor and flush output highlight(x, y, ro ? 3 : side); - xflush(1); + xflush(); // Wait for next key key = scan_key(keybuf, -1); diff --git a/toys/other/losetup.c b/toys/other/losetup.c index 917e64ea..d77a9500 100644 --- a/toys/other/losetup.c +++ b/toys/other/losetup.c @@ -4,7 +4,7 @@ * * No standard. (Sigh.) -USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdcaD[!afj]", TOYFLAG_SBIN)) +USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdca[!afj]", TOYFLAG_SBIN)) config LOSETUP bool "losetup" @@ -18,18 +18,17 @@ config LOSETUP Instead of a device: -a Iterate through all loopback devices -f Find first unused loop device (may create one) - -j FILE Iterate through all loopback devices associated with FILE + -j Iterate through all loopback devices associated with FILE existing: -c Check capacity (file size changed) - -d DEV Detach loopback device - -D Detach all loopback devices + -d Detach loopback device new: -s Show device name (alias --show) - -o OFF Start association at offset OFF into FILE + -o Start association at OFFSET into FILE -r Read only - -S SIZE Limit SIZE of loopback association (alias --sizelimit) + -S Limit SIZE of loopback association (alias --sizelimit) */ #define FOR_losetup @@ -43,17 +42,16 @@ GLOBALS( int openflags; dev_t jdev; ino_t jino; - char *dir; ) // -f: *device is NULL // Perform requested operation on one device. Returns 1 if handled, 0 if error -static int loopback_setup(char *device, char *file) +static void loopback_setup(char *device, char *file) { struct loop_info64 *loop = (void *)(toybuf+32); int lfd = -1, ffd = ffd; - int racy = !device; + unsigned flags = toys.optflags; // Open file (ffd) and loop device (lfd) @@ -66,8 +64,10 @@ static int loopback_setup(char *device, char *file) // mount -o loop depends on found device being at the start of toybuf. if (cfd != -1) { - if (0 <= (i = ioctl(cfd, LOOP_CTL_GET_FREE))) { - sprintf(device = toybuf, "%s/loop%d", TT.dir, i); + if (0 <= (i = ioctl(cfd, 0x4C82))) { // LOOP_CTL_GET_FREE + sprintf(device = toybuf, "/dev/loop%d", i); + // Fallback for Android + if (access(toybuf, F_OK)) sprintf(toybuf, "/dev/block/loop%d", i); } close(cfd); } @@ -78,12 +78,7 @@ static int loopback_setup(char *device, char *file) // Stat the loop device to see if there's a current association. memset(loop, 0, sizeof(struct loop_info64)); if (-1 == lfd || ioctl(lfd, LOOP_GET_STATUS64, loop)) { - if (errno == ENXIO && (FLAG(a) || FLAG(j))) goto done; - // ENXIO expected if we're just trying to print the first unused device. - if (errno == ENXIO && FLAG(f) && !file) { - puts(device); - goto done; - } + if (errno == ENXIO && (flags & (FLAG_a|FLAG_j))) goto done; if (errno != ENXIO || !file) { perror_msg_raw(device ? device : "-f"); goto done; @@ -95,9 +90,9 @@ static int loopback_setup(char *device, char *file) goto done; // Check size of file or delete existing association - if (FLAG(c) || FLAG(d)) { + if (flags & (FLAG_c|FLAG_d)) { // The constant is LOOP_SET_CAPACITY - if (ioctl(lfd, FLAG(c) ? 0x4C07 : LOOP_CLR_FD, 0)) { + if (ioctl(lfd, (flags & FLAG_c) ? 0x4C07 : LOOP_CLR_FD, 0)) { perror_msg_raw(device); goto done; } @@ -106,19 +101,17 @@ static int loopback_setup(char *device, char *file) char *s = xabspath(file, 1); if (!s) perror_exit("file"); // already opened, but if deleted since... - if (ioctl(lfd, LOOP_SET_FD, ffd)) { - if (racy && errno == EBUSY) return 1; - perror_exit("%s=%s", device, file); - } + if (ioctl(lfd, LOOP_SET_FD, ffd)) perror_exit("%s=%s", device, file); loop->lo_offset = TT.o; loop->lo_sizelimit = TT.S; xstrncpy((char *)loop->lo_file_name, s, LO_NAME_SIZE); + s[LO_NAME_SIZE-1] = 0; if (ioctl(lfd, LOOP_SET_STATUS64, loop)) perror_exit("%s=%s", device, file); - if (FLAG(s)) puts(device); + if (flags & FLAG_s) printf("%s", device); free(s); - } + } else if (flags & FLAG_f) printf("%s", device); else { - xprintf("%s: [%lld]:%llu (%s)", device, (long long)loop->lo_device, + xprintf("%s: [%04llx]:%llu (%s)", device, (long long)loop->lo_device, (long long)loop->lo_inode, loop->lo_file_name); if (loop->lo_offset) xprintf(", offset %llu", (unsigned long long)loop->lo_offset); @@ -130,7 +123,6 @@ static int loopback_setup(char *device, char *file) done: if (file) close(ffd); if (lfd != -1) close(lfd); - return 0; } // Perform an action on all currently existing loop devices @@ -153,8 +145,7 @@ void losetup_main(void) { char **s; - TT.dir = CFG_TOYBOX_ON_ANDROID ? "/dev/block" : "/dev"; - TT.openflags = FLAG(r) ? O_RDONLY : O_RDWR; + TT.openflags = (toys.optflags & FLAG_r) ? O_RDONLY : O_RDWR; if (TT.j) { struct stat st; @@ -173,19 +164,17 @@ void losetup_main(void) // -f(dc FILE) - if (FLAG(D)) toys.optflags |= FLAG_a | FLAG_d; - - if (FLAG(f)) { + if (toys.optflags & FLAG_f) { if (toys.optc > 1) perror_exit("max 1 arg"); - while (loopback_setup(NULL, *toys.optargs)); - } else if (FLAG(a) || FLAG(j)) { + loopback_setup(NULL, *toys.optargs); + } else if (toys.optflags & (FLAG_a|FLAG_j)) { if (toys.optc) error_exit("bad args"); - dirtree_read(TT.dir, dash_a); + dirtree_read("/dev", dash_a); // Do we need one DEVICE argument? } else { - char *file = (FLAG(c) || FLAG(d)) ? NULL : toys.optargs[1]; + char *file = (toys.optflags & (FLAG_d|FLAG_c)) ? NULL : toys.optargs[1]; - if (!toys.optc || (file && toys.optc != 2)) + if (!toys.optc || (file && toys.optc != 2)) help_exit("needs %d arg%s", 1+!!file, file ? "s" : ""); for (s = toys.optargs; *s; s++) { loopback_setup(*s, file); diff --git a/toys/other/lsattr.c b/toys/other/lsattr.c index 5a102011..ec7d88e5 100644 --- a/toys/other/lsattr.c +++ b/toys/other/lsattr.c @@ -288,13 +288,15 @@ static int update_attr(struct dirtree *root) if (ext2_setflag(fd, &(root->st), fval) < 0) perror_msg("setting flags '%s'", fpath); } - // set file version - if (chattr.vflag && (ioctl(fd, FS_IOC_SETVERSION, &chattr.version)<0)) - perror_msg("while setting version on '%s'", fpath); + if (chattr.vflag) { // set file version + if (ioctl(fd, FS_IOC_SETVERSION, (void*)&chattr.version) < 0) + perror_msg("while setting version on '%s'", fpath); + } free(fpath); xclose(fd); - return (S_ISDIR(root->st.st_mode) && chattr.recursive) ? DIRTREE_RECURSE : 0; + if (S_ISDIR(root->st.st_mode) && chattr.recursive) return DIRTREE_RECURSE; + return 0; } void chattr_main(void) diff --git a/toys/other/makedevs.c b/toys/other/makedevs.c index a6998fcc..fa2b72d8 100644 --- a/toys/other/makedevs.c +++ b/toys/other/makedevs.c @@ -17,7 +17,7 @@ config MAKEDEVS -d File containing device table (default reads from stdin) - Each line of the device table has the fields: + Each line of of the device table has the fields: <name> <type> <mode> <uid> <gid> <major> <minor> <start> <increment> <count> Where name is the file name, and type is one of the following: @@ -36,7 +36,7 @@ config MAKEDEVS #include "toys.h" GLOBALS( - char *d; + char *fname; ) void makedevs_main() @@ -46,9 +46,9 @@ void makedevs_main() // Open file and chdir, verbosely xprintf("rootdir = %s\n", *toys.optargs); - if ((toys.optflags & FLAG_d) && strcmp(TT.d, "-")) { - fd = xopenro(TT.d); - xprintf("table = %s\n", TT.d); + if (toys.optflags & FLAG_d && strcmp(TT.fname, "-")) { + fd = xopenro(TT.fname); + xprintf("table = %s\n", TT.fname); } else xprintf("table = <stdin>\n"); xchdir(*toys.optargs); diff --git a/toys/other/modinfo.c b/toys/other/modinfo.c index 286570f1..eaf6cb98 100644 --- a/toys/other/modinfo.c +++ b/toys/other/modinfo.c @@ -10,14 +10,10 @@ config MODINFO bool "modinfo" default y help - usage: modinfo [-0] [-b basedir] [-k kernel] [-F field] [module|file...] + usage: modinfo [-0] [-b basedir] [-k kernrelease] [-F field] [modulename...] - Display module fields for modules specified by name or .ko path. - - -F Only show the given field - -0 Separate fields with NUL rather than newline - -b Use <basedir> as root for /lib/modules/ - -k Look in given directory under /lib/modules/ + Display module fields for all specified modules, looking in + <basedir>/lib/modules/<kernrelease>/ (kernrelease defaults to uname -r). */ #define FOR_modinfo @@ -27,7 +23,6 @@ GLOBALS( char *F, *k, *b; long mod; - int count; ) static void output_field(char *field, char *value) @@ -35,7 +30,7 @@ static void output_field(char *field, char *value) if (!TT.F) xprintf("%s:%*c", field, 15-(int)strlen(field), ' '); else if (strcmp(TT.F, field)) return; xprintf("%s", value); - xputc(FLAG(0) ? 0 : '\n'); + xputc((toys.optflags & FLAG_0) ? 0 : '\n'); } static void modinfo_file(char *full_name) @@ -58,7 +53,6 @@ static void modinfo_file(char *full_name) return; } - TT.count++; output_field("filename", full_name); for (pos = buf; pos < buf+len; pos++) { @@ -106,30 +100,19 @@ static int check_module(struct dirtree *new) void modinfo_main(void) { - struct utsname uts; - - // Android (as shipped by Google) currently only has modules on /vendor. - // Android does not support multiple sets of modules for different kernels. - if (CFG_TOYBOX_ON_ANDROID) { - if (!TT.b) TT.b = "/vendor"; - if (!TT.k) TT.k = ""; - } else { - uname(&uts); - if (!TT.b) TT.b = ""; - if (!TT.k) TT.k = uts.release; - } - - for (TT.mod = 0; TT.mod<toys.optc; TT.mod++) { + for(TT.mod = 0; TT.mod<toys.optc; TT.mod++) { char *s = strstr(toys.optargs[TT.mod], ".ko"); if (s && !s[3]) modinfo_file(toys.optargs[TT.mod]); else { - char *path = xmprintf("%s/lib/modules/%s", TT.b, TT.k); - - TT.count = 0; - dirtree_read(path, check_module); - if (!TT.count) error_msg("%s: not found", toys.optargs[TT.mod]); - free(path); + struct utsname uts; + + if (uname(&uts) < 0) perror_exit("bad uname"); + if (snprintf(toybuf, sizeof(toybuf), "%s/lib/modules/%s", + (toys.optflags & FLAG_b) ? TT.b : "", + (toys.optflags & FLAG_k) ? TT.k : uts.release) >= sizeof(toybuf)) + perror_exit("basedir/kernrelease too long"); + dirtree_read(toybuf, check_module); } } } diff --git a/toys/other/nbd_client.c b/toys/other/nbd_client.c index ad3440af..fcd0fca8 100644 --- a/toys/other/nbd_client.c +++ b/toys/other/nbd_client.c @@ -52,7 +52,7 @@ void nbd_client_main(void) // Find and connect to server - sock = xconnectany(xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0)); + sock = xconnect(xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0)); temp = 1; setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &temp, sizeof(int)); diff --git a/toys/other/printenv.c b/toys/other/printenv.c index 431bf1de..65f62edf 100644 --- a/toys/other/printenv.c +++ b/toys/other/printenv.c @@ -17,6 +17,8 @@ config PRINTENV #include "toys.h" +extern char **environ; + void printenv_main(void) { char **env, **var = toys.optargs; diff --git a/toys/other/readlink.c b/toys/other/readlink.c index 9ebf68d7..beef92b0 100644 --- a/toys/other/readlink.c +++ b/toys/other/readlink.c @@ -2,13 +2,13 @@ * * Copyright 2007 Rob Landley <rob@landley.net> -USE_READLINK(NEWTOY(readlink, "<1nqmef(canonicalize)[-mef]", TOYFLAG_USR|TOYFLAG_BIN)) +USE_READLINK(NEWTOY(readlink, "<1>1nqmef(canonicalize)[-mef]", TOYFLAG_USR|TOYFLAG_BIN)) config READLINK bool "readlink" default y help - usage: readlink FILE... + usage: readlink FILE With no options, show what symlink points to, return error if not symlink. @@ -26,18 +26,17 @@ config READLINK void readlink_main(void) { - char **arg, *s; - - for (arg = toys.optargs; *arg; arg++) { - // Calculating full canonical path? - // Take advantage of flag positions to calculate m = -1, f = 0, e = 1 - if (toys.optflags & (FLAG_f|FLAG_e|FLAG_m)) - s = xabspath(*arg, (toys.optflags&(FLAG_f|FLAG_e))-1); - else s = xreadlink(*arg); - - if (s) { - if (!FLAG(q)) xprintf(FLAG(n) ? "%s" : "%s\n", s); - if (CFG_TOYBOX_FREE) free(s); - } else toys.exitval = 1; - } + char *s; + + // Calculating full canonical path? + // Take advantage of flag positions to calculate m = -1, f = 0, e = 1 + if (toys.optflags & (FLAG_f|FLAG_e|FLAG_m)) + s = xabspath(*toys.optargs, (toys.optflags&(FLAG_f|FLAG_e))-1); + else s = xreadlink(*toys.optargs); + + if (s) { + if (!(toys.optflags & FLAG_q)) + xprintf((toys.optflags & FLAG_n) ? "%s" : "%s\n", s); + if (CFG_TOYBOX_FREE) free(s); + } else toys.exitval = 1; } diff --git a/toys/other/rev.c b/toys/other/rev.c index adfc90da..15066310 100644 --- a/toys/other/rev.c +++ b/toys/other/rev.c @@ -15,25 +15,27 @@ config REV #include "toys.h" -static void rev_line(char **pline, long len) +static void do_rev(int fd, char *name) { - char *line; - long i; + char *c; - if (!pline) return; - line = *pline; - if (len && line[len-1]=='\n') line[--len] = 0; + for (;;) { + unsigned len, i; - if (len--) for (i = 0; i <= len/2; i++) { - char tmp = line[i]; + if (!(c = get_line(fd))) break; + len = strlen(c); + if (len--) for (i = 0; i <= len/2; i++) { + char tmp = c[i]; - line[i] = line[len-i]; - line[len-i] = tmp; + c[i] = c[len-i]; + c[len-i] = tmp; + } + xputs(c); + free(c); } - xputs(line); } void rev_main(void) { - loopfiles_lines(toys.optargs, rev_line); + loopfiles(toys.optargs, do_rev); } diff --git a/toys/other/stat.c b/toys/other/stat.c index d99331b7..d828534c 100644 --- a/toys/other/stat.c +++ b/toys/other/stat.c @@ -20,15 +20,14 @@ config STAT The valid format escape sequences for files: %a Access bits (octal) |%A Access bits (flags)|%b Size/512 - %B Bytes per %b (512) |%C Security context |%d Device ID (dec) - %D Device ID (hex) |%f All mode bits (hex)|%F File type - %g Group ID |%G Group name |%h Hard links - %i Inode |%m Mount point |%n Filename - %N Long filename |%o I/O block size |%s Size (bytes) - %t Devtype major (hex) |%T Devtype minor (hex)|%u User ID - %U User name |%x Access time |%X Access unix time - %y Modification time |%Y Mod unix time |%z Creation time - %Z Creation unix time + %B Bytes per %b (512) |%d Device ID (dec) |%D Device ID (hex) + %f All mode bits (hex) |%F File type |%g Group ID + %G Group name |%h Hard links |%i Inode + %m Mount point |%n Filename |%N Long filename + %o I/O block size |%s Size (bytes) |%t Devtype major (hex) + %T Devtype minor (hex) |%u User ID |%U User name + %x Access time |%X Access unix time |%y Modification time + %Y Mod unix time |%z Creation time |%Z Creation unix time The valid format escape sequences for filesystems: %a Available blocks |%b Total blocks |%c Total inodes @@ -83,12 +82,7 @@ static void print_stat(char type) strout(str); } else if (type == 'b') out('u', stat->st_blocks); else if (type == 'B') out('d', 512); - else if (type == 'C') { - char *context = NULL; - - strout(lsm_get_context(TT.file, &context) != -1 ? context : "?"); - free(context); - } else if (type == 'd') out('d', stat->st_dev); + else if (type == 'd') out('d', stat->st_dev); else if (type == 'D') out('x', stat->st_dev); else if (type == 'f') out('x', stat->st_mode); else if (type == 'F') { @@ -114,10 +108,10 @@ static void print_stat(char type) } llist_traverse(mt, free); } else if (type == 'N') { - printf("%s", TT.file); + xprintf("%s", TT.file); if (S_ISLNK(stat->st_mode)) if (readlink0(TT.file, toybuf, sizeof(toybuf))) - printf(" -> `%s'", toybuf); + xprintf(" -> `%s'", toybuf); } else if (type == 'o') out('u', stat->st_blksize); else if (type == 's') out('u', stat->st_size); else if (type == 't') out('x', dev_major(stat->st_rdev)); @@ -130,7 +124,7 @@ static void print_stat(char type) else if (type == 'Y') out('u', stat->st_mtime); else if (type == 'z') date_stat_format(&stat->st_ctim); else if (type == 'Z') out('u', stat->st_ctime); - else putchar('?'); + else xprintf("?"); } static void print_statfs(char type) { @@ -141,15 +135,8 @@ static void print_statfs(char type) { else if (type == 'c') out('u', statfs->f_files); else if (type == 'd') out('u', statfs->f_ffree); else if (type == 'f') out('u', statfs->f_bfree); - else if (type == 'l') { -#ifdef __APPLE__ - // TODO: move this into portability.c somehow, or just use this everywhere? - // (glibc and bionic will just re-do the statfs and return f_namelen.) - out('d', pathconf(TT.file, _PC_NAME_MAX)); -#else - out('d', statfs->f_namelen); -#endif - } else if (type == 't') out('x', statfs->f_type); + else if (type == 'l') out('d', statfs->f_namelen); + else if (type == 't') out('x', statfs->f_type); else if (type == 'T') { char *s = "unknown"; struct {unsigned num; char *name;} nn[] = { @@ -168,10 +155,9 @@ static void print_statfs(char type) { if (nn[i].num == statfs->f_type) s = nn[i].name; strout(s); } else if (type == 'i') { - int *val = (int *) &statfs->f_fsid; char buf[32]; - sprintf(buf, "%08x%08x", val[0], val[1]); + sprintf(buf, "%08x%08x", statfs->f_fsid.__val[0], statfs->f_fsid.__val[1]); strout(buf); } else if (type == 's') out('d', statfs->f_frsize); else if (type == 'S') out('d', statfs->f_bsize); @@ -180,43 +166,40 @@ static void print_statfs(char type) { void stat_main(void) { - int flagf = FLAG(f), i; + int flagf = toys.optflags & FLAG_f, i; char *format, *f; - if (FLAG(t)) format = flagf - ? "%n %i %l %t %s %S %b %f %a %c %d" - : "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; - else format = flagf + if (toys.optflags&FLAG_t) { + format = flagf ? "%n %i %l %t %s %S %b %f %a %c %d" : + "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; + } else format = flagf ? " File: \"%n\"\n ID: %i Namelen: %l Type: %T\n" "Block Size: %s Fundamental block size: %S\n" "Blocks: Total: %b\tFree: %f\tAvailable: %a\n" "Inodes: Total: %c\tFree: %d" - : " File: %N\n Size: %s\t Blocks: %b\t IO Blocks: %B\t %F\n" - "Device: %Dh/%dd\t Inode: %i\t Links: %h\t Device type: %t,%T\n" - "Access: (%04a/%A)\tUid: (%5u/%8U)\tGid: (%5g/%8G)\n" + : " File: %N\n Size: %s\t Blocks: %b\t IO Blocks: %B\t%F\n" + "Device: %Dh/%dd\t Inode: %i\t Links: %h\n" + "Access: (0%a/%A)\tUid: (%5u/%8U)\tGid: (%5g/%8G)\n" "Access: %x\nModify: %y\nChange: %z"; - if (FLAG(c)) format = TT.c; + if (toys.optflags & FLAG_c) format = TT.c; - // loop through files listed on command line for (i = 0; toys.optargs[i]; i++) { + int L = toys.optflags & FLAG_L; - // stat the file or filesystem TT.file = toys.optargs[i]; if (flagf && !statfs(TT.file, (void *)&TT.stat)); - else if (flagf || (FLAG(L) ? stat : lstat)(TT.file, (void *)&TT.stat)) { + else if (flagf || (L ? stat : lstat)(TT.file, (void *)&TT.stat)) { perror_msg("'%s'", TT.file); continue; } - // parse format and print what it says for (f = format; *f; f++) { - if (*f != '%' || !f[1]) putchar(*f); - else if (f[1]=='%') putchar(*f++); + if (*f != '%') putchar(*f); else { f = next_printf(f, &TT.pattern); TT.patlen = f-TT.pattern; - if (!*f || TT.patlen>99) error_exit("bad %s", TT.pattern); + if (TT.patlen>99) error_exit("bad %s", TT.pattern); if (*f == 'n') strout(TT.file); else if (flagf) print_statfs(*f); else print_stat(*f); diff --git a/toys/other/tac.c b/toys/other/tac.c index 2a9e003d..d5f72fd2 100644 --- a/toys/other/tac.c +++ b/toys/other/tac.c @@ -13,28 +13,37 @@ config TAC Output lines in reverse order. */ -#define FOR_tac #include "toys.h" -GLOBALS( - struct double_list *dl; -) - -static void do_tac(char **pline, long len) +static void do_tac(int fd, char *name) { - if (pline) { - dlist_add(&TT.dl, *pline); - *pline = 0; - } else while (TT.dl) { - struct double_list *dl = dlist_lpop(&TT.dl); - - xprintf("%s", dl->data); - free(dl->data); - free(dl); + struct arg_list *list = NULL; + char *c; + + // Read in lines + for (;;) { + struct arg_list *temp; + long len; + + if (!(c = get_rawline(fd, &len, '\n'))) break; + + 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; + xprintf("%s", list->arg); + free(list->arg); + free(list); + list = temp; } } void tac_main(void) { - loopfiles_lines(toys.optargs, do_tac); + loopfiles(toys.optargs, do_tac); } diff --git a/toys/other/timeout.c b/toys/other/timeout.c index 55b3dca1..dc48f55b 100644 --- a/toys/other/timeout.c +++ b/toys/other/timeout.c @@ -42,8 +42,8 @@ static void handler(int i) if (FLAG(v)) fprintf(stderr, "timeout pid %d signal %d\n", TT.pid, TT.nextsig); - toys.exitval = (TT.nextsig==9) ? 137 : 124; kill(TT.pid, TT.nextsig); + if (TT.k) { TT.k = 0; TT.nextsig = SIGKILL; @@ -65,8 +65,9 @@ void xparsetimeval(char *s, struct timeval *tv) void timeout_main(void) { - // Use same ARGFAIL value for any remaining parsing errors toys.exitval = 125; + + // Parse early to get any errors out of the way. xparsetimeval(*toys.optargs, &TT.itv.it_value); if (TT.k) xparsetimeval(TT.k, &TT.ktv); @@ -76,7 +77,6 @@ void timeout_main(void) if (!FLAG(foreground)) setpgid(0, 0); - toys.exitval = 0; if (!(TT.pid = XVFORK())) xexec(toys.optargs+1); else { int status; @@ -84,7 +84,9 @@ void timeout_main(void) xsignal(SIGALRM, handler); setitimer(ITIMER_REAL, &TT.itv, (void *)toybuf); - status = xwaitpid(TT.pid); - if (FLAG(preserve_status) || !toys.exitval) toys.exitval = status; + while (-1 == waitpid(TT.pid, &status, 0) && errno == EINTR); + if (WIFEXITED(status)) toys.exitval = WEXITSTATUS(status); + else if (WTERMSIG(status)==SIGKILL) toys.exitval = 137; + else toys.exitval = FLAG(preserve_status) ? 128+WTERMSIG(status) : 124; } } |