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