xref: /aosp_15_r20/external/e2fsprogs/misc/e2initrd_helper.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker  * e2initrd_helper.c - Get the filesystem table
3*6a54128fSAndroid Build Coastguard Worker  *
4*6a54128fSAndroid Build Coastguard Worker  * Copyright 2004 by Theodore Ts'o.
5*6a54128fSAndroid Build Coastguard Worker  *
6*6a54128fSAndroid Build Coastguard Worker  * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker  * This file may be redistributed under the terms of the GNU Public
8*6a54128fSAndroid Build Coastguard Worker  * License.
9*6a54128fSAndroid Build Coastguard Worker  * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker  */
11*6a54128fSAndroid Build Coastguard Worker 
12*6a54128fSAndroid Build Coastguard Worker #include "config.h"
13*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
14*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
15*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_STDLIB_H
16*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
17*6a54128fSAndroid Build Coastguard Worker #endif
18*6a54128fSAndroid Build Coastguard Worker #include <ctype.h>
19*6a54128fSAndroid Build Coastguard Worker #include <string.h>
20*6a54128fSAndroid Build Coastguard Worker #include <time.h>
21*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_ERRNO_H
22*6a54128fSAndroid Build Coastguard Worker #include <errno.h>
23*6a54128fSAndroid Build Coastguard Worker #endif
24*6a54128fSAndroid Build Coastguard Worker #include <sys/types.h>
25*6a54128fSAndroid Build Coastguard Worker #include <sys/stat.h>
26*6a54128fSAndroid Build Coastguard Worker #include <fcntl.h>
27*6a54128fSAndroid Build Coastguard Worker #include <utime.h>
28*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_GETOPT_H
29*6a54128fSAndroid Build Coastguard Worker #include <getopt.h>
30*6a54128fSAndroid Build Coastguard Worker #else
31*6a54128fSAndroid Build Coastguard Worker extern int optind;
32*6a54128fSAndroid Build Coastguard Worker extern char *optarg;
33*6a54128fSAndroid Build Coastguard Worker #endif
34*6a54128fSAndroid Build Coastguard Worker 
35*6a54128fSAndroid Build Coastguard Worker #include "ext2fs/ext2_fs.h"
36*6a54128fSAndroid Build Coastguard Worker #include "ext2fs/ext2fs.h"
37*6a54128fSAndroid Build Coastguard Worker #include "blkid/blkid.h"
38*6a54128fSAndroid Build Coastguard Worker #include "support/nls-enable.h"
39*6a54128fSAndroid Build Coastguard Worker #include "support/devname.h"
40*6a54128fSAndroid Build Coastguard Worker 
41*6a54128fSAndroid Build Coastguard Worker #include "../version.h"
42*6a54128fSAndroid Build Coastguard Worker 
43*6a54128fSAndroid Build Coastguard Worker static const char * program_name = "e2initrd_helper";
44*6a54128fSAndroid Build Coastguard Worker static char * device_name;
45*6a54128fSAndroid Build Coastguard Worker static int open_flag;
46*6a54128fSAndroid Build Coastguard Worker static int root_type;
47*6a54128fSAndroid Build Coastguard Worker static blkid_cache cache = NULL;
48*6a54128fSAndroid Build Coastguard Worker 
49*6a54128fSAndroid Build Coastguard Worker struct mem_file {
50*6a54128fSAndroid Build Coastguard Worker 	char	*buf;
51*6a54128fSAndroid Build Coastguard Worker 	int	size;
52*6a54128fSAndroid Build Coastguard Worker 	int	ptr;
53*6a54128fSAndroid Build Coastguard Worker };
54*6a54128fSAndroid Build Coastguard Worker 
55*6a54128fSAndroid Build Coastguard Worker struct fs_info {
56*6a54128fSAndroid Build Coastguard Worker 	char  *device;
57*6a54128fSAndroid Build Coastguard Worker 	char  *mountpt;
58*6a54128fSAndroid Build Coastguard Worker 	char  *type;
59*6a54128fSAndroid Build Coastguard Worker 	char  *opts;
60*6a54128fSAndroid Build Coastguard Worker 	int   freq;
61*6a54128fSAndroid Build Coastguard Worker 	int   passno;
62*6a54128fSAndroid Build Coastguard Worker 	int   flags;
63*6a54128fSAndroid Build Coastguard Worker 	struct fs_info *next;
64*6a54128fSAndroid Build Coastguard Worker };
65*6a54128fSAndroid Build Coastguard Worker 
usage(void)66*6a54128fSAndroid Build Coastguard Worker static void usage(void)
67*6a54128fSAndroid Build Coastguard Worker {
68*6a54128fSAndroid Build Coastguard Worker 	fprintf(stderr,
69*6a54128fSAndroid Build Coastguard Worker 		_("Usage: %s -r device\n"), program_name);
70*6a54128fSAndroid Build Coastguard Worker 	exit (1);
71*6a54128fSAndroid Build Coastguard Worker }
72*6a54128fSAndroid Build Coastguard Worker 
get_file(ext2_filsys fs,const char * filename,struct mem_file * ret_file)73*6a54128fSAndroid Build Coastguard Worker static errcode_t get_file(ext2_filsys fs, const char * filename,
74*6a54128fSAndroid Build Coastguard Worker 		   struct mem_file *ret_file)
75*6a54128fSAndroid Build Coastguard Worker {
76*6a54128fSAndroid Build Coastguard Worker 	errcode_t	retval;
77*6a54128fSAndroid Build Coastguard Worker 	char 		*buf;
78*6a54128fSAndroid Build Coastguard Worker 	ext2_file_t	e2_file = NULL;
79*6a54128fSAndroid Build Coastguard Worker 	unsigned int	got;
80*6a54128fSAndroid Build Coastguard Worker 	struct ext2_inode inode;
81*6a54128fSAndroid Build Coastguard Worker 	ext2_ino_t	ino;
82*6a54128fSAndroid Build Coastguard Worker 
83*6a54128fSAndroid Build Coastguard Worker 	ret_file->buf = 0;
84*6a54128fSAndroid Build Coastguard Worker 	ret_file->size = 0;
85*6a54128fSAndroid Build Coastguard Worker 	ret_file->ptr = 0;
86*6a54128fSAndroid Build Coastguard Worker 
87*6a54128fSAndroid Build Coastguard Worker 	retval = ext2fs_namei(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
88*6a54128fSAndroid Build Coastguard Worker 			      filename, &ino);
89*6a54128fSAndroid Build Coastguard Worker 	if (retval)
90*6a54128fSAndroid Build Coastguard Worker 		return retval;
91*6a54128fSAndroid Build Coastguard Worker 
92*6a54128fSAndroid Build Coastguard Worker 	retval = ext2fs_read_inode(fs, ino, &inode);
93*6a54128fSAndroid Build Coastguard Worker 	if (retval)
94*6a54128fSAndroid Build Coastguard Worker 		return retval;
95*6a54128fSAndroid Build Coastguard Worker 
96*6a54128fSAndroid Build Coastguard Worker 	if (inode.i_size_high || (inode.i_size > 65536))
97*6a54128fSAndroid Build Coastguard Worker 		return EFBIG;
98*6a54128fSAndroid Build Coastguard Worker 
99*6a54128fSAndroid Build Coastguard Worker 	buf = malloc(inode.i_size + 1);
100*6a54128fSAndroid Build Coastguard Worker 	if (!buf)
101*6a54128fSAndroid Build Coastguard Worker 		return ENOMEM;
102*6a54128fSAndroid Build Coastguard Worker 	memset(buf, 0, inode.i_size+1);
103*6a54128fSAndroid Build Coastguard Worker 
104*6a54128fSAndroid Build Coastguard Worker 	retval = ext2fs_file_open(fs, ino, 0, &e2_file);
105*6a54128fSAndroid Build Coastguard Worker 	if (retval)
106*6a54128fSAndroid Build Coastguard Worker 		goto errout;
107*6a54128fSAndroid Build Coastguard Worker 
108*6a54128fSAndroid Build Coastguard Worker 	retval = ext2fs_file_read(e2_file, buf, inode.i_size, &got);
109*6a54128fSAndroid Build Coastguard Worker 	if (retval)
110*6a54128fSAndroid Build Coastguard Worker 		goto errout;
111*6a54128fSAndroid Build Coastguard Worker 
112*6a54128fSAndroid Build Coastguard Worker 	retval = ext2fs_file_close(e2_file);
113*6a54128fSAndroid Build Coastguard Worker 	if (retval)
114*6a54128fSAndroid Build Coastguard Worker 		goto errout;
115*6a54128fSAndroid Build Coastguard Worker 
116*6a54128fSAndroid Build Coastguard Worker 	ret_file->buf = buf;
117*6a54128fSAndroid Build Coastguard Worker 	ret_file->size = (int) got;
118*6a54128fSAndroid Build Coastguard Worker 	return 0;
119*6a54128fSAndroid Build Coastguard Worker 
120*6a54128fSAndroid Build Coastguard Worker errout:
121*6a54128fSAndroid Build Coastguard Worker 	free(buf);
122*6a54128fSAndroid Build Coastguard Worker 	if (e2_file)
123*6a54128fSAndroid Build Coastguard Worker 		ext2fs_file_close(e2_file);
124*6a54128fSAndroid Build Coastguard Worker 	return retval;
125*6a54128fSAndroid Build Coastguard Worker }
126*6a54128fSAndroid Build Coastguard Worker 
get_line(struct mem_file * file)127*6a54128fSAndroid Build Coastguard Worker static char *get_line(struct mem_file *file)
128*6a54128fSAndroid Build Coastguard Worker {
129*6a54128fSAndroid Build Coastguard Worker 	char	*cp, *ret;
130*6a54128fSAndroid Build Coastguard Worker 	int	s = 0;
131*6a54128fSAndroid Build Coastguard Worker 
132*6a54128fSAndroid Build Coastguard Worker 	cp = file->buf + file->ptr;
133*6a54128fSAndroid Build Coastguard Worker 	while (*cp && *cp != '\n') {
134*6a54128fSAndroid Build Coastguard Worker 		cp++;
135*6a54128fSAndroid Build Coastguard Worker 		s++;
136*6a54128fSAndroid Build Coastguard Worker 	}
137*6a54128fSAndroid Build Coastguard Worker 	ret = malloc(s+1);
138*6a54128fSAndroid Build Coastguard Worker 	if (!ret)
139*6a54128fSAndroid Build Coastguard Worker 		return 0;
140*6a54128fSAndroid Build Coastguard Worker 	ret[s]=0;
141*6a54128fSAndroid Build Coastguard Worker 	memcpy(ret, file->buf + file->ptr, s);
142*6a54128fSAndroid Build Coastguard Worker 	while (*cp && (*cp == '\n' || *cp == '\r')) {
143*6a54128fSAndroid Build Coastguard Worker 		cp++;
144*6a54128fSAndroid Build Coastguard Worker 		s++;
145*6a54128fSAndroid Build Coastguard Worker 	}
146*6a54128fSAndroid Build Coastguard Worker 	file->ptr += s;
147*6a54128fSAndroid Build Coastguard Worker 	return ret;
148*6a54128fSAndroid Build Coastguard Worker }
149*6a54128fSAndroid Build Coastguard Worker 
mem_file_eof(struct mem_file * file)150*6a54128fSAndroid Build Coastguard Worker static int mem_file_eof(struct mem_file *file)
151*6a54128fSAndroid Build Coastguard Worker {
152*6a54128fSAndroid Build Coastguard Worker 	return (file->ptr >= file->size);
153*6a54128fSAndroid Build Coastguard Worker }
154*6a54128fSAndroid Build Coastguard Worker 
155*6a54128fSAndroid Build Coastguard Worker /*
156*6a54128fSAndroid Build Coastguard Worker  * fstab parsing code
157*6a54128fSAndroid Build Coastguard Worker  */
string_copy(const char * s)158*6a54128fSAndroid Build Coastguard Worker static char *string_copy(const char *s)
159*6a54128fSAndroid Build Coastguard Worker {
160*6a54128fSAndroid Build Coastguard Worker 	char	*ret;
161*6a54128fSAndroid Build Coastguard Worker 
162*6a54128fSAndroid Build Coastguard Worker 	if (!s)
163*6a54128fSAndroid Build Coastguard Worker 		return 0;
164*6a54128fSAndroid Build Coastguard Worker 	ret = malloc(strlen(s)+1);
165*6a54128fSAndroid Build Coastguard Worker 	if (ret)
166*6a54128fSAndroid Build Coastguard Worker 		strcpy(ret, s);
167*6a54128fSAndroid Build Coastguard Worker 	return ret;
168*6a54128fSAndroid Build Coastguard Worker }
169*6a54128fSAndroid Build Coastguard Worker 
skip_over_blank(char * cp)170*6a54128fSAndroid Build Coastguard Worker static char *skip_over_blank(char *cp)
171*6a54128fSAndroid Build Coastguard Worker {
172*6a54128fSAndroid Build Coastguard Worker 	while (*cp && isspace(*cp))
173*6a54128fSAndroid Build Coastguard Worker 		cp++;
174*6a54128fSAndroid Build Coastguard Worker 	return cp;
175*6a54128fSAndroid Build Coastguard Worker }
176*6a54128fSAndroid Build Coastguard Worker 
skip_over_word(char * cp)177*6a54128fSAndroid Build Coastguard Worker static char *skip_over_word(char *cp)
178*6a54128fSAndroid Build Coastguard Worker {
179*6a54128fSAndroid Build Coastguard Worker 	while (*cp && !isspace(*cp))
180*6a54128fSAndroid Build Coastguard Worker 		cp++;
181*6a54128fSAndroid Build Coastguard Worker 	return cp;
182*6a54128fSAndroid Build Coastguard Worker }
183*6a54128fSAndroid Build Coastguard Worker 
parse_word(char ** buf)184*6a54128fSAndroid Build Coastguard Worker static char *parse_word(char **buf)
185*6a54128fSAndroid Build Coastguard Worker {
186*6a54128fSAndroid Build Coastguard Worker 	char *word, *next;
187*6a54128fSAndroid Build Coastguard Worker 
188*6a54128fSAndroid Build Coastguard Worker 	word = *buf;
189*6a54128fSAndroid Build Coastguard Worker 	if (*word == 0)
190*6a54128fSAndroid Build Coastguard Worker 		return 0;
191*6a54128fSAndroid Build Coastguard Worker 
192*6a54128fSAndroid Build Coastguard Worker 	word = skip_over_blank(word);
193*6a54128fSAndroid Build Coastguard Worker 	next = skip_over_word(word);
194*6a54128fSAndroid Build Coastguard Worker 	if (*next)
195*6a54128fSAndroid Build Coastguard Worker 		*next++ = 0;
196*6a54128fSAndroid Build Coastguard Worker 	*buf = next;
197*6a54128fSAndroid Build Coastguard Worker 	return word;
198*6a54128fSAndroid Build Coastguard Worker }
199*6a54128fSAndroid Build Coastguard Worker 
parse_escape(char * word)200*6a54128fSAndroid Build Coastguard Worker static void parse_escape(char *word)
201*6a54128fSAndroid Build Coastguard Worker {
202*6a54128fSAndroid Build Coastguard Worker 	char	*p, *q;
203*6a54128fSAndroid Build Coastguard Worker 	int	ac, i;
204*6a54128fSAndroid Build Coastguard Worker 
205*6a54128fSAndroid Build Coastguard Worker 	if (!word)
206*6a54128fSAndroid Build Coastguard Worker 		return;
207*6a54128fSAndroid Build Coastguard Worker 
208*6a54128fSAndroid Build Coastguard Worker 	for (p = word, q = word; *p; p++, q++) {
209*6a54128fSAndroid Build Coastguard Worker 		*q = *p;
210*6a54128fSAndroid Build Coastguard Worker 		if (*p != '\\')
211*6a54128fSAndroid Build Coastguard Worker 			continue;
212*6a54128fSAndroid Build Coastguard Worker 		if (*++p == 0)
213*6a54128fSAndroid Build Coastguard Worker 			break;
214*6a54128fSAndroid Build Coastguard Worker 		if (*p == 't') {
215*6a54128fSAndroid Build Coastguard Worker 			*q = '\t';
216*6a54128fSAndroid Build Coastguard Worker 			continue;
217*6a54128fSAndroid Build Coastguard Worker 		}
218*6a54128fSAndroid Build Coastguard Worker 		if (*p == 'n') {
219*6a54128fSAndroid Build Coastguard Worker 			*q = '\n';
220*6a54128fSAndroid Build Coastguard Worker 			continue;
221*6a54128fSAndroid Build Coastguard Worker 		}
222*6a54128fSAndroid Build Coastguard Worker 		if (!isdigit(*p)) {
223*6a54128fSAndroid Build Coastguard Worker 			*q = *p;
224*6a54128fSAndroid Build Coastguard Worker 			continue;
225*6a54128fSAndroid Build Coastguard Worker 		}
226*6a54128fSAndroid Build Coastguard Worker 		ac = 0;
227*6a54128fSAndroid Build Coastguard Worker 		for (i = 0; i < 3; i++, p++) {
228*6a54128fSAndroid Build Coastguard Worker 			if (!isdigit(*p))
229*6a54128fSAndroid Build Coastguard Worker 				break;
230*6a54128fSAndroid Build Coastguard Worker 			ac = (ac * 8) + (*p - '0');
231*6a54128fSAndroid Build Coastguard Worker 		}
232*6a54128fSAndroid Build Coastguard Worker 		*q = ac;
233*6a54128fSAndroid Build Coastguard Worker 		p--;
234*6a54128fSAndroid Build Coastguard Worker 	}
235*6a54128fSAndroid Build Coastguard Worker 	*q = 0;
236*6a54128fSAndroid Build Coastguard Worker }
237*6a54128fSAndroid Build Coastguard Worker 
parse_fstab_line(char * line,struct fs_info * fs)238*6a54128fSAndroid Build Coastguard Worker static int parse_fstab_line(char *line, struct fs_info *fs)
239*6a54128fSAndroid Build Coastguard Worker {
240*6a54128fSAndroid Build Coastguard Worker 	char	*dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;
241*6a54128fSAndroid Build Coastguard Worker 
242*6a54128fSAndroid Build Coastguard Worker 	if ((cp = strchr(line, '#')))
243*6a54128fSAndroid Build Coastguard Worker 		*cp = 0;	/* Ignore everything after the comment char */
244*6a54128fSAndroid Build Coastguard Worker 	cp = line;
245*6a54128fSAndroid Build Coastguard Worker 
246*6a54128fSAndroid Build Coastguard Worker 	device = parse_word(&cp);
247*6a54128fSAndroid Build Coastguard Worker 	mntpnt = parse_word(&cp);
248*6a54128fSAndroid Build Coastguard Worker 	type = parse_word(&cp);
249*6a54128fSAndroid Build Coastguard Worker 	opts = parse_word(&cp);
250*6a54128fSAndroid Build Coastguard Worker 	freq = parse_word(&cp);
251*6a54128fSAndroid Build Coastguard Worker 	passno = parse_word(&cp);
252*6a54128fSAndroid Build Coastguard Worker 
253*6a54128fSAndroid Build Coastguard Worker 	if (!device)
254*6a54128fSAndroid Build Coastguard Worker 		return -1;	/* Allow blank lines */
255*6a54128fSAndroid Build Coastguard Worker 
256*6a54128fSAndroid Build Coastguard Worker 	if (!mntpnt || !type)
257*6a54128fSAndroid Build Coastguard Worker 		return -1;
258*6a54128fSAndroid Build Coastguard Worker 
259*6a54128fSAndroid Build Coastguard Worker 	parse_escape(device);
260*6a54128fSAndroid Build Coastguard Worker 	parse_escape(mntpnt);
261*6a54128fSAndroid Build Coastguard Worker 	parse_escape(type);
262*6a54128fSAndroid Build Coastguard Worker 	parse_escape(opts);
263*6a54128fSAndroid Build Coastguard Worker 	parse_escape(freq);
264*6a54128fSAndroid Build Coastguard Worker 	parse_escape(passno);
265*6a54128fSAndroid Build Coastguard Worker 
266*6a54128fSAndroid Build Coastguard Worker 	dev = get_devname(cache, device, NULL);
267*6a54128fSAndroid Build Coastguard Worker 	if (dev)
268*6a54128fSAndroid Build Coastguard Worker 		device = dev;
269*6a54128fSAndroid Build Coastguard Worker 
270*6a54128fSAndroid Build Coastguard Worker 	if (strchr(type, ','))
271*6a54128fSAndroid Build Coastguard Worker 		type = 0;
272*6a54128fSAndroid Build Coastguard Worker 
273*6a54128fSAndroid Build Coastguard Worker 	fs->device = string_copy(device);
274*6a54128fSAndroid Build Coastguard Worker 	fs->mountpt = string_copy(mntpnt);
275*6a54128fSAndroid Build Coastguard Worker 	fs->type = string_copy(type);
276*6a54128fSAndroid Build Coastguard Worker 	fs->opts = string_copy(opts ? opts : "");
277*6a54128fSAndroid Build Coastguard Worker 	fs->freq = freq ? atoi(freq) : -1;
278*6a54128fSAndroid Build Coastguard Worker 	fs->passno = passno ? atoi(passno) : -1;
279*6a54128fSAndroid Build Coastguard Worker 	fs->flags = 0;
280*6a54128fSAndroid Build Coastguard Worker 	fs->next = NULL;
281*6a54128fSAndroid Build Coastguard Worker 
282*6a54128fSAndroid Build Coastguard Worker 	free(dev);
283*6a54128fSAndroid Build Coastguard Worker 
284*6a54128fSAndroid Build Coastguard Worker 	return 0;
285*6a54128fSAndroid Build Coastguard Worker }
286*6a54128fSAndroid Build Coastguard Worker 
free_fstab_line(struct fs_info * fs)287*6a54128fSAndroid Build Coastguard Worker static void free_fstab_line(struct fs_info *fs)
288*6a54128fSAndroid Build Coastguard Worker {
289*6a54128fSAndroid Build Coastguard Worker 	if (fs->device)
290*6a54128fSAndroid Build Coastguard Worker 		fs->device = 0;
291*6a54128fSAndroid Build Coastguard Worker 	if (fs->mountpt)
292*6a54128fSAndroid Build Coastguard Worker 		fs->mountpt = 0;
293*6a54128fSAndroid Build Coastguard Worker 	if (fs->type)
294*6a54128fSAndroid Build Coastguard Worker 		fs->type = 0;
295*6a54128fSAndroid Build Coastguard Worker 	if (fs->opts)
296*6a54128fSAndroid Build Coastguard Worker 		fs->opts = 0;
297*6a54128fSAndroid Build Coastguard Worker 	memset(fs, 0, sizeof(struct fs_info));
298*6a54128fSAndroid Build Coastguard Worker }
299*6a54128fSAndroid Build Coastguard Worker 
300*6a54128fSAndroid Build Coastguard Worker 
PRS(int argc,char ** argv)301*6a54128fSAndroid Build Coastguard Worker static void PRS(int argc, char **argv)
302*6a54128fSAndroid Build Coastguard Worker {
303*6a54128fSAndroid Build Coastguard Worker 	int c;
304*6a54128fSAndroid Build Coastguard Worker 
305*6a54128fSAndroid Build Coastguard Worker #ifdef ENABLE_NLS
306*6a54128fSAndroid Build Coastguard Worker 	setlocale(LC_MESSAGES, "");
307*6a54128fSAndroid Build Coastguard Worker 	setlocale(LC_CTYPE, "");
308*6a54128fSAndroid Build Coastguard Worker 	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
309*6a54128fSAndroid Build Coastguard Worker 	textdomain(NLS_CAT_NAME);
310*6a54128fSAndroid Build Coastguard Worker 	set_com_err_gettext(gettext);
311*6a54128fSAndroid Build Coastguard Worker #endif
312*6a54128fSAndroid Build Coastguard Worker 
313*6a54128fSAndroid Build Coastguard Worker 	while ((c = getopt(argc, argv, "rv")) != EOF) {
314*6a54128fSAndroid Build Coastguard Worker 		switch (c) {
315*6a54128fSAndroid Build Coastguard Worker 		case 'r':
316*6a54128fSAndroid Build Coastguard Worker 			root_type++;
317*6a54128fSAndroid Build Coastguard Worker 			break;
318*6a54128fSAndroid Build Coastguard Worker 
319*6a54128fSAndroid Build Coastguard Worker 		case 'v':
320*6a54128fSAndroid Build Coastguard Worker 			printf("%s %s (%s)\n", program_name,
321*6a54128fSAndroid Build Coastguard Worker 			       E2FSPROGS_VERSION, E2FSPROGS_DATE);
322*6a54128fSAndroid Build Coastguard Worker 			break;
323*6a54128fSAndroid Build Coastguard Worker 		default:
324*6a54128fSAndroid Build Coastguard Worker 			usage();
325*6a54128fSAndroid Build Coastguard Worker 		}
326*6a54128fSAndroid Build Coastguard Worker 	}
327*6a54128fSAndroid Build Coastguard Worker 	if (optind < argc - 1 || optind == argc)
328*6a54128fSAndroid Build Coastguard Worker 		usage();
329*6a54128fSAndroid Build Coastguard Worker 	device_name = get_devname(NULL, argv[optind], NULL);
330*6a54128fSAndroid Build Coastguard Worker 	if (!device_name) {
331*6a54128fSAndroid Build Coastguard Worker 		com_err(program_name, 0, _("Unable to resolve '%s'"),
332*6a54128fSAndroid Build Coastguard Worker 			argv[optind]);
333*6a54128fSAndroid Build Coastguard Worker 		exit(1);
334*6a54128fSAndroid Build Coastguard Worker 	}
335*6a54128fSAndroid Build Coastguard Worker }
336*6a54128fSAndroid Build Coastguard Worker 
get_root_type(ext2_filsys fs)337*6a54128fSAndroid Build Coastguard Worker static void get_root_type(ext2_filsys fs)
338*6a54128fSAndroid Build Coastguard Worker {
339*6a54128fSAndroid Build Coastguard Worker 	errcode_t retval;
340*6a54128fSAndroid Build Coastguard Worker 	struct mem_file file;
341*6a54128fSAndroid Build Coastguard Worker 	char 		*buf;
342*6a54128fSAndroid Build Coastguard Worker 	struct fs_info fs_info;
343*6a54128fSAndroid Build Coastguard Worker 	int		ret;
344*6a54128fSAndroid Build Coastguard Worker 
345*6a54128fSAndroid Build Coastguard Worker 	retval = get_file(fs, "/etc/fstab", &file);
346*6a54128fSAndroid Build Coastguard Worker 	if (retval) {
347*6a54128fSAndroid Build Coastguard Worker 		com_err(program_name, retval, "couldn't open /etc/fstab");
348*6a54128fSAndroid Build Coastguard Worker 		exit(1);
349*6a54128fSAndroid Build Coastguard Worker 	}
350*6a54128fSAndroid Build Coastguard Worker 
351*6a54128fSAndroid Build Coastguard Worker 	while (!mem_file_eof(&file)) {
352*6a54128fSAndroid Build Coastguard Worker 		buf = get_line(&file);
353*6a54128fSAndroid Build Coastguard Worker 		if (!buf)
354*6a54128fSAndroid Build Coastguard Worker 			continue;
355*6a54128fSAndroid Build Coastguard Worker 
356*6a54128fSAndroid Build Coastguard Worker 		ret = parse_fstab_line(buf, &fs_info);
357*6a54128fSAndroid Build Coastguard Worker 		if (ret < 0)
358*6a54128fSAndroid Build Coastguard Worker 			goto next_line;
359*6a54128fSAndroid Build Coastguard Worker 
360*6a54128fSAndroid Build Coastguard Worker 		if (!strcmp(fs_info.mountpt, "/"))
361*6a54128fSAndroid Build Coastguard Worker 			printf("%s\n", fs_info.type);
362*6a54128fSAndroid Build Coastguard Worker 
363*6a54128fSAndroid Build Coastguard Worker 		free_fstab_line(&fs_info);
364*6a54128fSAndroid Build Coastguard Worker 
365*6a54128fSAndroid Build Coastguard Worker 	next_line:
366*6a54128fSAndroid Build Coastguard Worker 		free(buf);
367*6a54128fSAndroid Build Coastguard Worker 	}
368*6a54128fSAndroid Build Coastguard Worker }
369*6a54128fSAndroid Build Coastguard Worker 
370*6a54128fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)371*6a54128fSAndroid Build Coastguard Worker int main (int argc, char ** argv)
372*6a54128fSAndroid Build Coastguard Worker {
373*6a54128fSAndroid Build Coastguard Worker 	errcode_t retval;
374*6a54128fSAndroid Build Coastguard Worker 	ext2_filsys fs;
375*6a54128fSAndroid Build Coastguard Worker 	io_manager io_ptr;
376*6a54128fSAndroid Build Coastguard Worker 
377*6a54128fSAndroid Build Coastguard Worker 	add_error_table(&et_ext2_error_table);
378*6a54128fSAndroid Build Coastguard Worker 
379*6a54128fSAndroid Build Coastguard Worker 	blkid_get_cache(&cache, NULL);
380*6a54128fSAndroid Build Coastguard Worker 	PRS(argc, argv);
381*6a54128fSAndroid Build Coastguard Worker 
382*6a54128fSAndroid Build Coastguard Worker #ifdef CONFIG_TESTIO_DEBUG
383*6a54128fSAndroid Build Coastguard Worker 	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
384*6a54128fSAndroid Build Coastguard Worker 		io_ptr = test_io_manager;
385*6a54128fSAndroid Build Coastguard Worker 		test_io_backing_manager = unix_io_manager;
386*6a54128fSAndroid Build Coastguard Worker 	} else
387*6a54128fSAndroid Build Coastguard Worker #endif
388*6a54128fSAndroid Build Coastguard Worker 		io_ptr = unix_io_manager;
389*6a54128fSAndroid Build Coastguard Worker 	retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs);
390*6a54128fSAndroid Build Coastguard Worker         if (retval)
391*6a54128fSAndroid Build Coastguard Worker 		exit(1);
392*6a54128fSAndroid Build Coastguard Worker 
393*6a54128fSAndroid Build Coastguard Worker 	if (root_type)
394*6a54128fSAndroid Build Coastguard Worker 		get_root_type(fs);
395*6a54128fSAndroid Build Coastguard Worker 
396*6a54128fSAndroid Build Coastguard Worker 	remove_error_table(&et_ext2_error_table);
397*6a54128fSAndroid Build Coastguard Worker 	return (ext2fs_close (fs) ? 1 : 0);
398*6a54128fSAndroid Build Coastguard Worker }
399