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.c96
1 files changed, 75 insertions, 21 deletions
diff --git a/src/lib/rib.c b/src/lib/rib.c
index fa525c50..97a20f47 100644
--- a/src/lib/rib.c
+++ b/src/lib/rib.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2018
+ * 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;
@@ -101,10 +100,12 @@ static int rib_read(const char * path,
char comp[RIB_PATH_LEN + 1];
char * c;
- strcpy(comp, path + 1);
+ if (strlen(path) > RIB_PATH_LEN)
+ return -1;
- c = strstr(comp, "/");
+ strcpy(comp, path + 1);
+ c = strstr(comp, RIB_SEPARATOR);
if (c != NULL)
*c = '\0';
@@ -116,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;
}
@@ -138,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);
@@ -182,21 +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;
- strcpy(comp, path + 1);
+ if (strlen(path) > RIB_PATH_LEN)
+ return -1;
- c = strstr(comp, "/");
+ strcpy(comp, path + 1);
+ 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;
}
}
@@ -214,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);
@@ -240,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;
}
@@ -260,8 +281,7 @@ static void * fuse_thr(void * o)
}
#endif /* HAVE_FUSE */
-
-int rib_init(const char * prefix)
+int rib_init(const char * mountpt)
{
#ifdef HAVE_FUSE
struct stat st;
@@ -274,21 +294,25 @@ int rib_init(const char * prefix)
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.%d", prefix, getpid());
+ sprintf(rib.mnt, FUSE_PREFIX "/%s", mountpt);
if (stat(rib.mnt, &st) == -1)
switch(errno) {
case ENOENT:
- mkdir(rib.mnt, 0777);
+ if (mkdir(rib.mnt, 0777))
+ 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);
@@ -322,9 +346,12 @@ int rib_init(const char * prefix)
fail_mount:
fuse_opt_free_args(&args);
rmdir(rib.mnt);
+ fail_mnt:
+ memset(rib.mnt, 0, sizeof(rib.mnt));
+ fail:
return -1;
#else
- (void) prefix;
+ (void) mountpt;
return 0;
#endif
}
@@ -335,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);
@@ -356,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
}
@@ -366,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) {
@@ -385,6 +430,12 @@ int rib_reg(const char * path,
return -ENOMEM;
}
+ if (strlen(path) > RIB_PATH_LEN) {
+ pthread_rwlock_unlock(&rib.lock);
+ free(rc);
+ return -1;
+ }
+
strcpy(rc->path, path);
rc->ops = ops;
@@ -404,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) {