agendafs
A filesystem for your calendar.
git clone git://mccd.space/agendafscommit 3a3d9770d3cdf542c3956b3468a3b3db4eda7491
parent c54832fbe8785da3c9b2bb743d16171cdbd55816
Author: Marc Coquand <marc@coquand.email>
Date: Mon, 30 Jun 2025 12:30:02 +0100
Fix inotify bugs
Implements: https://todo.sr.ht/~marcc/agendafs/20
Closes: https://todo.sr.ht/~marcc/agendafs/19
Diffstat:
| M | journal_entry.c | | | 62 | ++++++++++++++++++++++++++++++++++++++++++-------------------- |
| M | main.c | | | 35 | ++++++++++++++++++++--------------- |
| M | tree.c | | | 2 | +- |
3 files changed, 63 insertions(+), 36 deletions(-)
diff --git a/journal_entry.c b/journal_entry.c
@@ -26,7 +26,8 @@ static const char *IS_DIRECTORY_PROPERTY = "X-CALDAVFS-ISDIRECTORY";
// tree of journal entries
struct tree_node *fuse_tree_root = NULL;
-// journal_entry
+// journal_entry, keys are the filename as stored in ICS_DIR
+// I.E. bcb4c14b-8f3f-4a53-ad33-1f4499071a9m-caldavfs.ics
struct hashmap *entries_original_ics = NULL;
struct tree_node *
@@ -36,6 +37,7 @@ create_file_node(struct journal_entry *entry)
create_tree_node(entry, free_journal_entry);
return file_node;
}
+
struct journal_entry *
get_entry(tree_node *node)
{
@@ -602,6 +604,8 @@ load_journal_entries()
free_journal_entry(new_entry);
continue;
}
+ LOG("Inserted filename_original: %s",
+ new_entry->filename_original);
}
}
closedir(dir);
@@ -1082,38 +1086,56 @@ create_directory_from_fuse_path(const char *fuse_path)
// TODO: Add return status
void
-update_or_create_fuse_entry_from_original(const char *filename)
+update_or_create_fuse_entry_from_original(const char *filepath_original)
{
- char *base_name = strrchr(filename, '/');
- struct journal_entry *new_entry =
+ char *filename_original = get_filename(filepath_original);
+ LOG("Filename original is %s", filename_original);
+
+ struct journal_entry *updated_entry =
xcalloc(1, sizeof(struct journal_entry));
- if (load_journal_entry_from_ics_file(base_name, new_entry) != 0) {
+ if (load_journal_entry_from_ics_file(filename_original,
+ updated_entry) != 0) {
// Parsing failed, clean up and maybe remove old entry
// if any
LOG("PARSING FAILED");
- free_journal_entry(new_entry);
- return;
- }
- const char *target_uuid = icalcomponent_get_uid(new_entry->component);
- if (!target_uuid) {
return;
}
- // TODO: Handle directories
- tree_node *existing_node = get_node_by_uuid(target_uuid);
+ tree_node *new_or_updated_node =
+ hashmap_get(entries_original_ics, filename_original);
- // TODO: Enable subdirectories
- if (existing_node) {
- update_node_data(existing_node, new_entry);
+ if (new_or_updated_node) {
+ LOG("Updating existing entry");
+ update_node_data(new_or_updated_node, updated_entry);
}
else {
- tree_node *new_node = create_file_node(new_entry);
- // TODO: Look for child-parent relationship and update
- // accordingly
- add_child(fuse_tree_root, new_node);
+ LOG("Creating new entry");
+ new_or_updated_node = create_file_node(updated_entry);
hashmap_insert(entries_original_ics,
- new_entry->filename_original, new_node);
+ updated_entry->filename_original,
+ new_or_updated_node);
+ }
+
+ const char *parent_uid = get_parent_uid(updated_entry->component);
+ LOG("Looking up updated_entry %s, %s", updated_entry->filename_original,
+ updated_entry->filename);
+ if (parent_uid) {
+ LOG("Has parent");
+ tree_node *parent = get_node_by_uuid(parent_uid);
+ if (parent) {
+ move_node(new_or_updated_node->parent, parent,
+ new_or_updated_node);
+ }
+ else {
+ LOG("Parent not found, adding to root");
+ add_child(fuse_tree_root, new_or_updated_node);
+ }
+ }
+ else {
+ LOG("Does not have parent");
+ detach_tree_node(new_or_updated_node);
+ add_child(fuse_tree_root, new_or_updated_node);
}
LOG("File updated");
diff --git a/main.c b/main.c
@@ -383,7 +383,13 @@ watch_ics_dir(void *arg)
pthread_mutex_unlock(&entries_mutex);
}
else if (event->mask & IN_CREATE) {
- // TODO
+ pthread_mutex_lock(&entries_mutex);
+
+ // Reload entries on any change
+ update_or_create_fuse_entry_from_original(
+ full_path);
+
+ pthread_mutex_unlock(&entries_mutex);
}
}
free(full_path);
@@ -398,26 +404,25 @@ watch_ics_dir(void *arg)
}
// Ignore for now
-static int
+int
journal_utimens(const char *path, const struct timespec tv[2],
struct fuse_file_info *info)
{
return 0;
}
-static const struct fuse_operations journal_oper = {.getattr = journal_getattr,
- .readdir = journal_readdir,
- .open = journal_open,
- .read = journal_read,
- .utimens = journal_utimens,
- .write = journal_write,
- .create = journal_create,
- .mkdir = journal_mkdir,
- .unlink = journal_unlink,
- .rmdir = journal_rmdir,
- .readlink =
- journal_readlink,
- .rename = journal_rename};
+struct fuse_operations journal_oper = {.getattr = journal_getattr,
+ .readdir = journal_readdir,
+ .open = journal_open,
+ .read = journal_read,
+ .utimens = journal_utimens,
+ .write = journal_write,
+ .create = journal_create,
+ .mkdir = journal_mkdir,
+ .unlink = journal_unlink,
+ .rmdir = journal_rmdir,
+ .readlink = journal_readlink,
+ .rename = journal_rename};
int
main(int argc, char *argv[])
diff --git a/tree.c b/tree.c
@@ -85,7 +85,7 @@ print_tree(tree_node *node, int depth, void (*print_data)(void *))
bool
detach_tree_node(tree_node *node)
{
- if (!node || !node->parent)
+ if (!node->parent)
return false;
tree_node *parent = node->parent;