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/chmod.c

    r821 r1765  
    1212
    1313/* BB_AUDIT SUSv3 compliant */
    14 /* BB_AUDIT GNU defects - unsupported options -c, -f, -v, and long options. */
     14/* BB_AUDIT GNU defects - unsupported long options. */
    1515/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
    1616
    17 #include <stdio.h>
    18 #include <stdlib.h>
    19 #include <string.h>
    20 #include <unistd.h>
    21 #include <sys/stat.h>
    22 #include "busybox.h"
     17#include "libbb.h"
    2318
    24 static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
     19/* This is a NOEXEC applet. Be very careful! */
     20
     21
     22#define OPT_RECURSE (option_mask32 & 1)
     23#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 2) SKIP_DESKTOP(0))
     24#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 4) SKIP_DESKTOP(0))
     25#define OPT_QUIET   (USE_DESKTOP(option_mask32 & 8) SKIP_DESKTOP(0))
     26#define OPT_STR     "R" USE_DESKTOP("vcf")
     27
     28/* coreutils:
     29 * chmod never changes the permissions of symbolic links; the chmod
     30 * system call cannot change their permissions. This is not a problem
     31 * since the permissions of symbolic links are never used.
     32 * However, for each symbolic link listed on the command line, chmod changes
     33 * the permissions of the pointed-to file. In contrast, chmod ignores
     34 * symbolic links encountered during recursive directory traversals.
     35 */
     36
     37static int fileAction(const char *fileName, struct stat *statbuf, void* param, int depth)
    2538{
    26     if (!bb_parse_mode((char *)junk, &(statbuf->st_mode)))
    27         bb_error_msg_and_die( "invalid mode: %s", (char *)junk);
    28     if (chmod(fileName, statbuf->st_mode) == 0)
    29         return (TRUE);
    30     bb_perror_msg("%s", fileName);  /* Avoid multibyte problems. */
    31     return (FALSE);
     39    mode_t newmode;
     40
     41    /* match coreutils behavior */
     42    if (depth == 0) {
     43        /* statbuf holds lstat result, but we need stat (follow link) */
     44        if (stat(fileName, statbuf))
     45            goto err;
     46    } else { /* depth > 0: skip links */
     47        if (S_ISLNK(statbuf->st_mode))
     48            return TRUE;
     49    }
     50    newmode = statbuf->st_mode;
     51
     52    if (!bb_parse_mode((char *)param, &newmode))
     53        bb_error_msg_and_die("invalid mode: %s", (char *)param);
     54
     55    if (chmod(fileName, newmode) == 0) {
     56        if (OPT_VERBOSE
     57         || (OPT_CHANGED && statbuf->st_mode != newmode)
     58        ) {
     59            printf("mode of '%s' changed to %04o (%s)\n", fileName,
     60                newmode & 07777, bb_mode_string(newmode)+1);
     61        }
     62        return TRUE;
     63    }
     64 err:
     65    if (!OPT_QUIET)
     66        bb_perror_msg("%s", fileName);
     67    return FALSE;
    3268}
    3369
    34 int chmod_main(int ATTRIBUTE_UNUSED argc, char **argv)
     70int chmod_main(int argc, char **argv);
     71int chmod_main(int argc, char **argv)
    3572{
    3673    int retval = EXIT_SUCCESS;
    37     int recursiveFlag = FALSE;
    38     int count;
     74    char *arg, **argp;
    3975    char *smode;
    40     char **p;
    41     char *p0;
    42     char opt = '-';
    4376
    44     ++argv;
    45     count = 0;
    46 
    47     for (p = argv  ; *p ; p++) {
    48         p0 = p[0];
    49         if (p0[0] == opt) {
    50             if ((p0[1] == '-') && !p0[2]) {
    51                 opt = 0;    /* Disable further option processing. */
    52                 continue;
    53             }
    54             if (p0[1] == 'R') {
    55                 char *s = p0 + 2;
    56                 while (*s == 'R') {
    57                     ++s;
    58                 }
    59                 if (*s) {
    60                     bb_show_usage();
    61                 }
    62                 recursiveFlag = TRUE;
    63                 continue;
    64             }
    65             if (count) {
    66                 bb_show_usage();
    67             }
     77    /* Convert first encountered -r into ar, -w into aw etc
     78     * so that getopt would not eat it */
     79    argp = argv;
     80    while ((arg = *++argp)) {
     81        /* Mode spec must be the first arg (sans -R etc) */
     82        /* (protect against mishandling e.g. "chmod 644 -r") */
     83        if (arg[0] != '-') {
     84            arg = NULL;
     85            break;
    6886        }
    69         argv[count] = p0;
    70         ++count;
     87        /* An option. Not a -- or valid option? */
     88        if (arg[1] && !strchr("-"OPT_STR, arg[1])) {
     89            arg[0] = 'a';
     90            break;
     91        }
    7192    }
    7293
    73     argv[count] = NULL;
     94    /* Parse options */
     95    opt_complementary = "-2";
     96    getopt32(argv, ("-"OPT_STR) + 1); /* Reuse string */
     97    argv += optind;
    7498
    75     if (count < 2) {
    76         bb_show_usage();
    77     }
    78 
    79     smode = *argv;
    80     ++argv;
     99    /* Restore option-like mode if needed */
     100    if (arg) arg[0] = '-';
    81101
    82102    /* Ok, ready to do the deed now */
     103    smode = *argv++;
    83104    do {
    84         if (! recursive_action (*argv, recursiveFlag, TRUE, FALSE,
    85                                 fileAction, fileAction, smode)) {
     105        if (!recursive_action(*argv,
     106            OPT_RECURSE,    // recurse
     107            fileAction,     // file action
     108            fileAction,     // dir action
     109            smode,          // user data
     110            0)              // depth
     111        ) {
    86112            retval = EXIT_FAILURE;
    87113        }
     
    90116    return retval;
    91117}
     118
     119/*
     120Security: chmod is too important and too subtle.
     121This is a test script (busybox chmod versus coreutils).
     122Run it in empty directory.
     123
     124#!/bin/sh
     125t1="/tmp/busybox chmod"
     126t2="/usr/bin/chmod"
     127create() {
     128    rm -rf $1; mkdir $1
     129    (
     130    cd $1 || exit 1
     131    mkdir dir
     132    >up
     133    >file
     134    >dir/file
     135    ln -s dir linkdir
     136    ln -s file linkfile
     137    ln -s ../up dir/up
     138    )
     139}
     140tst() {
     141    (cd test1; $t1 $1)
     142    (cd test2; $t2 $1)
     143    (cd test1; ls -lR) >out1
     144    (cd test2; ls -lR) >out2
     145    echo "chmod $1" >out.diff
     146    if ! diff -u out1 out2 >>out.diff; then exit 1; fi
     147    rm out.diff
     148}
     149echo "If script produced 'out.diff' file, then at least one testcase failed"
     150create test1; create test2
     151tst "a+w file"
     152tst "a-w dir"
     153tst "a+w linkfile"
     154tst "a-w linkdir"
     155tst "-R a+w file"
     156tst "-R a-w dir"
     157tst "-R a+w linkfile"
     158tst "-R a-w linkdir"
     159tst "a-r,a+x linkfile"
     160*/
Note: See TracChangeset for help on using the changeset viewer.