agendafs

A filesystem for your calendar.

git clone git://mccd.space/agendafs
commit e355e4e5659c560f4f9105c4b2caff0730ffcc8d
parent bf02536a0f7f28bba661a5cfead7e694bce03325
Author: Marc Coquand <marc@coquand.email>
Date:   Sat, 26 Jul 2025 12:15:10 +0200

Cleanup

Diffstat:
Magenda_entry.c | 4----
Mfuse_node.c | 103+++++++------------------------------------------------------------------------
Mfuse_node.h | 12------------
Mfuse_node_store.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mfuse_node_store.h | 11++++++++++-
Mmain.c | 25+++++++++++++++++++++++++
6 files changed, 103 insertions(+), 111 deletions(-)
diff --git a/agenda_entry.c b/agenda_entry.c
@@ -57,10 +57,6 @@ create_agenda_entry(memory_region *mreg, const char *filename,
 	struct agenda_entry *copy = xmalloc(sizeof(struct agenda_entry));
 	copy->filename = xstrdup(filename);
 	copy->filename_vdir = xstrdup(filename_vdir);
-	// TODO: These should be read from icalcomponent instead
-	// copy->gid = src->gid;
-	// copy->uid = src->uid;
-	// copy->ino = src->ino;
 	region_register(mreg, copy, (void *)free_agenda_entry);
 	return copy;
 }
diff --git a/fuse_node.c b/fuse_node.c
@@ -39,15 +39,6 @@ get_node_by_uuid(memory_region *mreg, const char *target_uuid)
 	return node;
 }
 
-char *
-get_node_filename(memory_region *mreg, const struct tree_node *node)
-{
-	struct agenda_entry *entry = node->data;
-	if (entry == NULL)
-		return "";
-	return rstrdup(mreg, entry->filename);
-}
-
 struct tree_node *
 get_node_by_path(memory_region *mreg, const char *path)
 {
@@ -85,12 +76,6 @@ get_node_by_path(memory_region *mreg, const char *path)
 }
 
 bool
-is_root_node(const struct tree_node *node)
-{
-	return !node->data;
-}
-
-bool
 node_is_directory(memory_region *mreg, const struct tree_node *node,
 		  icalcomponent *node_ics)
 {
@@ -147,7 +132,7 @@ get_icalcomponent_from_node(memory_region *mreg, const struct tree_node *n)
 		return NULL;
 	}
 
-	char *orig_path = get_vdir_filepath(mreg, n);
+	const char *orig_path = get_vdir_filepath(mreg, n);
 	// TODO: Cache intermediate results within context
 	icalcomponent *ic = parse_ics_file(mreg, orig_path);
 	return ic;
@@ -195,11 +180,10 @@ parse_ics_to_agenda_entry(memory_region *mreg, const char *vdir_filepath)
 		LOG("No summary found");
 		return NULL;
 	}
-	struct agenda_entry *e = xmalloc(sizeof(struct agenda_entry));
-	e->filename = xstrdup(icalcomponent_get_summary(component));
-	e->filename_vdir = xstrdup(get_filename(vdir_filepath));
 
-	region_register(mreg, e, (void *)free_agenda_entry);
+	struct agenda_entry *e =
+	    create_agenda_entry(mreg, icalcomponent_get_summary(component),
+				get_filename(vdir_filepath));
 
 	return e;
 }
@@ -213,7 +197,7 @@ load_agenda_entry_from_ics_file(memory_region *mreg, const char *filename)
 
 	struct stat fileStat;
 	if (stat(filepath, &fileStat) == -1) {
-		LOG("Can not stat %s. skipping", filepath);
+		LOG("Can not stat %s.", filepath);
 		return NULL;
 	}
 
@@ -257,7 +241,7 @@ load_root_node_tree()
 				    new_entry->filename_vdir);
 			}
 			else {
-				LOG("Could not load entry. Skipping");
+				LOG("Skipping %s", entry->d_name);
 			}
 		}
 	}
@@ -301,31 +285,6 @@ load_root_node_tree()
 	LOG("Done");
 }
 
-size_t
-load_agendafs_environment(char *vdir_env)
-{
-	wordexp_t expanded;
-	if (wordexp(vdir_env, &expanded, 0) != 0 || expanded.we_wordc == 0) {
-		fprintf(stderr, "Failed to expand CALDAVFS_ICS_DIR\n");
-		wordfree(&expanded);
-		return -1;
-	}
-
-	char *expanded_path = expanded.we_wordv[0];
-
-	struct stat s;
-	if (stat(expanded_path, &s) == 0 && S_ISDIR(s.st_mode)) {
-		assert(strlen(expanded_path) < 256);
-		set_vdir(expanded_path);
-		wordfree(&expanded);
-		return 0;
-	}
-
-	fprintf(stderr, "CALDAVFS_ICS_DIR is not a directory: %s\n",
-		expanded_path);
-	return -1;
-}
-
 static int
 append_category_to_memstream(FILE *memstream, const char *category,
 			     bool is_first_category)
@@ -511,7 +470,7 @@ get_node_stat(memory_region *mreg, const struct tree_node *node,
 	}
 	else {
 		struct stat vdir_stat = {0};
-		char *vdir_path = get_vdir_filepath(mreg, node);
+		const char *vdir_path = get_vdir_filepath(mreg, node);
 		int res = stat(vdir_path, &vdir_stat);
 		assert(res == 0);
 		vdir_stat.st_size =
@@ -695,7 +654,7 @@ delete_dir_from_fuse_path(memory_region *mreg, const char *filepath)
 		return -ENOTEMPTY;
 	}
 
-	char *filepath_original = get_vdir_filepath(mreg, node);
+	const char *filepath_original = get_vdir_filepath(mreg, node);
 	if (!filepath_original) {
 		LOG("Entry not found");
 		return -EIO;
@@ -776,7 +735,7 @@ delete_from_fuse_path(memory_region *mreg, const char *filepath)
 	if (node_is_directory(mreg, node, node_ics)) {
 		return -EISDIR;
 	}
-	char *filepath_original = get_vdir_filepath(mreg, node);
+	const char *filepath_original = get_vdir_filepath(mreg, node);
 
 	LOG("Deleting file %s, located at %s", filepath, filepath_original);
 
@@ -789,50 +748,6 @@ delete_from_fuse_path(memory_region *mreg, const char *filepath)
 	return res;
 }
 
-char *
-get_node_path(memory_region *mreg, struct tree_node *node)
-{
-	if (!node->parent) {
-		return "/";
-	}
-
-	struct tree_node *curr = node;
-	char *result = NULL;
-	size_t result_len = 0;
-
-	FILE *stream = open_memstream(&result, &result_len);
-	assert(stream);
-
-	do {
-		if (!is_root_node(curr)) {
-			char *filename = get_node_filename(mreg, curr);
-			fprintf(stream, "/%s", filename);
-		}
-
-		curr = curr->parent;
-
-	} while (curr->parent);
-
-	fclose(stream);
-	if (result) {
-		region_register(mreg, result, free);
-	}
-
-	return result;
-}
-
-char *
-get_fuse_path_from_vdir(memory_region *mreg, const char *filepath)
-{
-	struct tree_node *node =
-	    hashmap_get(entries_vdir, get_filename(filepath));
-
-	if (node) {
-		return get_node_path(mreg, node);
-	}
-	return NULL;
-}
-
 int
 delete_from_vdir_path(memory_region *mreg, const char *filepath)
 {
diff --git a/fuse_node.h b/fuse_node.h
@@ -27,16 +27,10 @@
 struct tree_node *
 get_node_by_uuid(memory_region *mreg, const char *target_uuid);
 
-char *
-get_node_filename(memory_region *mreg, const struct tree_node *node);
-
 struct tree_node *
 get_node_by_path(memory_region *mreg, const char *path);
 
 bool
-is_root_node(const struct tree_node *node);
-
-bool
 node_is_directory(memory_region *mreg, const struct tree_node *node,
 		  icalcomponent *node_ics);
 
@@ -71,9 +65,6 @@ load_agenda_entry_from_ics_file(memory_region *mreg, const char *filename);
 void
 load_root_node_tree();
 
-size_t
-load_agendafs_environment(char *vdir_env);
-
 // Returns comma separated list of categories for a file
 char *
 get_node_categories(memory_region *mreg, const struct tree_node *node);
@@ -124,9 +115,6 @@ int
 delete_from_fuse_path(memory_region *mreg, const char *filepath);
 
 char *
-get_node_path(memory_region *mreg, struct tree_node *node);
-
-char *
 get_fuse_path_from_vdir(memory_region *mreg, const char *filepath);
 
 int
diff --git a/fuse_node_store.c b/fuse_node_store.c
@@ -41,7 +41,66 @@ get_entry(const struct tree_node *node)
 	return node->data;
 }
 
+bool
+is_root_node(const struct tree_node *node)
+{
+	return !node->data;
+}
+
+char *
+get_node_filename(memory_region *mreg, const struct tree_node *node)
+{
+	struct agenda_entry *entry = node->data;
+	if (entry == NULL)
+		return "";
+	return rstrdup(mreg, entry->filename);
+}
+
 char *
+get_node_path(memory_region *mreg, struct tree_node *node)
+{
+	if (!node->parent) {
+		return "/";
+	}
+
+	struct tree_node *curr = node;
+	char *result = NULL;
+	size_t result_len = 0;
+
+	FILE *stream = open_memstream(&result, &result_len);
+	assert(stream);
+
+	do {
+		if (!is_root_node(curr)) {
+			char *filename = get_node_filename(mreg, curr);
+			fprintf(stream, "/%s", filename);
+		}
+
+		curr = curr->parent;
+
+	} while (curr->parent);
+
+	fclose(stream);
+	if (result) {
+		region_register(mreg, result, free);
+	}
+
+	return result;
+}
+
+const char *
+get_fuse_path_from_vdir(memory_region *mreg, const char *filepath_vdir)
+{
+	struct tree_node *node =
+	    hashmap_get(entries_vdir, get_filename(filepath_vdir));
+
+	if (node) {
+		return get_node_path(mreg, node);
+	}
+	return NULL;
+}
+
+const char *
 get_vdir_filepath(memory_region *mreg, const struct tree_node *node)
 {
 	const struct agenda_entry *entry = get_entry(node);
diff --git a/fuse_node_store.h b/fuse_node_store.h
@@ -26,9 +26,18 @@ get_fuse_node_from_vdir_name(const char *vdir_name);
 const struct agenda_entry *
 get_entry(const struct tree_node *node);
 
-char *
+const char *
 get_vdir_filepath(memory_region *mreg, const struct tree_node *node);
 
+bool
+is_root_node(const struct tree_node *node);
+
+char *
+get_node_filename(memory_region *mreg, const struct tree_node *node);
+
+char *
+get_node_path(memory_region *mreg, struct tree_node *node);
+
 int
 set_node_filename(struct tree_node *node, const char *filename);
 
diff --git a/main.c b/main.c
@@ -637,6 +637,31 @@ agendafs_opt_proc(void *data, const char *arg, int key,
 	return 1;
 }
 
+size_t
+load_agendafs_environment(char *vdir_env)
+{
+	wordexp_t expanded;
+	if (wordexp(vdir_env, &expanded, 0) != 0 || expanded.we_wordc == 0) {
+		fprintf(stderr, "Failed to expand CALDAVFS_ICS_DIR\n");
+		wordfree(&expanded);
+		return -1;
+	}
+
+	char *expanded_path = expanded.we_wordv[0];
+
+	struct stat s;
+	if (stat(expanded_path, &s) == 0 && S_ISDIR(s.st_mode)) {
+		assert(strlen(expanded_path) < 256);
+		set_vdir(expanded_path);
+		wordfree(&expanded);
+		return 0;
+	}
+
+	fprintf(stderr, "CALDAVFS_ICS_DIR is not a directory: %s\n",
+		expanded_path);
+	return -1;
+}
+
 int
 main(int argc, char *argv[])
 {