agendafs

A filesystem for your calendar.

git clone git://mccd.space/agendafs
commit 9b5cb3d2381f1cca01e06d8cc4838a46a6659e1e
parent e8bc0c04171c9e69c3fd34901ce74845570f8dc6
Author: Marc Coquand <marc@coquand.email>
Date:   Fri, 30 May 2025 18:37:20 +0100

Add debug and logs

Diffstat:
MMakefile | 3+++
Mjournalfs | 0
Mmain.c | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Asample_ics/2025-01-02.ics | 8++++++++
4 files changed, 115 insertions(+), 47 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,5 +7,8 @@ all: journalfs
 journalfs: main.c
 	$(CC) $(CFLAGS) main.c -o journalfs $(LIBS)
 
+debug: main.c
+	$(CC) $(CFLAGS) $(DEBUG_FLAGS) main.c -o journalfs-debug $(LIBS)
+
 clean:
 	rm -f journalfs
diff --git a/journalfs b/journalfs
Binary files differ.
diff --git a/main.c b/main.c
@@ -3,77 +3,133 @@
 #include <fuse3/fuse.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#include <dirent.h>
 #include <errno.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#define ICS_DIR "./sample_ics"
+
+typedef struct {
+    char *filename;
+    char *summary;
+    char *description;
+    time_t timestamp;
+} journal_entry;
+
+static journal_entry *entries = NULL;
+static size_t entry_count = 0;
+
+static void load_journal_entries() {
+    printf("Loading journal entries from: %s\n", ICS_DIR);
+    DIR *dir = opendir(ICS_DIR);
+    if (!dir) {
+        perror("opendir");
+        return;
+    }
+
+    struct dirent *entry;
+    char filepath[512];
+    while ((entry = readdir(dir))) {
+        if (entry->d_type == DT_REG && strstr(entry->d_name, ".ics")) {
+            snprintf(filepath, sizeof(filepath), "%s/%s", ICS_DIR, entry->d_name);
+            FILE *file = fopen(filepath, "r");
+            if (file) {
+                // Simulate parsing a VJOURNAL from the .ics file
+                printf("Found .ics file: %s\n", filepath);
+                entries = realloc(entries, sizeof(journal_entry) * (entry_count + 1));
+                entries[entry_count].filename = strdup(entry->d_name);
+                entries[entry_count].summary = strdup("Mock summary from .ics");
+                entries[entry_count].description = strdup("Mock description from .ics");
+                entries[entry_count].timestamp = time(NULL);
+                entry_count++;
+                fclose(file);
+            } else {
+                perror("fopen");
+            }
+        }
+    }
 
-static const char *virtual_file_path = "/journal.txt";
-static const char *virtual_content = "This is a journal entry.\n";
+    printf("Loaded %zu journal entries.\n", entry_count);
+    closedir(dir);
+}
 
-static int journal_getattr(const char *path, struct stat *stbuf,
-                           struct fuse_file_info *fi)
-{
-    (void) fi;
+static int journal_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) {
+    printf("getattr called for: %s\n", path);
     memset(stbuf, 0, sizeof(struct stat));
 
     if (strcmp(path, "/") == 0) {
         stbuf->st_mode = S_IFDIR | 0755;
         stbuf->st_nlink = 2;
-    } else if (strcmp(path, virtual_file_path) == 0) {
-        stbuf->st_mode = S_IFREG | 0444;
-        stbuf->st_nlink = 1;
-        stbuf->st_size = strlen(virtual_content);
-    } else {
-        return -ENOENT;
+        return 0;
     }
 
-    return 0;
+    for (size_t i = 0; i < entry_count; i++) {
+        char entry_path[256];
+        snprintf(entry_path, sizeof(entry_path), "/%s.txt", entries[i].filename);
+        if (strcmp(path, entry_path) == 0) {
+            stbuf->st_mode = S_IFREG | 0444;
+            stbuf->st_nlink = 1;
+            stbuf->st_size = strlen(entries[i].summary) + strlen(entries[i].description) + 2;
+            return 0;
+        }
+    }
+
+    return -ENOENT;
 }
 
 static int journal_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                            off_t offset, struct fuse_file_info *fi,
-                           enum fuse_readdir_flags flags)
-{
-    (void) offset;
-    (void) fi;
-    (void) flags;
-
+                           enum fuse_readdir_flags flags) {
+    printf("readdir called for: %s\n", path);
     if (strcmp(path, "/") != 0)
         return -ENOENT;
 
     filler(buf, ".", NULL, 0, 0);
     filler(buf, "..", NULL, 0, 0);
-    filler(buf, virtual_file_path + 1, NULL, 0, 0); // remove leading slash
+
+    for (size_t i = 0; i < entry_count; i++) {
+        char entry_name[256];
+        snprintf(entry_name, sizeof(entry_name), "%s.txt", entries[i].filename);
+        printf("readdir exposing: %s\n", entry_name);
+        filler(buf, entry_name, NULL, 0, 0);
+    }
 
     return 0;
 }
 
-static int journal_open(const char *path, struct fuse_file_info *fi)
-{
-    if (strcmp(path, virtual_file_path) != 0)
-        return -ENOENT;
-
-    // Only allow read-only
-    if ((fi->flags & O_ACCMODE) != O_RDONLY)
-        return -EACCES;
-
-    return 0;
+static int journal_open(const char *path, struct fuse_file_info *fi) {
+    printf("open called for: %s\n", path);
+    for (size_t i = 0; i < entry_count; i++) {
+        char entry_path[256];
+        snprintf(entry_path, sizeof(entry_path), "/%s.txt", entries[i].filename);
+        if (strcmp(path, entry_path) == 0) {
+            return 0;
+        }
+    }
+    return -ENOENT;
 }
 
 static int journal_read(const char *path, char *buf, size_t size, off_t offset,
-                        struct fuse_file_info *fi)
-{
-    (void) fi;
-    size_t len = strlen(virtual_content);
-    if (strcmp(path, virtual_file_path) != 0)
-        return -ENOENT;
-
-    if (offset >= len)
-        return 0;
-
-    if (offset + size > len)
-        size = len - offset;
-
-    memcpy(buf, virtual_content + offset, size);
-    return size;
+                        struct fuse_file_info *fi) {
+    printf("read called for: %s (offset: %ld, size: %zu)\n", path, offset, size);
+    for (size_t i = 0; i < entry_count; i++) {
+        char entry_path[256];
+        snprintf(entry_path, sizeof(entry_path), "/%s.txt", entries[i].filename);
+        if (strcmp(path, entry_path) == 0) {
+            const char *summary = entries[i].summary;
+            size_t len = strlen(summary);
+            if (offset < len) {
+                if (offset + size > len)
+                    size = len - offset;
+                memcpy(buf, summary + offset, size);
+            } else
+                size = 0;
+            return size;
+        }
+    }
+    return -ENOENT;
 }
 
 static const struct fuse_operations journal_oper = {
@@ -83,8 +139,9 @@ static const struct fuse_operations journal_oper = {
     .read    = journal_read,
 };
 
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
+    printf("Starting journalfs...\n");
+    load_journal_entries();
     return fuse_main(argc, argv, &journal_oper, NULL);
 }
 
diff --git a/sample_ics/2025-01-02.ics b/sample_ics/2025-01-02.ics
@@ -0,0 +1,8 @@
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+UID:20250102T120000Z-002@host.com
+DTSTAMP:20250102T120000Z
+SUMMARY:Project Kickoff
+DESCRIPTION:Initial meeting for the upcoming project, discussing objectives and timelines.
+END:VJOURNAL
+END:VCALENDAR