agendafs

A filesystem for your calendar.

git clone git://mccd.space/agendafs
commit 9f362615d8f52b47cd09f7f309c720ed963e516a
parent 6339ca61a670c72b012c764c34a91ccbc585914e
Author: Marc Coquand <marc@coquand.email>
Date:   Mon, 18 Aug 2025 13:33:24 +0200

refactor and code cleanup

Diffstat:
Mical_extra.c | 5+++--
Mical_extra.h | 2+-
Mmain.c | 65+++++++++++++++++++++++++++++++++++++++++++++--------------------
3 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/ical_extra.c b/ical_extra.c
@@ -62,7 +62,7 @@ parse_ical_class(const char *input)
 	else if (strcmp(input, "confidential") == 0) {
 		return ICAL_CLASS_CONFIDENTIAL;
 	}
-	return ICAL_CLASS_X;
+	return ICAL_CLASS_NONE;
 }
 
 const char *
@@ -110,6 +110,7 @@ parse_ics_file(memory_region *mreg, const char *filename)
 	LOG("filename is %s", filename);
 
 	struct stat st;
+	// Each node corresponds to a file on the system.
 	assert(stat(filename, &st) == 0);
 
 	size_t size = st.st_size;
@@ -344,7 +345,7 @@ icalcomponent_remove_x_prop(icalcomponent *component, const char *key)
 }
 
 void
-icalcomponent_write_x_props(FILE *memstream, icalcomponent *component)
+icalcomponent_print_x_props(FILE *memstream, icalcomponent *component)
 {
 	icalcomponent *inner = icalcomponent_get_innermost(component);
 	icalproperty *prop_iter =
diff --git a/ical_extra.h b/ical_extra.h
@@ -75,6 +75,6 @@ icalcomponent_remove_custom_prop(memory_region *mreg, icalcomponent *component,
 				 const char *key);
 
 void
-icalcomponent_write_x_props(FILE *memstream, icalcomponent *component);
+icalcomponent_print_x_props(FILE *memstream, icalcomponent *component);
 
 #endif // ical_extra_h_INCLUDED
diff --git a/main.c b/main.c
@@ -28,6 +28,8 @@
 
 // Listening to file changes of the original content
 #define EVENT_BUF_LEN (1024 * (sizeof(struct inotify_event) + 16))
+
+// Between the inotify event listener and the fuse filesystem
 static pthread_rwlock_t entries_lock = PTHREAD_RWLOCK_INITIALIZER;
 
 #define FUSE_WRITE_BEGIN                                                       \
@@ -143,7 +145,6 @@ fuse_open(const char *path, struct fuse_file_info *fi)
 	LOG("%s", path);
 	const struct tree_node *node = get_node_by_path(mreg, path);
 	if (!node) {
-		LOG("Entry not found");
 		status = -ENOENT;
 	}
 
@@ -241,7 +242,7 @@ fuse_write(const char *path, const char *buf, size_t size, off_t offset,
 
 	icalcomponent *ic = get_icalcomponent_from_node(mreg, node);
 
-	// Is it possible to write to "/"?
+	// It possible to write to "/". The rest have an icalcomponent
 	assert(ic);
 
 	icalcomponent_insert_description(mreg, ic, buf, size, offset);
@@ -412,32 +413,37 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 	FUSE_WRITE_BEGIN;
 	LOG("'%s' '%s' '%zu' '%s' '%d'", path, attribute, s, attribute, flags);
 
-	// Limit imposed in xattr(7)
+	// Limit documented in xattr(7)
 	if (strlen(attribute) >= 256) {
 		status = -EMSGSIZE;
 		goto cleanup_return;
 	}
 
+	// Limit documented in xattr(7)
 	if (strlen(value) >= 64 * 1024) {
 		status = -EMSGSIZE;
 		goto cleanup_return;
 	}
+
 	struct tree_node *node = get_node_by_path(mreg, path);
 	if (!node) {
 		status = -ENONET;
 		goto cleanup_return;
 	}
 
+	// uid is set by the ics file and is immutable
 	if (strcmp(attribute, "user.uid") == 0) {
 		status = -EPERM;
 		goto cleanup_return;
 	}
 
-	if (strcmp(attribute, "user.sibling") == 0) {
+	// user.sibling is reserved but not implemented
+	else if (strcmp(attribute, "user.sibling") == 0) {
 		status = -EPERM;
 		goto cleanup_return;
 	}
-	if (strcmp(attribute, "user.dtstart") == 0) {
+
+	else if (strcmp(attribute, "user.dtstart") == 0) {
 		if (strcmp(value, "") == 0) {
 			status = clear_dtstart(mreg, node);
 		}
@@ -446,14 +452,16 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 		}
 		goto cleanup_return;
 	}
-	if (strcmp(attribute, "user.categories") == 0) {
+
+	else if (strcmp(attribute, "user.categories") == 0) {
 		status = set_node_categories(mreg, node, value, s);
 		goto cleanup_return;
 	}
+
 	else if (strcmp(attribute, "user.class") == 0) {
 		enum icalproperty_class iclass = parse_ical_class(value);
 
-		if (iclass == ICAL_CLASS_X) {
+		if (iclass == ICAL_CLASS_NONE) {
 			status = -EINVAL;
 			goto cleanup_return;
 		}
@@ -471,6 +479,7 @@ fuse_setxattr(const char *path, const char *attribute, const char *value,
 	}
 	else {
 		status = -EINVAL;
+		goto cleanup_return;
 	}
 
 cleanup_return:
@@ -485,8 +494,8 @@ fuse_listxattr(const char *path, char *list, size_t size)
 	LOG("%s %zu", list, size);
 
 	FILE *stream;
-	char *membuffer = NULL;
-	size_t membuffer_len = 0;
+	char *xattribute_list = NULL;
+	size_t xattr_list_len = 0;
 
 	struct tree_node *node = get_node_by_path(mreg, path);
 	if (!node) {
@@ -502,7 +511,7 @@ fuse_listxattr(const char *path, char *list, size_t size)
 	icalcomponent *comp = get_icalcomponent_from_node(mreg, node);
 	assert(comp);
 
-	stream = open_memstream(&membuffer, &membuffer_len);
+	stream = open_memstream(&xattribute_list, &xattr_list_len);
 	if (stream == NULL) {
 		status = -EIO;
 		goto cleanup_return_2;
@@ -530,7 +539,7 @@ fuse_listxattr(const char *path, char *list, size_t size)
 		fputc('\0', stream);
 	}
 
-	icalcomponent_write_x_props(stream, comp);
+	icalcomponent_print_x_props(stream, comp);
 
 	if (fclose(stream) != 0) {
 		status = -EIO;
@@ -538,18 +547,17 @@ fuse_listxattr(const char *path, char *list, size_t size)
 	}
 
 	if (size > 0) {
-		if (membuffer_len < size) {
-			memcpy(list, membuffer, membuffer_len);
+		if (xattr_list_len < size) {
+			memcpy(list, xattribute_list, xattr_list_len);
 		}
 		else {
-			memcpy(list, membuffer, size);
-			list[size - 1] = '\0';
+			memcpy(list, xattribute_list, size);
 		}
 	}
-	status = membuffer_len;
+	status = xattr_list_len;
 
 cleanup_return:
-	free(membuffer);
+	free(xattribute_list);
 cleanup_return_2:
 	FUSE_CLEANUP;
 	return status;
@@ -592,7 +600,13 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		assert(uid);
 
 		int string_len = strlen(uid);
-		snprintf(buf, s, "%s", uid);
+
+		// If s == 0 we don't need to write, just return size to
+		// allocate
+		if (s > 0) {
+			snprintf(buf, s, "%s", uid);
+		}
+
 		status = string_len;
 		goto cleanup_return;
 	}
@@ -620,7 +634,12 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		}
 
 		int string_len = strlen(res);
-		snprintf(buf, s, "%s", res);
+
+		// If s == 0 we don't need to write, just return size to
+		// allocate
+		if (s > 0) {
+			snprintf(buf, s, "%s", res);
+		}
 
 		status = string_len;
 		goto cleanup_return;
@@ -637,7 +656,13 @@ fuse_getxattr(const char *path, const char *attribute, char *buf, size_t s)
 		}
 
 		int string_len = strlen(value);
-		snprintf(buf, s, "%s", value);
+
+		// If s == 0 we don't need to write, just return size to
+		// allocate
+		if (s > 0) {
+			snprintf(buf, s, "%s", value);
+		}
+
 		status = string_len;
 		goto cleanup_return;
 	}