15d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o/* 25d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * e2initrd_helper.c - Get the filesystem table 35d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * 45d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * Copyright 2004 by Theodore Ts'o. 55d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * 65d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * %Begin-Header% 75d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * This file may be redistributed under the terms of the GNU Public 85d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * License. 95d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * %End-Header% 105d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o */ 115d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 125d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <stdio.h> 135d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <unistd.h> 14f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o#ifdef HAVE_STDLIB_H 155d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <stdlib.h> 16f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o#endif 175d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <ctype.h> 185d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <string.h> 195d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <time.h> 205d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#ifdef HAVE_ERRNO_H 215d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <errno.h> 225d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#endif 235d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <sys/types.h> 245d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <sys/stat.h> 255d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <fcntl.h> 265d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <utime.h> 275d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#ifdef HAVE_GETOPT_H 285d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include <getopt.h> 29efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#else 305d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'oextern int optind; 315d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'oextern char *optarg; 325d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#endif 335d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 345d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include "ext2fs/ext2_fs.h" 355d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include "ext2fs/ext2fs.h" 365d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include "blkid/blkid.h" 375d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 385d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include "../version.h" 395d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#include "nls-enable.h" 405d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic const char * program_name = "e2initrd_helper"; 42e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic char * device_name; 435d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic int open_flag; 445d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic int root_type; 455d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic blkid_cache cache = NULL; 465d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 475d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostruct mem_file { 485d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *buf; 495d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int size; 505d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int ptr; 515d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o}; 525d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 535d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostruct fs_info { 545d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *device; 555d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *mountpt; 565d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *type; 575d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *opts; 585d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int freq; 595d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int passno; 605d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int flags; 615d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o struct fs_info *next; 625d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o}; 635d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 645d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic void usage(void) 655d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 665d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fprintf(stderr, 675d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o _("Usage: %s -r device\n"), program_name); 685d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o exit (1); 695d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 705d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 71efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t get_file(ext2_filsys fs, const char * filename, 725d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o struct mem_file *ret_file) 735d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 745d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o errcode_t retval; 755d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *buf; 76e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2_file_t e2_file = NULL; 775d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o unsigned int got; 785d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o struct ext2_inode inode; 795d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ext2_ino_t ino; 805d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 815d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret_file->buf = 0; 825d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret_file->size = 0; 835d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret_file->ptr = 0; 845d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 85efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = ext2fs_namei(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 865d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o filename, &ino); 875d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (retval) 885d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return retval; 895d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 905d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o retval = ext2fs_read_inode(fs, ino, &inode); 915d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (retval) 925d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return retval; 935d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 945d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (inode.i_size_high || (inode.i_size > 65536)) 955d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return EFBIG; 965d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 975d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o buf = malloc(inode.i_size + 1); 985d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!buf) 995d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return ENOMEM; 1005d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o memset(buf, 0, inode.i_size+1); 1015d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1025d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o retval = ext2fs_file_open(fs, ino, 0, &e2_file); 1035d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (retval) 104e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto errout; 1055d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1065d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o retval = ext2fs_file_read(e2_file, buf, inode.i_size, &got); 107efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if (retval) 1085d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o goto errout; 1095d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1105d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o retval = ext2fs_file_close(e2_file); 1115d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (retval) 112e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto errout; 1135d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1145d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret_file->buf = buf; 1155d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret_file->size = (int) got; 116e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 1175d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1185d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'oerrout: 119e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall free(buf); 120e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (e2_file) 121e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_file_close(e2_file); 1225d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return retval; 1235d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 1245d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1256e82cd7e953bc6f00c47ca8f29c61d61fb39d3d3Theodore Ts'ostatic char *get_line(struct mem_file *file) 1265d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 1275d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *cp, *ret; 1285d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int s = 0; 1295d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1305d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o cp = file->buf + file->ptr; 1315d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o while (*cp && *cp != '\n') { 1325d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o cp++; 1335d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o s++; 1345d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 1355d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret = malloc(s+1); 1365d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!ret) 1375d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return 0; 1385d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret[s]=0; 1395d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o memcpy(ret, file->buf + file->ptr, s); 1405d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o while (*cp && (*cp == '\n' || *cp == '\r')) { 1415d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o cp++; 1425d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o s++; 1435d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 1445d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o file->ptr += s; 1455d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return ret; 1465d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 1475d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1486e82cd7e953bc6f00c47ca8f29c61d61fb39d3d3Theodore Ts'ostatic int mem_file_eof(struct mem_file *file) 1495d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 1505d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return (file->ptr >= file->size); 1515d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 1525d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1535d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o/* 1545d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o * fstab parsing code 1555d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o */ 1565d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic char *string_copy(const char *s) 1575d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 1585d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *ret; 1595d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1605d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!s) 1615d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return 0; 1625d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret = malloc(strlen(s)+1); 1635d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (ret) 1645d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o strcpy(ret, s); 1655d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return ret; 1665d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 1675d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1685d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic char *skip_over_blank(char *cp) 1695d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 1705d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o while (*cp && isspace(*cp)) 1715d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o cp++; 1725d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return cp; 1735d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 1745d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1755d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic char *skip_over_word(char *cp) 1765d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 1775d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o while (*cp && !isspace(*cp)) 1785d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o cp++; 1795d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return cp; 1805d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 1815d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1825d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic char *parse_word(char **buf) 1835d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 1845d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *word, *next; 1855d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1865d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o word = *buf; 1875d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (*word == 0) 1885d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return 0; 1895d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1905d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o word = skip_over_blank(word); 1915d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o next = skip_over_word(word); 1925d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (*next) 1935d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *next++ = 0; 1945d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *buf = next; 1955d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return word; 1965d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 1975d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 1985d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic void parse_escape(char *word) 1995d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 2005d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *p, *q; 2015d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int ac, i; 2025d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2035d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!word) 2045d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return; 2055d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2065d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o for (p = word, q = word; *p; p++, q++) { 2075d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *q = *p; 2085d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (*p != '\\') 2095d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o continue; 2105d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (*++p == 0) 2115d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o break; 2125d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (*p == 't') { 2135d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *q = '\t'; 2145d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o continue; 2155d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 2165d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (*p == 'n') { 2175d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *q = '\n'; 2185d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o continue; 2195d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 2205d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!isdigit(*p)) { 2215d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *q = *p; 2225d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o continue; 2235d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 2245d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ac = 0; 2255d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o for (i = 0; i < 3; i++, p++) { 2265d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!isdigit(*p)) 2275d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o break; 2285d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ac = (ac * 8) + (*p - '0'); 2295d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 2305d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *q = ac; 2315d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o p--; 2325d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 2335d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *q = 0; 2345d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 2355d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2365d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic int parse_fstab_line(char *line, struct fs_info *fs) 2375d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 2385d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp; 2395d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2405d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if ((cp = strchr(line, '#'))) 2415d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o *cp = 0; /* Ignore everything after the comment char */ 2425d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o cp = line; 2435d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2445d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o device = parse_word(&cp); 2455d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o mntpnt = parse_word(&cp); 2465d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o type = parse_word(&cp); 2475d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o opts = parse_word(&cp); 2485d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o freq = parse_word(&cp); 2495d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o passno = parse_word(&cp); 2505d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2515d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!device) 2525d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return -1; /* Allow blank lines */ 253efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 2545d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!mntpnt || !type) 2555d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return -1; 2565d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2575d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o parse_escape(device); 2585d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o parse_escape(mntpnt); 2595d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o parse_escape(type); 2605d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o parse_escape(opts); 2615d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o parse_escape(freq); 2625d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o parse_escape(passno); 2635d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2645d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o dev = blkid_get_devname(cache, device, NULL); 2655d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (dev) 2665d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o device = dev; 2675d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2685d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (strchr(type, ',')) 2695d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o type = 0; 2705d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2715d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->device = string_copy(device); 2725d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->mountpt = string_copy(mntpnt); 2735d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->type = string_copy(type); 2745d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->opts = string_copy(opts ? opts : ""); 2755d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->freq = freq ? atoi(freq) : -1; 2765d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->passno = passno ? atoi(passno) : -1; 2775d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->flags = 0; 2785d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->next = NULL; 2795d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 28045e338f5332a54295893dba2e32cc093d1316f60Jim Meyering free(dev); 281efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 2825d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return 0; 2835d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 2845d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2856e82cd7e953bc6f00c47ca8f29c61d61fb39d3d3Theodore Ts'ostatic void free_fstab_line(struct fs_info *fs) 2865d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 2875d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (fs->device) 2885d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->device = 0; 2895d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (fs->mountpt) 2905d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->mountpt = 0; 2915d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (fs->type) 2925d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->type = 0; 2935d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (fs->opts) 2945d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o fs->opts = 0; 2955d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o memset(fs, 0, sizeof(struct fs_info)); 2965d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 2975d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2985d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 2995d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'ostatic void PRS(int argc, char **argv) 3005d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 3015d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int c; 3025d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3035d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#ifdef ENABLE_NLS 3045d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o setlocale(LC_MESSAGES, ""); 3055d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o setlocale(LC_CTYPE, ""); 3065d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 3075d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o textdomain(NLS_CAT_NAME); 308e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall set_com_err_gettext(gettext); 3095d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#endif 3105d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3115d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o while ((c = getopt(argc, argv, "rv")) != EOF) { 3125d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o switch (c) { 3135d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o case 'r': 3145d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o root_type++; 3155d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o break; 3165d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3175d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o case 'v': 318efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o printf("%s %s (%s)\n", program_name, 3195d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o E2FSPROGS_VERSION, E2FSPROGS_DATE); 3205d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o break; 3215d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o default: 3225d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o usage(); 3235d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 3245d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 3255d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (optind < argc - 1 || optind == argc) 3265d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o usage(); 3275d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o device_name = blkid_get_devname(NULL, argv[optind], NULL); 3285d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!device_name) { 329e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(program_name, 0, _("Unable to resolve '%s'"), 3305d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o argv[optind]); 3315d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o exit(1); 3325d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 3335d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 3345d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3356e82cd7e953bc6f00c47ca8f29c61d61fb39d3d3Theodore Ts'ostatic void get_root_type(ext2_filsys fs) 3365d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 3375d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o errcode_t retval; 3385d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o struct mem_file file; 3395d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o char *buf; 3405d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o struct fs_info fs_info; 3415d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o int ret; 3425d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3435d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o retval = get_file(fs, "/etc/fstab", &file); 344e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval) { 345e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(program_name, retval, "couldn't open /etc/fstab"); 346e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall exit(1); 347e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 3485d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3495d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o while (!mem_file_eof(&file)) { 3505d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o buf = get_line(&file); 3515d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!buf) 3525d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o continue; 353efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 3545d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ret = parse_fstab_line(buf, &fs_info); 355efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if (ret < 0) 3565d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o goto next_line; 3575d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3585d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (!strcmp(fs_info.mountpt, "/")) 3595d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o printf("%s\n", fs_info.type); 3605d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3615d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o free_fstab_line(&fs_info); 3625d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3635d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o next_line: 3645d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o free(buf); 3655d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o } 3665d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 3675d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3685d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3695d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'oint main (int argc, char ** argv) 3705d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o{ 3715d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o errcode_t retval; 3725d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o ext2_filsys fs; 3735d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o io_manager io_ptr; 3745d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 375a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o add_error_table(&et_ext2_error_table); 3765d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 3775d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o blkid_get_cache(&cache, NULL); 3785d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o PRS(argc, argv); 379efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 3805d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#ifdef CONFIG_TESTIO_DEBUG 381f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { 382f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o io_ptr = test_io_manager; 383f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o test_io_backing_manager = unix_io_manager; 384f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o } else 3855d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o#endif 386f38cf3cb34addaa53d1f855d7607b151082a4229Theodore Ts'o io_ptr = unix_io_manager; 3875d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs); 3885d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o if (retval) 3895d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o exit(1); 3905d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 391efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if (root_type) 3925d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o get_root_type(fs); 3935d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o 394a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o remove_error_table(&et_ext2_error_table); 3955d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o return (ext2fs_close (fs) ? 1 : 0); 3965d40773ba8447640a5aeaaa2e98bc7feecd61698Theodore Ts'o} 397