1/* vi: set sw=4 ts=4: */ 2/* 3 * lsattr.c - List file attributes on an ext2 file system 4 * 5 * Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr> 6 * Laboratoire MASI, Institut Blaise Pascal 7 * Universite Pierre et Marie Curie (Paris VI) 8 * 9 * This file can be redistributed under the terms of the GNU General 10 * Public License 11 */ 12 13/* 14 * History: 15 * 93/10/30 - Creation 16 * 93/11/13 - Replace stat() calls by lstat() to avoid loops 17 * 94/02/27 - Integrated in Ted's distribution 18 * 98/12/29 - Display version info only when -V specified (G M Sipe) 19 */ 20 21#include "libbb.h" 22#include "e2fs_lib.h" 23 24enum { 25 OPT_RECUR = 0x1, 26 OPT_ALL = 0x2, 27 OPT_DIRS_OPT = 0x4, 28 OPT_PF_LONG = 0x8, 29 OPT_GENERATION = 0x10, 30}; 31 32static void list_attributes(const char *name) 33{ 34 unsigned long fsflags; 35 unsigned long generation; 36 37 if (fgetflags(name, &fsflags) != 0) 38 goto read_err; 39 40 if (option_mask32 & OPT_GENERATION) { 41 if (fgetversion(name, &generation) != 0) 42 goto read_err; 43 printf("%5lu ", generation); 44 } 45 46 if (option_mask32 & OPT_PF_LONG) { 47 printf("%-28s ", name); 48 print_flags(stdout, fsflags, PFOPT_LONG); 49 puts(""); 50 } else { 51 print_flags(stdout, fsflags, 0); 52 printf(" %s\n", name); 53 } 54 55 return; 56 read_err: 57 bb_perror_msg("reading %s", name); 58} 59 60static int lsattr_dir_proc(const char *dir_name, struct dirent *de, 61 void *private) 62{ 63 struct stat st; 64 char *path; 65 66 path = concat_path_file(dir_name, de->d_name); 67 68 if (lstat(path, &st) != 0) 69 bb_perror_msg("stat %s", path); 70 else if (de->d_name[0] != '.' || (option_mask32 & OPT_ALL)) { 71 list_attributes(path); 72 if (S_ISDIR(st.st_mode) && (option_mask32 & OPT_RECUR) 73 && !DOT_OR_DOTDOT(de->d_name) 74 ) { 75 printf("\n%s:\n", path); 76 iterate_on_dir(path, lsattr_dir_proc, NULL); 77 puts(""); 78 } 79 } 80 81 free(path); 82 return 0; 83} 84 85static void lsattr_args(const char *name) 86{ 87 struct stat st; 88 89 if (lstat(name, &st) == -1) { 90 bb_perror_msg("stat %s", name); 91 } else if (S_ISDIR(st.st_mode) && !(option_mask32 & OPT_DIRS_OPT)) { 92 iterate_on_dir(name, lsattr_dir_proc, NULL); 93 } else { 94 list_attributes(name); 95 } 96} 97 98int lsattr_main(int argc, char **argv); 99int lsattr_main(int argc, char **argv) 100{ 101 getopt32(argv, "Radlv"); 102 argv += optind; 103 104 if (!*argv) 105 lsattr_args("."); 106 else { 107 while (*argv) 108 lsattr_args(*argv++); 109 } 110 111 return EXIT_SUCCESS; 112} 113