2 * e2initrd_helper.c - Get the filesystem table
4 * Copyright 2004 by Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
24 #include <sys/types.h>
35 #include "ext2fs/ext2_fs.h"
36 #include "ext2fs/ext2fs.h"
37 #include "blkid/blkid.h"
38 #include "support/nls-enable.h"
39 #include "support/devname.h"
41 #include "../version.h"
43 static const char * program_name
= "e2initrd_helper";
44 static char * device_name
;
47 static blkid_cache cache
= NULL
;
66 static void usage(void)
69 _("Usage: %s -r device\n"), program_name
);
73 static errcode_t
get_file(ext2_filsys fs
, const char * filename
,
74 struct mem_file
*ret_file
)
78 ext2_file_t e2_file
= NULL
;
80 struct ext2_inode inode
;
87 retval
= ext2fs_namei(fs
, EXT2_ROOT_INO
, EXT2_ROOT_INO
,
92 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
96 if (inode
.i_size_high
|| (inode
.i_size
> 65536))
99 buf
= malloc(inode
.i_size
+ 1);
102 memset(buf
, 0, inode
.i_size
+1);
104 retval
= ext2fs_file_open(fs
, ino
, 0, &e2_file
);
108 retval
= ext2fs_file_read(e2_file
, buf
, inode
.i_size
, &got
);
112 retval
= ext2fs_file_close(e2_file
);
117 ret_file
->size
= (int) got
;
123 ext2fs_file_close(e2_file
);
127 static char *get_line(struct mem_file
*file
)
132 cp
= file
->buf
+ file
->ptr
;
133 while (*cp
&& *cp
!= '\n') {
141 memcpy(ret
, file
->buf
+ file
->ptr
, s
);
142 while (*cp
&& (*cp
== '\n' || *cp
== '\r')) {
150 static int mem_file_eof(struct mem_file
*file
)
152 return (file
->ptr
>= file
->size
);
158 static char *string_copy(const char *s
)
164 ret
= malloc(strlen(s
)+1);
170 static char *skip_over_blank(char *cp
)
172 while (*cp
&& isspace(*cp
))
177 static char *skip_over_word(char *cp
)
179 while (*cp
&& !isspace(*cp
))
184 static char *parse_word(char **buf
)
192 word
= skip_over_blank(word
);
193 next
= skip_over_word(word
);
200 static void parse_escape(char *word
)
208 for (p
= word
, q
= word
; *p
; p
++, q
++) {
227 for (i
= 0; i
< 3; i
++, p
++) {
230 ac
= (ac
* 8) + (*p
- '0');
238 static int parse_fstab_line(char *line
, struct fs_info
*fs
)
240 char *dev
, *device
, *mntpnt
, *type
, *opts
, *freq
, *passno
, *cp
;
242 if ((cp
= strchr(line
, '#')))
243 *cp
= 0; /* Ignore everything after the comment char */
246 device
= parse_word(&cp
);
247 mntpnt
= parse_word(&cp
);
248 type
= parse_word(&cp
);
249 opts
= parse_word(&cp
);
250 freq
= parse_word(&cp
);
251 passno
= parse_word(&cp
);
254 return -1; /* Allow blank lines */
256 if (!mntpnt
|| !type
)
259 parse_escape(device
);
260 parse_escape(mntpnt
);
264 parse_escape(passno
);
266 dev
= get_devname(cache
, device
, NULL
);
270 if (strchr(type
, ','))
273 fs
->device
= string_copy(device
);
274 fs
->mountpt
= string_copy(mntpnt
);
275 fs
->type
= string_copy(type
);
276 fs
->opts
= string_copy(opts
? opts
: "");
277 fs
->freq
= freq
? atoi(freq
) : -1;
278 fs
->passno
= passno
? atoi(passno
) : -1;
287 static void free_fstab_line(struct fs_info
*fs
)
297 memset(fs
, 0, sizeof(struct fs_info
));
301 static void PRS(int argc
, char **argv
)
306 setlocale(LC_MESSAGES
, "");
307 setlocale(LC_CTYPE
, "");
308 bindtextdomain(NLS_CAT_NAME
, LOCALEDIR
);
309 textdomain(NLS_CAT_NAME
);
310 set_com_err_gettext(gettext
);
313 while ((c
= getopt(argc
, argv
, "rv")) != EOF
) {
320 printf("%s %s (%s)\n", program_name
,
321 E2FSPROGS_VERSION
, E2FSPROGS_DATE
);
327 if (optind
< argc
- 1 || optind
== argc
)
329 device_name
= get_devname(NULL
, argv
[optind
], NULL
);
331 com_err(program_name
, 0, _("Unable to resolve '%s'"),
337 static void get_root_type(ext2_filsys fs
)
340 struct mem_file file
;
342 struct fs_info fs_info
;
345 retval
= get_file(fs
, "/etc/fstab", &file
);
347 com_err(program_name
, retval
, "couldn't open /etc/fstab");
351 while (!mem_file_eof(&file
)) {
352 buf
= get_line(&file
);
356 ret
= parse_fstab_line(buf
, &fs_info
);
360 if (!strcmp(fs_info
.mountpt
, "/"))
361 printf("%s\n", fs_info
.type
);
363 free_fstab_line(&fs_info
);
371 int main (int argc
, char ** argv
)
377 add_error_table(&et_ext2_error_table
);
379 blkid_get_cache(&cache
, NULL
);
382 #ifdef CONFIG_TESTIO_DEBUG
383 if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
384 io_ptr
= test_io_manager
;
385 test_io_backing_manager
= unix_io_manager
;
388 io_ptr
= unix_io_manager
;
389 retval
= ext2fs_open (device_name
, open_flag
, 0, 0, io_ptr
, &fs
);
396 remove_error_table(&et_ext2_error_table
);
397 return (ext2fs_close (fs
) ? 1 : 0);