aboutsummaryrefslogtreecommitdiff
path: root/e2fsprogs/e2p
diff options
context:
space:
mode:
authorvapier <vapier@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-04-24 05:07:59 +0000
committervapier <vapier@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-04-24 05:07:59 +0000
commit4c0d08bb6e9d9ba2d02a640874531f1baecc2716 (patch)
tree9aec1ca3d0a479bef39bd63c14f4292061d34675 /e2fsprogs/e2p
parent9fbf0da14393884fd9b05b4a61baac189ff14035 (diff)
downloadbusybox-w32-4c0d08bb6e9d9ba2d02a640874531f1baecc2716.tar.gz
busybox-w32-4c0d08bb6e9d9ba2d02a640874531f1baecc2716.tar.bz2
busybox-w32-4c0d08bb6e9d9ba2d02a640874531f1baecc2716.zip
add new subdir for e2fsprogs
git-svn-id: svn://busybox.net/trunk/busybox@10171 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'e2fsprogs/e2p')
-rw-r--r--e2fsprogs/e2p/README4
-rw-r--r--e2fsprogs/e2p/e2p.h52
-rw-r--r--e2fsprogs/e2p/feature.c190
-rw-r--r--e2fsprogs/e2p/fgetflags.c92
-rw-r--r--e2fsprogs/e2p/fgetversion.c62
-rw-r--r--e2fsprogs/e2p/fsetflags.c96
-rw-r--r--e2fsprogs/e2p/fsetversion.c60
-rw-r--r--e2fsprogs/e2p/getflags.c66
-rw-r--r--e2fsprogs/e2p/getversion.c37
-rw-r--r--e2fsprogs/e2p/hashstr.c70
-rw-r--r--e2fsprogs/e2p/iod.c72
-rw-r--r--e2fsprogs/e2p/ls.c276
-rw-r--r--e2fsprogs/e2p/mntopts.c136
-rw-r--r--e2fsprogs/e2p/ostype.c73
-rw-r--r--e2fsprogs/e2p/parse_num.c64
-rw-r--r--e2fsprogs/e2p/pe.c37
-rw-r--r--e2fsprogs/e2p/pf.c74
-rw-r--r--e2fsprogs/e2p/ps.c29
-rw-r--r--e2fsprogs/e2p/setflags.c72
-rw-r--r--e2fsprogs/e2p/setversion.c36
-rw-r--r--e2fsprogs/e2p/uuid.c79
21 files changed, 1677 insertions, 0 deletions
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 @@
1Simply copy the 'e2p' dir from e2fsprogs/lib/ and then delete the extra
2files 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
4appending 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
17int fgetflags (const char * name, unsigned long * flags);
18int fgetversion (const char * name, unsigned long * version);
19int fsetflags (const char * name, unsigned long flags);
20int fsetversion (const char * name, unsigned long version);
21int getflags (int fd, unsigned long * flags);
22int getversion (int fd, unsigned long * version);
23int iterate_on_dir (const char * dir_name,
24 int (*func) (const char *, struct dirent *, void *),
25 void * private);
26void list_super(struct ext2_super_block * s);
27void list_super2(struct ext2_super_block * s, FILE *f);
28void print_fs_errors (FILE * f, unsigned short errors);
29void print_flags (FILE * f, unsigned long flags, unsigned options);
30void print_fs_state (FILE * f, unsigned short state);
31int setflags (int fd, unsigned long flags);
32int setversion (int fd, unsigned long version);
33
34const char *e2p_feature2string(int compat, unsigned int mask);
35int e2p_string2feature(char *string, int *compat, unsigned int *mask);
36int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array);
37
38int e2p_is_null_uuid(void *uu);
39void e2p_uuid_to_str(void *uu, char *out);
40const char *e2p_uuid2str(void *uu);
41
42const char *e2p_hash2string(int num);
43int e2p_string2hash(char *string);
44
45const char *e2p_mntopt2string(unsigned int mask);
46int e2p_string2mntopt(char *string, unsigned int *mask);
47int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok);
48
49unsigned long parse_num_blocks(const char *arg, int log_block_size);
50
51char *e2p_os2string(int os_type);
52int 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
19struct feature {
20 int compat;
21 unsigned int mask;
22 const char *string;
23};
24
25static 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
57const 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
88int 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
131static char *skip_over_blanks(char *cp)
132{
133 while (*cp && isspace(*cp))
134 cp++;
135 return cp;
136}
137
138static 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 */
150int 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
38int 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
89notsupp:
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
34int 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
47int 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
93notsupp:
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
34int 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
28int 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
63notsupp:
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
24int 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
19struct hash {
20 int num;
21 const char *string;
22};
23
24static 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
31const 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 */
47int 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
24int 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
23static 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
35static 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
53static 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
94static 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
115static 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
149void 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
272void 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
19struct mntopt {
20 unsigned int mask;
21 const char *string;
22};
23
24static 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
36const 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
51int 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
77static char *skip_over_blanks(char *cp)
78{
79 while (*cp && isspace(*cp))
80 cp++;
81 return cp;
82}
83
84static 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 */
96int 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
13const 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 */
24char *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 */
42int 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
55int 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
14unsigned 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
49main(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
21void 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
21struct flags_name {
22 unsigned long flag;
23 const char *short_name;
24 const char *long_name;
25};
26
27static 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
50void 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
21void 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
37int 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
24int 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
11struct 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 */
20int 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
31static 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
57void 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
70const 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