summaryrefslogtreecommitdiffstats
path: root/src/getfsent_a.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/getfsent_a.c')
-rw-r--r--src/getfsent_a.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/getfsent_a.c b/src/getfsent_a.c
new file mode 100644
index 0000000..3d302b7
--- /dev/null
+++ b/src/getfsent_a.c
@@ -0,0 +1,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;
+ }
+}