summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2020-08-25 20:04:42 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2020-08-25 20:04:42 +0000
commitc43a9ae78220daadd71e00fc0596ceb839621e28 (patch)
treef263485ed0a09b31afe38be42e151cf9fc1dad9c
downloadlibfstab-c43a9ae78220daadd71e00fc0596ceb839621e28.tar.gz
Initial commit.HEADmaster
-rw-r--r--.gitignore2
-rw-r--r--COPYING24
-rw-r--r--Makefile34
-rw-r--r--README4
-rw-r--r--include/fstab.h37
-rw-r--r--src/fclose_keep_errno.c9
-rw-r--r--src/getfs_a.c29
-rw-r--r--src/getfsent.c35
-rw-r--r--src/getfsent_a.c78
-rw-r--r--src/include/fsent.h11
10 files changed, 263 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d19bb5e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+libfstab.a
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d239786
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,24 @@
+(Original MIT license.)
+(For inclusion into musl, assign the copyright to Rich Felker.)
+----------------------------------------------------------------------
+Copyright (C)2020 Laurent Bercot.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5a29d42
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,34 @@
+
+LIBDIR := /usr/lib
+INCLUDEDIR := /usr/include
+
+CC := gcc
+CFLAGS := -fPIC
+AR := ar
+RANLIB := ranlib
+INSTALL := install
+
+OBJS := fclose_keep_errno.o getfs_a.o getfsent.o getfsent_a.o
+
+it: include/fstab.h libfstab.a
+
+clean:
+ @exec rm -f *.o libfstab.a
+
+install: $(DESTDIR)$(INCLUDEDIR)/fstab.h $(DESTDIR)$(LIBDIR)/libfstab.a
+
+
+$(DESTDIR)$(INCLUDEDIR)/fstab.h: include/fstab.h
+ exec $(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(LIBDIR)/libfstab.a: libfstab.a
+ exec $(INSTALL) -D -m 644 $< $@
+
+%.o: src/%.c
+ exec $(CC) $(CFLAGS) -c -o $@ -I include -I src/include $<
+
+libfstab.a: $(OBJS)
+ exec $(AR) rc $@ $^
+ exec $(RANLIB) $@
+
+.PHONY: it clean install
diff --git a/README b/README
new file mode 100644
index 0000000..c5c1031
--- /dev/null
+++ b/README
@@ -0,0 +1,4 @@
+libfstab - an implementation of fstab.h for musl
+------------------------------------------------
+
+ See https://www.gnu.org/software/libc/manual/html_node/fstab.html
diff --git a/include/fstab.h b/include/fstab.h
new file mode 100644
index 0000000..526329e
--- /dev/null
+++ b/include/fstab.h
@@ -0,0 +1,37 @@
+#ifndef _FSTAB_H
+#define _FSTAB_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _PATH_FSTAB "/etc/fstab"
+
+#define FSTAB_RW "rw"
+#define FSTAB_RQ "rq"
+#define FSTAB_RO "ro"
+#define FSTAB_SW "sw"
+#define FSTAB_XX "xx"
+
+struct fstab {
+ char *fs_spec;
+ char *fs_file;
+ char *fs_vfstype;
+ char *fs_mntops;
+ char const *fs_type;
+ int fs_freq;
+ int fs_passno;
+};
+
+struct fstab *getfsent (void);
+struct fstab *getfsspec (char const *);
+struct fstab *getfsfile (char const *);
+int setfsent (void);
+void endfsent (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/fclose_keep_errno.c b/src/fclose_keep_errno.c
new file mode 100644
index 0000000..68d6113
--- /dev/null
+++ b/src/fclose_keep_errno.c
@@ -0,0 +1,9 @@
+#include <errno.h>
+#include "fsent.h"
+
+void __fclose_keep_errno(FILE *f)
+{
+ int e = errno;
+ fclose(f);
+ errno = e;
+}
diff --git a/src/getfs_a.c b/src/getfs_a.c
new file mode 100644
index 0000000..22a18d2
--- /dev/null
+++ b/src/getfs_a.c
@@ -0,0 +1,29 @@
+#include <pthread.h>
+#include "fsent.h"
+
+int __getfs_a(char const *spec, char const *file, struct fstab *fstab, char **line, size_t *size)
+{
+ int r;
+ int cs;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+ FILE *f = fopen(_PATH_FSTAB, "rbe");
+ if (!f)
+ {
+ pthread_setcancelstate(cs, 0);
+ return 0;
+ }
+
+ for (;;)
+ {
+ r = __getfsent_a(f, fstab, line, size);
+ if (!r) break;
+ if (spec && !strcmp(spec, fstab->fs_spec)
+ || file && !strcmp(file, fstab->fs_file))
+ break;
+ }
+
+ __fclose_keep_errno(f);
+ pthread_setcancelstate(cs, 0);
+ return r;
+}
diff --git a/src/getfsent.c b/src/getfsent.c
new file mode 100644
index 0000000..ccfc0d3
--- /dev/null
+++ b/src/getfsent.c
@@ -0,0 +1,35 @@
+#include "fsent.h"
+
+static FILE *f;
+static char *line;
+static struct fstab fstab;
+static size_t size;
+
+void endfsent()
+{
+ if (f) __fclose_keep_errno(f);
+ f = 0;
+}
+
+int setfsent()
+{
+ endfsent();
+ return 1;
+}
+
+struct fstab *getfsent()
+{
+ if (!f) f = fopen(_PATH_FSTAB, "rbe");
+ if (!f) return 0;
+ return __getfsent_a(f, &fstab, &line, &size) ? &fstab : 0;
+}
+
+struct fstab *getfsspec(char const *spec)
+{
+ return __getfs_a(spec, 0, &fstab, &line, &size) ? &fstab : 0;
+}
+
+struct fstab *getfsfile(char const *file)
+{
+ return __getfs_a(0, file, &fstab, &line, &size) ? &fstab : 0;
+}
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;
+ }
+}
diff --git a/src/include/fsent.h b/src/include/fsent.h
new file mode 100644
index 0000000..676130c
--- /dev/null
+++ b/src/include/fsent.h
@@ -0,0 +1,11 @@
+#include <string.h>
+#include <stdio.h>
+#ifdef IN_MUSL
+#include <fstab.h>
+#else
+#include "fstab.h"
+#endif
+
+void __fclose_keep_errno(FILE *);
+int __getfs_a(char const *, char const *, struct fstab *, char **, size_t *);
+int __getfsent_a(FILE *, struct fstab *, char **, size_t *);