lsattr.c revision a418d3ad819323f871005d253f7f9ac378e78ba5
13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * lsattr.c		- List file attributes on an ext2 file system
33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *                           Laboratoire MASI, Institut Blaise Pascal
63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *                           Universite Pierre et Marie Curie (Paris VI)
73839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
83839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This file can be redistributed under the terms of the GNU General
93839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Public License
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * History:
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/10/30	- Creation
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/11/13	- Replace stat() calls by lstat() to avoid loops
163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 94/02/27	- Integrated in Ted's distribution
173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
19a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <sys/types.h>
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <dirent.h>
21a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#ifdef HAVE_ERRNO_H
223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <errno.h>
23a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#endif
243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h>
25a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#ifdef HAVE_GETOPT_H
263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <getopt.h>
27a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#else
28a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'oextern int optind;
29a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'oextern char *optarg;
30a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#endif
313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
33a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <stdlib.h>
343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/param.h>
353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h>
363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <linux/ext2_fs.h>
373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "et/com_err.h"
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2p/e2p.h"
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "../version.h"
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oconst char * program_name = "lsattr";
443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint all = 0;
463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint d_opt = 0;
47f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'oint l_opt = 0;
483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint recursive = 0;
493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint v_opt = 0;
503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void volatile usage (void)
523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
53f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	fprintf (stderr, "Usage: %s [-Radlv] [files...]\n", program_name);
543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	exit (1);
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void list_attributes (const char * name)
583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	unsigned long flags;
603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	unsigned long version;
613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (fgetflags (name, &flags) == -1)
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err (program_name, errno, "While reading flags on %s",
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			 name);
653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else if (fgetversion (name, &version) == -1)
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err (program_name, errno, "While reading version on %s",
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			 name);
683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	{
703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (v_opt)
713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			printf ("%5lu ", version);
72f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		print_flags (stdout, flags, l_opt);
733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		printf (" %s\n", name);
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int lsattr_dir_proc (const char *, struct dirent *, void *);
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void lsattr_args (const char * name)
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct stat st;
823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (lstat (name, &st) == -1)
843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err (program_name, errno, "while stating %s", name);
853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	{
873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (S_ISDIR(st.st_mode) && !d_opt)
883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			iterate_on_dir (name, lsattr_dir_proc, (void *) NULL);
893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		else
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			list_attributes (name);
913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int lsattr_dir_proc (const char * dir_name, struct dirent * de, void * private)
953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct stat st;
97a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	char *path;
98a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o
99a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1);
1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	sprintf (path, "%s/%s", dir_name, de->d_name);
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (lstat (path, &st) == -1)
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		perror (path);
104a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	else {
105a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o		if (de->d_name[0] != '.' || all) {
1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			list_attributes (path);
1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (S_ISDIR(st.st_mode) && recursive &&
108a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o			    strcmp(de->d_name, ".") &&
109a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o			    strcmp(de->d_name, "..")) {
1103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				printf ("\n%s:\n", path);
111a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o				iterate_on_dir (path, lsattr_dir_proc,
112a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o						(void *) NULL);
1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				printf ("\n");
1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			}
1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
117a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	free(path);
1183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid main (int argc, char ** argv)
1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char c;
1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int i;
1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fprintf (stderr, "lsattr %s, %s for EXT2 FS %s, %s\n",
1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 E2FSPROGS_VERSION, E2FSPROGS_DATE,
1283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 EXT2FS_VERSION, EXT2FS_DATE);
1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (argc && *argv)
1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		program_name = *argv;
1313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	while ((c = getopt (argc, argv, "Radlv")) != EOF)
1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		switch (c)
1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		{
1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'R':
1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				recursive = 1;
1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'a':
1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				all = 1;
1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
1403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'd':
1413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				d_opt = 1;
1423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
143f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o			case 'l':
144f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				l_opt = 1;
145f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				break;
1463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'v':
1473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				v_opt = 1;
1483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
1493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			default:
1503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				usage ();
1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (optind > argc - 1)
1543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		lsattr_args (".");
1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
1563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		for (i = optind; i < argc; i++)
1573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			lsattr_args (argv[i]);
1583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
159