lsattr.c revision 519149fb458b0fa69c10fecd83fae42e838cf01d
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>
3419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o#include <string.h>
353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/param.h>
363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h>
373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <linux/ext2_fs.h>
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "et/com_err.h"
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2p/e2p.h"
413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "../version.h"
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oconst char * program_name = "lsattr";
453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint all = 0;
473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint d_opt = 0;
48f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'oint l_opt = 0;
493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint recursive = 0;
503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint v_opt = 0;
513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void volatile usage (void)
533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
54f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	fprintf (stderr, "Usage: %s [-Radlv] [files...]\n", program_name);
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	exit (1);
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void list_attributes (const char * name)
593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	unsigned long flags;
613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	unsigned long version;
623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (fgetflags (name, &flags) == -1)
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err (program_name, errno, "While reading flags on %s",
653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			 name);
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else if (fgetversion (name, &version) == -1)
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err (program_name, errno, "While reading version on %s",
683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			 name);
693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	{
713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (v_opt)
723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			printf ("%5lu ", version);
73f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		print_flags (stdout, flags, l_opt);
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		printf (" %s\n", name);
753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int lsattr_dir_proc (const char *, struct dirent *, void *);
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void lsattr_args (const char * name)
813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct stat st;
833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (lstat (name, &st) == -1)
853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		com_err (program_name, errno, "while stating %s", name);
863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	{
883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (S_ISDIR(st.st_mode) && !d_opt)
893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			iterate_on_dir (name, lsattr_dir_proc, (void *) NULL);
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		else
913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			list_attributes (name);
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int lsattr_dir_proc (const char * dir_name, struct dirent * de, void * private)
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct stat st;
98a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	char *path;
99a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o
100a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1);
1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	sprintf (path, "%s/%s", dir_name, de->d_name);
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (lstat (path, &st) == -1)
1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		perror (path);
105a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	else {
106a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o		if (de->d_name[0] != '.' || all) {
1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			list_attributes (path);
1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (S_ISDIR(st.st_mode) && recursive &&
109a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o			    strcmp(de->d_name, ".") &&
110a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o			    strcmp(de->d_name, "..")) {
1113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				printf ("\n%s:\n", path);
112a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o				iterate_on_dir (path, lsattr_dir_proc,
113a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o						(void *) NULL);
1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				printf ("\n");
1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			}
1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
118a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o	free(path);
1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
12200e5433eb5e9f70f485968b809fdcf297d7fe7b9Theodore Ts'oint main (int argc, char ** argv)
1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
124519149fb458b0fa69c10fecd83fae42e838cf01dTheodore Ts'o	int c;
1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int i;
1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	fprintf (stderr, "lsattr %s, %s for EXT2 FS %s, %s\n",
1283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 E2FSPROGS_VERSION, E2FSPROGS_DATE,
1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 EXT2FS_VERSION, EXT2FS_DATE);
1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (argc && *argv)
1313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		program_name = *argv;
1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	while ((c = getopt (argc, argv, "Radlv")) != EOF)
1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		switch (c)
1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		{
1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'R':
1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				recursive = 1;
1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'a':
1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				all = 1;
1403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
1413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'd':
1423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				d_opt = 1;
1433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
144f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o			case 'l':
145f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				l_opt = 1;
146f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o				break;
1473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			case 'v':
1483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				v_opt = 1;
1493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
1503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			default:
1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				usage ();
1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (optind > argc - 1)
1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		lsattr_args (".");
1563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
1573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		for (i = optind; i < argc; i++)
1583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			lsattr_args (argv[i]);
15900e5433eb5e9f70f485968b809fdcf297d7fe7b9Theodore Ts'o	exit(0);
1603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
161