Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/coreutils/chown.c

    r821 r1765  
    88 */
    99
    10 /* BB_AUDIT SUSv3 defects - unsupported options -h, -H, -L, and -P. */
    11 /* BB_AUDIT GNU defects - unsupported options -h, -c, -f, -v, and long options. */
    12 /* BB_AUDIT Note: gnu chown does not support -H, -L, or -P. */
     10/* BB_AUDIT SUSv3 defects - none? */
     11/* BB_AUDIT GNU defects - unsupported long options. */
    1312/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */
    1413
    15 #include <stdlib.h>
    16 #include <unistd.h>
    17 #include <string.h>
    18 #include "busybox.h"
     14#include "libbb.h"
    1915
    20 static uid_t uid = -1;
    21 static gid_t gid = -1;
     16/* This is a NOEXEC applet. Be very careful! */
    2217
    23 static int (*chown_func)(const char *, uid_t, gid_t) = chown;
     18
     19#define OPT_STR     ("Rh" USE_DESKTOP("vcfLHP"))
     20#define BIT_RECURSE 1
     21#define OPT_RECURSE (option_mask32 & 1)
     22#define OPT_NODEREF (option_mask32 & 2)
     23#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 0x04) SKIP_DESKTOP(0))
     24#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 0x08) SKIP_DESKTOP(0))
     25#define OPT_QUIET   (USE_DESKTOP(option_mask32 & 0x10) SKIP_DESKTOP(0))
     26/* POSIX options
     27 * -L traverse every symbolic link to a directory encountered
     28 * -H if a command line argument is a symbolic link to a directory, traverse it
     29 * -P do not traverse any symbolic links (default)
     30 * We do not conform to the following:
     31 * "Specifying more than one of -H, -L, and -P is not an error.
     32 * The last option specified shall determine the behavior of the utility." */
     33/* -L */
     34#define BIT_TRAVERSE 0x20
     35#define OPT_TRAVERSE (USE_DESKTOP(option_mask32 & BIT_TRAVERSE) SKIP_DESKTOP(0))
     36/* -H or -L */
     37#define BIT_TRAVERSE_TOP (0x20|0x40)
     38#define OPT_TRAVERSE_TOP (USE_DESKTOP(option_mask32 & BIT_TRAVERSE_TOP) SKIP_DESKTOP(0))
     39
     40typedef int (*chown_fptr)(const char *, uid_t, gid_t);
     41
     42static struct bb_uidgid_t ugid = { -1, -1 };
    2443
    2544static int fileAction(const char *fileName, struct stat *statbuf,
    26         void ATTRIBUTE_UNUSED *junk)
     45        void *cf, int depth)
    2746{
    28     if (!chown_func(fileName,
    29                 (uid == (uid_t)-1) ? statbuf->st_uid : uid,
    30                 (gid == (gid_t)-1) ? statbuf->st_gid : gid)) {
     47    uid_t u = (ugid.uid == (uid_t)-1) ? statbuf->st_uid : ugid.uid;
     48    gid_t g = (ugid.gid == (gid_t)-1) ? statbuf->st_gid : ugid.gid;
     49
     50    if (!((chown_fptr)cf)(fileName, u, g)) {
     51        if (OPT_VERBOSE
     52         || (OPT_CHANGED && (statbuf->st_uid != u || statbuf->st_gid != g))
     53        ) {
     54            printf("changed ownership of '%s' to %u:%u\n",
     55                    fileName, (unsigned)u, (unsigned)g);
     56        }
    3157        return TRUE;
    3258    }
    33     bb_perror_msg("%s", fileName);  /* A filename could have % in it... */
     59    if (!OPT_QUIET)
     60        bb_perror_msg("%s", fileName);  /* A filename can have % in it... */
    3461    return FALSE;
    3562}
    3663
    37 #define FLAG_R 1
    38 #define FLAG_h 2
    39 
     64int chown_main(int argc, char **argv);
    4065int chown_main(int argc, char **argv)
    4166{
     67    int retval = EXIT_SUCCESS;
    4268    int flags;
    43     int retval = EXIT_SUCCESS;
    44     char *groupName;
     69    chown_fptr chown_func;
    4570
    46     flags = bb_getopt_ulflags(argc, argv, "Rh");
     71    opt_complementary = "-2";
     72    getopt32(argv, OPT_STR);
     73    argv += optind;
    4774
    48     if (flags & FLAG_h) chown_func = lchown;
    49 
    50     if (argc - optind < 2) {
    51         bb_show_usage();
     75    /* This matches coreutils behavior (almost - see below) */
     76    chown_func = chown;
     77    if (OPT_NODEREF
     78        /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
     79        USE_DESKTOP( || (option_mask32 & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
     80    ) {
     81        chown_func = lchown;
    5282    }
    5383
    54     argv += optind;
     84    flags = ACTION_DEPTHFIRST; /* match coreutils order */
     85    if (OPT_RECURSE)
     86        flags |= ACTION_RECURSE;
     87    if (OPT_TRAVERSE_TOP)
     88        flags |= ACTION_FOLLOWLINKS_L0; /* -H/-L: follow links on depth 0 */
     89    if (OPT_TRAVERSE)
     90        flags |= ACTION_FOLLOWLINKS; /* follow links if -L */
    5591
    56     /* First, check if there is a group name here */
    57     if ((groupName = strchr(*argv, '.')) == NULL) {
    58         groupName = strchr(*argv, ':');
    59     }
    60 
    61     /* Check for the username and groupname */
    62     if (groupName) {
    63         *groupName++ = '\0';
    64         gid = get_ug_id(groupName, bb_xgetgrnam);
    65     }
    66     if (--groupName != *argv) uid = get_ug_id(*argv, bb_xgetpwnam);
    67     ++argv;
     92    parse_chown_usergroup_or_die(&ugid, argv[0]);
    6893
    6994    /* Ok, ready to do the deed now */
     95    argv++;
    7096    do {
    71         if (! recursive_action (*argv, (flags & FLAG_R), FALSE, FALSE,
    72                                 fileAction, fileAction, NULL)) {
     97        if (!recursive_action(*argv,
     98                flags,          /* flags */
     99                fileAction,     /* file action */
     100                fileAction,     /* dir action */
     101                chown_func,     /* user data */
     102                0)              /* depth */
     103        ) {
    73104            retval = EXIT_FAILURE;
    74105        }
     
    77108    return retval;
    78109}
     110
     111/*
     112Testcase. Run in empty directory.
     113
     114#!/bin/sh
     115t1="/tmp/busybox chown"
     116t2="/usr/bin/chown"
     117create() {
     118    rm -rf $1; mkdir $1
     119    (
     120    cd $1 || exit 1
     121    mkdir dir dir2
     122    >up
     123    >file
     124    >dir/file
     125    >dir2/file
     126    ln -s dir linkdir
     127    ln -s file linkfile
     128    ln -s ../up dir/linkup
     129    ln -s ../dir2 dir/linkupdir2
     130    )
     131    chown -R 0:0 $1
     132}
     133tst() {
     134    create test1
     135    create test2
     136    echo "[$1]" >>test1.out
     137    echo "[$1]" >>test2.out
     138    (cd test1; $t1 $1) >>test1.out 2>&1
     139    (cd test2; $t2 $1) >>test2.out 2>&1
     140    (cd test1; ls -lnR) >out1
     141    (cd test2; ls -lnR) >out2
     142    echo "chown $1" >out.diff
     143    if ! diff -u out1 out2 >>out.diff; then exit 1; fi
     144    rm out.diff
     145}
     146tst_for_each() {
     147    tst "$1 1:1 file"
     148    tst "$1 1:1 dir"
     149    tst "$1 1:1 linkdir"
     150    tst "$1 1:1 linkfile"
     151}
     152echo "If script produced 'out.diff' file, then at least one testcase failed"
     153>test1.out
     154>test2.out
     155# These match coreutils 6.8:
     156tst_for_each "-v"
     157tst_for_each "-vR"
     158tst_for_each "-vRP"
     159tst_for_each "-vRL"
     160tst_for_each "-vRH"
     161tst_for_each "-vh"
     162tst_for_each "-vhR"
     163tst_for_each "-vhRP"
     164tst_for_each "-vhRL"
     165tst_for_each "-vhRH"
     166# Fix `name' in coreutils output
     167sed 's/`/'"'"'/g' -i test2.out
     168# Compare us with coreutils output
     169diff -u test1.out test2.out
     170
     171*/
Note: See TracChangeset for help on using the changeset viewer.