diff options
Diffstat (limited to 'toys')
53 files changed, 176 insertions, 351 deletions
diff --git a/toys/lsb/dmesg.c b/toys/lsb/dmesg.c index e54a9e11..8d73513b 100644 --- a/toys/lsb/dmesg.c +++ b/toys/lsb/dmesg.c @@ -21,16 +21,15 @@ config DMESG -c Clear the ring buffer after printing. */ +#define FOR_dmesg #include "toys.h" #include <sys/klog.h> -DEFINE_GLOBALS( +GLOBALS( long level; long size; ) -#define TT this.dmesg - void dmesg_main(void) { // For -n just tell kernel to which messages to keep. diff --git a/toys/lsb/hostname.c b/toys/lsb/hostname.c index bd319188..ca436833 100644 --- a/toys/lsb/hostname.c +++ b/toys/lsb/hostname.c @@ -17,6 +17,7 @@ config HOSTNAME Get/Set the current hostname */ +#define FOR_hostname #include "toys.h" void hostname_main(void) diff --git a/toys/lsb/killall.c b/toys/lsb/killall.c index 80f0253c..ec9df62e 100644 --- a/toys/lsb/killall.c +++ b/toys/lsb/killall.c @@ -20,15 +20,12 @@ config KILLALL -q don't print any warnings or error messages */ +#define FOR_killall #include "toys.h" -#define FLAG_q 1 -#define FLAG_l 2 - -DEFINE_GLOBALS( +GLOBALS( int signum; ) -#define TT this.killall static void kill_process(pid_t pid) { diff --git a/toys/lsb/mknod.c b/toys/lsb/mknod.c index fbdc8800..c1d78b10 100644 --- a/toys/lsb/mknod.c +++ b/toys/lsb/mknod.c @@ -20,6 +20,7 @@ config MKNOD p named pipe (ignores MAJOR/MINOR) */ +#define FOR_mknod #include "toys.h" void mknod_main(void) diff --git a/toys/lsb/mktemp.c b/toys/lsb/mktemp.c index c42588ab..1b2222c0 100644 --- a/toys/lsb/mktemp.c +++ b/toys/lsb/mktemp.c @@ -22,18 +22,13 @@ config MKTEMP -q Quiet */ +#define FOR_mktemp #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char * tmpdir; ) -#define FLAG_p 1 -#define FLAG_d 2 -#define FLAG_q 4 - -#define TT this.mktemp - void mktemp_main(void) { int d_flag = toys.optflags & FLAG_d; diff --git a/toys/lsb/passwd.c b/toys/lsb/passwd.c index 348c9c21..ef119c5d 100644 --- a/toys/lsb/passwd.c +++ b/toys/lsb/passwd.c @@ -24,21 +24,14 @@ config PASSWD */ +#define FOR_passwd #include "toys.h" #include <time.h> - -DEFINE_GLOBALS( +GLOBALS( char *algo; ) -#define TT this.passwd - -#define FLAG_u (1 << 0) -#define FLAG_l (1 << 1) -#define FLAG_d (1 << 2) -#define FLAG_a (1 << 3) - #define MAX_SALT_LEN 20 //3 for id, 16 for key, 1 for '\0' #define URANDOM_PATH "/dev/urandom" diff --git a/toys/other/catv.c b/toys/other/catv.c index 221549f3..a0790a9b 100644 --- a/toys/other/catv.c +++ b/toys/other/catv.c @@ -23,12 +23,9 @@ config CATV -v Don't use ^x or M-x escapes. */ +#define FOR_catv #include "toys.h" -#define FLAG_v 4 -#define FLAG_t 2 -#define FLAG_e 1 - // Callback function for loopfiles() static void do_catv(int fd, char *name) diff --git a/toys/other/dos2unix.c b/toys/other/dos2unix.c index 07e68055..15cc1706 100644 --- a/toys/other/dos2unix.c +++ b/toys/other/dos2unix.c @@ -17,14 +17,13 @@ config DOS2UNIX If no files listed copy from stdin, "-" is a synonym for stdin. */ +#define FOR_dos2unix #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *tempfile; ) -#define TT this.dos2unix - static void do_dos2unix(int fd, char *name) { char c = toys.which->name[0]; diff --git a/toys/other/free.c b/toys/other/free.c index b009b8b0..aa344928 100644 --- a/toys/other/free.c +++ b/toys/other/free.c @@ -18,6 +18,7 @@ config FREE -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, @@ -34,10 +35,10 @@ void free_main(void) sysinfo(&info); if (info.mem_unit) iscale = info.mem_unit; - if (toys.optflags & 1) oscale = 0; - if (toys.optflags & 2) oscale = 10; - if (toys.optflags & 4) oscale = 20; - if (toys.optflags & 8) oscale = 30; + 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", diff --git a/toys/other/hello.c b/toys/other/hello.c index cfab40df..2b469591 100644 --- a/toys/other/hello.c +++ b/toys/other/hello.c @@ -21,11 +21,12 @@ config HELLO occasionally nice to test kernel booting via "init=/bin/hello". */ +#define FOR_hello #include "toys.h" // Hello doesn't use these globals, they're here for example/skeleton purposes. -DEFINE_GLOBALS( +GLOBALS( char *b_string; long c_number; struct arg_list *d_list; @@ -34,14 +35,6 @@ DEFINE_GLOBALS( int more_globals; ) -#define TT this.hello - -#define FLAG_a 1 -#define FLAG_b 2 -#define FLAG_c 4 -#define FLAG_d 8 -#define FLAG_e 16 - void hello_main(void) { printf("Hello world\n"); diff --git a/toys/other/login.c b/toys/other/login.c index 8c542a7e..a9e7562c 100644 --- a/toys/other/login.c +++ b/toys/other/login.c @@ -21,6 +21,7 @@ config LOGIN -f Do not perform authentication */ +#define FOR_login #include "toys.h" #define LOGIN_TIMEOUT 60 @@ -28,10 +29,9 @@ config LOGIN #define USER_NAME_MAX_SIZE 32 #define HOSTNAME_SIZE 32 -DEFINE_GLOBALS( +GLOBALS( char *hostname; ) -#define TT this.login static void login_timeout_handler(int sig __attribute__((unused))) { @@ -162,9 +162,8 @@ void setup_environment(const struct passwd *pwd, int clear_env) void login_main(void) { - int f_flag = (toys.optflags & 4) >> 2; - int p_flag = (toys.optflags & 2) >> 1; - int h_flag = toys.optflags & 1; + 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; @@ -215,7 +214,7 @@ query_pass: f_flag = 0; syslog(LOG_WARNING, "invalid password for '%s' on %s %s %s", username, - ttyname(0), (h_flag)?"from":"", (h_flag)?TT.hostname:""); + ttyname(0), h_flag?"from":"", h_flag?TT.hostname:""); sleep(LOGIN_FAIL_TIMEOUT); puts("Login incorrect"); @@ -234,12 +233,12 @@ query_pass: if (change_identity(pwd)) error_exit("Failed to change identity"); - setup_environment(pwd, !p_flag); + setup_environment(pwd, !(toys.optflags & FLAG_p)); handle_motd(); syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name, - ttyname(0), (h_flag)?"from":"", (h_flag)?TT.hostname:""); + ttyname(0), h_flag?"from":"", h_flag?TT.hostname:""); spawn_shell(pwd->pw_shell); } diff --git a/toys/other/mke2fs.c b/toys/other/mke2fs.c index 837ea214..5745d519 100644 --- a/toys/other/mke2fs.c +++ b/toys/other/mke2fs.c @@ -73,9 +73,10 @@ config MKE2FS_EXTENDED sparse_super Don't allocate huge numbers of redundant superblocks */ +#define FOR_mke2fs #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( // Command line arguments. long blocksize; long bytes_per_inode; @@ -102,9 +103,6 @@ DEFINE_GLOBALS( struct ext2_superblock sb; ) -// Shortcut to our global data structure, since we use it so much. -#define TT this.mke2fs - #define INODES_RESERVED 10 static uint32_t div_round_up(uint32_t a, uint32_t b) diff --git a/toys/other/modinfo.c b/toys/other/modinfo.c index c878fc4e..0c5f177f 100644 --- a/toys/other/modinfo.c +++ b/toys/other/modinfo.c @@ -14,14 +14,12 @@ config MODINFO usage: modinfo [-0] [-F field] [modulename...] */ +#define FOR_modinfo #include "toys.h" -#define FLAG_0 (1 << 0) - -DEFINE_GLOBALS( +GLOBALS( char *field; ) -#define TT this.modinfo static const char *modinfo_tags[] = { "alias", "license", "description", "author", "vermagic", diff --git a/toys/other/mountpoint.c b/toys/other/mountpoint.c index 1bb0b3a7..fe63b725 100644 --- a/toys/other/mountpoint.c +++ b/toys/other/mountpoint.c @@ -17,19 +17,20 @@ config MOUNTPOINT -x Print major/minor device number of the block device */ +#define FOR_mountpoint #include "toys.h" void mountpoint_main(void) { struct stat st1, st2; int res = 0; - int quiet = toys.optflags & 0x4; + int quiet = toys.optflags & FLAG_q; toys.exitval = 1; // be pessimistic strncpy(toybuf, toys.optargs[0], sizeof(toybuf)); - if (((toys.optflags & 0x1) && lstat(toybuf, &st1)) || stat(toybuf, &st1)) + if (((toys.optflags & FLAG_x) && lstat(toybuf, &st1)) || stat(toybuf, &st1)) perror_exit("%s", toybuf); - if (toys.optflags & 0x1){ + 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; @@ -48,7 +49,7 @@ void mountpoint_main(void) 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 & 0x2) + 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 6442c09b..2e90737d 100644 --- a/toys/other/netcat.c +++ b/toys/other/netcat.c @@ -3,6 +3,9 @@ * 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)) @@ -40,10 +43,11 @@ config NETCAT_LISTEN netcat -s 127.0.0.1 -p 1234 -tL /bin/bash -l */ +#define FOR_netcat #include "toys.h" #include "toynet.h" -DEFINE_GLOBALS( +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. @@ -51,13 +55,6 @@ DEFINE_GLOBALS( long wait; // -w Wait # seconds for a connection. ) -#define TT this.netcat - -#define FLAG_f 1 -#define FLAG_L 32 -#define FLAG_l 64 -#define FLAG_t 128 - static void timeout(int signum) { if (TT.wait) error_exit("Timeout"); diff --git a/toys/other/oneit.c b/toys/other/oneit.c index ff7aa914..8bb482da 100644 --- a/toys/other/oneit.c +++ b/toys/other/oneit.c @@ -24,15 +24,14 @@ config ONEIT which point it reboots (or with -p, powers off) the system. */ +#define FOR_oneit #include "toys.h" #include <sys/reboot.h> -DEFINE_GLOBALS( +GLOBALS( char *console; ) -#define TT this.oneit - // The minimum amount of work necessary to get ctrl-c and such to work is: // // - Fork a child (PID 1 is special: can't exit, has various signals blocked). @@ -59,7 +58,8 @@ void oneit_main(void) // 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&1) ? RB_POWER_OFF : RB_AUTOBOOT); + if (!vfork()) + reboot((toys.optflags & FLAG_p) ? RB_POWER_OFF : RB_AUTOBOOT); sleep(5); _exit(1); } diff --git a/toys/other/rmmod.c b/toys/other/rmmod.c index cfc978ab..18ace3fa 100644 --- a/toys/other/rmmod.c +++ b/toys/other/rmmod.c @@ -18,6 +18,7 @@ config RMMOD */ +#define FOR_rmmod #include "toys.h" #include <sys/syscall.h> @@ -41,8 +42,8 @@ void rmmod_main(void) if (len > 3 && !strcmp(&mod_name[len-3], ".ko" )) mod_name[len-3] = 0; - if (toys.optflags & 1) flags |= O_TRUNC; - if (toys.optflags & 2) flags &= ~O_NONBLOCK; + 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/sha1sum.c b/toys/other/sha1sum.c index 3165effc..8833c8de 100644 --- a/toys/other/sha1sum.c +++ b/toys/other/sha1sum.c @@ -18,9 +18,10 @@ config SHA1SUM Calculate sha1 hash of files (or stdin). */ +#define FOR_sha1sum #include <toys.h> -DEFINE_GLOBALS( +GLOBALS( uint32_t state[5]; uint32_t oldstate[5]; uint64_t count; @@ -30,8 +31,6 @@ DEFINE_GLOBALS( } buffer; ) -#define TT this.sha1sum - #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) // blk0() and blk() perform the initial expand. diff --git a/toys/other/swapon.c b/toys/other/swapon.c index 4b9734e4..db7c45b0 100644 --- a/toys/other/swapon.c +++ b/toys/other/swapon.c @@ -15,19 +15,18 @@ config SWAPON Enable swapping on a given device/file. */ +#define FOR_swapon #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long priority; ) -#define TT this.swapon - void swapon_main(void) { int flags = 0; - if (toys.optflags & 1) + if (toys.optflags) flags = SWAP_FLAG_PREFER | (TT.priority << SWAP_FLAG_PRIO_SHIFT); if (swapon(*toys.optargs, flags)) diff --git a/toys/other/switch_root.c b/toys/other/switch_root.c index b4c0b7dd..6451ec15 100644 --- a/toys/other/switch_root.c +++ b/toys/other/switch_root.c @@ -17,20 +17,16 @@ config SWITCH_ROOT -h Hang instead of exiting on failure (avoids kernel panic) */ +#define FOR_switch_root #include "toys.h" #include <sys/vfs.h> -DEFINE_GLOBALS( +GLOBALS( char *console; dev_t rootdev; ) -#define TT this.switch_root - -#define FLAG_h (1<<0) -#define FLAG_c (1<<1) - static int del_node(struct dirtree *node) { if (node->st.st_dev == TT.rootdev && dirtree_notdotdot(node)) { diff --git a/toys/other/taskset.c b/toys/other/taskset.c index 9b219044..74cbfffa 100644 --- a/toys/other/taskset.c +++ b/toys/other/taskset.c @@ -22,11 +22,9 @@ config TASKSET -a Set/get the affinity of all threads of the PID. */ +#define FOR_taskset #include "toys.h" -#define FLAG_a 0x1 -#define FLAG_p 0x2 - // Prototype for syscall wrappers sched.h refuses to give us int sched_setaffinity(pid_t pid, size_t size, void *cpuset); int sched_getaffinity(pid_t pid, size_t size, void *cpuset); diff --git a/toys/other/truncate.c b/toys/other/truncate.c index aa952b16..47b07583 100644 --- a/toys/other/truncate.c +++ b/toys/other/truncate.c @@ -17,14 +17,13 @@ config TRUNCATE -s New size */ +#define FOR_truncate #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long size; ) -#define TT this.truncate - static void do_truncate(int fd, char *name) { if (fd<0) return; diff --git a/toys/other/vmstat.c b/toys/other/vmstat.c index b4858227..1c348f2a 100644 --- a/toys/other/vmstat.c +++ b/toys/other/vmstat.c @@ -122,7 +122,7 @@ void vmstat_main(void) 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 & 0x1; + int no_header = toys.optflags; unsigned num_rows = 22; if (toys.optc >= 1) diff --git a/toys/posix/chgrp.c b/toys/posix/chgrp.c index 892e78d7..48ce6751 100644 --- a/toys/posix/chgrp.c +++ b/toys/posix/chgrp.c @@ -30,25 +30,16 @@ config CHGRP -v verbose output. */ +#define FOR_chgrp #include "toys.h" -#define FLAG_v 1 -#define FLAG_f 2 -#define FLAG_R 4 -#define FLAG_H 8 -#define FLAG_L 16 -#define FLAG_P 32 -#define FLAG_h 64 - -DEFINE_GLOBALS( +GLOBALS( uid_t owner; gid_t group; char *owner_name, *group_name; int symfollow; ) -#define TT this.chgrp - static int do_chgrp(struct dirtree *node) { int fd, ret, flags = toys.optflags; diff --git a/toys/posix/chmod.c b/toys/posix/chmod.c index 2a32db10..dcef9751 100644 --- a/toys/posix/chmod.c +++ b/toys/posix/chmod.c @@ -34,17 +34,13 @@ config CHMOD chmod 744 file - user can read/write/execute, everyone else read only */ +#define FOR_chmod #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *mode; ) -#define TT this.chmod - -#define FLAG_R 1 -#define FLAG_v 2 - int do_chmod(struct dirtree *try) { mode_t mode; diff --git a/toys/posix/cksum.c b/toys/posix/cksum.c index f0aedfd0..3e27b4cb 100644 --- a/toys/posix/cksum.c +++ b/toys/posix/cksum.c @@ -23,14 +23,13 @@ config CKSUM -N Do not include length in CRC calculation */ +#define FOR_cksum #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( unsigned crc_table[256]; ) -#define TT this.cksum - static unsigned cksum_be(unsigned crc, unsigned char c) { return (crc<<8)^TT.crc_table[(crc>>24)^c]; diff --git a/toys/posix/cmp.c b/toys/posix/cmp.c index c41f98b8..4bbd3f30 100644 --- a/toys/posix/cmp.c +++ b/toys/posix/cmp.c @@ -20,18 +20,14 @@ config CMP -s silent */ +#define FOR_cmp #include "toys.h" -#define FLAG_s 1 -#define FLAG_l 2 - -DEFINE_GLOBALS( +GLOBALS( int fd; char *name; ) -#define TT this.cmp - // This handles opening the file and void do_cmp(int fd, char *name) diff --git a/toys/posix/comm.c b/toys/posix/comm.c index 761a62b2..477d5160 100644 --- a/toys/posix/comm.c +++ b/toys/posix/comm.c @@ -24,12 +24,9 @@ config COMM -3 suppress the output column of lines duplicated in FILE1 and FILE2 */ +#define FOR_comm #include "toys.h" -#define FLAG_1 1 -#define FLAG_2 2 -#define FLAG_3 4 - static void writeline(const char *line, int col) { if (col == 0 && toys.optflags & FLAG_1) return; diff --git a/toys/posix/cp.c b/toys/posix/cp.c index 232d8fab..b7834e86 100644 --- a/toys/posix/cp.c +++ b/toys/posix/cp.c @@ -6,53 +6,53 @@ * * See http://opengroup.org/onlinepubs/9699919799/utilities/cp.html * - * "R+ra+d+p+r" -USE_CP(NEWTOY(cp, "<2vslrRdpaHLPif", TOYFLAG_BIN)) + * TODO: "R+ra+d+p+r" sHLPR + +USE_CP(NEWTOY(cp, "<2"USE_CP_MORE("rdavsl")"RHLPfip", TOYFLAG_BIN)) config CP bool "cp (broken by dirtree changes)" default n help - usage: cp -fiprdal SOURCE... DEST + usage: cp [-fipRHLP] SOURCE... DEST - Copy files from SOURCE to DEST. If more than one SOURCE, DEST must - be a directory. + Copy files from SOURCE to DEST. If more than one SOURCE, DEST must + be a directory. -f force copy by deleting destination file -i interactive, prompt before overwriting existing DEST -p preserve timestamps, ownership, and permissions - -r recurse into subdirectories (DEST must be a directory) + -R recurse into subdirectories (DEST must be a directory) + -H Follow symlinks listed on command line + -L Follow all symlinks + -P Do not follow symlinks [default] + +config CP_MORE + bool "cp -rdavsl options" + default y + depends on CP + help + usage: cp [-rdavsl] + + -r synonym for -R -d don't dereference symlinks -a same as -dpr - -l hard link instead of copying + -l hard link instead of copy + -s symlink instead of copy -v verbose */ +#define FOR_cp #include "toys.h" -#define FLAG_f 1 -#define FLAG_i 2 -#define FLAG_P 4 // todo -#define FLAG_L 8 // todo -#define FLAG_H 16 // todo -#define FLAG_a 32 -#define FLAG_p 64 -#define FLAG_d 128 // todo -#define FLAG_R 256 -#define FLAG_r 512 -#define FLAG_l 1024 // todo -#define FLAG_s 2048 // todo -#define FLAG_v 4098 - -DEFINE_GLOBALS( +// TODO: PLHlsd + +GLOBALS( char *destname; int destisdir; - int destisnew; int keep_symlinks; ) -#define TT this.cp - // Copy an individual file or directory to target. void cp_file(char *src, char *dst, struct stat *srcst) @@ -156,42 +156,36 @@ int cp_node(struct dirtree *node) void cp_main(void) { - struct stat st; + char *dpath = NULL; + struct stat st, std; int i; - // Grab target argument. (Guaranteed to be there due to "<2" above.) - - TT.destname = toys.optargs[--toys.optc]; + // Identify destination - // If destination doesn't exist, are we ok with that? + if (!stat(TT.destname, &std) && S_ISDIR(std.st_mode)) TT.destisdir++; + else if (toys.optc>1) error_exit("'%s' not directory", TT.destname); - if (stat(TT.destname, &st)) { - if (toys.optc>1) goto error_notdir; - TT.destisnew++; + // TODO: This is too early: we haven't created it yet if we need to + if (toys.optflags & (FLAG_R|FLAG_r|FLAG_a)) + dpath = realpath(TT.destname = toys.optargs[--toys.optc], NULL); - // If destination exists... - - } else { - if (S_ISDIR(st.st_mode)) TT.destisdir++; - else if (toys.optc > 1) goto error_notdir; - } - - // Handle sources + // Loop through sources for (i=0; i<toys.optc; i++) { - char *src = toys.optargs[i]; - char *dst; + char *dst, *src = toys.optargs[i]; // Skip src==dest (TODO check inodes to catch "cp blah ./blah"). - if (!strcmp(src, TT.destname)) continue; + if (!strncmp(src, TT.destname)) continue; // Skip nonexistent sources. TT.keep_symlinks = toys.optflags & (FLAG_d|FLAG_a); - if (TT.keep_symlinks ? lstat(src, &st) : stat(src, &st)) + if (TT.keep_symlinks ? lstat(src, &st) : stat(src, &st) + || (st.st_dev = dst.st_dev && st.st_ino == dst.dst_ino)) { - perror_msg("'%s'", src); +objection: + perror_msg("bad '%s'", src); toys.exitval = 1; continue; } @@ -199,26 +193,35 @@ void cp_main(void) // Copy directory or file. if (TT.destisdir) { + char *s; + + // Catch "cp -R .. ." and friends that would go on forever + if (dpath && (s = realpath(src, NULL)) { + int i = strlen(s); + i = (!strncmp(s, dst, i) && (!s[i] || s[i]=='/')); + free(s); + + if (i) goto objection; + } + + // Create destination filename within directory dst = strrchr(src, '/'); if (dst) dst++; else dst=src; dst = xmsprintf("%s/%s", TT.destname, dst); } else dst = TT.destname; + if (S_ISDIR(st.st_mode)) { if (toys.optflags & (FLAG_r|FLAG_R|FLAG_a)) { cp_file(src, dst, &st); TT.keep_symlinks++; - strncpy(toybuf, src, sizeof(toybuf)-1); - toybuf[sizeof(toybuf)-1]=0; - dirtree_read(toybuf, cp_node); + dirtree_read(src, cp_node); } else error_msg("Skipped dir '%s'", src); } else cp_file(src, dst, &st); if (TT.destisdir) free(dst); } + if (CFG_TOYBOX_FREE) free(dpath); return; - -error_notdir: - error_exit("'%s' isn't a directory", TT.destname); } diff --git a/toys/posix/date.c b/toys/posix/date.c index 07d8c1d6..9beaaa1a 100644 --- a/toys/posix/date.c +++ b/toys/posix/date.c @@ -17,17 +17,13 @@ config DATE Set/get the current date/time */ +#define FOR_date #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *file; ) -#define TT this.date - -#define FLAG_u 1 -#define FLAG_r 2 - void date_main(void) { const char *format_string = "%a %b %e %H:%M:%S %Z %Y"; diff --git a/toys/posix/df.c b/toys/posix/df.c index e889907d..dc87fda3 100644 --- a/toys/posix/df.c +++ b/toys/posix/df.c @@ -37,16 +37,15 @@ config DF_PEDANTIC -k Sets units back to 1024 bytes (the default without -P) */ +#define FOR_df #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( struct arg_list *fstype; long units; ) -#define TT this.df - static void show_mt(struct mtab_list *mt) { int len; @@ -67,7 +66,7 @@ static void show_mt(struct mtab_list *mt) } // If we don't have -a, skip synthetic filesystems - if (!(toys.optflags & 1) && !mt->statvfs.f_blocks) return; + if (!(toys.optflags & FLAG_a) && !mt->statvfs.f_blocks) return; // Figure out how much total/used/free space this filesystem has, // forcing 64-bit math because filesystems are big now. @@ -83,7 +82,7 @@ static void show_mt(struct mtab_list *mt) // Figure out appropriate spacing len = 25 - strlen(mt->device); if (len < 1) len = 1; - if (CFG_DF_PEDANTIC && (toys.optflags & 8)) { + if (CFG_DF_PEDANTIC && (toys.optflags & FLAG_P)) { printf("%s %ld %ld %ld %ld%% %s\n", mt->device, size, used, avail, percent, mt->dir); } else { @@ -98,9 +97,9 @@ void df_main(void) // Handle -P and -k TT.units = 1024; - if (CFG_DF_PEDANTIC && (toys.optflags & 8)) { + if (CFG_DF_PEDANTIC && (toys.optflags & FLAG_P)) { // Units are 512 bytes if you select "pedantic" without "kilobytes". - if ((toys.optflags&3) == 1) TT.units = 512; + if ((toys.optflags&(FLAG_P|FLAG_k)) == FLAG_P) TT.units = 512; printf("Filesystem %ld-blocks Used Available Capacity Mounted on\n", TT.units); } else puts("Filesystem\t1K-blocks\tUsed Available Use% Mounted on"); diff --git a/toys/posix/du.c b/toys/posix/du.c index 83aa88ec..8013810c 100644 --- a/toys/posix/du.c +++ b/toys/posix/du.c @@ -28,9 +28,10 @@ config DU -m Sizes in megabytes */ +#define FOR_du #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long maxdepth; long depth; long *dirsum; @@ -39,20 +40,6 @@ DEFINE_GLOBALS( struct arg_list *inodes; ) -#define TT this.du - -#define FLAG_x 1 -#define FLAG_s 2 -#define FLAG_L 4 -#define FLAG_k 8 -#define FLAG_H 16 -#define FLAG_a 32 -#define FLAG_c 64 -#define FLAG_l 128 -#define FLAG_m 256 -#define FLAG_h 512 -#define FLAG_d 1024 - typedef struct node_size { struct dirtree *node; long size; diff --git a/toys/posix/echo.c b/toys/posix/echo.c index 576cad70..1bf4d399 100644 --- a/toys/posix/echo.c +++ b/toys/posix/echo.c @@ -32,12 +32,9 @@ config ECHO \xHH hexadecimal values (1 to 2 digits) */ -#define THIS echo +#define FOR_echo #include "toys.h" -#define FLAG_e (1<<1) -#define FLAG_n (1<<0) - void echo_main(void) { int i = 0, out; diff --git a/toys/posix/env.c b/toys/posix/env.c index 4427d01e..32272799 100644 --- a/toys/posix/env.c +++ b/toys/posix/env.c @@ -29,7 +29,7 @@ void env_main(void) char **command = NULL; char *del = "="; - if (toys.optflags & 1) clearenv(); + if (toys.optflags) clearenv(); for (ev = toys.optargs; *ev != NULL; ev++) { char *env, *val = NULL; diff --git a/toys/posix/head.c b/toys/posix/head.c index a7271cd5..77978f74 100644 --- a/toys/posix/head.c +++ b/toys/posix/head.c @@ -20,15 +20,14 @@ config HEAD -n Number of lines to copy. */ +#define FOR_head #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long lines; int file_no; ) -#define TT this.head - static void do_head(int fd, char *name) { int i, len, lines=TT.lines, size=sizeof(toybuf); diff --git a/toys/posix/id.c b/toys/posix/id.c index d93bc2bc..523d4f3a 100644 --- a/toys/posix/id.c +++ b/toys/posix/id.c @@ -25,14 +25,9 @@ config ID -u Show only the effective user ID */ +#define FOR_id #include "toys.h" -#define FLAG_n (1<<4) -#define FLAG_G (1<<3) -#define FLAG_g (1<<2) -#define FLAG_r (1<<1) -#define FLAG_u 1 - static void s_or_u(char *s, unsigned u, int done) { if (toys.optflags & FLAG_n) printf("%s", s); diff --git a/toys/posix/kill.c b/toys/posix/kill.c index e64a146b..7810b899 100644 --- a/toys/posix/kill.c +++ b/toys/posix/kill.c @@ -18,14 +18,13 @@ config KILL */ +#define FOR_kill #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *signame; ) -#define TT this.kill - void kill_main(void) { int signum; @@ -33,7 +32,7 @@ void kill_main(void) pid_t pid; // list signal(s) - if (toys.optflags & 1) { + if (toys.optflags & FLAG_l) { if (*args) { int signum = sig_to_num(*args); char *s = NULL; diff --git a/toys/posix/ln.c b/toys/posix/ln.c index ec3317d2..a83df7f6 100644 --- a/toys/posix/ln.c +++ b/toys/posix/ln.c @@ -22,12 +22,9 @@ config LN -n Symlink at destination treated as file */ +#define FOR_ln #include "toys.h" -#define FLAG_s 1 -#define FLAG_f 2 -#define FLAG_n 4 - void ln_main(void) { char *dest = toys.optargs[--toys.optc], *new; diff --git a/toys/posix/ls.c b/toys/posix/ls.c index a68533ff..6492fb9e 100644 --- a/toys/posix/ls.c +++ b/toys/posix/ls.c @@ -50,40 +50,14 @@ config LS -S size */ +#define FOR_ls #include "toys.h" -#define FLAG_1 (1<<0) -#define FLAG_x (1<<1) -#define FLAG_u (1<<2) -#define FLAG_t (1<<3) -#define FLAG_s (1<<4) -#define FLAG_r (1<<5) -#define FLAG_q (1<<6) -#define FLAG_p (1<<7) -#define FLAG_n (1<<8) -#define FLAG_m (1<<9) -#define FLAG_l (1<<10) -#define FLAG_k (1<<11) -#define FLAG_i (1<<12) -#define FLAG_f (1<<13) -#define FLAG_d (1<<14) -#define FLAG_c (1<<15) -#define FLAG_a (1<<16) -#define FLAG_S (1<<17) -#define FLAG_R (1<<18) -#define FLAG_L (1<<19) -#define FLAG_H (1<<20) -#define FLAG_F (1<<21) -#define FLAG_C (1<<22) -#define FLAG_A (1<<23) -#define FLAG_o (1<<24) -#define FLAG_g (1<<25) - // test sst output (suid/sticky in ls flaglist) // ls -lR starts .: then ./subdir: -DEFINE_GLOBALS( +GLOBALS( struct dirtree *files; unsigned screen_width; @@ -93,8 +67,6 @@ DEFINE_GLOBALS( char uid_buf[12]; ) -#define TT this.ls - void dlist_to_dirtree(struct dirtree *parent) { // Turn double_list into dirtree diff --git a/toys/posix/mkdir.c b/toys/posix/mkdir.c index c3bbb636..e4e591d7 100644 --- a/toys/posix/mkdir.c +++ b/toys/posix/mkdir.c @@ -20,14 +20,13 @@ config MKDIR -p make parent directories as needed. */ +#define FOR_mkdir #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long mode; ) -#define TT this.mkdir - static int do_mkdir(char *dir) { struct stat buf; diff --git a/toys/posix/mkfifo.c b/toys/posix/mkfifo.c index e5c15389..44775788 100644 --- a/toys/posix/mkfifo.c +++ b/toys/posix/mkfifo.c @@ -19,16 +19,14 @@ config MKFIFO Create FIFOs (named pipes). */ +#define FOR_mkfifo #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *m_string; mode_t mode; ) -#define TT this.mkfifo -#define FLAG_m (1) - void mkfifo_main(void) { char **s; diff --git a/toys/posix/nice.c b/toys/posix/nice.c index 4f522aa7..d45429f8 100644 --- a/toys/posix/nice.c +++ b/toys/posix/nice.c @@ -22,14 +22,13 @@ config NICE priority. Only root can set a negative niceness level. */ +#define FOR_nice #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long priority; ) -#define TT this.nice - void nice_main(void) { if (!toys.optflags) TT.priority = 10; diff --git a/toys/posix/od.c b/toys/posix/od.c index 3c84cb51..ef420b87 100644 --- a/toys/posix/od.c +++ b/toys/posix/od.c @@ -19,20 +19,10 @@ config OD -t output type(s) a (ascii) c (char) d (decimal) foux */ +#define FOR_od #include "toys.h" -#define FLAG_t (1 << 0) -#define FLAG_A (1 << 1) -#define FLAG_b (1 << 2) -#define FLAG_c (1 << 3) -#define FLAG_d (1 << 4) -#define FLAG_o (1 << 5) -#define FLAG_s (1 << 6) -#define FLAG_x (1 << 7) -#define FLAG_N (1 << 8) -#define FLAG_v (1 << 9) - -DEFINE_GLOBALS( +GLOBALS( struct arg_list *output_base; char *address_base; long max_count; @@ -44,8 +34,6 @@ DEFINE_GLOBALS( off_t pos; ) -#define TT this.od - static char *ascii = "nulsohstxetxeotenqackbel bs ht nl vt ff cr so si" "dledc1dc2dc3dc4naksynetbcan emsubesc fs gs rs us sp"; diff --git a/toys/posix/patch.c b/toys/posix/patch.c index a19cc8d3..fae908db 100644 --- a/toys/posix/patch.c +++ b/toys/posix/patch.c @@ -45,9 +45,10 @@ config PATCH created/deleted as appropriate. */ +#define FOR_patch #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *infile; long prefix; @@ -58,14 +59,6 @@ DEFINE_GLOBALS( char *tempname; ) -#define TT this.patch - -#define FLAG_R (1<<0) -#define FLAG_i (1<<1) -#define FLAG_l (1<<2) -#define FLAG_p (1<<3) -#define FLAG_u (1<<4) - // Dispose of a line of input, either by writing it out or discarding it. // state < 2: just free diff --git a/toys/posix/sed.c b/toys/posix/sed.c index 4097585e..a3ba9e38 100644 --- a/toys/posix/sed.c +++ b/toys/posix/sed.c @@ -18,15 +18,14 @@ config SED of input. */ +#define FOR_sed #include "toys.h" #include "lib/xregcomp.h" -DEFINE_GLOBALS( +GLOBALS( struct arg_list *commands; ) -#define TT this.sed - struct sed_command { // Doubly linked list of commands. struct sed_command *next, *prev; diff --git a/toys/posix/sh.c b/toys/posix/sh.c index f0bcdc38..44c39119 100644 --- a/toys/posix/sh.c +++ b/toys/posix/sh.c @@ -176,14 +176,13 @@ config CD_P -L Cancel previous -P and restore default behavior. */ +#define FOR_sh #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *command; ) -#define TT this.sh - // A single executable, its arguments, and other information we know about it. #define SH_FLAG_EXIT 1 #define SH_FLAG_SUSPEND 2 diff --git a/toys/posix/sort.c b/toys/posix/sort.c index 27aeb777..8f26f5d3 100644 --- a/toys/posix/sort.c +++ b/toys/posix/sort.c @@ -60,9 +60,10 @@ config SORT_FLOAT */ +#define FOR_sort #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( char *key_separator; struct arg_list *raw_keys; char *outfile; @@ -73,30 +74,11 @@ DEFINE_GLOBALS( char **lines; ) -#define TT this.sort - // The sort types are n, g, and M. // u, c, s, and z apply to top level only, not to keys. // b at top level implies bb. // The remaining options can be applied to search keys. -#define FLAG_n (1<<0) // Sort type: numeric -#define FLAG_u (1<<1) // Unique -#define FLAG_r (1<<2) // Reverse output order - -#define FLAG_i (1<<3) // Ignore !isprint() -#define FLAG_f (1<<4) // Force uppercase -#define FLAG_d (1<<5) // Ignore !(isalnum()|isspace()) -#define FLAG_z (1<<6) // Input is null terminated, not \n -#define FLAG_s (1<<7) // Stable sort, no ascii fallback at end -#define FLAG_c (1<<8) // Check only. No output, exit(!ordered) -#define FLAG_M (1<<9) // Sort type: date -#define FLAG_b (1<<10) // Ignore leading blanks -#define FLAG_x (1<<11) // Hex sort -#define FLAG_g (1<<18) // Sort type: strtod() - -// Left off dealing with FLAG_b/FLAG_bb logic... - #define FLAG_bb (1<<31) // Ignore trailing blanks struct sort_key diff --git a/toys/posix/tail.c b/toys/posix/tail.c index 83a47674..d0711c0c 100644 --- a/toys/posix/tail.c +++ b/toys/posix/tail.c @@ -29,21 +29,16 @@ config TAIL_SEEK This version uses lseek, which is faster on large files. */ +#define FOR_tail #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long lines; long bytes; int file_no; ) -#define TT this.tail - -#define FLAG_n 1 -#define FLAG_c 2 -#define FLAG_f 4 - struct line_list { struct line_list *next, *prev; char *data; diff --git a/toys/posix/tee.c b/toys/posix/tee.c index 15a40fe7..e6342f4c 100644 --- a/toys/posix/tee.c +++ b/toys/posix/tee.c @@ -21,14 +21,13 @@ config TEE -i ignore SIGINT. */ +#define FOR_tee #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( void *outputs; ) -#define TT this.tee - struct fd_list { struct fd_list *next; int fd; @@ -48,12 +47,12 @@ static void do_tee_open(int fd, char *name) void tee_main(void) { - if (toys.optflags&2) signal(SIGINT, SIG_IGN); + if (toys.optflags & FLAG_i) signal(SIGINT, SIG_IGN); // Open output files loopfiles_rw(toys.optargs, - O_RDWR|O_CREAT|((toys.optflags&1)?O_APPEND:O_TRUNC), 0666, 0, - do_tee_open); + O_RDWR|O_CREAT|((toys.optflags & FLAG_a)?O_APPEND:O_TRUNC), + 0666, 0, do_tee_open); for (;;) { struct fd_list *fdl; diff --git a/toys/posix/uname.c b/toys/posix/uname.c index c1f2b490..3c774b3c 100644 --- a/toys/posix/uname.c +++ b/toys/posix/uname.c @@ -24,6 +24,7 @@ config UNAME -a All of the above */ +#define FOR_uname #include "toys.h" // If a 32 bit x86 build environment working in a chroot under an x86-64 @@ -39,15 +40,13 @@ config UNAME #define GROSS "i386" #endif -#define FLAG_a (1<<5) - void uname_main(void) { int i, flags = toys.optflags, needspace=0; uname((void *)toybuf); - if (!flags) flags=1; + if (!flags) flags = FLAG_s; for (i=0; i<5; i++) { char *c = toybuf+(65*i); diff --git a/toys/posix/uniq.c b/toys/posix/uniq.c index 1418904a..f42b7293 100644 --- a/toys/posix/uniq.c +++ b/toys/posix/uniq.c @@ -26,23 +26,16 @@ config UNIQ -s ignore first X chars */ +#define FOR_uniq #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long maxchars; long nchars; long nfields; long repeats; ) -#define TT this.uniq - -#define FLAG_z 16 -#define FLAG_i 8 -#define FLAG_c 4 -#define FLAG_d 2 -#define FLAG_u 1 - static char *skip(char *str) { long nchars = TT.nchars, nfields; diff --git a/toys/posix/wc.c b/toys/posix/wc.c index 9d11577c..7a5e5a30 100644 --- a/toys/posix/wc.c +++ b/toys/posix/wc.c @@ -24,14 +24,13 @@ config WC argument (or from stdin if none). */ +#define FOR_wc #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( unsigned long totals[3]; ) -#define TT this.wc - static void show_lengths(unsigned long *lengths, char *name) { int i, nospace = 1; diff --git a/toys/posix/xargs.c b/toys/posix/xargs.c index 0d513253..8f19d07f 100644 --- a/toys/posix/xargs.c +++ b/toys/posix/xargs.c @@ -29,9 +29,10 @@ config XARGS -E stop at line matching string */ +#define FOR_xargs #include "toys.h" -DEFINE_GLOBALS( +GLOBALS( long max_bytes; long max_entries; long L; @@ -42,8 +43,6 @@ DEFINE_GLOBALS( char delim; ) -#define TT this.xargs - // If out==NULL count TT.bytes and TT.entries, stopping at max. // Otherwise, fill out out[] @@ -105,7 +104,7 @@ void xargs_main(void) int entries, bytes, done = 0, status; char *data = NULL; - if (!(toys.optflags&1)) TT.delim = '\n'; + if (!(toys.optflags & FLAG_0)) TT.delim = '\n'; // If no optargs, call echo. if (!toys.optc) { |