agendafs
A filesystem for your calendar.
git clone git://mccd.space/agendafscommit e8bc0c04171c9e69c3fd34901ce74845570f8dc6
Author: Marc Coquand <marc@coquand.email>
Date: Fri, 30 May 2025 18:19:52 +0100
initial commit
Diffstat:
5 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,11 @@
+CC = gcc
+CFLAGS = -Wall -g
+LIBS = `pkg-config fuse3 --cflags --libs`
+
+all: journalfs
+
+journalfs: main.c
+ $(CC) $(CFLAGS) main.c -o journalfs $(LIBS)
+
+clean:
+ rm -f journalfs
diff --git a/journalfs b/journalfs
Binary files differ.
diff --git a/main.c b/main.c
@@ -0,0 +1,90 @@
+#define FUSE_USE_VERSION 31
+
+#include <fuse3/fuse.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+static const char *virtual_file_path = "/journal.txt";
+static const char *virtual_content = "This is a journal entry.\n";
+
+static int journal_getattr(const char *path, struct stat *stbuf,
+ struct fuse_file_info *fi)
+{
+ (void) fi;
+ 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;
+}
+
+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;
+
+ 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
+
+ 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_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;
+}
+
+static const struct fuse_operations journal_oper = {
+ .getattr = journal_getattr,
+ .readdir = journal_readdir,
+ .open = journal_open,
+ .read = journal_read,
+};
+
+int main(int argc, char *argv[])
+{
+ return fuse_main(argc, argv, &journal_oper, NULL);
+}
+
diff --git a/sample_ics/2025-01-01.ics b/sample_ics/2025-01-01.ics
@@ -0,0 +1,8 @@
+BEGIN:VCALENDAR
+BEGIN:VJOURNAL
+UID:20250101T120000Z-001@host.com
+DTSTAMP:20250101T120000Z
+SUMMARY:New Year's Day Reflections
+DESCRIPTION:Reflecting on the past year and setting goals for the new one.
+END:VJOURNAL
+END:VCALENDAR
diff --git a/shell.nix b/shell.nix
@@ -0,0 +1,13 @@
+{
+ pkgs ? import <nixpkgs> { },
+}:
+
+pkgs.mkShell {
+ hardeningDisable = [ "all" ];
+ packages = with pkgs; [
+ clang-tools
+ fuse3
+ gdb
+ pkg-config
+ ];
+}