fix #>&- syntax for closing fds
[oweals/busybox.git] / e2fsprogs / lsattr.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * lsattr.c             - List file attributes on an ext2 file system
4  *
5  * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
6  *                           Laboratoire MASI, Institut Blaise Pascal
7  *                           Universite Pierre et Marie Curie (Paris VI)
8  *
9  * This file can be redistributed under the terms of the GNU General
10  * Public License
11  */
12
13 /*
14  * History:
15  * 93/10/30     - Creation
16  * 93/11/13     - Replace stat() calls by lstat() to avoid loops
17  * 94/02/27     - Integrated in Ted's distribution
18  * 98/12/29     - Display version info only when -V specified (G M Sipe)
19  */
20
21 #include "libbb.h"
22 #include "e2fs_lib.h"
23
24 enum {
25         OPT_RECUR      = 0x1,
26         OPT_ALL        = 0x2,
27         OPT_DIRS_OPT   = 0x4,
28         OPT_PF_LONG    = 0x8,
29         OPT_GENERATION = 0x10,
30 };
31
32 static void list_attributes(const char *name)
33 {
34         unsigned long fsflags;
35         unsigned long generation;
36
37         if (fgetflags(name, &fsflags) != 0)
38                 goto read_err;
39
40         if (option_mask32 & OPT_GENERATION) {
41                 if (fgetversion(name, &generation) != 0)
42                         goto read_err;
43                 printf("%5lu ", generation);
44         }
45
46         if (option_mask32 & OPT_PF_LONG) {
47                 printf("%-28s ", name);
48                 print_e2flags(stdout, fsflags, PFOPT_LONG);
49                 bb_putchar('\n');
50         } else {
51                 print_e2flags(stdout, fsflags, 0);
52                 printf(" %s\n", name);
53         }
54
55         return;
56  read_err:
57         bb_perror_msg("reading %s", name);
58 }
59
60 static int lsattr_dir_proc(const char *dir_name, struct dirent *de,
61                            void *private UNUSED_PARAM)
62 {
63         struct stat st;
64         char *path;
65
66         path = concat_path_file(dir_name, de->d_name);
67
68         if (lstat(path, &st) != 0)
69                 bb_perror_msg("stat %s", path);
70         else if (de->d_name[0] != '.' || (option_mask32 & OPT_ALL)) {
71                 list_attributes(path);
72                 if (S_ISDIR(st.st_mode) && (option_mask32 & OPT_RECUR)
73                  && !DOT_OR_DOTDOT(de->d_name)
74                 ) {
75                         printf("\n%s:\n", path);
76                         iterate_on_dir(path, lsattr_dir_proc, NULL);
77                         bb_putchar('\n');
78                 }
79         }
80
81         free(path);
82         return 0;
83 }
84
85 static void lsattr_args(const char *name)
86 {
87         struct stat st;
88
89         if (lstat(name, &st) == -1) {
90                 bb_perror_msg("stat %s", name);
91         } else if (S_ISDIR(st.st_mode) && !(option_mask32 & OPT_DIRS_OPT)) {
92                 iterate_on_dir(name, lsattr_dir_proc, NULL);
93         } else {
94                 list_attributes(name);
95         }
96 }
97
98 int lsattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
99 int lsattr_main(int argc UNUSED_PARAM, char **argv)
100 {
101         getopt32(argv, "Radlv");
102         argv += optind;
103
104         if (!*argv)
105                 *--argv = (char*)".";
106         do lsattr_args(*argv++); while (*argv);
107
108         return EXIT_SUCCESS;
109 }