diff options
author | Mike Frysinger <vapier@gentoo.org> | 2005-04-24 05:07:59 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2005-04-24 05:07:59 +0000 |
commit | d89e629e52c3b525424be958de238ed1dc5a0361 (patch) | |
tree | 9aec1ca3d0a479bef39bd63c14f4292061d34675 | |
parent | 408ae211ceaf33bf758207cd5329903c39e8880c (diff) | |
download | busybox-w32-d89e629e52c3b525424be958de238ed1dc5a0361.tar.gz busybox-w32-d89e629e52c3b525424be958de238ed1dc5a0361.tar.bz2 busybox-w32-d89e629e52c3b525424be958de238ed1dc5a0361.zip |
add new subdir for e2fsprogs
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | e2fsprogs/README | 3 | ||||
-rw-r--r-- | e2fsprogs/chattr.c | 305 | ||||
-rw-r--r-- | e2fsprogs/e2fsbb.h | 38 | ||||
-rw-r--r-- | e2fsprogs/e2p/README | 4 | ||||
-rw-r--r-- | e2fsprogs/e2p/e2p.h | 52 | ||||
-rw-r--r-- | e2fsprogs/e2p/feature.c | 190 | ||||
-rw-r--r-- | e2fsprogs/e2p/fgetflags.c | 92 | ||||
-rw-r--r-- | e2fsprogs/e2p/fgetversion.c | 62 | ||||
-rw-r--r-- | e2fsprogs/e2p/fsetflags.c | 96 | ||||
-rw-r--r-- | e2fsprogs/e2p/fsetversion.c | 60 | ||||
-rw-r--r-- | e2fsprogs/e2p/getflags.c | 66 | ||||
-rw-r--r-- | e2fsprogs/e2p/getversion.c | 37 | ||||
-rw-r--r-- | e2fsprogs/e2p/hashstr.c | 70 | ||||
-rw-r--r-- | e2fsprogs/e2p/iod.c | 72 | ||||
-rw-r--r-- | e2fsprogs/e2p/ls.c | 276 | ||||
-rw-r--r-- | e2fsprogs/e2p/mntopts.c | 136 | ||||
-rw-r--r-- | e2fsprogs/e2p/ostype.c | 73 | ||||
-rw-r--r-- | e2fsprogs/e2p/parse_num.c | 64 | ||||
-rw-r--r-- | e2fsprogs/e2p/pe.c | 37 | ||||
-rw-r--r-- | e2fsprogs/e2p/pf.c | 74 | ||||
-rw-r--r-- | e2fsprogs/e2p/ps.c | 29 | ||||
-rw-r--r-- | e2fsprogs/e2p/setflags.c | 72 | ||||
-rw-r--r-- | e2fsprogs/e2p/setversion.c | 36 | ||||
-rw-r--r-- | e2fsprogs/e2p/uuid.c | 79 | ||||
-rw-r--r-- | e2fsprogs/lsattr.c | 193 | ||||
-rw-r--r-- | sysdeps/linux/Config.in | 2 |
27 files changed, 2218 insertions, 2 deletions
@@ -42,7 +42,7 @@ include $(top_builddir)/Rules.mak | |||
42 | DIRS:=applets archival archival/libunarchive coreutils console-tools \ | 42 | DIRS:=applets archival archival/libunarchive coreutils console-tools \ |
43 | debianutils editors findutils init miscutils modutils networking \ | 43 | debianutils editors findutils init miscutils modutils networking \ |
44 | networking/libiproute networking/udhcp procps loginutils shell \ | 44 | networking/libiproute networking/udhcp procps loginutils shell \ |
45 | sysklogd util-linux libpwdgrp coreutils/libcoreutils libbb | 45 | sysklogd util-linux e2fsprogs libpwdgrp coreutils/libcoreutils libbb |
46 | 46 | ||
47 | SRC_DIRS:=$(patsubst %,$(top_srcdir)/%,$(DIRS)) | 47 | SRC_DIRS:=$(patsubst %,$(top_srcdir)/%,$(DIRS)) |
48 | 48 | ||
diff --git a/e2fsprogs/README b/e2fsprogs/README new file mode 100644 index 000000000..fac090193 --- /dev/null +++ b/e2fsprogs/README | |||
@@ -0,0 +1,3 @@ | |||
1 | This is a pretty straight rip from the e2fsprogs pkg. | ||
2 | |||
3 | See README's in subdirs for specific info. | ||
diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c new file mode 100644 index 000000000..7abc83176 --- /dev/null +++ b/e2fsprogs/chattr.c | |||
@@ -0,0 +1,305 @@ | |||
1 | /* | ||
2 | * chattr.c - Change 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 - Ignore symlinks when working recursively (G M Sipe) | ||
18 | * 98/12/29 - Display version info only when -V specified (G M Sipe) | ||
19 | */ | ||
20 | |||
21 | #include <sys/types.h> | ||
22 | #include <dirent.h> | ||
23 | #include <fcntl.h> | ||
24 | #include <stdio.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <unistd.h> | ||
27 | #include <string.h> | ||
28 | #include <errno.h> | ||
29 | #include <sys/param.h> | ||
30 | #include <sys/stat.h> | ||
31 | #include <ext2fs/ext2_fs.h> | ||
32 | |||
33 | #ifdef __GNUC__ | ||
34 | #define EXT2FS_ATTR(x) __attribute__(x) | ||
35 | #else | ||
36 | #define EXT2FS_ATTR(x) | ||
37 | #endif | ||
38 | |||
39 | #ifndef S_ISLNK /* So we can compile even with gcc-warn */ | ||
40 | # ifdef __S_IFLNK | ||
41 | # define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK) | ||
42 | # else | ||
43 | # define S_ISLNK(mode) 0 | ||
44 | # endif | ||
45 | #endif | ||
46 | |||
47 | #include "e2fsbb.h" | ||
48 | #include "e2p/e2p.h" | ||
49 | |||
50 | static int add; | ||
51 | static int rem; | ||
52 | static int set; | ||
53 | static int set_version; | ||
54 | |||
55 | static unsigned long version; | ||
56 | |||
57 | static int recursive; | ||
58 | static int verbose; | ||
59 | |||
60 | static unsigned long af; | ||
61 | static unsigned long rf; | ||
62 | static unsigned long sf; | ||
63 | |||
64 | #ifdef _LFS64_LARGEFILE | ||
65 | #define LSTAT lstat64 | ||
66 | #define STRUCT_STAT struct stat64 | ||
67 | #else | ||
68 | #define LSTAT lstat | ||
69 | #define STRUCT_STAT struct stat | ||
70 | #endif | ||
71 | |||
72 | #if 0 | ||
73 | static void fatal_error(const char * fmt_string, int errcode) | ||
74 | { | ||
75 | fprintf (stderr, fmt_string, program_name); | ||
76 | exit (errcode); | ||
77 | } | ||
78 | |||
79 | #define usage() fatal_error(_("usage: %s [-RV] [-+=AacDdijsSu] [-v version] files...\n"), \ | ||
80 | 1) | ||
81 | #endif | ||
82 | |||
83 | struct flags_char { | ||
84 | unsigned long flag; | ||
85 | char optchar; | ||
86 | }; | ||
87 | |||
88 | static const struct flags_char flags_array[] = { | ||
89 | { EXT2_NOATIME_FL, 'A' }, | ||
90 | { EXT2_SYNC_FL, 'S' }, | ||
91 | { EXT2_DIRSYNC_FL, 'D' }, | ||
92 | { EXT2_APPEND_FL, 'a' }, | ||
93 | { EXT2_COMPR_FL, 'c' }, | ||
94 | { EXT2_NODUMP_FL, 'd' }, | ||
95 | { EXT2_IMMUTABLE_FL, 'i' }, | ||
96 | { EXT3_JOURNAL_DATA_FL, 'j' }, | ||
97 | { EXT2_SECRM_FL, 's' }, | ||
98 | { EXT2_UNRM_FL, 'u' }, | ||
99 | { EXT2_NOTAIL_FL, 't' }, | ||
100 | { EXT2_TOPDIR_FL, 'T' }, | ||
101 | { 0, 0 } | ||
102 | }; | ||
103 | |||
104 | static unsigned long get_flag(char c) | ||
105 | { | ||
106 | const struct flags_char *fp; | ||
107 | |||
108 | for (fp = flags_array; fp->flag != 0; fp++) { | ||
109 | if (fp->optchar == c) | ||
110 | return fp->flag; | ||
111 | } | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | |||
116 | static int decode_arg (int * i, int argc, char ** argv) | ||
117 | { | ||
118 | char * p; | ||
119 | char * tmp; | ||
120 | unsigned long fl; | ||
121 | |||
122 | switch (argv[*i][0]) | ||
123 | { | ||
124 | case '-': | ||
125 | for (p = &argv[*i][1]; *p; p++) { | ||
126 | if (*p == 'R') { | ||
127 | recursive = 1; | ||
128 | continue; | ||
129 | } | ||
130 | if (*p == 'V') { | ||
131 | verbose = 1; | ||
132 | continue; | ||
133 | } | ||
134 | if (*p == 'v') { | ||
135 | (*i)++; | ||
136 | if (*i >= argc) | ||
137 | usage (); | ||
138 | version = strtol (argv[*i], &tmp, 0); | ||
139 | if (*tmp) { | ||
140 | com_err (program_name, 0, | ||
141 | _("bad version - %s\n"), | ||
142 | argv[*i]); | ||
143 | usage (); | ||
144 | } | ||
145 | set_version = 1; | ||
146 | continue; | ||
147 | } | ||
148 | if ((fl = get_flag(*p)) == 0) | ||
149 | usage(); | ||
150 | rf |= fl; | ||
151 | rem = 1; | ||
152 | } | ||
153 | break; | ||
154 | case '+': | ||
155 | add = 1; | ||
156 | for (p = &argv[*i][1]; *p; p++) { | ||
157 | if ((fl = get_flag(*p)) == 0) | ||
158 | usage(); | ||
159 | af |= fl; | ||
160 | } | ||
161 | break; | ||
162 | case '=': | ||
163 | set = 1; | ||
164 | for (p = &argv[*i][1]; *p; p++) { | ||
165 | if ((fl = get_flag(*p)) == 0) | ||
166 | usage(); | ||
167 | sf |= fl; | ||
168 | } | ||
169 | break; | ||
170 | default: | ||
171 | return EOF; | ||
172 | break; | ||
173 | } | ||
174 | return 1; | ||
175 | } | ||
176 | |||
177 | static int chattr_dir_proc (const char *, struct dirent *, void *); | ||
178 | |||
179 | static void change_attributes (const char * name) | ||
180 | { | ||
181 | unsigned long flags; | ||
182 | STRUCT_STAT st; | ||
183 | |||
184 | if (LSTAT (name, &st) == -1) { | ||
185 | com_err (program_name, errno, _("while trying to stat %s"), | ||
186 | name); | ||
187 | return; | ||
188 | } | ||
189 | if (S_ISLNK(st.st_mode) && recursive) | ||
190 | return; | ||
191 | |||
192 | /* Don't try to open device files, fifos etc. We probably | ||
193 | ought to display an error if the file was explicitly given | ||
194 | on the command line (whether or not recursive was | ||
195 | requested). */ | ||
196 | if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && | ||
197 | !S_ISDIR(st.st_mode)) | ||
198 | return; | ||
199 | |||
200 | if (set) { | ||
201 | if (verbose) { | ||
202 | printf (_("Flags of %s set as "), name); | ||
203 | print_flags (stdout, sf, 0); | ||
204 | printf ("\n"); | ||
205 | } | ||
206 | if (fsetflags (name, sf) == -1) | ||
207 | perror (name); | ||
208 | } else { | ||
209 | if (fgetflags (name, &flags) == -1) | ||
210 | com_err (program_name, errno, | ||
211 | _("while reading flags on %s"), name); | ||
212 | else { | ||
213 | if (rem) | ||
214 | flags &= ~rf; | ||
215 | if (add) | ||
216 | flags |= af; | ||
217 | if (verbose) { | ||
218 | printf (_("Flags of %s set as "), name); | ||
219 | print_flags (stdout, flags, 0); | ||
220 | printf ("\n"); | ||
221 | } | ||
222 | if (!S_ISDIR(st.st_mode)) | ||
223 | flags &= ~EXT2_DIRSYNC_FL; | ||
224 | if (fsetflags (name, flags) == -1) | ||
225 | com_err (program_name, errno, | ||
226 | _("while setting flags on %s"), name); | ||
227 | } | ||
228 | } | ||
229 | if (set_version) { | ||
230 | if (verbose) | ||
231 | printf (_("Version of %s set as %lu\n"), name, version); | ||
232 | if (fsetversion (name, version) == -1) | ||
233 | com_err (program_name, errno, | ||
234 | _("while setting version on %s"), name); | ||
235 | } | ||
236 | if (S_ISDIR(st.st_mode) && recursive) | ||
237 | iterate_on_dir (name, chattr_dir_proc, NULL); | ||
238 | } | ||
239 | |||
240 | static int chattr_dir_proc (const char * dir_name, struct dirent * de, | ||
241 | void * private EXT2FS_ATTR((unused))) | ||
242 | { | ||
243 | if (strcmp (de->d_name, ".") && strcmp (de->d_name, "..")) { | ||
244 | char *path; | ||
245 | |||
246 | path = malloc(strlen (dir_name) + 1 + strlen (de->d_name) + 1); | ||
247 | if (!path) | ||
248 | fatal_error(_("Couldn't allocate path variable " | ||
249 | "in chattr_dir_proc"), 1); | ||
250 | sprintf (path, "%s/%s", dir_name, de->d_name); | ||
251 | change_attributes (path); | ||
252 | free(path); | ||
253 | } | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | int chattr_main (int argc, char ** argv) | ||
258 | { | ||
259 | int i, j; | ||
260 | int end_arg = 0; | ||
261 | |||
262 | #ifdef ENABLE_NLS | ||
263 | setlocale(LC_MESSAGES, ""); | ||
264 | setlocale(LC_CTYPE, ""); | ||
265 | bindtextdomain(NLS_CAT_NAME, LOCALEDIR); | ||
266 | textdomain(NLS_CAT_NAME); | ||
267 | #endif | ||
268 | #if 0 | ||
269 | if (argc && *argv) | ||
270 | program_name = *argv; | ||
271 | #endif | ||
272 | i = 1; | ||
273 | while (i < argc && !end_arg) { | ||
274 | /* '--' arg should end option processing */ | ||
275 | if (strcmp(argv[i], "--") == 0) { | ||
276 | i++; | ||
277 | end_arg = 1; | ||
278 | } else if (decode_arg (&i, argc, argv) == EOF) | ||
279 | end_arg = 1; | ||
280 | else | ||
281 | i++; | ||
282 | } | ||
283 | if (i >= argc) | ||
284 | usage (); | ||
285 | if (set && (add || rem)) { | ||
286 | fputs(_("= is incompatible with - and +\n"), stderr); | ||
287 | exit (1); | ||
288 | } | ||
289 | if ((rf & af) != 0) { | ||
290 | fputs("Can't both set and unset same flag.\n", stderr); | ||
291 | exit (1); | ||
292 | } | ||
293 | if (!(add || rem || set || set_version)) { | ||
294 | fputs(_("Must use '-v', =, - or +\n"), stderr); | ||
295 | exit (1); | ||
296 | } | ||
297 | #if 0 | ||
298 | if (verbose) | ||
299 | fprintf (stderr, "chattr %s (%s)\n", | ||
300 | E2FSPROGS_VERSION, E2FSPROGS_DATE); | ||
301 | #endif | ||
302 | for (j = i; j < argc; j++) | ||
303 | change_attributes (argv[j]); | ||
304 | exit(0); | ||
305 | } | ||
diff --git a/e2fsprogs/e2fsbb.h b/e2fsprogs/e2fsbb.h new file mode 100644 index 000000000..358cfe099 --- /dev/null +++ b/e2fsprogs/e2fsbb.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * File: e2fsbb.h | ||
3 | * | ||
4 | * Redefine a bunch of e2fsprogs stuff to use busybox routines | ||
5 | * instead. This makes upgrade between e2fsprogs versions easy. | ||
6 | */ | ||
7 | |||
8 | #ifndef __E2FSBB_H__ | ||
9 | #define __E2FSBB_H__ 1 | ||
10 | |||
11 | #include "libbb.h" | ||
12 | |||
13 | /* version we've last synced against */ | ||
14 | #define E2FSPROGS_VERSION "1.37" | ||
15 | #define E2FSPROGS_DATE "21-Mar-2005" | ||
16 | |||
17 | /* make sure com_err.h isnt included before us */ | ||
18 | #ifdef __COM_ERR_H__ | ||
19 | #error You should not have included com_err.h ! | ||
20 | #endif | ||
21 | #define __COM_ERR_H__ | ||
22 | |||
23 | /* com_err crap */ | ||
24 | #define com_err(w, c, fmt, args...) bb_error_msg(fmt, ## args) | ||
25 | typedef long errcode_t; | ||
26 | #define ERRCODE_RANGE 8 | ||
27 | #define error_message(code) strerror((int) (code & ((1<<ERRCODE_RANGE)-1))) | ||
28 | |||
29 | /* NLS crap */ | ||
30 | #define _(x) x | ||
31 | |||
32 | /* misc crap */ | ||
33 | #define fputs(msg, fd) bb_error_msg(msg) | ||
34 | #define fatal_error(msg, err) bb_error_msg_and_die(msg) | ||
35 | #define usage() bb_show_usage() | ||
36 | #define perror(msg) bb_perror_msg(msg) | ||
37 | |||
38 | #endif /* __E2FSBB_H__ */ | ||
diff --git a/e2fsprogs/e2p/README b/e2fsprogs/e2p/README new file mode 100644 index 000000000..769947340 --- /dev/null +++ b/e2fsprogs/e2p/README | |||
@@ -0,0 +1,4 @@ | |||
1 | Simply copy the 'e2p' dir from e2fsprogs/lib/ and then delete the extra | ||
2 | files we don't need (Makefile.in, e2p.pc.in, etc...). Remove all of the | ||
3 | _LARGEFILE* define's from the few source files that use it since we'll be | ||
4 | appending it ourselves to CFLAGS when we compile. All done ! :) | ||
diff --git a/e2fsprogs/e2p/e2p.h b/e2fsprogs/e2p/e2p.h new file mode 100644 index 000000000..d208b46a8 --- /dev/null +++ b/e2fsprogs/e2p/e2p.h | |||
@@ -0,0 +1,52 @@ | |||
1 | #include <sys/types.h> /* Needed by dirent.h on netbsd */ | ||
2 | #include <stdio.h> | ||
3 | #include <dirent.h> | ||
4 | |||
5 | #include <ext2fs/ext2_fs.h> | ||
6 | |||
7 | #define E2P_FEATURE_COMPAT 0 | ||
8 | #define E2P_FEATURE_INCOMPAT 1 | ||
9 | #define E2P_FEATURE_RO_INCOMPAT 2 | ||
10 | |||
11 | |||
12 | /* `options' for print_flags() */ | ||
13 | |||
14 | #define PFOPT_LONG 1 /* Must be 1 for compatibility with `int long_format'. */ | ||
15 | |||
16 | |||
17 | int fgetflags (const char * name, unsigned long * flags); | ||
18 | int fgetversion (const char * name, unsigned long * version); | ||
19 | int fsetflags (const char * name, unsigned long flags); | ||
20 | int fsetversion (const char * name, unsigned long version); | ||
21 | int getflags (int fd, unsigned long * flags); | ||
22 | int getversion (int fd, unsigned long * version); | ||
23 | int iterate_on_dir (const char * dir_name, | ||
24 | int (*func) (const char *, struct dirent *, void *), | ||
25 | void * private); | ||
26 | void list_super(struct ext2_super_block * s); | ||
27 | void list_super2(struct ext2_super_block * s, FILE *f); | ||
28 | void print_fs_errors (FILE * f, unsigned short errors); | ||
29 | void print_flags (FILE * f, unsigned long flags, unsigned options); | ||
30 | void print_fs_state (FILE * f, unsigned short state); | ||
31 | int setflags (int fd, unsigned long flags); | ||
32 | int setversion (int fd, unsigned long version); | ||
33 | |||
34 | const char *e2p_feature2string(int compat, unsigned int mask); | ||
35 | int e2p_string2feature(char *string, int *compat, unsigned int *mask); | ||
36 | int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array); | ||
37 | |||
38 | int e2p_is_null_uuid(void *uu); | ||
39 | void e2p_uuid_to_str(void *uu, char *out); | ||
40 | const char *e2p_uuid2str(void *uu); | ||
41 | |||
42 | const char *e2p_hash2string(int num); | ||
43 | int e2p_string2hash(char *string); | ||
44 | |||
45 | const char *e2p_mntopt2string(unsigned int mask); | ||
46 | int e2p_string2mntopt(char *string, unsigned int *mask); | ||
47 | int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok); | ||
48 | |||
49 | unsigned long parse_num_blocks(const char *arg, int log_block_size); | ||
50 | |||
51 | char *e2p_os2string(int os_type); | ||
52 | int e2p_string2os(char *str); | ||
diff --git a/e2fsprogs/e2p/feature.c b/e2fsprogs/e2p/feature.c new file mode 100644 index 000000000..ef11d93b7 --- /dev/null +++ b/e2fsprogs/e2p/feature.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /* | ||
2 | * feature.c --- convert between features and strings | ||
3 | * | ||
4 | * Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu> | ||
5 | * | ||
6 | * This file can be redistributed under the terms of the GNU Library General | ||
7 | * Public License | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <string.h> | ||
14 | #include <ctype.h> | ||
15 | #include <errno.h> | ||
16 | |||
17 | #include "e2p.h" | ||
18 | |||
19 | struct feature { | ||
20 | int compat; | ||
21 | unsigned int mask; | ||
22 | const char *string; | ||
23 | }; | ||
24 | |||
25 | static struct feature feature_list[] = { | ||
26 | { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC, | ||
27 | "dir_prealloc" }, | ||
28 | { E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL, | ||
29 | "has_journal" }, | ||
30 | { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES, | ||
31 | "imagic_inodes" }, | ||
32 | { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR, | ||
33 | "ext_attr" }, | ||
34 | { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX, | ||
35 | "dir_index" }, | ||
36 | { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE, | ||
37 | "resize_inode" }, | ||
38 | { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER, | ||
39 | "sparse_super" }, | ||
40 | { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE, | ||
41 | "large_file" }, | ||
42 | { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION, | ||
43 | "compression" }, | ||
44 | { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE, | ||
45 | "filetype" }, | ||
46 | { E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER, | ||
47 | "needs_recovery" }, | ||
48 | { E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV, | ||
49 | "journal_dev" }, | ||
50 | { E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS, | ||
51 | "extents" }, | ||
52 | { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG, | ||
53 | "meta_bg" }, | ||
54 | { 0, 0, 0 }, | ||
55 | }; | ||
56 | |||
57 | const char *e2p_feature2string(int compat, unsigned int mask) | ||
58 | { | ||
59 | struct feature *f; | ||
60 | static char buf[20]; | ||
61 | char fchar; | ||
62 | int fnum; | ||
63 | |||
64 | for (f = feature_list; f->string; f++) { | ||
65 | if ((compat == f->compat) && | ||
66 | (mask == f->mask)) | ||
67 | return f->string; | ||
68 | } | ||
69 | switch (compat) { | ||
70 | case E2P_FEATURE_COMPAT: | ||
71 | fchar = 'C'; | ||
72 | break; | ||
73 | case E2P_FEATURE_INCOMPAT: | ||
74 | fchar = 'I'; | ||
75 | break; | ||
76 | case E2P_FEATURE_RO_INCOMPAT: | ||
77 | fchar = 'R'; | ||
78 | break; | ||
79 | default: | ||
80 | fchar = '?'; | ||
81 | break; | ||
82 | } | ||
83 | for (fnum = 0; mask >>= 1; fnum++); | ||
84 | sprintf(buf, "FEATURE_%c%d", fchar, fnum); | ||
85 | return buf; | ||
86 | } | ||
87 | |||
88 | int e2p_string2feature(char *string, int *compat_type, unsigned int *mask) | ||
89 | { | ||
90 | struct feature *f; | ||
91 | char *eptr; | ||
92 | int num; | ||
93 | |||
94 | for (f = feature_list; f->string; f++) { | ||
95 | if (!strcasecmp(string, f->string)) { | ||
96 | *compat_type = f->compat; | ||
97 | *mask = f->mask; | ||
98 | return 0; | ||
99 | } | ||
100 | } | ||
101 | if (strncasecmp(string, "FEATURE_", 8)) | ||
102 | return 1; | ||
103 | |||
104 | switch (string[8]) { | ||
105 | case 'c': | ||
106 | case 'C': | ||
107 | *compat_type = E2P_FEATURE_COMPAT; | ||
108 | break; | ||
109 | case 'i': | ||
110 | case 'I': | ||
111 | *compat_type = E2P_FEATURE_INCOMPAT; | ||
112 | break; | ||
113 | case 'r': | ||
114 | case 'R': | ||
115 | *compat_type = E2P_FEATURE_RO_INCOMPAT; | ||
116 | break; | ||
117 | default: | ||
118 | return 1; | ||
119 | } | ||
120 | if (string[9] == 0) | ||
121 | return 1; | ||
122 | num = strtol(string+9, &eptr, 10); | ||
123 | if (num > 32 || num < 0) | ||
124 | return 1; | ||
125 | if (*eptr) | ||
126 | return 1; | ||
127 | *mask = 1 << num; | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static char *skip_over_blanks(char *cp) | ||
132 | { | ||
133 | while (*cp && isspace(*cp)) | ||
134 | cp++; | ||
135 | return cp; | ||
136 | } | ||
137 | |||
138 | static char *skip_over_word(char *cp) | ||
139 | { | ||
140 | while (*cp && !isspace(*cp) && *cp != ',') | ||
141 | cp++; | ||
142 | return cp; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Edit a feature set array as requested by the user. The ok_array, | ||
147 | * if set, allows the application to limit what features the user is | ||
148 | * allowed to set or clear using this function. | ||
149 | */ | ||
150 | int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array) | ||
151 | { | ||
152 | char *cp, *buf, *next; | ||
153 | int neg; | ||
154 | unsigned int mask; | ||
155 | int compat_type; | ||
156 | |||
157 | buf = malloc(strlen(str)+1); | ||
158 | if (!buf) | ||
159 | return 1; | ||
160 | strcpy(buf, str); | ||
161 | cp = buf; | ||
162 | while (cp && *cp) { | ||
163 | neg = 0; | ||
164 | cp = skip_over_blanks(cp); | ||
165 | next = skip_over_word(cp); | ||
166 | if (*next == 0) | ||
167 | next = 0; | ||
168 | else | ||
169 | *next = 0; | ||
170 | switch (*cp) { | ||
171 | case '-': | ||
172 | case '^': | ||
173 | neg++; | ||
174 | case '+': | ||
175 | cp++; | ||
176 | break; | ||
177 | } | ||
178 | if (e2p_string2feature(cp, &compat_type, &mask)) | ||
179 | return 1; | ||
180 | if (ok_array && !(ok_array[compat_type] & mask)) | ||
181 | return 1; | ||
182 | if (neg) | ||
183 | compat_array[compat_type] &= ~mask; | ||
184 | else | ||
185 | compat_array[compat_type] |= mask; | ||
186 | cp = next ? next+1 : 0; | ||
187 | } | ||
188 | return 0; | ||
189 | } | ||
190 | |||
diff --git a/e2fsprogs/e2p/fgetflags.c b/e2fsprogs/e2p/fgetflags.c new file mode 100644 index 000000000..6db729e08 --- /dev/null +++ b/e2fsprogs/e2p/fgetflags.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * fgetflags.c - Get a file flags 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #if HAVE_UNISTD_H | ||
21 | #include <unistd.h> | ||
22 | #endif | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #if HAVE_EXT2_IOCTLS | ||
26 | #include <fcntl.h> | ||
27 | #include <sys/ioctl.h> | ||
28 | #endif | ||
29 | |||
30 | #include "e2p.h" | ||
31 | |||
32 | #ifdef O_LARGEFILE | ||
33 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) | ||
34 | #else | ||
35 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) | ||
36 | #endif | ||
37 | |||
38 | int fgetflags (const char * name, unsigned long * flags) | ||
39 | { | ||
40 | struct stat buf; | ||
41 | #if HAVE_STAT_FLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS) | ||
42 | |||
43 | if (stat (name, &buf) == -1) | ||
44 | return -1; | ||
45 | |||
46 | *flags = 0; | ||
47 | #ifdef UF_IMMUTABLE | ||
48 | if (buf.st_flags & UF_IMMUTABLE) | ||
49 | *flags |= EXT2_IMMUTABLE_FL; | ||
50 | #endif | ||
51 | #ifdef UF_APPEND | ||
52 | if (buf.st_flags & UF_APPEND) | ||
53 | *flags |= EXT2_APPEND_FL; | ||
54 | #endif | ||
55 | #ifdef UF_NODUMP | ||
56 | if (buf.st_flags & UF_NODUMP) | ||
57 | *flags |= EXT2_NODUMP_FL; | ||
58 | #endif | ||
59 | |||
60 | return 0; | ||
61 | #else | ||
62 | #if HAVE_EXT2_IOCTLS | ||
63 | int fd, r, f, save_errno = 0; | ||
64 | |||
65 | if (!stat(name, &buf) && | ||
66 | !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) { | ||
67 | goto notsupp; | ||
68 | } | ||
69 | #if !APPLE_DARWIN | ||
70 | fd = open (name, OPEN_FLAGS); | ||
71 | if (fd == -1) | ||
72 | return -1; | ||
73 | r = ioctl (fd, EXT2_IOC_GETFLAGS, &f); | ||
74 | if (r == -1) | ||
75 | save_errno = errno; | ||
76 | *flags = f; | ||
77 | close (fd); | ||
78 | if (save_errno) | ||
79 | errno = save_errno; | ||
80 | return r; | ||
81 | #else | ||
82 | f = -1; | ||
83 | save_errno = syscall(SYS_fsctl, name, EXT2_IOC_GETFLAGS, &f, 0); | ||
84 | *flags = f; | ||
85 | return (save_errno); | ||
86 | #endif | ||
87 | #endif /* HAVE_EXT2_IOCTLS */ | ||
88 | #endif | ||
89 | notsupp: | ||
90 | errno = EOPNOTSUPP; | ||
91 | return -1; | ||
92 | } | ||
diff --git a/e2fsprogs/e2p/fgetversion.c b/e2fsprogs/e2p/fgetversion.c new file mode 100644 index 000000000..351a7d5d0 --- /dev/null +++ b/e2fsprogs/e2p/fgetversion.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * fgetversion.c - Get a file version 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #if HAVE_UNISTD_H | ||
21 | #include <unistd.h> | ||
22 | #endif | ||
23 | #include <fcntl.h> | ||
24 | #include <sys/ioctl.h> | ||
25 | |||
26 | #include "e2p.h" | ||
27 | |||
28 | #ifdef O_LARGEFILE | ||
29 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) | ||
30 | #else | ||
31 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) | ||
32 | #endif | ||
33 | |||
34 | int fgetversion (const char * name, unsigned long * version) | ||
35 | { | ||
36 | #if HAVE_EXT2_IOCTLS | ||
37 | #if !APPLE_DARWIN | ||
38 | int fd, r, ver, save_errno = 0; | ||
39 | |||
40 | fd = open (name, OPEN_FLAGS); | ||
41 | if (fd == -1) | ||
42 | return -1; | ||
43 | r = ioctl (fd, EXT2_IOC_GETVERSION, &ver); | ||
44 | if (r == -1) | ||
45 | save_errno = errno; | ||
46 | *version = ver; | ||
47 | close (fd); | ||
48 | if (save_errno) | ||
49 | errno = save_errno; | ||
50 | return r; | ||
51 | #else | ||
52 | int ver=-1, err; | ||
53 | err = syscall(SYS_fsctl, name, EXT2_IOC_GETVERSION, &ver, 0); | ||
54 | *version = ver; | ||
55 | return(err); | ||
56 | #endif | ||
57 | #else /* ! HAVE_EXT2_IOCTLS */ | ||
58 | extern int errno; | ||
59 | errno = EOPNOTSUPP; | ||
60 | return -1; | ||
61 | #endif /* ! HAVE_EXT2_IOCTLS */ | ||
62 | } | ||
diff --git a/e2fsprogs/e2p/fsetflags.c b/e2fsprogs/e2p/fsetflags.c new file mode 100644 index 000000000..40e7292dd --- /dev/null +++ b/e2fsprogs/e2p/fsetflags.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * fsetflags.c - Set a file flags 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #if HAVE_UNISTD_H | ||
21 | #include <unistd.h> | ||
22 | #endif | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #if HAVE_EXT2_IOCTLS | ||
26 | #include <fcntl.h> | ||
27 | #include <sys/ioctl.h> | ||
28 | #endif | ||
29 | |||
30 | #include "e2p.h" | ||
31 | |||
32 | /* | ||
33 | * Deal with lame glibc's that define this function without actually | ||
34 | * implementing it. Can you say "attractive nuisance", boys and girls? | ||
35 | * I knew you could! | ||
36 | */ | ||
37 | #ifdef __linux__ | ||
38 | #undef HAVE_CHFLAGS | ||
39 | #endif | ||
40 | |||
41 | #ifdef O_LARGEFILE | ||
42 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) | ||
43 | #else | ||
44 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) | ||
45 | #endif | ||
46 | |||
47 | int fsetflags (const char * name, unsigned long flags) | ||
48 | { | ||
49 | struct stat buf; | ||
50 | #if HAVE_CHFLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS) | ||
51 | unsigned long bsd_flags = 0; | ||
52 | |||
53 | #ifdef UF_IMMUTABLE | ||
54 | if (flags & EXT2_IMMUTABLE_FL) | ||
55 | bsd_flags |= UF_IMMUTABLE; | ||
56 | #endif | ||
57 | #ifdef UF_APPEND | ||
58 | if (flags & EXT2_APPEND_FL) | ||
59 | bsd_flags |= UF_APPEND; | ||
60 | #endif | ||
61 | #ifdef UF_NODUMP | ||
62 | if (flags & EXT2_NODUMP_FL) | ||
63 | bsd_flags |= UF_NODUMP; | ||
64 | #endif | ||
65 | |||
66 | return chflags (name, bsd_flags); | ||
67 | #else | ||
68 | #if HAVE_EXT2_IOCTLS | ||
69 | int fd, r, f, save_errno = 0; | ||
70 | |||
71 | if (!stat(name, &buf) && | ||
72 | !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) { | ||
73 | goto notsupp; | ||
74 | } | ||
75 | #if !APPLE_DARWIN | ||
76 | fd = open (name, OPEN_FLAGS); | ||
77 | if (fd == -1) | ||
78 | return -1; | ||
79 | f = (int) flags; | ||
80 | r = ioctl (fd, EXT2_IOC_SETFLAGS, &f); | ||
81 | if (r == -1) | ||
82 | save_errno = errno; | ||
83 | close (fd); | ||
84 | if (save_errno) | ||
85 | errno = save_errno; | ||
86 | #else | ||
87 | f = (int) flags; | ||
88 | return syscall(SYS_fsctl, name, EXT2_IOC_SETFLAGS, &f, 0); | ||
89 | #endif | ||
90 | return r; | ||
91 | #endif /* HAVE_EXT2_IOCTLS */ | ||
92 | #endif | ||
93 | notsupp: | ||
94 | errno = EOPNOTSUPP; | ||
95 | return -1; | ||
96 | } | ||
diff --git a/e2fsprogs/e2p/fsetversion.c b/e2fsprogs/e2p/fsetversion.c new file mode 100644 index 000000000..93243d6e0 --- /dev/null +++ b/e2fsprogs/e2p/fsetversion.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * fsetversion.c - Set a file version 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #if HAVE_UNISTD_H | ||
21 | #include <unistd.h> | ||
22 | #endif | ||
23 | #include <fcntl.h> | ||
24 | #include <sys/ioctl.h> | ||
25 | |||
26 | #include "e2p.h" | ||
27 | |||
28 | #ifdef O_LARGEFILE | ||
29 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) | ||
30 | #else | ||
31 | #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) | ||
32 | #endif | ||
33 | |||
34 | int fsetversion (const char * name, unsigned long version) | ||
35 | { | ||
36 | #if HAVE_EXT2_IOCTLS | ||
37 | #if !APPLE_DARWIN | ||
38 | int fd, r, ver, save_errno = 0; | ||
39 | |||
40 | fd = open (name, OPEN_FLAGS); | ||
41 | if (fd == -1) | ||
42 | return -1; | ||
43 | ver = (int) version; | ||
44 | r = ioctl (fd, EXT2_IOC_SETVERSION, &ver); | ||
45 | if (r == -1) | ||
46 | save_errno = errno; | ||
47 | close (fd); | ||
48 | if (save_errno) | ||
49 | errno = save_errno; | ||
50 | return r; | ||
51 | #else | ||
52 | int ver = (int)version; | ||
53 | return syscall(SYS_fsctl, name, EXT2_IOC_SETVERSION, &ver, 0); | ||
54 | #endif | ||
55 | #else /* ! HAVE_EXT2_IOCTLS */ | ||
56 | extern int errno; | ||
57 | errno = EOPNOTSUPP; | ||
58 | return -1; | ||
59 | #endif /* ! HAVE_EXT2_IOCTLS */ | ||
60 | } | ||
diff --git a/e2fsprogs/e2p/getflags.c b/e2fsprogs/e2p/getflags.c new file mode 100644 index 000000000..acf7a122b --- /dev/null +++ b/e2fsprogs/e2p/getflags.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * getflags.c - Get a file flags 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #include <sys/types.h> | ||
21 | #include <sys/stat.h> | ||
22 | #if HAVE_EXT2_IOCTLS | ||
23 | #include <sys/ioctl.h> | ||
24 | #endif | ||
25 | |||
26 | #include "e2p.h" | ||
27 | |||
28 | int getflags (int fd, unsigned long * flags) | ||
29 | { | ||
30 | struct stat buf; | ||
31 | #if HAVE_STAT_FLAGS | ||
32 | |||
33 | if (fstat (fd, &buf) == -1) | ||
34 | return -1; | ||
35 | |||
36 | *flags = 0; | ||
37 | #ifdef UF_IMMUTABLE | ||
38 | if (buf.st_flags & UF_IMMUTABLE) | ||
39 | *flags |= EXT2_IMMUTABLE_FL; | ||
40 | #endif | ||
41 | #ifdef UF_APPEND | ||
42 | if (buf.st_flags & UF_APPEND) | ||
43 | *flags |= EXT2_APPEND_FL; | ||
44 | #endif | ||
45 | #ifdef UF_NODUMP | ||
46 | if (buf.st_flags & UF_NODUMP) | ||
47 | *flags |= EXT2_NODUMP_FL; | ||
48 | #endif | ||
49 | |||
50 | return 0; | ||
51 | #else | ||
52 | #if HAVE_EXT2_IOCTLS | ||
53 | int r, f; | ||
54 | |||
55 | if (!fstat(fd, &buf) && | ||
56 | !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) | ||
57 | goto notsupp; | ||
58 | r = ioctl (fd, EXT2_IOC_GETFLAGS, &f); | ||
59 | *flags = f; | ||
60 | return r; | ||
61 | #endif /* HAVE_EXT2_IOCTLS */ | ||
62 | #endif | ||
63 | notsupp: | ||
64 | errno = EOPNOTSUPP; | ||
65 | return -1; | ||
66 | } | ||
diff --git a/e2fsprogs/e2p/getversion.c b/e2fsprogs/e2p/getversion.c new file mode 100644 index 000000000..38b7d0fb0 --- /dev/null +++ b/e2fsprogs/e2p/getversion.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * getversion.c - Get a file version 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #include <sys/ioctl.h> | ||
21 | |||
22 | #include "e2p.h" | ||
23 | |||
24 | int getversion (int fd, unsigned long * version) | ||
25 | { | ||
26 | #if HAVE_EXT2_IOCTLS | ||
27 | int r, ver; | ||
28 | |||
29 | r = ioctl (fd, EXT2_IOC_GETVERSION, &ver); | ||
30 | *version = ver; | ||
31 | return 0; | ||
32 | #else /* ! HAVE_EXT2_IOCTLS */ | ||
33 | extern int errno; | ||
34 | errno = EOPNOTSUPP; | ||
35 | return -1; | ||
36 | #endif /* ! HAVE_EXT2_IOCTLS */ | ||
37 | } | ||
diff --git a/e2fsprogs/e2p/hashstr.c b/e2fsprogs/e2p/hashstr.c new file mode 100644 index 000000000..b257eb26c --- /dev/null +++ b/e2fsprogs/e2p/hashstr.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * feature.c --- convert between features and strings | ||
3 | * | ||
4 | * Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu> | ||
5 | * | ||
6 | * This file can be redistributed under the terms of the GNU Library General | ||
7 | * Public License | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <string.h> | ||
14 | #include <ctype.h> | ||
15 | #include <errno.h> | ||
16 | |||
17 | #include "e2p.h" | ||
18 | |||
19 | struct hash { | ||
20 | int num; | ||
21 | const char *string; | ||
22 | }; | ||
23 | |||
24 | static struct hash hash_list[] = { | ||
25 | { EXT2_HASH_LEGACY, "legacy" }, | ||
26 | { EXT2_HASH_HALF_MD4, "half_md4" }, | ||
27 | { EXT2_HASH_TEA, "tea" }, | ||
28 | { 0, 0 }, | ||
29 | }; | ||
30 | |||
31 | const char *e2p_hash2string(int num) | ||
32 | { | ||
33 | struct hash *p; | ||
34 | static char buf[20]; | ||
35 | |||
36 | for (p = hash_list; p->string; p++) { | ||
37 | if (num == p->num) | ||
38 | return p->string; | ||
39 | } | ||
40 | sprintf(buf, "HASHALG_%d", num); | ||
41 | return buf; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * Returns the hash algorithm, or -1 on error | ||
46 | */ | ||
47 | int e2p_string2hash(char *string) | ||
48 | { | ||
49 | struct hash *p; | ||
50 | char *eptr; | ||
51 | int num; | ||
52 | |||
53 | for (p = hash_list; p->string; p++) { | ||
54 | if (!strcasecmp(string, p->string)) { | ||
55 | return p->num; | ||
56 | } | ||
57 | } | ||
58 | if (strncasecmp(string, "HASHALG_", 8)) | ||
59 | return -1; | ||
60 | |||
61 | if (string[8] == 0) | ||
62 | return -1; | ||
63 | num = strtol(string+8, &eptr, 10); | ||
64 | if (num > 255 || num < 0) | ||
65 | return -1; | ||
66 | if (*eptr) | ||
67 | return -1; | ||
68 | return num; | ||
69 | } | ||
70 | |||
diff --git a/e2fsprogs/e2p/iod.c b/e2fsprogs/e2p/iod.c new file mode 100644 index 000000000..808d3a39d --- /dev/null +++ b/e2fsprogs/e2p/iod.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * iod.c - Iterate a function on each entry of a directory | ||
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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #include "e2p.h" | ||
18 | #if HAVE_UNISTD_H | ||
19 | #include <unistd.h> | ||
20 | #endif | ||
21 | #include <stdlib.h> | ||
22 | #include <string.h> | ||
23 | |||
24 | int iterate_on_dir (const char * dir_name, | ||
25 | int (*func) (const char *, struct dirent *, void *), | ||
26 | void * private) | ||
27 | { | ||
28 | DIR * dir; | ||
29 | struct dirent *de, *dep; | ||
30 | int max_len = -1, len; | ||
31 | |||
32 | #if HAVE_PATHCONF && defined(_PC_NAME_MAX) | ||
33 | max_len = pathconf(dir_name, _PC_NAME_MAX); | ||
34 | #endif | ||
35 | if (max_len == -1) { | ||
36 | #ifdef _POSIX_NAME_MAX | ||
37 | max_len = _POSIX_NAME_MAX; | ||
38 | #else | ||
39 | #ifdef NAME_MAX | ||
40 | max_len = NAME_MAX; | ||
41 | #else | ||
42 | max_len = 256; | ||
43 | #endif /* NAME_MAX */ | ||
44 | #endif /* _POSIX_NAME_MAX */ | ||
45 | } | ||
46 | max_len += sizeof(struct dirent); | ||
47 | |||
48 | de = malloc(max_len+1); | ||
49 | if (!de) | ||
50 | return -1; | ||
51 | memset(de, 0, max_len+1); | ||
52 | |||
53 | dir = opendir (dir_name); | ||
54 | if (dir == NULL) { | ||
55 | free(de); | ||
56 | return -1; | ||
57 | } | ||
58 | while ((dep = readdir (dir))) { | ||
59 | len = sizeof(struct dirent); | ||
60 | #ifdef HAVE_RECLEN_DIRENT | ||
61 | if (len < dep->d_reclen) | ||
62 | len = dep->d_reclen; | ||
63 | if (len > max_len) | ||
64 | len = max_len; | ||
65 | #endif | ||
66 | memcpy(de, dep, len); | ||
67 | (*func) (dir_name, de, private); | ||
68 | } | ||
69 | free(de); | ||
70 | closedir(dir); | ||
71 | return 0; | ||
72 | } | ||
diff --git a/e2fsprogs/e2p/ls.c b/e2fsprogs/e2p/ls.c new file mode 100644 index 000000000..e8d9d482d --- /dev/null +++ b/e2fsprogs/e2p/ls.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * ls.c - List the contents of an ext2fs superblock | ||
3 | * | ||
4 | * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr> | ||
5 | * Laboratoire MASI, Institut Blaise Pascal | ||
6 | * Universite Pierre et Marie Curie (Paris VI) | ||
7 | * | ||
8 | * Copyright (C) 1995, 1996, 1997 Theodore Ts'o <tytso@mit.edu> | ||
9 | * | ||
10 | * This file can be redistributed under the terms of the GNU Library General | ||
11 | * Public License | ||
12 | */ | ||
13 | |||
14 | #include <stdio.h> | ||
15 | #include <sys/types.h> | ||
16 | #include <string.h> | ||
17 | #include <grp.h> | ||
18 | #include <pwd.h> | ||
19 | #include <time.h> | ||
20 | |||
21 | #include "e2p.h" | ||
22 | |||
23 | static void print_user (unsigned short uid, FILE *f) | ||
24 | { | ||
25 | struct passwd *pw; | ||
26 | |||
27 | fprintf(f, "%u ", uid); | ||
28 | pw = getpwuid (uid); | ||
29 | if (pw == NULL) | ||
30 | fprintf(f, "(user unknown)\n"); | ||
31 | else | ||
32 | fprintf(f, "(user %s)\n", pw->pw_name); | ||
33 | } | ||
34 | |||
35 | static void print_group (unsigned short gid, FILE *f) | ||
36 | { | ||
37 | struct group *gr; | ||
38 | |||
39 | fprintf(f, "%u ", gid); | ||
40 | gr = getgrgid (gid); | ||
41 | if (gr == NULL) | ||
42 | fprintf(f, "(group unknown)\n"); | ||
43 | else | ||
44 | fprintf(f, "(group %s)\n", gr->gr_name); | ||
45 | } | ||
46 | |||
47 | #define MONTH_INT (86400 * 30) | ||
48 | #define WEEK_INT (86400 * 7) | ||
49 | #define DAY_INT (86400) | ||
50 | #define HOUR_INT (60 * 60) | ||
51 | #define MINUTE_INT (60) | ||
52 | |||
53 | static const char *interval_string(unsigned int secs) | ||
54 | { | ||
55 | static char buf[256], tmp[80]; | ||
56 | int hr, min, num; | ||
57 | |||
58 | buf[0] = 0; | ||
59 | |||
60 | if (secs == 0) | ||
61 | return "<none>"; | ||
62 | |||
63 | if (secs >= MONTH_INT) { | ||
64 | num = secs / MONTH_INT; | ||
65 | secs -= num*MONTH_INT; | ||
66 | sprintf(buf, "%d month%s", num, (num>1) ? "s" : ""); | ||
67 | } | ||
68 | if (secs >= WEEK_INT) { | ||
69 | num = secs / WEEK_INT; | ||
70 | secs -= num*WEEK_INT; | ||
71 | sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "", | ||
72 | num, (num>1) ? "s" : ""); | ||
73 | strcat(buf, tmp); | ||
74 | } | ||
75 | if (secs >= DAY_INT) { | ||
76 | num = secs / DAY_INT; | ||
77 | secs -= num*DAY_INT; | ||
78 | sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "", | ||
79 | num, (num>1) ? "s" : ""); | ||
80 | strcat(buf, tmp); | ||
81 | } | ||
82 | if (secs > 0) { | ||
83 | hr = secs / HOUR_INT; | ||
84 | secs -= hr*HOUR_INT; | ||
85 | min = secs / MINUTE_INT; | ||
86 | secs -= min*MINUTE_INT; | ||
87 | sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "", | ||
88 | hr, min, secs); | ||
89 | strcat(buf, tmp); | ||
90 | } | ||
91 | return buf; | ||
92 | } | ||
93 | |||
94 | static void print_features(struct ext2_super_block * s, FILE *f) | ||
95 | { | ||
96 | #ifdef EXT2_DYNAMIC_REV | ||
97 | int i, j, printed=0; | ||
98 | __u32 *mask = &s->s_feature_compat, m; | ||
99 | |||
100 | fprintf(f, "Filesystem features: "); | ||
101 | for (i=0; i <3; i++,mask++) { | ||
102 | for (j=0,m=1; j < 32; j++, m<<=1) { | ||
103 | if (*mask & m) { | ||
104 | fprintf(f, " %s", e2p_feature2string(i, m)); | ||
105 | printed++; | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | if (printed == 0) | ||
110 | fprintf(f, " (none)"); | ||
111 | fprintf(f, "\n"); | ||
112 | #endif | ||
113 | } | ||
114 | |||
115 | static void print_mntopts(struct ext2_super_block * s, FILE *f) | ||
116 | { | ||
117 | #ifdef EXT2_DYNAMIC_REV | ||
118 | int i, printed=0; | ||
119 | __u32 mask = s->s_default_mount_opts, m; | ||
120 | |||
121 | fprintf(f, "Default mount options: "); | ||
122 | if (mask & EXT3_DEFM_JMODE) { | ||
123 | fprintf(f, " %s", e2p_mntopt2string(mask & EXT3_DEFM_JMODE)); | ||
124 | printed++; | ||
125 | } | ||
126 | for (i=0,m=1; i < 32; i++, m<<=1) { | ||
127 | if (m & EXT3_DEFM_JMODE) | ||
128 | continue; | ||
129 | if (mask & m) { | ||
130 | fprintf(f, " %s", e2p_mntopt2string(m)); | ||
131 | printed++; | ||
132 | } | ||
133 | } | ||
134 | if (printed == 0) | ||
135 | fprintf(f, " (none)"); | ||
136 | fprintf(f, "\n"); | ||
137 | #endif | ||
138 | } | ||
139 | |||
140 | |||
141 | #ifndef EXT2_INODE_SIZE | ||
142 | #define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode) | ||
143 | #endif | ||
144 | |||
145 | #ifndef EXT2_GOOD_OLD_REV | ||
146 | #define EXT2_GOOD_OLD_REV 0 | ||
147 | #endif | ||
148 | |||
149 | void list_super2(struct ext2_super_block * sb, FILE *f) | ||
150 | { | ||
151 | int inode_blocks_per_group; | ||
152 | char buf[80], *str; | ||
153 | time_t tm; | ||
154 | |||
155 | inode_blocks_per_group = (((sb->s_inodes_per_group * | ||
156 | EXT2_INODE_SIZE(sb)) + | ||
157 | EXT2_BLOCK_SIZE(sb) - 1) / | ||
158 | EXT2_BLOCK_SIZE(sb)); | ||
159 | if (sb->s_volume_name[0]) { | ||
160 | memset(buf, 0, sizeof(buf)); | ||
161 | strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name)); | ||
162 | } else | ||
163 | strcpy(buf, "<none>"); | ||
164 | fprintf(f, "Filesystem volume name: %s\n", buf); | ||
165 | if (sb->s_last_mounted[0]) { | ||
166 | memset(buf, 0, sizeof(buf)); | ||
167 | strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted)); | ||
168 | } else | ||
169 | strcpy(buf, "<not available>"); | ||
170 | fprintf(f, "Last mounted on: %s\n", buf); | ||
171 | fprintf(f, "Filesystem UUID: %s\n", e2p_uuid2str(sb->s_uuid)); | ||
172 | fprintf(f, "Filesystem magic number: 0x%04X\n", sb->s_magic); | ||
173 | fprintf(f, "Filesystem revision #: %d", sb->s_rev_level); | ||
174 | if (sb->s_rev_level == EXT2_GOOD_OLD_REV) { | ||
175 | fprintf(f, " (original)\n"); | ||
176 | #ifdef EXT2_DYNAMIC_REV | ||
177 | } else if (sb->s_rev_level == EXT2_DYNAMIC_REV) { | ||
178 | fprintf(f, " (dynamic)\n"); | ||
179 | #endif | ||
180 | } else | ||
181 | fprintf(f, " (unknown)\n"); | ||
182 | print_features(sb, f); | ||
183 | print_mntopts(sb, f); | ||
184 | fprintf(f, "Filesystem state: "); | ||
185 | print_fs_state (f, sb->s_state); | ||
186 | fprintf(f, "\n"); | ||
187 | fprintf(f, "Errors behavior: "); | ||
188 | print_fs_errors(f, sb->s_errors); | ||
189 | fprintf(f, "\n"); | ||
190 | str = e2p_os2string(sb->s_creator_os); | ||
191 | fprintf(f, "Filesystem OS type: %s\n", str); | ||
192 | free(str); | ||
193 | fprintf(f, "Inode count: %u\n", sb->s_inodes_count); | ||
194 | fprintf(f, "Block count: %u\n", sb->s_blocks_count); | ||
195 | fprintf(f, "Reserved block count: %u\n", sb->s_r_blocks_count); | ||
196 | fprintf(f, "Free blocks: %u\n", sb->s_free_blocks_count); | ||
197 | fprintf(f, "Free inodes: %u\n", sb->s_free_inodes_count); | ||
198 | fprintf(f, "First block: %u\n", sb->s_first_data_block); | ||
199 | fprintf(f, "Block size: %u\n", EXT2_BLOCK_SIZE(sb)); | ||
200 | fprintf(f, "Fragment size: %u\n", EXT2_FRAG_SIZE(sb)); | ||
201 | if (sb->s_reserved_gdt_blocks) | ||
202 | fprintf(f, "Reserved GDT blocks: %u\n", | ||
203 | sb->s_reserved_gdt_blocks); | ||
204 | fprintf(f, "Blocks per group: %u\n", sb->s_blocks_per_group); | ||
205 | fprintf(f, "Fragments per group: %u\n", sb->s_frags_per_group); | ||
206 | fprintf(f, "Inodes per group: %u\n", sb->s_inodes_per_group); | ||
207 | fprintf(f, "Inode blocks per group: %u\n", inode_blocks_per_group); | ||
208 | if (sb->s_first_meta_bg) | ||
209 | fprintf(f, "First meta block group: %u\n", | ||
210 | sb->s_first_meta_bg); | ||
211 | if (sb->s_mkfs_time) { | ||
212 | tm = sb->s_mkfs_time; | ||
213 | fprintf(f, "Filesystem created: %s", ctime(&tm)); | ||
214 | } | ||
215 | tm = sb->s_mtime; | ||
216 | fprintf(f, "Last mount time: %s", | ||
217 | sb->s_mtime ? ctime(&tm) : "n/a\n"); | ||
218 | tm = sb->s_wtime; | ||
219 | fprintf(f, "Last write time: %s", ctime(&tm)); | ||
220 | fprintf(f, "Mount count: %u\n", sb->s_mnt_count); | ||
221 | fprintf(f, "Maximum mount count: %d\n", sb->s_max_mnt_count); | ||
222 | tm = sb->s_lastcheck; | ||
223 | fprintf(f, "Last checked: %s", ctime(&tm)); | ||
224 | fprintf(f, "Check interval: %u (%s)\n", sb->s_checkinterval, | ||
225 | interval_string(sb->s_checkinterval)); | ||
226 | if (sb->s_checkinterval) | ||
227 | { | ||
228 | time_t next; | ||
229 | |||
230 | next = sb->s_lastcheck + sb->s_checkinterval; | ||
231 | fprintf(f, "Next check after: %s", ctime(&next)); | ||
232 | } | ||
233 | fprintf(f, "Reserved blocks uid: "); | ||
234 | print_user(sb->s_def_resuid, f); | ||
235 | fprintf(f, "Reserved blocks gid: "); | ||
236 | print_group(sb->s_def_resgid, f); | ||
237 | if (sb->s_rev_level >= EXT2_DYNAMIC_REV) { | ||
238 | fprintf(f, "First inode: %d\n", sb->s_first_ino); | ||
239 | fprintf(f, "Inode size: %d\n", sb->s_inode_size); | ||
240 | } | ||
241 | if (!e2p_is_null_uuid(sb->s_journal_uuid)) | ||
242 | fprintf(f, "Journal UUID: %s\n", | ||
243 | e2p_uuid2str(sb->s_journal_uuid)); | ||
244 | if (sb->s_journal_inum) | ||
245 | fprintf(f, "Journal inode: %u\n", | ||
246 | sb->s_journal_inum); | ||
247 | if (sb->s_journal_dev) | ||
248 | fprintf(f, "Journal device: 0x%04x\n", | ||
249 | sb->s_journal_dev); | ||
250 | if (sb->s_last_orphan) | ||
251 | fprintf(f, "First orphan inode: %u\n", | ||
252 | sb->s_last_orphan); | ||
253 | if ((sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) || | ||
254 | sb->s_def_hash_version) | ||
255 | fprintf(f, "Default directory hash: %s\n", | ||
256 | e2p_hash2string(sb->s_def_hash_version)); | ||
257 | if (!e2p_is_null_uuid(sb->s_hash_seed)) | ||
258 | fprintf(f, "Directory Hash Seed: %s\n", | ||
259 | e2p_uuid2str(sb->s_hash_seed)); | ||
260 | if (sb->s_jnl_backup_type) { | ||
261 | fprintf(f, "Journal backup: "); | ||
262 | switch (sb->s_jnl_backup_type) { | ||
263 | case 1: | ||
264 | fprintf(f, "inode blocks\n"); | ||
265 | break; | ||
266 | default: | ||
267 | fprintf(f, "type %u\n", sb->s_jnl_backup_type); | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | void list_super (struct ext2_super_block * s) | ||
273 | { | ||
274 | list_super2(s, stdout); | ||
275 | } | ||
276 | |||
diff --git a/e2fsprogs/e2p/mntopts.c b/e2fsprogs/e2p/mntopts.c new file mode 100644 index 000000000..6d0eca0ae --- /dev/null +++ b/e2fsprogs/e2p/mntopts.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * mountopts.c --- convert between default mount options and strings | ||
3 | * | ||
4 | * Copyright (C) 2002 Theodore Ts'o <tytso@mit.edu> | ||
5 | * | ||
6 | * This file can be redistributed under the terms of the GNU Library General | ||
7 | * Public License | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <string.h> | ||
14 | #include <ctype.h> | ||
15 | #include <errno.h> | ||
16 | |||
17 | #include "e2p.h" | ||
18 | |||
19 | struct mntopt { | ||
20 | unsigned int mask; | ||
21 | const char *string; | ||
22 | }; | ||
23 | |||
24 | static struct mntopt mntopt_list[] = { | ||
25 | { EXT2_DEFM_DEBUG, "debug" }, | ||
26 | { EXT2_DEFM_BSDGROUPS, "bsdgroups" }, | ||
27 | { EXT2_DEFM_XATTR_USER, "user_xattr" }, | ||
28 | { EXT2_DEFM_ACL, "acl" }, | ||
29 | { EXT2_DEFM_UID16, "uid16" }, | ||
30 | { EXT3_DEFM_JMODE_DATA, "journal_data" }, | ||
31 | { EXT3_DEFM_JMODE_ORDERED, "journal_data_ordered" }, | ||
32 | { EXT3_DEFM_JMODE_WBACK, "journal_data_writeback" }, | ||
33 | { 0, 0 }, | ||
34 | }; | ||
35 | |||
36 | const char *e2p_mntopt2string(unsigned int mask) | ||
37 | { | ||
38 | struct mntopt *f; | ||
39 | static char buf[20]; | ||
40 | int fnum; | ||
41 | |||
42 | for (f = mntopt_list; f->string; f++) { | ||
43 | if (mask == f->mask) | ||
44 | return f->string; | ||
45 | } | ||
46 | for (fnum = 0; mask >>= 1; fnum++); | ||
47 | sprintf(buf, "MNTOPT_%d", fnum); | ||
48 | return buf; | ||
49 | } | ||
50 | |||
51 | int e2p_string2mntopt(char *string, unsigned int *mask) | ||
52 | { | ||
53 | struct mntopt *f; | ||
54 | char *eptr; | ||
55 | int num; | ||
56 | |||
57 | for (f = mntopt_list; f->string; f++) { | ||
58 | if (!strcasecmp(string, f->string)) { | ||
59 | *mask = f->mask; | ||
60 | return 0; | ||
61 | } | ||
62 | } | ||
63 | if (strncasecmp(string, "MNTOPT_", 8)) | ||
64 | return 1; | ||
65 | |||
66 | if (string[8] == 0) | ||
67 | return 1; | ||
68 | num = strtol(string+8, &eptr, 10); | ||
69 | if (num > 32 || num < 0) | ||
70 | return 1; | ||
71 | if (*eptr) | ||
72 | return 1; | ||
73 | *mask = 1 << num; | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static char *skip_over_blanks(char *cp) | ||
78 | { | ||
79 | while (*cp && isspace(*cp)) | ||
80 | cp++; | ||
81 | return cp; | ||
82 | } | ||
83 | |||
84 | static char *skip_over_word(char *cp) | ||
85 | { | ||
86 | while (*cp && !isspace(*cp) && *cp != ',') | ||
87 | cp++; | ||
88 | return cp; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * Edit a mntopt set array as requested by the user. The ok | ||
93 | * parameter, if non-zero, allows the application to limit what | ||
94 | * mntopts the user is allowed to set or clear using this function. | ||
95 | */ | ||
96 | int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok) | ||
97 | { | ||
98 | char *cp, *buf, *next; | ||
99 | int neg; | ||
100 | unsigned int mask; | ||
101 | |||
102 | buf = malloc(strlen(str)+1); | ||
103 | if (!buf) | ||
104 | return 1; | ||
105 | strcpy(buf, str); | ||
106 | cp = buf; | ||
107 | while (cp && *cp) { | ||
108 | neg = 0; | ||
109 | cp = skip_over_blanks(cp); | ||
110 | next = skip_over_word(cp); | ||
111 | if (*next == 0) | ||
112 | next = 0; | ||
113 | else | ||
114 | *next = 0; | ||
115 | switch (*cp) { | ||
116 | case '-': | ||
117 | case '^': | ||
118 | neg++; | ||
119 | case '+': | ||
120 | cp++; | ||
121 | break; | ||
122 | } | ||
123 | if (e2p_string2mntopt(cp, &mask)) | ||
124 | return 1; | ||
125 | if (ok && !(ok & mask)) | ||
126 | return 1; | ||
127 | if (mask & EXT3_DEFM_JMODE) | ||
128 | *mntopts &= ~EXT3_DEFM_JMODE; | ||
129 | if (neg) | ||
130 | *mntopts &= ~mask; | ||
131 | else | ||
132 | *mntopts |= mask; | ||
133 | cp = next ? next+1 : 0; | ||
134 | } | ||
135 | return 0; | ||
136 | } | ||
diff --git a/e2fsprogs/e2p/ostype.c b/e2fsprogs/e2p/ostype.c new file mode 100644 index 000000000..fe6597dd5 --- /dev/null +++ b/e2fsprogs/e2p/ostype.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * getostype.c - Get the Filesystem OS type | ||
3 | * | ||
4 | * Copyright (C) 2004,2005 Theodore Ts'o <tytso@mit.edu> | ||
5 | * | ||
6 | * This file can be redistributed under the terms of the GNU Library General | ||
7 | * Public License | ||
8 | */ | ||
9 | |||
10 | #include "e2p.h" | ||
11 | #include <string.h> | ||
12 | |||
13 | const char *os_tab[] = | ||
14 | { "Linux", | ||
15 | "Hurd", | ||
16 | "Masix", | ||
17 | "FreeBSD", | ||
18 | "Lites", | ||
19 | 0 }; | ||
20 | |||
21 | /* | ||
22 | * Convert an os_type to a string | ||
23 | */ | ||
24 | char *e2p_os2string(int os_type) | ||
25 | { | ||
26 | const char *os; | ||
27 | char *ret; | ||
28 | |||
29 | if (os_type <= EXT2_OS_LITES) | ||
30 | os = os_tab[os_type]; | ||
31 | else | ||
32 | os = "(unknown os)"; | ||
33 | |||
34 | ret = malloc(strlen(os)+1); | ||
35 | strcpy(ret, os); | ||
36 | return ret; | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Convert an os_type to a string | ||
41 | */ | ||
42 | int e2p_string2os(char *str) | ||
43 | { | ||
44 | const char **cpp; | ||
45 | int i = 0; | ||
46 | |||
47 | for (cpp = os_tab; *cpp; cpp++, i++) { | ||
48 | if (!strcasecmp(str, *cpp)) | ||
49 | return i; | ||
50 | } | ||
51 | return -1; | ||
52 | } | ||
53 | |||
54 | #ifdef TEST_PROGRAM | ||
55 | int main(int argc, char **argv) | ||
56 | { | ||
57 | char *s; | ||
58 | int i, os; | ||
59 | |||
60 | for (i=0; i <= EXT2_OS_LITES; i++) { | ||
61 | s = e2p_os2string(i); | ||
62 | os = e2p_string2os(s); | ||
63 | printf("%d: %s (%d)\n", i, s, os); | ||
64 | if (i != os) { | ||
65 | fprintf(stderr, "Failure!\n"); | ||
66 | exit(1); | ||
67 | } | ||
68 | } | ||
69 | exit(0); | ||
70 | } | ||
71 | #endif | ||
72 | |||
73 | |||
diff --git a/e2fsprogs/e2p/parse_num.c b/e2fsprogs/e2p/parse_num.c new file mode 100644 index 000000000..3910e70de --- /dev/null +++ b/e2fsprogs/e2p/parse_num.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * parse_num.c - Parse the number of blocks | ||
3 | * | ||
4 | * Copyright (C) 2004,2005 Theodore Ts'o <tytso@mit.edu> | ||
5 | * | ||
6 | * This file can be redistributed under the terms of the GNU Library General | ||
7 | * Public License | ||
8 | */ | ||
9 | |||
10 | #include "e2p.h" | ||
11 | |||
12 | #include <stdlib.h> | ||
13 | |||
14 | unsigned long parse_num_blocks(const char *arg, int log_block_size) | ||
15 | { | ||
16 | char *p; | ||
17 | unsigned long long num; | ||
18 | |||
19 | num = strtoull(arg, &p, 0); | ||
20 | |||
21 | if (p[0] && p[1]) | ||
22 | return 0; | ||
23 | |||
24 | switch (*p) { /* Using fall-through logic */ | ||
25 | case 'T': case 't': | ||
26 | num <<= 10; | ||
27 | case 'G': case 'g': | ||
28 | num <<= 10; | ||
29 | case 'M': case 'm': | ||
30 | num <<= 10; | ||
31 | case 'K': case 'k': | ||
32 | num >>= log_block_size; | ||
33 | break; | ||
34 | case 's': | ||
35 | num >>= 1; | ||
36 | break; | ||
37 | case '\0': | ||
38 | break; | ||
39 | default: | ||
40 | return 0; | ||
41 | } | ||
42 | return num; | ||
43 | } | ||
44 | |||
45 | #ifdef DEBUG | ||
46 | #include <unistd.h> | ||
47 | #include <stdio.h> | ||
48 | |||
49 | main(int argc, char **argv) | ||
50 | { | ||
51 | unsigned long num; | ||
52 | int log_block_size = 0; | ||
53 | |||
54 | if (argc != 2) { | ||
55 | fprintf(stderr, "Usage: %s arg\n", argv[0]); | ||
56 | exit(1); | ||
57 | } | ||
58 | |||
59 | num = parse_num_blocks(argv[1], log_block_size); | ||
60 | |||
61 | printf("Parsed number: %lu\n", num); | ||
62 | exit(0); | ||
63 | } | ||
64 | #endif | ||
diff --git a/e2fsprogs/e2p/pe.c b/e2fsprogs/e2p/pe.c new file mode 100644 index 000000000..4cce69117 --- /dev/null +++ b/e2fsprogs/e2p/pe.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * pe.c - Print a second extended filesystem errors behavior | ||
3 | * | ||
4 | * Copyright (C) 1992, 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 94/01/09 - Creation | ||
15 | */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | |||
19 | #include "e2p.h" | ||
20 | |||
21 | void print_fs_errors (FILE * f, unsigned short errors) | ||
22 | { | ||
23 | switch (errors) | ||
24 | { | ||
25 | case EXT2_ERRORS_CONTINUE: | ||
26 | fprintf (f, "Continue"); | ||
27 | break; | ||
28 | case EXT2_ERRORS_RO: | ||
29 | fprintf (f, "Remount read-only"); | ||
30 | break; | ||
31 | case EXT2_ERRORS_PANIC: | ||
32 | fprintf (f, "Panic"); | ||
33 | break; | ||
34 | default: | ||
35 | fprintf (f, "Unknown (continue)"); | ||
36 | } | ||
37 | } | ||
diff --git a/e2fsprogs/e2p/pf.c b/e2fsprogs/e2p/pf.c new file mode 100644 index 000000000..48d75a9ae --- /dev/null +++ b/e2fsprogs/e2p/pf.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * pf.c - Print 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | |||
19 | #include "e2p.h" | ||
20 | |||
21 | struct flags_name { | ||
22 | unsigned long flag; | ||
23 | const char *short_name; | ||
24 | const char *long_name; | ||
25 | }; | ||
26 | |||
27 | static struct flags_name flags_array[] = { | ||
28 | { EXT2_SECRM_FL, "s", "Secure_Deletion" }, | ||
29 | { EXT2_UNRM_FL, "u" , "Undelete" }, | ||
30 | { EXT2_SYNC_FL, "S", "Synchronous_Updates" }, | ||
31 | { EXT2_DIRSYNC_FL, "D", "Synchronous_Directory_Updates" }, | ||
32 | { EXT2_IMMUTABLE_FL, "i", "Immutable" }, | ||
33 | { EXT2_APPEND_FL, "a", "Append_Only" }, | ||
34 | { EXT2_NODUMP_FL, "d", "No_Dump" }, | ||
35 | { EXT2_NOATIME_FL, "A", "No_Atime" }, | ||
36 | { EXT2_COMPR_FL, "c", "Compression_Requested" }, | ||
37 | #ifdef ENABLE_COMPRESSION | ||
38 | { EXT2_COMPRBLK_FL, "B", "Compressed_File" }, | ||
39 | { EXT2_DIRTY_FL, "Z", "Compressed_Dirty_File" }, | ||
40 | { EXT2_NOCOMPR_FL, "X", "Compression_Raw_Access" }, | ||
41 | { EXT2_ECOMPR_FL, "E", "Compression_Error" }, | ||
42 | #endif | ||
43 | { EXT3_JOURNAL_DATA_FL, "j", "Journaled_Data" }, | ||
44 | { EXT2_INDEX_FL, "I", "Indexed_direcctory" }, | ||
45 | { EXT2_NOTAIL_FL, "t", "No_Tailmerging" }, | ||
46 | { EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" }, | ||
47 | { 0, NULL, NULL } | ||
48 | }; | ||
49 | |||
50 | void print_flags (FILE * f, unsigned long flags, unsigned options) | ||
51 | { | ||
52 | int long_opt = (options & PFOPT_LONG); | ||
53 | struct flags_name *fp; | ||
54 | int first = 1; | ||
55 | |||
56 | for (fp = flags_array; fp->flag != 0; fp++) { | ||
57 | if (flags & fp->flag) { | ||
58 | if (long_opt) { | ||
59 | if (first) | ||
60 | first = 0; | ||
61 | else | ||
62 | fputs(", ", f); | ||
63 | fputs(fp->long_name, f); | ||
64 | } else | ||
65 | fputs(fp->short_name, f); | ||
66 | } else { | ||
67 | if (!long_opt) | ||
68 | fputs("-", f); | ||
69 | } | ||
70 | } | ||
71 | if (long_opt && first) | ||
72 | fputs("---", f); | ||
73 | } | ||
74 | |||
diff --git a/e2fsprogs/e2p/ps.c b/e2fsprogs/e2p/ps.c new file mode 100644 index 000000000..bec8b4195 --- /dev/null +++ b/e2fsprogs/e2p/ps.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * ps.c - Print filesystem state | ||
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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/12/22 - Creation | ||
15 | */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | |||
19 | #include "e2p.h" | ||
20 | |||
21 | void print_fs_state (FILE * f, unsigned short state) | ||
22 | { | ||
23 | if (state & EXT2_VALID_FS) | ||
24 | fprintf (f, " clean"); | ||
25 | else | ||
26 | fprintf (f, " not clean"); | ||
27 | if (state & EXT2_ERROR_FS) | ||
28 | fprintf (f, " with errors"); | ||
29 | } | ||
diff --git a/e2fsprogs/e2p/setflags.c b/e2fsprogs/e2p/setflags.c new file mode 100644 index 000000000..47c52a7ad --- /dev/null +++ b/e2fsprogs/e2p/setflags.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * setflags.c - Set a file flags 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #include <sys/types.h> | ||
21 | #include <sys/stat.h> | ||
22 | #if HAVE_EXT2_IOCTLS | ||
23 | #include <sys/ioctl.h> | ||
24 | #endif | ||
25 | |||
26 | #include "e2p.h" | ||
27 | |||
28 | /* | ||
29 | * Deal with lame glibc's that define this function without actually | ||
30 | * implementing it. Can you say "attractive nuisance", boys and girls? | ||
31 | * I knew you could! | ||
32 | */ | ||
33 | #ifdef __linux__ | ||
34 | #undef HAVE_CHFLAGS | ||
35 | #endif | ||
36 | |||
37 | int setflags (int fd, unsigned long flags) | ||
38 | { | ||
39 | struct stat buf; | ||
40 | #if HAVE_CHFLAGS | ||
41 | unsigned long bsd_flags = 0; | ||
42 | |||
43 | #ifdef UF_IMMUTABLE | ||
44 | if (flags & EXT2_IMMUTABLE_FL) | ||
45 | bsd_flags |= UF_IMMUTABLE; | ||
46 | #endif | ||
47 | #ifdef UF_APPEND | ||
48 | if (flags & EXT2_APPEND_FL) | ||
49 | bsd_flags |= UF_APPEND; | ||
50 | #endif | ||
51 | #ifdef UF_NODUMP | ||
52 | if (flags & EXT2_NODUMP_FL) | ||
53 | bsd_flags |= UF_NODUMP; | ||
54 | #endif | ||
55 | |||
56 | return fchflags (fd, bsd_flags); | ||
57 | #else | ||
58 | #if HAVE_EXT2_IOCTLS | ||
59 | int f; | ||
60 | |||
61 | if (!fstat(fd, &buf) && | ||
62 | !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) { | ||
63 | errno = EOPNOTSUPP; | ||
64 | return -1; | ||
65 | } | ||
66 | f = (int) flags; | ||
67 | return ioctl (fd, EXT2_IOC_SETFLAGS, &f); | ||
68 | #endif /* HAVE_EXT2_IOCTLS */ | ||
69 | #endif | ||
70 | errno = EOPNOTSUPP; | ||
71 | return -1; | ||
72 | } | ||
diff --git a/e2fsprogs/e2p/setversion.c b/e2fsprogs/e2p/setversion.c new file mode 100644 index 000000000..bd00df668 --- /dev/null +++ b/e2fsprogs/e2p/setversion.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * setversion.c - Set a file version 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 Library General | ||
9 | * Public License | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * History: | ||
14 | * 93/10/30 - Creation | ||
15 | */ | ||
16 | |||
17 | #if HAVE_ERRNO_H | ||
18 | #include <errno.h> | ||
19 | #endif | ||
20 | #include <sys/ioctl.h> | ||
21 | |||
22 | #include "e2p.h" | ||
23 | |||
24 | int setversion (int fd, unsigned long version) | ||
25 | { | ||
26 | #if HAVE_EXT2_IOCTLS | ||
27 | int ver; | ||
28 | |||
29 | ver = (int) version; | ||
30 | return ioctl (fd, EXT2_IOC_SETVERSION, &ver); | ||
31 | #else /* ! HAVE_EXT2_IOCTLS */ | ||
32 | extern int errno; | ||
33 | errno = EOPNOTSUPP; | ||
34 | return -1; | ||
35 | #endif /* ! HAVE_EXT2_IOCTLS */ | ||
36 | } | ||
diff --git a/e2fsprogs/e2p/uuid.c b/e2fsprogs/e2p/uuid.c new file mode 100644 index 000000000..fef3b91e7 --- /dev/null +++ b/e2fsprogs/e2p/uuid.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * uuid.c -- utility routines for manipulating UUID's. | ||
3 | */ | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <string.h> | ||
7 | #include <ext2fs/ext2_types.h> | ||
8 | |||
9 | #include "e2p.h" | ||
10 | |||
11 | struct uuid { | ||
12 | __u32 time_low; | ||
13 | __u16 time_mid; | ||
14 | __u16 time_hi_and_version; | ||
15 | __u16 clock_seq; | ||
16 | __u8 node[6]; | ||
17 | }; | ||
18 | |||
19 | /* Returns 1 if the uuid is the NULL uuid */ | ||
20 | int e2p_is_null_uuid(void *uu) | ||
21 | { | ||
22 | __u8 *cp; | ||
23 | int i; | ||
24 | |||
25 | for (i=0, cp = uu; i < 16; i++) | ||
26 | if (*cp) | ||
27 | return 0; | ||
28 | return 1; | ||
29 | } | ||
30 | |||
31 | static void e2p_unpack_uuid(void *in, struct uuid *uu) | ||
32 | { | ||
33 | __u8 *ptr = in; | ||
34 | __u32 tmp; | ||
35 | |||
36 | tmp = *ptr++; | ||
37 | tmp = (tmp << 8) | *ptr++; | ||
38 | tmp = (tmp << 8) | *ptr++; | ||
39 | tmp = (tmp << 8) | *ptr++; | ||
40 | uu->time_low = tmp; | ||
41 | |||
42 | tmp = *ptr++; | ||
43 | tmp = (tmp << 8) | *ptr++; | ||
44 | uu->time_mid = tmp; | ||
45 | |||
46 | tmp = *ptr++; | ||
47 | tmp = (tmp << 8) | *ptr++; | ||
48 | uu->time_hi_and_version = tmp; | ||
49 | |||
50 | tmp = *ptr++; | ||
51 | tmp = (tmp << 8) | *ptr++; | ||
52 | uu->clock_seq = tmp; | ||
53 | |||
54 | memcpy(uu->node, ptr, 6); | ||
55 | } | ||
56 | |||
57 | void e2p_uuid_to_str(void *uu, char *out) | ||
58 | { | ||
59 | struct uuid uuid; | ||
60 | |||
61 | e2p_unpack_uuid(uu, &uuid); | ||
62 | sprintf(out, | ||
63 | "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", | ||
64 | uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, | ||
65 | uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, | ||
66 | uuid.node[0], uuid.node[1], uuid.node[2], | ||
67 | uuid.node[3], uuid.node[4], uuid.node[5]); | ||
68 | } | ||
69 | |||
70 | const char *e2p_uuid2str(void *uu) | ||
71 | { | ||
72 | static char buf[80]; | ||
73 | |||
74 | if (e2p_is_null_uuid(uu)) | ||
75 | return "<none>"; | ||
76 | e2p_uuid_to_str(uu, buf); | ||
77 | return buf; | ||
78 | } | ||
79 | |||
diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c new file mode 100644 index 000000000..0f1c6f22c --- /dev/null +++ b/e2fsprogs/lsattr.c | |||
@@ -0,0 +1,193 @@ | |||
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 | #include <errno.h> | ||
23 | #include <fcntl.h> | ||
24 | #include <getopt.h> | ||
25 | #include <stdio.h> | ||
26 | #include <unistd.h> | ||
27 | #include <stdlib.h> | ||
28 | #include <string.h> | ||
29 | #include <sys/param.h> | ||
30 | #include <sys/stat.h> | ||
31 | |||
32 | #include <ext2fs/ext2_fs.h> | ||
33 | #include "e2fsbb.h" | ||
34 | #include "e2p/e2p.h" | ||
35 | |||
36 | #ifdef __GNUC__ | ||
37 | #define EXT2FS_ATTR(x) __attribute__(x) | ||
38 | #else | ||
39 | #define EXT2FS_ATTR(x) | ||
40 | #endif | ||
41 | |||
42 | static int all; | ||
43 | static int dirs_opt; | ||
44 | static unsigned pf_options; | ||
45 | static int recursive; | ||
46 | static int verbose; | ||
47 | static int generation_opt; | ||
48 | |||
49 | #ifdef _LFS64_LARGEFILE | ||
50 | #define LSTAT lstat64 | ||
51 | #define STRUCT_STAT struct stat64 | ||
52 | #else | ||
53 | #define LSTAT lstat | ||
54 | #define STRUCT_STAT struct stat | ||
55 | #endif | ||
56 | |||
57 | #if 0 | ||
58 | static void usage(void) | ||
59 | { | ||
60 | fprintf(stderr, _("Usage: %s [-RVadlv] [files...]\n"), program_name); | ||
61 | exit(1); | ||
62 | } | ||
63 | #endif | ||
64 | |||
65 | static void list_attributes (const char * name) | ||
66 | { | ||
67 | unsigned long flags; | ||
68 | unsigned long generation; | ||
69 | |||
70 | if (fgetflags (name, &flags) == -1) { | ||
71 | com_err (program_name, errno, _("While reading flags on %s"), | ||
72 | name); | ||
73 | return; | ||
74 | } | ||
75 | if (generation_opt) { | ||
76 | if (fgetversion (name, &generation) == -1) { | ||
77 | com_err (program_name, errno, | ||
78 | _("While reading version on %s"), | ||
79 | name); | ||
80 | return; | ||
81 | } | ||
82 | printf ("%5lu ", generation); | ||
83 | } | ||
84 | if (pf_options & PFOPT_LONG) { | ||
85 | printf("%-28s ", name); | ||
86 | print_flags(stdout, flags, pf_options); | ||
87 | fputc('\n', stdout); | ||
88 | } else { | ||
89 | print_flags(stdout, flags, pf_options); | ||
90 | printf(" %s\n", name); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | static int lsattr_dir_proc (const char *, struct dirent *, void *); | ||
95 | |||
96 | static void lsattr_args (const char * name) | ||
97 | { | ||
98 | STRUCT_STAT st; | ||
99 | |||
100 | if (LSTAT (name, &st) == -1) | ||
101 | com_err (program_name, errno, _("while trying to stat %s"), | ||
102 | name); | ||
103 | else { | ||
104 | if (S_ISDIR(st.st_mode) && !dirs_opt) | ||
105 | iterate_on_dir (name, lsattr_dir_proc, NULL); | ||
106 | else | ||
107 | list_attributes (name); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static int lsattr_dir_proc (const char * dir_name, struct dirent * de, | ||
112 | void * private EXT2FS_ATTR((unused))) | ||
113 | { | ||
114 | STRUCT_STAT st; | ||
115 | char *path; | ||
116 | int dir_len = strlen(dir_name); | ||
117 | |||
118 | path = malloc(dir_len + strlen (de->d_name) + 2); | ||
119 | |||
120 | if (dir_len && dir_name[dir_len-1] == '/') | ||
121 | sprintf (path, "%s%s", dir_name, de->d_name); | ||
122 | else | ||
123 | sprintf (path, "%s/%s", dir_name, de->d_name); | ||
124 | if (LSTAT (path, &st) == -1) | ||
125 | perror (path); | ||
126 | else { | ||
127 | if (de->d_name[0] != '.' || all) { | ||
128 | list_attributes (path); | ||
129 | if (S_ISDIR(st.st_mode) && recursive && | ||
130 | strcmp(de->d_name, ".") && | ||
131 | strcmp(de->d_name, "..")) { | ||
132 | printf ("\n%s:\n", path); | ||
133 | iterate_on_dir (path, lsattr_dir_proc, NULL); | ||
134 | printf ("\n"); | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | free(path); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | int lsattr_main (int argc, char ** argv) | ||
143 | { | ||
144 | int c; | ||
145 | int i; | ||
146 | |||
147 | #ifdef ENABLE_NLS | ||
148 | setlocale(LC_MESSAGES, ""); | ||
149 | setlocale(LC_CTYPE, ""); | ||
150 | bindtextdomain(NLS_CAT_NAME, LOCALEDIR); | ||
151 | textdomain(NLS_CAT_NAME); | ||
152 | #endif | ||
153 | #if 0 | ||
154 | if (argc && *argv) | ||
155 | program_name = *argv; | ||
156 | #endif | ||
157 | while ((c = getopt (argc, argv, "Radlv")) != EOF) | ||
158 | switch (c) | ||
159 | { | ||
160 | case 'R': | ||
161 | recursive = 1; | ||
162 | break; | ||
163 | case 'V': | ||
164 | verbose = 1; | ||
165 | break; | ||
166 | case 'a': | ||
167 | all = 1; | ||
168 | break; | ||
169 | case 'd': | ||
170 | dirs_opt = 1; | ||
171 | break; | ||
172 | case 'l': | ||
173 | pf_options = PFOPT_LONG; | ||
174 | break; | ||
175 | case 'v': | ||
176 | generation_opt = 1; | ||
177 | break; | ||
178 | default: | ||
179 | usage(); | ||
180 | } | ||
181 | |||
182 | #if 0 | ||
183 | if (verbose) | ||
184 | fprintf (stderr, "lsattr %s (%s)\n", | ||
185 | E2FSPROGS_VERSION, E2FSPROGS_DATE); | ||
186 | #endif | ||
187 | if (optind > argc - 1) | ||
188 | lsattr_args ("."); | ||
189 | else | ||
190 | for (i = optind; i < argc; i++) | ||
191 | lsattr_args (argv[i]); | ||
192 | exit(0); | ||
193 | } | ||
diff --git a/sysdeps/linux/Config.in b/sysdeps/linux/Config.in index 744a84d18..e926b5973 100644 --- a/sysdeps/linux/Config.in +++ b/sysdeps/linux/Config.in | |||
@@ -221,6 +221,7 @@ source archival/Config.in | |||
221 | source coreutils/Config.in | 221 | source coreutils/Config.in |
222 | source console-tools/Config.in | 222 | source console-tools/Config.in |
223 | source debianutils/Config.in | 223 | source debianutils/Config.in |
224 | source e2fsprogs/Config.in | ||
224 | source editors/Config.in | 225 | source editors/Config.in |
225 | source findutils/Config.in | 226 | source findutils/Config.in |
226 | source init/Config.in | 227 | source init/Config.in |
@@ -291,4 +292,3 @@ endchoice | |||
291 | 292 | ||
292 | 293 | ||
293 | endmenu | 294 | endmenu |
294 | |||