aboutsummaryrefslogtreecommitdiff
path: root/toys/other
diff options
context:
space:
mode:
Diffstat (limited to 'toys/other')
-rw-r--r--toys/other/blkid.c76
-rw-r--r--toys/other/help.c4
-rw-r--r--toys/other/hexedit.c7
-rw-r--r--toys/other/losetup.c63
-rw-r--r--toys/other/lsattr.c10
-rw-r--r--toys/other/makedevs.c10
-rw-r--r--toys/other/modinfo.c43
-rw-r--r--toys/other/nbd_client.c2
-rw-r--r--toys/other/printenv.c2
-rw-r--r--toys/other/readlink.c31
-rw-r--r--toys/other/rev.c26
-rw-r--r--toys/other/stat.c73
-rw-r--r--toys/other/tac.c41
-rw-r--r--toys/other/timeout.c12
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;
}
}