sysctl was seriously broken. And since in some cases 'CONFIG_SYSCTL'
[oweals/busybox.git] / e2fsprogs / lsattr.c
1 /*
2  * lsattr.c             - List file attributes on an ext2 file system
3  *
4  * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
5  *                           Laboratoire MASI, Institut Blaise Pascal
6  *                           Universite Pierre et Marie Curie (Paris VI)
7  *
8  * This file can be redistributed under the terms of the GNU General
9  * Public License
10  */
11
12 /*
13  * History:
14  * 93/10/30     - Creation
15  * 93/11/13     - Replace stat() calls by lstat() to avoid loops
16  * 94/02/27     - Integrated in Ted's distribution
17  * 98/12/29     - Display version info only when -V specified (G M Sipe)
18  */
19
20 #include <sys/types.h>
21 #include <dirent.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <getopt.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/param.h>
30 #include <sys/stat.h>
31
32 #include <ext2fs/ext2_fs.h>
33 #include "e2fsbb.h"
34 #include "e2p/e2p.h"
35
36 #ifdef __GNUC__
37 # define EXT2FS_ATTR(x) __attribute__(x)
38 #else
39 # define EXT2FS_ATTR(x)
40 #endif
41
42 #define OPT_RECUR 1
43 #define OPT_ALL 2
44 #define OPT_DIRS_OPT 4
45 #define OPT_PF_LONG 8
46 #define OPT_GENERATION 16
47 static int flags;
48
49 #ifdef CONFIG_LFS
50 # define LSTAT lstat64
51 # define STRUCT_STAT struct stat64
52 #else
53 # define LSTAT lstat
54 # define STRUCT_STAT struct stat
55 #endif
56
57 static void list_attributes(const char *name)
58 {
59         unsigned long fsflags;
60         unsigned long generation;
61
62         if (fgetflags(name, &fsflags) == -1)
63                 goto read_err;
64         if (flags & OPT_GENERATION) {
65                 if (fgetversion(name, &generation) == -1)
66                         goto read_err;
67                 printf("%5lu ", generation);
68         }
69
70         if (flags & OPT_PF_LONG) {
71                 printf("%-28s ", name);
72                 print_flags(stdout, fsflags, PFOPT_LONG);
73                 printf("\n");
74         } else {
75                 print_flags(stdout, fsflags, 0);
76                 printf(" %s\n", name);
77         }
78
79         return;
80 read_err:
81         bb_perror_msg("reading %s", name);
82 }
83
84 static int lsattr_dir_proc(const char *, struct dirent *, void *);
85
86 static void lsattr_args(const char *name)
87 {
88         STRUCT_STAT     st;
89
90         if (LSTAT(name, &st) == -1) {
91                 bb_perror_msg("stating %s", name);
92         } else {
93                 if (S_ISDIR(st.st_mode) && !(flags & OPT_DIRS_OPT))
94                         iterate_on_dir(name, lsattr_dir_proc, NULL);
95                 else
96                         list_attributes(name);
97         }
98 }
99
100 static int lsattr_dir_proc(const char *dir_name, struct dirent *de, 
101                            void *private EXT2FS_ATTR((unused)))
102 {
103         STRUCT_STAT     st;
104         char *path;
105
106         path = concat_path_file(dir_name, de->d_name);
107
108         if (LSTAT(path, &st) == -1)
109                 bb_perror_msg(path);
110         else {
111                 if (de->d_name[0] != '.' || (flags & OPT_ALL)) {
112                         list_attributes(path);
113                         if (S_ISDIR(st.st_mode) && (flags & OPT_RECUR) &&
114                            (de->d_name[0] != '.' && (de->d_name[1] != '\0' ||
115                            (de->d_name[1] != '.' && de->d_name[2] != '\0')))) {
116                                 printf("\n%s:\n", path);
117                                 iterate_on_dir(path, lsattr_dir_proc, NULL);
118                                 printf("\n");
119                         }
120                 }
121         }
122
123         free(path);
124
125         return 0;
126 }
127
128 int lsattr_main(int argc, char **argv)
129 {
130         int i;
131
132         flags = bb_getopt_ulflags(argc, argv, "Radlv");
133
134         if (optind > argc - 1)
135                 lsattr_args(".");
136         else
137                 for (i = optind; i < argc; i++)
138                         lsattr_args(argv[i]);
139
140         return EXIT_SUCCESS;
141 }