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/e2fsprogs/chattr.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * chattr.c     - Change file attributes on an ext2 file system
     
    1920 */
    2021
    21 #include <sys/types.h>
    22 #include <dirent.h>
    23 #include <fcntl.h>
    24 #include <stdio.h>
    25 #include <stdlib.h>
    26 #include <unistd.h>
    27 #include <string.h>
    28 #include <errno.h>
    29 #include <sys/param.h>
    30 #include <sys/stat.h>
    31 #include "ext2fs/ext2_fs.h"
    32 
    33 #ifdef __GNUC__
    34 # define EXT2FS_ATTR(x) __attribute__(x)
    35 #else
    36 # define EXT2FS_ATTR(x)
    37 #endif
    38 
    39 #include "e2fsbb.h"
    40 #include "e2p/e2p.h"
     22#include "libbb.h"
     23#include "e2fs_lib.h"
    4124
    4225#define OPT_ADD 1
     
    4427#define OPT_SET 4
    4528#define OPT_SET_VER 8
    46 static int flags;
    47 static int recursive;
    4829
    49 static unsigned long version;
    50 
    51 static unsigned long af;
    52 static unsigned long rf;
    53 static unsigned long sf;
    54 
    55 #ifdef CONFIG_LFS
    56 # define LSTAT lstat64
    57 # define STRUCT_STAT struct stat64
    58 #else
    59 # define LSTAT lstat
    60 # define STRUCT_STAT struct stat
    61 #endif
    62 
    63 struct flags_char {
    64     unsigned long flag;
    65     char optchar;
    66 };
    67 
    68 static const struct flags_char flags_array[] = {
    69     { EXT2_NOATIME_FL,      'A' },
    70     { EXT2_SYNC_FL,         'S' },
    71     { EXT2_DIRSYNC_FL,      'D' },
    72     { EXT2_APPEND_FL,       'a' },
    73     { EXT2_COMPR_FL,        'c' },
    74     { EXT2_NODUMP_FL,       'd' },
    75     { EXT2_IMMUTABLE_FL,    'i' },
    76     { EXT3_JOURNAL_DATA_FL, 'j' },
    77     { EXT2_SECRM_FL,        's' },
    78     { EXT2_UNRM_FL,         'u' },
    79     { EXT2_NOTAIL_FL,       't' },
    80     { EXT2_TOPDIR_FL,       'T' },
    81     { 0, 0 }
     30struct globals {
     31    unsigned long version;
     32    unsigned long af;
     33    unsigned long rf;
     34    smallint flags;
     35    smallint recursive;
    8236};
    8337
    8438static unsigned long get_flag(char c)
    8539{
    86     const struct flags_char *fp;
    87     for (fp = flags_array; fp->flag; fp++)
    88         if (fp->optchar == c)
    89             return fp->flag;
     40    /* Two separate vectors take less space than vector of structs */
     41    static const char flags_letter[] ALIGN1 = "ASDacdijsutT";
     42    static const unsigned long flags_val[] = {
     43        /* A */ EXT2_NOATIME_FL,
     44        /* S */ EXT2_SYNC_FL,
     45        /* D */ EXT2_DIRSYNC_FL,
     46        /* a */ EXT2_APPEND_FL,
     47        /* c */ EXT2_COMPR_FL,
     48        /* d */ EXT2_NODUMP_FL,
     49        /* i */ EXT2_IMMUTABLE_FL,
     50        /* j */ EXT3_JOURNAL_DATA_FL,
     51        /* s */ EXT2_SECRM_FL,
     52        /* u */ EXT2_UNRM_FL,
     53        /* t */ EXT2_NOTAIL_FL,
     54        /* T */ EXT2_TOPDIR_FL,
     55    };
     56    const char *fp;
     57
     58    for (fp = flags_letter; *fp; fp++)
     59        if (*fp == c)
     60            return flags_val[fp - flags_letter];
    9061    bb_show_usage();
    91     return 0;
    9262}
    9363
    94 static int decode_arg(char *arg)
     64static int decode_arg(const char *arg, struct globals *gp)
    9565{
    9666    unsigned long *fl;
    9767    char opt = *arg++;
    9868
     69    fl = &gp->af;
    9970    if (opt == '-') {
    100         flags |= OPT_REM;
    101         fl = &rf;
     71        gp->flags |= OPT_REM;
     72        fl = &gp->rf;
    10273    } else if (opt == '+') {
    103         flags |= OPT_ADD;
    104         fl = &af;
     74        gp->flags |= OPT_ADD;
    10575    } else if (opt == '=') {
    106         flags |= OPT_SET;
    107         fl = &sf;
     76        gp->flags |= OPT_SET;
    10877    } else
    109         return EOF;
     78        return 0;
    11079
    111     for (; *arg ; ++arg)
    112         (*fl) |= get_flag(*arg);
     80    while (*arg)
     81        *fl |= get_flag(*arg++);
    11382
    11483    return 1;
    11584}
    11685
    117 static int chattr_dir_proc(const char *, struct dirent *, void *);
     86static void change_attributes(const char *name, struct globals *gp);
    11887
    119 static void change_attributes(const char * name)
     88static int chattr_dir_proc(const char *dir_name, struct dirent *de, void *gp)
     89{
     90    char *path = concat_subpath_file(dir_name, de->d_name);
     91    /* path is NULL if de->d_name is "." or "..", else... */
     92    if (path) {
     93        change_attributes(path, gp);
     94        free(path);
     95    }
     96    return 0;
     97}
     98
     99static void change_attributes(const char *name, struct globals *gp)
    120100{
    121101    unsigned long fsflags;
    122     STRUCT_STAT st;
     102    struct stat st;
    123103
    124     if (LSTAT(name, &st) == -1) {
    125         bb_error_msg("stat %s failed", name);
     104    if (lstat(name, &st) != 0) {
     105        bb_perror_msg("stat %s", name);
    126106        return;
    127107    }
    128     if (S_ISLNK(st.st_mode) && recursive)
     108    if (S_ISLNK(st.st_mode) && gp->recursive)
    129109        return;
    130110
     
    136116        return;
    137117
    138     if (flags & OPT_SET_VER)
    139         if (fsetversion(name, version) == -1)
    140             bb_error_msg("setting version on %s", name);
     118    if (gp->flags & OPT_SET_VER)
     119        if (fsetversion(name, gp->version) != 0)
     120            bb_perror_msg("setting version on %s", name);
    141121
    142     if (flags & OPT_SET) {
    143         fsflags = sf;
     122    if (gp->flags & OPT_SET) {
     123        fsflags = gp->af;
    144124    } else {
    145         if (fgetflags(name, &fsflags) == -1) {
    146             bb_error_msg("reading flags on %s", name);
     125        if (fgetflags(name, &fsflags) != 0) {
     126            bb_perror_msg("reading flags on %s", name);
    147127            goto skip_setflags;
    148128        }
    149         if (flags & OPT_REM)
    150             fsflags &= ~rf;
    151         if (flags & OPT_ADD)
    152             fsflags |= af;
     129        /*if (gp->flags & OPT_REM) - not needed, rf is zero otherwise */
     130            fsflags &= ~gp->rf;
     131        /*if (gp->flags & OPT_ADD) - not needed, af is zero otherwise */
     132            fsflags |= gp->af;
     133        /* What is this? And why it's not done for SET case? */
    153134        if (!S_ISDIR(st.st_mode))
    154135            fsflags &= ~EXT2_DIRSYNC_FL;
    155136    }
    156     if (fsetflags(name, fsflags) == -1)
    157         bb_error_msg("setting flags on %s", name);
     137    if (fsetflags(name, fsflags) != 0)
     138        bb_perror_msg("setting flags on %s", name);
    158139
    159 skip_setflags:
    160     if (S_ISDIR(st.st_mode) && recursive)
    161         iterate_on_dir(name, chattr_dir_proc, NULL);
     140 skip_setflags:
     141    if (gp->recursive && S_ISDIR(st.st_mode))
     142        iterate_on_dir(name, chattr_dir_proc, gp);
    162143}
    163144
    164 static int chattr_dir_proc(const char *dir_name, struct dirent *de,
    165                void *private EXT2FS_ATTR((unused)))
    166 {
    167     /*if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {*/
    168     if (de->d_name[0] == '.' && (de->d_name[1] == '\0' || \
    169        (de->d_name[1] == '.' && de->d_name[2] == '\0'))) {
    170         char *path = concat_subpath_file(dir_name, de->d_name);
    171         if (path) {
    172             change_attributes(path);
    173             free(path);
    174         }
    175     }
    176     return 0;
    177 }
    178 
     145int chattr_main(int argc, char **argv);
    179146int chattr_main(int argc, char **argv)
    180147{
    181     int i;
     148    struct globals g;
    182149    char *arg;
    183150
     151    memset(&g, 0, sizeof(g));
     152
    184153    /* parse the args */
    185     for (i = 1; i < argc; ++i) {
    186         arg = argv[i];
    187 
     154    while ((arg = *++argv)) {
    188155        /* take care of -R and -v <version> */
    189         if (arg[0] == '-') {
    190             if (arg[1] == 'R' && arg[2] == '\0') {
    191                 recursive = 1;
    192                 continue;
    193             } else if (arg[1] == 'v' && arg[2] == '\0') {
    194                 char *tmp;
    195                 ++i;
    196                 if (i >= argc)
    197                     bb_show_usage();
    198                 version = strtol(argv[i], &tmp, 0);
    199                 if (*tmp)
    200                     bb_error_msg_and_die("bad version '%s'", arg);
    201                 flags |= OPT_SET_VER;
     156        if (arg[0] == '-'
     157         && (arg[1] == 'R' || arg[1] == 'v')
     158         && !arg[2]
     159        ) {
     160            if (arg[1] == 'R') {
     161                g.recursive = 1;
    202162                continue;
    203163            }
     164            /* arg[1] == 'v' */
     165            if (!*++argv)
     166                bb_show_usage();
     167            g.version = xatoul(*argv);
     168            g.flags |= OPT_SET_VER;
     169            continue;
    204170        }
    205171
    206         if (decode_arg(arg) == EOF)
     172        if (!decode_arg(arg, &g))
    207173            break;
    208174    }
    209175
    210176    /* run sanity checks on all the arguments given us */
    211     if (i >= argc)
     177    if (!*argv)
    212178        bb_show_usage();
    213     if ((flags & OPT_SET) && ((flags & OPT_ADD) || (flags & OPT_REM)))
     179    if ((g.flags & OPT_SET) && (g.flags & (OPT_ADD|OPT_REM)))
    214180        bb_error_msg_and_die("= is incompatible with - and +");
    215     if ((rf & af) != 0)
    216         bb_error_msg_and_die("Can't set and unset a flag");
    217     if (!flags)
    218         bb_error_msg_and_die("Must use '-v', =, - or +");
     181    if (g.rf & g.af)
     182        bb_error_msg_and_die("can't set and unset a flag");
     183    if (!g.flags)
     184        bb_error_msg_and_die("must use '-v', =, - or +");
    219185
    220186    /* now run chattr on all the files passed to us */
    221     while (i < argc)
    222         change_attributes(argv[i++]);
     187    do change_attributes(*argv, &g); while (*++argv);
    223188
    224189    return EXIT_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.