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