summaryrefslogtreecommitdiff
path: root/src/lib/rib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/rib.c')
-rw-r--r--src/lib/rib.c77
1 files changed, 59 insertions, 18 deletions
diff --git a/src/lib/rib.c b/src/lib/rib.c
index 684c5dcd..97a20f47 100644
--- a/src/lib/rib.c
+++ b/src/lib/rib.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2020
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* RIB export using FUSE
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -43,15 +43,14 @@
#define __USE_XOPEN
#elif defined (__FreeBSD__)
#define __XSI_VISIBLE 500
-#endif
+#endif /* __linux__ */
+#include <sys/stat.h>
#include <fuse.h>
#ifndef CLOCK_REALTIME_COARSE
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
#endif
-#define RT "/"
-
struct reg_comp {
struct list_head next;
@@ -106,8 +105,7 @@ static int rib_read(const char * path,
strcpy(comp, path + 1);
- c = strstr(comp, "/");
-
+ c = strstr(comp, RIB_SEPARATOR);
if (c != NULL)
*c = '\0';
@@ -119,7 +117,7 @@ static int rib_read(const char * path,
list_for_each(p, &rib.reg_comps) {
struct reg_comp * r = list_entry(p, struct reg_comp, next);
if (strcmp(comp, r->path) == 0) {
- int ret = r->ops->read(c + 1, buf, size);
+ int ret = r->ops->read(path + 1, buf, size);
pthread_rwlock_unlock(&rib.lock);
return ret;
}
@@ -141,12 +139,16 @@ static int rib_readdir(const char * path,
(void) offset;
(void) info;
+ /* Fix ls calling readdir in an infinite loop on raspbian. */
+ if (info != NULL && info->nonseekable != 0)
+ return -ENOENT;
+
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
pthread_rwlock_rdlock(&rib.lock);
- if (strcmp(path, RT) == 0) {
+ if (strcmp(path, RIB_SEPARATOR) == 0) {
list_for_each(p, &rib.reg_comps) {
struct reg_comp * c;
c = list_entry(p, struct reg_comp, next);
@@ -185,24 +187,35 @@ static size_t __getattr(const char * path,
struct list_head * p;
char comp[RIB_PATH_LEN + 1];
char * c;
+ struct rib_attr attr;
if (strlen(path) > RIB_PATH_LEN)
return -1;
strcpy(comp, path + 1);
- c = strstr(comp, "/");
-
+ c = strstr(comp, RIB_SEPARATOR);
if (c != NULL)
*c = '\0';
+ memset(&attr, 0, sizeof(attr));
+
pthread_rwlock_rdlock(&rib.lock);
list_for_each(p, &rib.reg_comps) {
struct reg_comp * r = list_entry(p, struct reg_comp, next);
if (strcmp(comp, r->path) == 0) {
- size_t ret = r->ops->getattr(c + 1, st);
+ size_t ret = r->ops->getattr(path + 1, &attr);
pthread_rwlock_unlock(&rib.lock);
+ st->st_mode = S_IFREG | 0644;
+ st->st_blocks = 1;
+ st->st_nlink = 1;
+ st->st_uid = getuid();
+ st->st_gid = getgid();
+ st->st_size = attr.size;
+ st->st_atime = attr.mtime;
+ st->st_mtime = attr.mtime;
+ st->st_ctime = attr.mtime;
return ret;
}
}
@@ -220,7 +233,7 @@ static int rib_getattr(const char * path,
memset(st, 0, sizeof(*st));
- if (strcmp(path, RT) == 0)
+ if (strcmp(path, RIB_SEPARATOR) == 0)
goto finish_dir;
pthread_rwlock_rdlock(&rib.lock);
@@ -246,6 +259,8 @@ static int rib_getattr(const char * path,
st->st_uid = getuid();
st->st_gid = getgid();
st->st_mtime = now.tv_sec;
+ st->st_atime = now.tv_sec;
+ st->st_ctime = now.tv_sec;
return 0;
}
@@ -266,7 +281,6 @@ static void * fuse_thr(void * o)
}
#endif /* HAVE_FUSE */
-
int rib_init(const char * mountpt)
{
#ifdef HAVE_FUSE
@@ -280,8 +294,11 @@ int rib_init(const char * mountpt)
NULL};
struct fuse_args args = FUSE_ARGS_INIT(3, argv);
+ if (access("/dev/fuse", R_OK))
+ goto fail;
+
if (stat(FUSE_PREFIX, &st) == -1)
- return -1;
+ goto fail;
sprintf(rib.mnt, FUSE_PREFIX "/%s", mountpt);
@@ -289,13 +306,13 @@ int rib_init(const char * mountpt)
switch(errno) {
case ENOENT:
if (mkdir(rib.mnt, 0777))
- return -1;
+ goto fail_mnt;
break;
case ENOTCONN:
fuse_unmount(rib.mnt, rib.ch);
break;
default:
- return -1;
+ goto fail_mnt;
}
fuse_opt_parse(&args, NULL, NULL, NULL);
@@ -329,6 +346,9 @@ int rib_init(const char * mountpt)
fail_mount:
fuse_opt_free_args(&args);
rmdir(rib.mnt);
+ fail_mnt:
+ memset(rib.mnt, 0, sizeof(rib.mnt));
+ fail:
return -1;
#else
(void) mountpt;
@@ -342,6 +362,9 @@ void rib_fini(void)
struct list_head * p;
struct list_head * h;
+ if (strlen(rib.mnt) == 0)
+ return;
+
fuse_exit(rib.fuse);
fuse_unmount(rib.mnt, rib.ch);
@@ -363,6 +386,18 @@ void rib_fini(void)
pthread_rwlock_unlock(&rib.lock);
pthread_rwlock_destroy(&rib.lock);
+
+ memset(rib.mnt, 0, sizeof(rib.mnt));
+#endif
+}
+
+void rib_cleanup(const char * mnt)
+{
+#ifdef HAVE_FUSE
+ fuse_unmount(mnt, NULL);
+ rmdir(mnt);
+#else
+ (void) mnt;
#endif
}
@@ -373,6 +408,9 @@ int rib_reg(const char * path,
struct reg_comp * rc;
struct list_head * p;
+ if (strlen(rib.mnt) == 0)
+ return 0;
+
pthread_rwlock_wrlock(&rib.lock);
list_for_each(p, &rib.reg_comps) {
@@ -417,6 +455,9 @@ void rib_unreg(const char * path)
struct list_head * p;
struct list_head * h;
+ if (strlen(rib.mnt) == 0)
+ return;
+
pthread_rwlock_wrlock(&rib.lock);
list_for_each_safe(p, h, &rib.reg_comps) {