From d166f83d74240e49bcc56ece0b709d773c2e8f62 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Thu, 5 Jul 2007 00:12:55 +0000 Subject: md5_sha1_sum: fix mishandling when run as /bin/md5sum (with path) chown/chgrp: completely match coreutils 6.8 wrt symlink handling function old new delta recursive_action 411 422 +11 arith 2033 2042 +9 collect_blk 467 474 +7 dhcprelay_main 1122 1125 +3 fsck_main 1909 1911 +2 singlemount 4555 4547 -8 xmalloc_realpath 14 - -14 get_lcm 123 105 -18 ed_main 3111 3084 -27 chown_main 217 183 -34 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 5/4 up/down: 32/-101) Total: -69 bytes text data bss dec hex filename 684132 2744 14000 700876 ab1cc busybox_old 684060 2744 14000 700804 ab184 busybox_unstripped --- coreutils/chown.c | 60 +++++++++++++++++++++++++----------------------- coreutils/md5_sha1_sum.c | 2 +- include/libbb.h | 11 +++++---- libbb/recursive_action.c | 26 ++++++++++----------- 4 files changed, 51 insertions(+), 48 deletions(-) diff --git a/coreutils/chown.c b/coreutils/chown.c index 7579e1735..eb8d8c450 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -65,6 +65,7 @@ int chown_main(int argc, char **argv); int chown_main(int argc, char **argv) { int retval = EXIT_SUCCESS; + int flags; chown_fptr chown_func; opt_complementary = "-2"; @@ -80,23 +81,21 @@ int chown_main(int argc, char **argv) chown_func = lchown; } + flags = ACTION_DEPTHFIRST; /* match coreutils order */ + if (OPT_RECURSE) + flags |= ACTION_RECURSE; + if (OPT_TRAVERSE_TOP) + flags |= ACTION_FOLLOWLINKS_L0; /* -H/-L: follow links on depth 0 */ + if (OPT_TRAVERSE) + flags |= ACTION_FOLLOWLINKS; /* follow links if -L */ + parse_chown_usergroup_or_die(&ugid, argv[0]); /* Ok, ready to do the deed now */ argv++; do { - char *arg = *argv; - - if (OPT_TRAVERSE_TOP) { - /* resolves symlink (even recursive) */ - arg = xmalloc_realpath(arg); - if (!arg) - continue; - } - - if (!recursive_action(arg, - (OPT_RECURSE ? ACTION_RECURSE : 0) | /* recurse */ - (OPT_TRAVERSE ? ACTION_FOLLOWLINKS : 0),/* follow links if -L */ + if (!recursive_action(*argv, + flags, /* flags */ fileAction, /* file action */ fileAction, /* dir action */ chown_func, /* user data */ @@ -104,9 +103,6 @@ int chown_main(int argc, char **argv) ) { retval = EXIT_FAILURE; } - - if (OPT_TRAVERSE_TOP) - free(arg); } while (*++argv); return retval; @@ -137,8 +133,10 @@ create() { tst() { create test1 create test2 - (cd test1; $t1 $1) - (cd test2; $t2 $1) + echo "[$1]" >>test1.out + echo "[$1]" >>test2.out + (cd test1; $t1 $1) >>test1.out 2>&1 + (cd test2; $t2 $1) >>test2.out 2>&1 (cd test1; ls -lnR) >out1 (cd test2; ls -lnR) >out2 echo "chown $1" >out.diff @@ -152,18 +150,22 @@ tst_for_each() { tst "$1 1:1 linkfile" } echo "If script produced 'out.diff' file, then at least one testcase failed" +>test1.out +>test2.out # These match coreutils 6.8: -tst_for_each "" -tst_for_each "-R" -tst_for_each "-RP" -tst_for_each "-RL" -tst_for_each "-RH" -tst_for_each "-h" -tst_for_each "-hR" -tst_for_each "-hRP" -# Below: with "chown linkdir" coreutils 6.8 will chown linkdir _target_, -# we lchown _the link_. I believe we are "more correct". -#tst_for_each "-hRL" -#tst_for_each "-hRH" +tst_for_each "-v" +tst_for_each "-vR" +tst_for_each "-vRP" +tst_for_each "-vRL" +tst_for_each "-vRH" +tst_for_each "-vh" +tst_for_each "-vhR" +tst_for_each "-vhRP" +tst_for_each "-vhRL" +tst_for_each "-vhRH" +# Fix `name' in coreutils output +sed 's/`/'"'"'/g' -i test2.out +# Compare us with coreutils output +diff -u test1.out test2.out */ diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 4523fa4ec..8bc203486 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c @@ -84,7 +84,7 @@ int md5_sha1_sum_main(int argc, char **argv) uint8_t *hash_value; unsigned flags; hash_algo_t hash_algo = ENABLE_MD5SUM - ? (ENABLE_SHA1SUM ? (**argv=='m' ? HASH_MD5 : HASH_SHA1) : HASH_MD5) + ? (ENABLE_SHA1SUM ? (applet_name[0] == 'm' ? HASH_MD5 : HASH_SHA1) : HASH_MD5) : HASH_SHA1; if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) diff --git a/include/libbb.h b/include/libbb.h index a95de848b..bf6ae923d 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -214,15 +214,16 @@ extern int is_directory(const char *name, int followLinks, struct stat *statBuf) extern int remove_file(const char *path, int flags); extern int copy_file(const char *source, const char *dest, int flags); enum { - ACTION_RECURSE = (1 << 0), - ACTION_FOLLOWLINKS = (1 << 1), - ACTION_DEPTHFIRST = (1 << 2), - /*ACTION_REVERSE = (1 << 3), - unused */ + ACTION_RECURSE = (1 << 0), + ACTION_FOLLOWLINKS = (1 << 1), + ACTION_FOLLOWLINKS_L0 = (1 << 2), + ACTION_DEPTHFIRST = (1 << 3), + /*ACTION_REVERSE = (1 << 4), - unused */ }; extern int recursive_action(const char *fileName, unsigned flags, int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData, int depth), int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData, int depth), - void* userData, const unsigned depth); + void* userData, unsigned depth); extern int device_open(const char *device, int mode); extern int get_console_fd(void); extern char *find_block_device(const char *path); diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c index be2a700f5..cb3b88d1d 100644 --- a/libbb/recursive_action.c +++ b/libbb/recursive_action.c @@ -46,7 +46,7 @@ int recursive_action(const char *fileName, int (*fileAction)(const char *fileName, struct stat *statbuf, void* userData, int depth), int (*dirAction)(const char *fileName, struct stat *statbuf, void* userData, int depth), void* userData, - const unsigned depth) + unsigned depth) { struct stat statbuf; int status; @@ -55,12 +55,13 @@ int recursive_action(const char *fileName, if (!fileAction) fileAction = true_action; if (!dirAction) dirAction = true_action; - status = (flags & ACTION_FOLLOWLINKS ? stat : lstat)(fileName, &statbuf); + status = ACTION_FOLLOWLINKS; /* hijack a variable for bitmask... */ + if (!depth) status = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; + status = ((flags & status) ? stat : lstat)(fileName, &statbuf); if (status < 0) { #ifdef DEBUG_RECURS_ACTION - bb_error_msg("status=%d followLinks=%d TRUE=%d", - status, flags & ACTION_FOLLOWLINKS, TRUE); + bb_error_msg("status=%d flags=%x", status, flags); #endif goto done_nak_warn; } @@ -82,9 +83,8 @@ int recursive_action(const char *fileName, if (!(flags & ACTION_DEPTHFIRST)) { status = dirAction(fileName, &statbuf, userData, depth); - if (!status) { + if (!status) goto done_nak_warn; - } if (status == SKIP) return TRUE; } @@ -103,23 +103,23 @@ int recursive_action(const char *fileName, nextFile = concat_subpath_file(fileName, next->d_name); if (nextFile == NULL) continue; - /* now descend into it, forcing recursion. */ - if (!recursive_action(nextFile, flags | ACTION_RECURSE, - fileAction, dirAction, userData, depth+1)) { + /* now descend into it (NB: ACTION_RECURSE is set in flags) */ + if (!recursive_action(nextFile, flags, fileAction, dirAction, userData, depth+1)) status = FALSE; - } free(nextFile); } closedir(dir); - if ((flags & ACTION_DEPTHFIRST) && - !dirAction(fileName, &statbuf, userData, depth)) { + + if (flags & ACTION_DEPTHFIRST) { + if (!dirAction(fileName, &statbuf, userData, depth)) goto done_nak_warn; } if (!status) return FALSE; return TRUE; -done_nak_warn: + + done_nak_warn: bb_perror_msg("%s", fileName); return FALSE; } -- cgit v1.2.3