blob: 6ce190c4328f2cd784cae00978116e8ed9a53d90 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
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
34const char * program_name = "lsattr";
35
36int all = 0;
37int d_opt = 0;
Theodore Ts'of3db3561997-04-26 13:34:30 +000038int l_opt = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +000039int recursive = 0;
40int v_opt = 0;
41
42static void volatile usage (void)
43{
Theodore Ts'of3db3561997-04-26 13:34:30 +000044 fprintf (stderr, "Usage: %s [-Radlv] [files...]\n", program_name);
Theodore Ts'o3839e651997-04-26 13:21:57 +000045 exit (1);
46}
47
48static void list_attributes (const char * name)
49{
50 unsigned long flags;
51 unsigned long version;
52
53 if (fgetflags (name, &flags) == -1)
54 com_err (program_name, errno, "While reading flags on %s",
55 name);
56 else if (fgetversion (name, &version) == -1)
57 com_err (program_name, errno, "While reading version on %s",
58 name);
59 else
60 {
61 if (v_opt)
62 printf ("%5lu ", version);
Theodore Ts'of3db3561997-04-26 13:34:30 +000063 print_flags (stdout, flags, l_opt);
Theodore Ts'o3839e651997-04-26 13:21:57 +000064 printf (" %s\n", name);
65 }
66}
67
68static int lsattr_dir_proc (const char *, struct dirent *, void *);
69
70static void lsattr_args (const char * name)
71{
72 struct stat st;
73
74 if (lstat (name, &st) == -1)
75 com_err (program_name, errno, "while stating %s", name);
76 else
77 {
78 if (S_ISDIR(st.st_mode) && !d_opt)
79 iterate_on_dir (name, lsattr_dir_proc, (void *) NULL);
80 else
81 list_attributes (name);
82 }
83}
84
85static int lsattr_dir_proc (const char * dir_name, struct dirent * de, void * private)
86{
87 char path [MAXPATHLEN];
88 struct stat st;
89
90 sprintf (path, "%s/%s", dir_name, de->d_name);
91 if (lstat (path, &st) == -1)
92 perror (path);
93 else
94 {
95 if (de->d_name[0] != '.' || all)
96 {
97 list_attributes (path);
98 if (S_ISDIR(st.st_mode) && recursive &&
99 strcmp (de->d_name, ".") && strcmp (de->d_name, ".."))
100 {
101 printf ("\n%s:\n", path);
102 iterate_on_dir (path, lsattr_dir_proc, (void *) NULL);
103 printf ("\n");
104 }
105 }
106 }
107 return 0;
108}
109
110void main (int argc, char ** argv)
111{
112 char c;
113 int i;
114
115 fprintf (stderr, "lsattr %s, %s for EXT2 FS %s, %s\n",
116 E2FSPROGS_VERSION, E2FSPROGS_DATE,
117 EXT2FS_VERSION, EXT2FS_DATE);
118 if (argc && *argv)
119 program_name = *argv;
120 while ((c = getopt (argc, argv, "Radlv")) != EOF)
121 switch (c)
122 {
123 case 'R':
124 recursive = 1;
125 break;
126 case 'a':
127 all = 1;
128 break;
129 case 'd':
130 d_opt = 1;
131 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000132 case 'l':
133 l_opt = 1;
134 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000135 case 'v':
136 v_opt = 1;
137 break;
138 default:
139 usage ();
140 }
141
142 if (optind > argc - 1)
143 lsattr_args (".");
144 else
145 for (i = optind; i < argc; i++)
146 lsattr_args (argv[i]);
147}