lsattr.c revision f10748d88cb9b79e1f1a41a12a3e4f411f2494c7
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#ifdef HAVE_ERRNO_H
23#include <errno.h>
24#endif
25#include <fcntl.h>
26#ifdef HAVE_GETOPT_H
27#include <getopt.h>
28#else
29extern int optind;
30extern char *optarg;
31#endif
32#include <stdio.h>
33#include <unistd.h>
34#include <stdlib.h>
35#include <string.h>
36#include <sys/param.h>
37#include <sys/stat.h>
38#include <linux/ext2_fs.h>
39
40#include "et/com_err.h"
41#include "e2p/e2p.h"
42
43#include "../version.h"
44#include "nls-enable.h"
45
46static const char * program_name = "lsattr";
47
48static int all;
49static int dirs_opt;
50static unsigned pf_options;
51static int recursive;
52static int verbose;
53static int generation_opt;
54
55static void usage(void)
56{
57	fprintf(stderr, _("Usage: %s [-RVadlv] [files...]\n"), program_name);
58	exit(1);
59}
60
61static void list_attributes (const char * name)
62{
63	unsigned long flags;
64	unsigned long generation;
65
66	if (fgetflags (name, &flags) == -1) {
67		com_err (program_name, errno, _("While reading flags on %s"),
68			 name);
69		return;
70	}
71	if (generation_opt) {
72		if (fgetversion (name, &generation) == -1) {
73			com_err (program_name, errno,
74				 _("While reading version on %s"),
75				 name);
76			return;
77		}
78		printf ("%5lu ", generation);
79	}
80	if (pf_options & PFOPT_LONG) {
81		printf("%-28s ", name);
82		print_flags(stdout, flags, pf_options);
83		fputc('\n', stdout);
84	} else {
85		print_flags(stdout, flags, pf_options);
86		printf(" %s\n", name);
87	}
88}
89
90static int lsattr_dir_proc (const char *, struct dirent *, void *);
91
92static void lsattr_args (const char * name)
93{
94	struct stat st;
95
96	if (lstat (name, &st) == -1)
97		com_err (program_name, errno, _("while trying to stat %s"),
98			 name);
99	else {
100		if (S_ISDIR(st.st_mode) && !dirs_opt)
101			iterate_on_dir (name, lsattr_dir_proc, NULL);
102		else
103			list_attributes (name);
104	}
105}
106
107static int lsattr_dir_proc (const char * dir_name, struct dirent * de, void * private)
108{
109	struct stat st;
110	char *path;
111
112	path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1);
113
114	sprintf (path, "%s/%s", dir_name, de->d_name);
115	if (lstat (path, &st) == -1)
116		perror (path);
117	else {
118		if (de->d_name[0] != '.' || all) {
119			list_attributes (path);
120			if (S_ISDIR(st.st_mode) && recursive &&
121			    strcmp(de->d_name, ".") &&
122			    strcmp(de->d_name, "..")) {
123				printf ("\n%s:\n", path);
124				iterate_on_dir (path, lsattr_dir_proc, NULL);
125				printf ("\n");
126			}
127		}
128	}
129	free(path);
130	return 0;
131}
132
133int main (int argc, char ** argv)
134{
135	int c;
136	int i;
137
138#ifdef ENABLE_NLS
139	setlocale(LC_MESSAGES, "");
140	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
141	textdomain(NLS_CAT_NAME);
142#endif
143	if (argc && *argv)
144		program_name = *argv;
145	while ((c = getopt (argc, argv, "RVadlv")) != EOF)
146		switch (c)
147		{
148			case 'R':
149				recursive = 1;
150				break;
151			case 'V':
152				verbose = 1;
153				break;
154			case 'a':
155				all = 1;
156				break;
157			case 'd':
158				dirs_opt = 1;
159				break;
160			case 'l':
161				pf_options = PFOPT_LONG;
162				break;
163			case 'v':
164				generation_opt = 1;
165				break;
166			default:
167				usage();
168		}
169
170	if (verbose)
171		fprintf (stderr, _("lsattr %s, %s for EXT2 FS %s, %s\n"),
172			 E2FSPROGS_VERSION, E2FSPROGS_DATE,
173			 EXT2FS_VERSION, EXT2FS_DATE);
174	if (optind > argc - 1)
175		lsattr_args (".");
176	else
177		for (i = optind; i < argc; i++)
178			lsattr_args (argv[i]);
179	exit(0);
180}
181