summaryrefslogtreecommitdiffstats
path: root/src/getfsent_a.c
blob: 3d302b7917beeef394eb42ee829574153295b5ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <ctype.h>
#include <stdlib.h>
#include "fsent.h"

static int nextword(char **s)
{
	for (; **s; (*s)++)
		if (!isspace(**s)) return 1;
	return 0;
}

static void endword(char **s)
{
	for (; **s; (*s)++)
		if (isspace(**s)) { *(*s)++ = 0; break; }
}

static int scan_int(char *s)
{
	unsigned int x = 0;
	for (; *s-'0'<10U; ++s) x = 10*x + (*s-'0');
	return (int)x;
}

static inline int hasmntopt(char const *blob, char const *opt)
{
	size_t optlen = strlen(opt);
	char const *s = blob;
	for (;;)
	{
		char const *p = strstr(s, opt);
		if (!p) break;
		if ((p == s || p[-1] == ',') && (!p[optlen] || p[optlen] == '=' || p[optlen] == ','))
			return 1;
		s = strchr(p, ',');
		if (!s) break;
		s++;
	}
	return 0;
}

static inline void compute_legacy_fs_type(struct fstab *fstab)
{
  if (!strcmp(fstab->fs_vfstype, "ignore")) fstab->fs_type = FSTAB_XX;
  else if (!strcmp(fstab->fs_vfstype, "swap")) fstab->fs_type = FSTAB_SW;
  else if (hasmntopt(fstab->fs_mntops, "ro")) fstab->fs_type = FSTAB_RO;
  else fstab->fs_type = FSTAB_RW;
}

int __getfsent_a(FILE *f, struct fstab *fstab, char **line, size_t *size)
{
	for (;;)
	{
		char *s;
		char *tmp;
		size_t l = getline(line, size, f);
		if (l < 0)
                {
			free(*line);
			*line = 0;
			return 0;
		}
		s = *line;

		if (*s == '#') continue;
		if (!nextword(&s)) continue; fstab->fs_spec = s; endword(&s);
		if (!nextword(&s)) continue; fstab->fs_file = s; endword(&s);
		if (!nextword(&s)) continue; fstab->fs_vfstype = s; endword(&s);
		if (!nextword(&s)) continue; fstab->fs_mntops = s; endword(&s);
		fstab->fs_freq = fstab->fs_passno = 0;
		compute_legacy_fs_type(fstab);
		if (!nextword(&s)) return 1; tmp = s; endword(&s);
		fstab->fs_freq = scan_int(tmp);
		if (!nextword(&s)) return 1; tmp = s; endword(&s);
		fstab->fs_passno = scan_int(tmp);
		return 1;
	}
}