md5_sha1_sum: fix mishandling when run as /bin/md5sum (with path) chown/chgrp: completely match coreutils 6.8 wrt symlink handling
No binary (build failed)
—
(log yok)
| @@ -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 |
| */ | |
| @@ -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) | |
| @@ -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); | |
| @@ -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; | |
| } | |