blob: 3fe4b9a0c6940af0820815c597bd86aecb7d83cc [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
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000019#include <sys/types.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000020#include <dirent.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000021#ifdef HAVE_ERRNO_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000022#include <errno.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000023#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000024#include <fcntl.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000025#ifdef HAVE_GETOPT_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000026#include <getopt.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000027#else
28extern int optind;
29extern char *optarg;
30#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000031#include <stdio.h>
32#include <unistd.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000033#include <stdlib.h>
Theodore Ts'o3839e651997-04-26 13:21:57 +000034#include <sys/param.h>
35#include <sys/stat.h>
36#include <linux/ext2_fs.h>
37
38#include "et/com_err.h"
39#include "e2p/e2p.h"
40
41#include "../version.h"
42
43const char * program_name = "lsattr";
44
45int all = 0;
46int d_opt = 0;
Theodore Ts'of3db3561997-04-26 13:34:30 +000047int l_opt = 0;
Theodore Ts'o3839e651997-04-26 13:21:57 +000048int recursive = 0;
49int v_opt = 0;
50
51static void volatile usage (void)
52{
Theodore Ts'of3db3561997-04-26 13:34:30 +000053 fprintf (stderr, "Usage: %s [-Radlv] [files...]\n", program_name);
Theodore Ts'o3839e651997-04-26 13:21:57 +000054 exit (1);
55}
56
57static void list_attributes (const char * name)
58{
59 unsigned long flags;
60 unsigned long version;
61
62 if (fgetflags (name, &flags) == -1)
63 com_err (program_name, errno, "While reading flags on %s",
64 name);
65 else if (fgetversion (name, &version) == -1)
66 com_err (program_name, errno, "While reading version on %s",
67 name);
68 else
69 {
70 if (v_opt)
71 printf ("%5lu ", version);
Theodore Ts'of3db3561997-04-26 13:34:30 +000072 print_flags (stdout, flags, l_opt);
Theodore Ts'o3839e651997-04-26 13:21:57 +000073 printf (" %s\n", name);
74 }
75}
76
77static int lsattr_dir_proc (const char *, struct dirent *, void *);
78
79static void lsattr_args (const char * name)
80{
81 struct stat st;
82
83 if (lstat (name, &st) == -1)
84 com_err (program_name, errno, "while stating %s", name);
85 else
86 {
87 if (S_ISDIR(st.st_mode) && !d_opt)
88 iterate_on_dir (name, lsattr_dir_proc, (void *) NULL);
89 else
90 list_attributes (name);
91 }
92}
93
94static int lsattr_dir_proc (const char * dir_name, struct dirent * de, void * private)
95{
Theodore Ts'o3839e651997-04-26 13:21:57 +000096 struct stat st;
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000097 char *path;
98
99 path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000100
101 sprintf (path, "%s/%s", dir_name, de->d_name);
102 if (lstat (path, &st) == -1)
103 perror (path);
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000104 else {
105 if (de->d_name[0] != '.' || all) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000106 list_attributes (path);
107 if (S_ISDIR(st.st_mode) && recursive &&
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000108 strcmp(de->d_name, ".") &&
109 strcmp(de->d_name, "..")) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000110 printf ("\n%s:\n", path);
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000111 iterate_on_dir (path, lsattr_dir_proc,
112 (void *) NULL);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000113 printf ("\n");
114 }
115 }
116 }
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000117 free(path);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000118 return 0;
119}
120
121void main (int argc, char ** argv)
122{
123 char c;
124 int i;
125
126 fprintf (stderr, "lsattr %s, %s for EXT2 FS %s, %s\n",
127 E2FSPROGS_VERSION, E2FSPROGS_DATE,
128 EXT2FS_VERSION, EXT2FS_DATE);
129 if (argc && *argv)
130 program_name = *argv;
131 while ((c = getopt (argc, argv, "Radlv")) != EOF)
132 switch (c)
133 {
134 case 'R':
135 recursive = 1;
136 break;
137 case 'a':
138 all = 1;
139 break;
140 case 'd':
141 d_opt = 1;
142 break;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000143 case 'l':
144 l_opt = 1;
145 break;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000146 case 'v':
147 v_opt = 1;
148 break;
149 default:
150 usage ();
151 }
152
153 if (optind > argc - 1)
154 lsattr_args (".");
155 else
156 for (i = optind; i < argc; i++)
157 lsattr_args (argv[i]);
158}