Whamcloud - gitweb
ae337d67cd2949c23e0c530af1e81fcad566d60b
[tools/e2fsprogs.git] / misc / 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  */
18
19 #include <dirent.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <getopt.h>
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <sys/param.h>
26 #include <sys/stat.h>
27 #include <linux/ext2_fs.h>
28
29 #include "et/com_err.h"
30 #include "e2p/e2p.h"
31
32 #include "../version.h"
33
34 const char * program_name = "lsattr";
35
36 int all = 0;
37 int d_opt = 0;
38 int recursive = 0;
39 int v_opt = 0;
40
41 static void volatile usage (void)
42 {
43         fprintf (stderr, "Usage: %s [-Radv] [files...]\n", program_name);
44         exit (1);
45 }
46
47 static void list_attributes (const char * name)
48 {
49         unsigned long flags;
50         unsigned long version;
51
52         if (fgetflags (name, &flags) == -1)
53                 com_err (program_name, errno, "While reading flags on %s",
54                          name);
55         else if (fgetversion (name, &version) == -1)
56                 com_err (program_name, errno, "While reading version on %s",
57                          name);
58         else
59         {
60                 if (v_opt)
61                         printf ("%5lu ", version);
62                 print_flags (stdout, flags);
63                 printf (" %s\n", name);
64         }
65 }
66
67 static int lsattr_dir_proc (const char *, struct dirent *, void *);
68
69 static void lsattr_args (const char * name)
70 {
71         struct stat st;
72
73         if (lstat (name, &st) == -1)
74                 com_err (program_name, errno, "while stating %s", name);
75         else
76         {
77                 if (S_ISDIR(st.st_mode) && !d_opt)
78                         iterate_on_dir (name, lsattr_dir_proc, (void *) NULL);
79                 else
80                         list_attributes (name);
81         }
82 }
83
84 static int lsattr_dir_proc (const char * dir_name, struct dirent * de, void * private)
85 {
86         char path [MAXPATHLEN];
87         struct stat st;
88
89         sprintf (path, "%s/%s", dir_name, de->d_name);
90         if (lstat (path, &st) == -1)
91                 perror (path);
92         else
93         {
94                 if (de->d_name[0] != '.' || all)
95                 {
96                         list_attributes (path);
97                         if (S_ISDIR(st.st_mode) && recursive &&
98                             strcmp (de->d_name, ".") && strcmp (de->d_name, ".."))
99                         {
100                                 printf ("\n%s:\n", path);
101                                 iterate_on_dir (path, lsattr_dir_proc, (void *) NULL);
102                                 printf ("\n");
103                         }
104                 }
105         }
106         return 0;
107 }
108
109 void main (int argc, char ** argv)
110 {
111         char c;
112         int i;
113
114         fprintf (stderr, "lsattr %s, %s for EXT2 FS %s, %s\n",
115                  E2FSPROGS_VERSION, E2FSPROGS_DATE,
116                  EXT2FS_VERSION, EXT2FS_DATE);
117         if (argc && *argv)
118                 program_name = *argv;
119         while ((c = getopt (argc, argv, "Radlv")) != EOF)
120                 switch (c)
121                 {
122                         case 'R':
123                                 recursive = 1;
124                                 break;
125                         case 'a':
126                                 all = 1;
127                                 break;
128                         case 'd':
129                                 d_opt = 1;
130                                 break;
131                         case 'v':
132                                 v_opt = 1;
133                                 break;
134                         default:
135                                 usage ();
136                 }
137
138         if (optind > argc - 1)
139                 lsattr_args (".");
140         else
141                 for (i = optind; i < argc; i++)
142                         lsattr_args (argv[i]);
143 }