agendafs
A filesystem for your calendar.
git clone git://mccd.space/agendafscommit 985fbcacfe752019b8da39c7660f142c18237466
parent 2c713772ae19d0d6cdae756c6c189a9e3c880932
Author: Marc Coquand <marc@coquand.email>
Date: Thu, 24 Jul 2025 10:51:09 +0200
Refactor out ical functions
Grouping the functions by what data they operate on.
Diffstat:
| M | Makefile | | | 2 | +- |
| M | agenda_entry.c | | | 267 | +------------------------------------------------------------------------------ |
| M | agenda_entry.h | | | 25 | ------------------------- |
| A | ical_extra.c | | | 265 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | ical_extra.h | | | 51 | +++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | main.c | | | 116 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
| M | util.h | | | 4 | ++++ |
7 files changed, 386 insertions(+), 344 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
CC ?= gcc
CFLAGS = -Wall -O3
-CFLAGS_DEBUG = -Wall -g
+CFLAGS_DEBUG = -Wall -g -DDEBUG
LIBS = `pkg-config uuid fuse3 libical --cflags --libs`
all: agendafs
diff --git a/agenda_entry.c b/agenda_entry.c
@@ -1,5 +1,6 @@
#include "agenda_entry.h"
#include "hashmap.h"
+#include "ical_extra.h"
#include "mregion.h"
#include "path.h"
#include "tree.h"
@@ -19,7 +20,6 @@
#include <uuid/uuid.h>
#include <wordexp.h>
-const char *IS_DIRECTORY_PROPERTY = "X-CALDAVFS-ISDIRECTORY";
char VDIR[256];
// Most memory is managed by memory_region, two exceptions are the
@@ -140,41 +140,6 @@ node_is_directory(memory_region *mreg, const struct tree_node *node,
}
bool
-is_directory_component(icalcomponent *component)
-{
- icalcomponent *journal = icalcomponent_get_first_component(
- component, ICAL_VJOURNAL_COMPONENT);
-
- for (icalproperty *prop = icalcomponent_get_first_property(
- journal, ICAL_RELATEDTO_PROPERTY);
- prop != NULL; prop = icalcomponent_get_next_property(
- journal, ICAL_RELATEDTO_PROPERTY)) {
-
- const char *reltype =
- icalproperty_get_parameter_as_string(prop, "RELTYPE");
- if (reltype && strcasecmp(reltype, "CHILD") == 0) {
- return true;
- }
- }
- for (icalproperty *prop =
- icalcomponent_get_first_property(journal, ICAL_X_PROPERTY);
- prop != NULL;
- prop = icalcomponent_get_next_property(journal, ICAL_X_PROPERTY)) {
- LOG("FOUND X PROPERTY");
-
- const char *prop_name = icalproperty_get_x_name(prop);
- if (prop_name &&
- strcmp(prop_name, IS_DIRECTORY_PROPERTY) == 0) {
- const char *value =
- icalproperty_get_value_as_string(prop);
- LOG("FOUND DIRECTORY");
- return value && strcmp(value, "YES") == 0;
- }
- }
- return false;
-}
-
-bool
is_root_node(const struct tree_node *node)
{
return !node->data;
@@ -194,36 +159,6 @@ get_vdir_filepath(memory_region *mreg, const struct tree_node *node)
return append_path(mreg, VDIR, entry->filename_vdir);
}
-// Owner: ctx
-icalcomponent *
-parse_ics_file(memory_region *mreg, const char *filename)
-{
-
- FILE *file = fopen(filename, "r");
- LOG("filename is %s", filename);
-
- struct stat st;
- assert(stat(filename, &st) == 0);
-
- size_t size = st.st_size;
- char *buffer = rmalloc(mreg, size + 1);
-
- size_t bytes_read = fread(buffer, 1, size, file);
- buffer[bytes_read] = '\0';
- fclose(file);
-
- icalcomponent *component = ricalcomponent_new_from_string(mreg, buffer);
-
- return component;
-}
-
-icaltimetype
-get_ical_now()
-{
- return icaltime_from_timet_with_zone(time(NULL), 0,
- icaltimezone_get_utc_timezone());
-}
-
size_t
write_ical_file(memory_region *mreg, const struct tree_node *node,
icalcomponent *ic)
@@ -272,72 +207,6 @@ get_icalcomponent_from_node(memory_region *mreg, const struct tree_node *n)
return ic;
}
-const char *
-get_parent_uid(icalcomponent *component)
-{
- icalcomponent *inner =
- icalcomponent_get_first_component(component, ICAL_ANY_COMPONENT);
-
- for (icalproperty *prop = icalcomponent_get_first_property(
- inner, ICAL_RELATEDTO_PROPERTY);
- prop != NULL; prop = icalcomponent_get_next_property(
- inner, ICAL_RELATEDTO_PROPERTY)) {
- const char *reltype =
- icalproperty_get_parameter_as_string(prop, "RELTYPE");
- if (reltype && strcasecmp(reltype, "PARENT") == 0) {
- return icalproperty_get_value_as_string(prop);
- }
- }
-
- return NULL;
-}
-
-void
-remove_parent_child_relationship_from_component(icalcomponent *parent,
- icalcomponent *child)
-{
-
- const char *parent_uid = icalcomponent_get_uid(parent);
-
- icalcomponent *inner =
- icalcomponent_get_first_component(child, ICAL_ANY_COMPONENT);
-
- icalproperty *prop =
- icalcomponent_get_first_property(inner, ICAL_RELATEDTO_PROPERTY);
- while (prop != NULL) {
- icalproperty *next = icalcomponent_get_next_property(
- inner, ICAL_RELATEDTO_PROPERTY);
- const char *value = icalproperty_get_relatedto(prop);
- icalparameter *reltype = icalproperty_get_first_parameter(
- prop, ICAL_RELTYPE_PARAMETER);
-
- if (value && strcmp(value, parent_uid) == 0 && reltype &&
- icalparameter_get_reltype(reltype) == ICAL_RELTYPE_PARENT) {
- icalcomponent_remove_property(inner, prop);
- icalproperty_free(prop);
- }
-
- prop = next;
- }
-}
-
-void
-set_parent_child_relationship_to_component(icalcomponent *parent,
- icalcomponent *child)
-{
- icalproperty *child_related_to_parent =
- icalproperty_new_relatedto(icalcomponent_get_uid(parent));
- icalparameter *reltype_child =
- icalparameter_new_reltype(ICAL_RELTYPE_PARENT);
- icalproperty_add_parameter(child_related_to_parent, reltype_child);
-
- icalcomponent *inner =
- icalcomponent_get_first_component(child, ICAL_ANY_COMPONENT);
- if (inner) {
- icalcomponent_add_property(inner, child_related_to_parent);
- }
-}
-
int
write_parent_child_components(memory_region *mreg,
const struct tree_node *parent,
@@ -493,19 +362,13 @@ load_root_node_tree()
icalcomponent *ic = get_icalcomponent_from_node(mreg, child);
LOG("Success");
- struct agenda_entry *entry = get_entry(child);
-
const char *parent_uid = get_parent_uid(ic);
- LOG("Looking up entry %s, %s", entry->filename_vdir,
- entry->filename);
if (parent_uid) {
LOG("Has parent");
struct tree_node *parent =
get_node_by_uuid(mreg, parent_uid);
if (parent) {
- struct agenda_entry *p_entry = parent->data;
- LOG("Adding to parent %s", p_entry->filename);
detach_tree_node(child);
add_child(parent, child);
}
@@ -679,36 +542,6 @@ set_node_categories(memory_region *mreg, const struct tree_node *node,
}
const char *
-format_ical_class(const enum icalproperty_class iclass)
-{
- if (iclass == ICAL_CLASS_PRIVATE) {
- return "private";
- }
- else if (iclass == ICAL_CLASS_PUBLIC) {
- return "public";
- }
- else if (iclass == ICAL_CLASS_CONFIDENTIAL) {
- return "confidential";
- }
- return NULL;
-}
-
-const icalproperty_class
-parse_ical_class(const char *input)
-{
- if (strcmp(input, "private") == 0) {
- return ICAL_CLASS_PRIVATE;
- }
- else if (strcmp(input, "public") == 0) {
- return ICAL_CLASS_PUBLIC;
- }
- else if (strcmp(input, "confidential") == 0) {
- return ICAL_CLASS_CONFIDENTIAL;
- }
- return ICAL_CLASS_X;
-}
-
-const char *
get_node_class(memory_region *mreg, const struct tree_node *node)
{
icalcomponent *component = get_icalcomponent_from_node(mreg, node);
@@ -768,49 +601,6 @@ set_node_class(memory_region *mreg, const struct tree_node *node,
return write_ical_file(mreg, node, component);
}
-char *
-create_new_unique_ics_uid(memory_region *mreg)
-{
- uuid_t uuid;
- char uuid_str[37]; // UUIDs are 36 characters + null terminator
- uuid_generate(uuid);
- uuid_unparse(uuid, uuid_str);
- char *res = NULL;
- size_t wRes = rasprintf(mreg, &res, "%s-caldavfs", uuid_str);
- assert(wRes != -1);
-
- return res;
-}
-
-icalcomponent *
-create_vjournal_entry(memory_region *mreg, const char *summary)
-{
-
- icalcomponent *calendar = ricalcomponent_new_vcalendar(mreg);
-
- icalcomponent_add_property(calendar, icalproperty_new_version("2.0"));
- icalcomponent_add_property(calendar,
- icalproperty_new_prodid("-//caldavfs//EN"));
-
- // Step 2: Create a VJOURNAL entry
- icalcomponent *journal = icalcomponent_new_vjournal();
- char *id = create_new_unique_ics_uid(mreg);
-
- icalcomponent_add_property(journal, icalproperty_new_uid(id));
- icalcomponent_add_property(journal,
- icalproperty_new_class(ICAL_CLASS_PRIVATE));
-
- icalcomponent_add_property(
- journal, icalproperty_new_dtstamp(icaltime_current_time_with_zone(
- icaltimezone_get_utc_timezone())));
- icalcomponent_add_property(journal, icalproperty_new_summary(summary));
- icalcomponent_add_property(journal, icalproperty_new_description(""));
-
- icalcomponent_add_component(calendar, journal);
-
- return calendar;
-}
-
uid_t
get_node_uid(const struct tree_node *node)
{
@@ -837,61 +627,6 @@ get_node_ino(const struct tree_node *node)
return get_entry(node)->ino;
}
-icaltimetype
-get_last_modified(icalcomponent *component)
-{
- icalproperty *last_modified_prop = icalcomponent_get_next_property(
- component, ICAL_LASTMODIFIED_PROPERTY);
-
- if (last_modified_prop) {
- icaltimetype ical_lastmodified =
- icalproperty_get_lastmodified(last_modified_prop);
- return ical_lastmodified;
- }
- else {
- return icalcomponent_get_dtstamp(component);
- }
-}
-
-size_t
-get_entry_content_size(icalcomponent *component)
-{
- size_t size =
- snprintf(NULL, 0, "%s", icalcomponent_get_description(component));
-
- assert(size != -1);
- return size;
-}
-
-icalcomponent *
-create_vjournal_directory(memory_region *mreg, const char *summary)
-{
-
- icalcomponent *calendar = icalcomponent_new_vcalendar();
-
- icalcomponent_add_property(calendar, icalproperty_new_version("2.0"));
- icalcomponent_add_property(calendar,
- icalproperty_new_prodid("-//caldavfs//EN"));
-
- icalcomponent *journal = icalcomponent_new_vjournal();
- char *id = create_new_unique_ics_uid(mreg);
-
- icalcomponent_add_property(journal, icalproperty_new_uid(id));
-
- icalcomponent_add_property(
- journal, icalproperty_new_dtstamp(icaltime_current_time_with_zone(
- icaltimezone_get_utc_timezone())));
- icalcomponent_add_property(journal, icalproperty_new_summary(summary));
-
- icalproperty *is_directory = icalproperty_new_x(IS_DIRECTORY_PROPERTY);
- icalproperty_set_x_name(is_directory, IS_DIRECTORY_PROPERTY);
- icalproperty_set_x(is_directory, "YES");
- icalcomponent_add_property(journal, is_directory);
-
- icalcomponent_add_component(calendar, journal);
- return calendar;
-}
-
int
create_entry_from_fuse(memory_region *mreg, const char *fuse_path)
{
diff --git a/agenda_entry.h b/agenda_entry.h
@@ -63,9 +63,6 @@ node_is_directory(memory_region *mreg, const struct tree_node *node,
icalcomponent *node_ics);
bool
-is_directory_component(icalcomponent *component);
-
-bool
is_root_node(const struct tree_node *node);
struct agenda_entry *
@@ -89,17 +86,6 @@ write_ical_file(memory_region *mreg, const struct tree_node *node,
icalcomponent *
get_icalcomponent_from_node(memory_region *mreg, const struct tree_node *n);
-const char *
-get_parent_uid(icalcomponent *component);
-
-void
-remove_parent_child_relationship_from_component(icalcomponent *parent,
- icalcomponent *child);
-
-void
-set_parent_child_relationship_to_component(icalcomponent *parent,
- icalcomponent *child);
-
int
write_parent_child_components(memory_region *mreg,
const struct tree_node *parent,
@@ -165,8 +151,6 @@ ino_t
get_node_ino(const struct tree_node *node);
char *
get_fuse_path_from_vdir(memory_region *mreg, const char *filepath);
-icalcomponent *
-create_vjournal_entry(memory_region *mreg, const char *summary);
uid_t
get_node_uid(const struct tree_node *node);
@@ -174,15 +158,6 @@ get_node_uid(const struct tree_node *node);
gid_t
get_node_gid(const struct tree_node *node);
-icaltimetype
-get_last_modified(icalcomponent *component);
-
-size_t
-get_entry_content_size(icalcomponent *component);
-
-icalcomponent *
-create_vjournal_directory(memory_region *mreg, const char *summary);
-
int
create_entry_from_fuse(memory_region *mreg, const char *fuse_path);
diff --git a/ical_extra.c b/ical_extra.c
@@ -0,0 +1,265 @@
+#include "libical/ical.h"
+#include "mregion.h"
+#include "sys/stat.h"
+#include "uuid/uuid.h"
+#include <stdbool.h>
+const char *IS_DIRECTORY_PROPERTY = "X-CALDAVFS-ISDIRECTORY";
+
+icaltimetype
+get_last_modified(icalcomponent *component)
+{
+ icalproperty *last_modified_prop = icalcomponent_get_next_property(
+ component, ICAL_LASTMODIFIED_PROPERTY);
+
+ if (last_modified_prop) {
+ icaltimetype ical_lastmodified =
+ icalproperty_get_lastmodified(last_modified_prop);
+ return ical_lastmodified;
+ }
+ else {
+ return icalcomponent_get_dtstamp(component);
+ }
+}
+
+const icalproperty_class
+parse_ical_class(const char *input)
+{
+ if (strcmp(input, "private") == 0) {
+ return ICAL_CLASS_PRIVATE;
+ }
+ else if (strcmp(input, "public") == 0) {
+ return ICAL_CLASS_PUBLIC;
+ }
+ else if (strcmp(input, "confidential") == 0) {
+ return ICAL_CLASS_CONFIDENTIAL;
+ }
+ return ICAL_CLASS_X;
+}
+
+const char *
+format_ical_class(const enum icalproperty_class iclass)
+{
+ if (iclass == ICAL_CLASS_PRIVATE) {
+ return "private";
+ }
+ else if (iclass == ICAL_CLASS_PUBLIC) {
+ return "public";
+ }
+ else if (iclass == ICAL_CLASS_CONFIDENTIAL) {
+ return "confidential";
+ }
+ return NULL;
+}
+
+bool
+is_directory_component(icalcomponent *component)
+{
+ icalcomponent *journal = icalcomponent_get_first_component(
+ component, ICAL_VJOURNAL_COMPONENT);
+
+ for (icalproperty *prop = icalcomponent_get_first_property(
+ journal, ICAL_RELATEDTO_PROPERTY);
+ prop != NULL; prop = icalcomponent_get_next_property(
+ journal, ICAL_RELATEDTO_PROPERTY)) {
+
+ const char *reltype =
+ icalproperty_get_parameter_as_string(prop, "RELTYPE");
+ if (reltype && strcasecmp(reltype, "CHILD") == 0) {
+ return true;
+ }
+ }
+ for (icalproperty *prop =
+ icalcomponent_get_first_property(journal, ICAL_X_PROPERTY);
+ prop != NULL;
+ prop = icalcomponent_get_next_property(journal, ICAL_X_PROPERTY)) {
+ LOG("FOUND X PROPERTY");
+
+ const char *prop_name = icalproperty_get_x_name(prop);
+ if (prop_name &&
+ strcmp(prop_name, IS_DIRECTORY_PROPERTY) == 0) {
+ const char *value =
+ icalproperty_get_value_as_string(prop);
+ LOG("FOUND DIRECTORY");
+ return value && strcmp(value, "YES") == 0;
+ }
+ }
+ return false;
+}
+
+// Owner: ctx
+icalcomponent *
+parse_ics_file(memory_region *mreg, const char *filename)
+{
+
+ FILE *file = fopen(filename, "r");
+ LOG("filename is %s", filename);
+
+ struct stat st;
+ assert(stat(filename, &st) == 0);
+
+ size_t size = st.st_size;
+ char *buffer = rmalloc(mreg, size + 1);
+
+ size_t bytes_read = fread(buffer, 1, size, file);
+ buffer[bytes_read] = '\0';
+ fclose(file);
+
+ icalcomponent *component = ricalcomponent_new_from_string(mreg, buffer);
+
+ return component;
+}
+
+icaltimetype
+get_ical_now()
+{
+ return icaltime_from_timet_with_zone(time(NULL), 0,
+ icaltimezone_get_utc_timezone());
+}
+
+size_t
+get_entry_content_size(icalcomponent *component)
+{
+ size_t size =
+ snprintf(NULL, 0, "%s", icalcomponent_get_description(component));
+
+ assert(size != -1);
+ return size;
+}
+
+char *
+create_new_unique_ics_uid(memory_region *mreg)
+{
+ uuid_t uuid;
+ char uuid_str[37]; // UUIDs are 36 characters + null terminator
+ uuid_generate(uuid);
+ uuid_unparse(uuid, uuid_str);
+ char *res = NULL;
+ size_t wRes = rasprintf(mreg, &res, "%s-caldavfs", uuid_str);
+ assert(wRes != -1);
+
+ return res;
+}
+
+icalcomponent *
+create_vjournal_directory(memory_region *mreg, const char *summary)
+{
+
+ icalcomponent *calendar = icalcomponent_new_vcalendar();
+
+ icalcomponent_add_property(calendar, icalproperty_new_version("2.0"));
+ icalcomponent_add_property(calendar,
+ icalproperty_new_prodid("-//caldavfs//EN"));
+
+ icalcomponent *journal = icalcomponent_new_vjournal();
+ char *id = create_new_unique_ics_uid(mreg);
+
+ icalcomponent_add_property(journal, icalproperty_new_uid(id));
+
+ icalcomponent_add_property(
+ journal, icalproperty_new_dtstamp(icaltime_current_time_with_zone(
+ icaltimezone_get_utc_timezone())));
+ icalcomponent_add_property(journal, icalproperty_new_summary(summary));
+
+ icalproperty *is_directory = icalproperty_new_x(IS_DIRECTORY_PROPERTY);
+ icalproperty_set_x_name(is_directory, IS_DIRECTORY_PROPERTY);
+ icalproperty_set_x(is_directory, "YES");
+ icalcomponent_add_property(journal, is_directory);
+
+ icalcomponent_add_component(calendar, journal);
+ return calendar;
+}
+
+icalcomponent *
+create_vjournal_entry(memory_region *mreg, const char *summary)
+{
+
+ icalcomponent *calendar = ricalcomponent_new_vcalendar(mreg);
+
+ icalcomponent_add_property(calendar, icalproperty_new_version("2.0"));
+ icalcomponent_add_property(calendar,
+ icalproperty_new_prodid("-//caldavfs//EN"));
+
+ // Step 2: Create a VJOURNAL entry
+ icalcomponent *journal = icalcomponent_new_vjournal();
+ char *id = create_new_unique_ics_uid(mreg);
+
+ icalcomponent_add_property(journal, icalproperty_new_uid(id));
+ icalcomponent_add_property(journal,
+ icalproperty_new_class(ICAL_CLASS_PRIVATE));
+
+ icalcomponent_add_property(
+ journal, icalproperty_new_dtstamp(icaltime_current_time_with_zone(
+ icaltimezone_get_utc_timezone())));
+ icalcomponent_add_property(journal, icalproperty_new_summary(summary));
+ icalcomponent_add_property(journal, icalproperty_new_description(""));
+
+ icalcomponent_add_component(calendar, journal);
+
+ return calendar;
+}
+
+const char *
+get_parent_uid(icalcomponent *component)
+{
+ icalcomponent *inner =
+ icalcomponent_get_first_component(component, ICAL_ANY_COMPONENT);
+
+ for (icalproperty *prop = icalcomponent_get_first_property(
+ inner, ICAL_RELATEDTO_PROPERTY);
+ prop != NULL; prop = icalcomponent_get_next_property(
+ inner, ICAL_RELATEDTO_PROPERTY)) {
+ const char *reltype =
+ icalproperty_get_parameter_as_string(prop, "RELTYPE");
+ if (reltype && strcasecmp(reltype, "PARENT") == 0) {
+ return icalproperty_get_value_as_string(prop);
+ }
+ }
+
+ return NULL;
+}
+
+void
+remove_parent_child_relationship_from_component(icalcomponent *parent,
+ icalcomponent *child)
+{
+
+ const char *parent_uid = icalcomponent_get_uid(parent);
+
+ icalcomponent *inner =
+ icalcomponent_get_first_component(child, ICAL_ANY_COMPONENT);
+
+ icalproperty *prop =
+ icalcomponent_get_first_property(inner, ICAL_RELATEDTO_PROPERTY);
+ while (prop != NULL) {
+ icalproperty *next = icalcomponent_get_next_property(
+ inner, ICAL_RELATEDTO_PROPERTY);
+ const char *value = icalproperty_get_relatedto(prop);
+ icalparameter *reltype = icalproperty_get_first_parameter(
+ prop, ICAL_RELTYPE_PARAMETER);
+
+ if (value && strcmp(value, parent_uid) == 0 && reltype &&
+ icalparameter_get_reltype(reltype) == ICAL_RELTYPE_PARENT) {
+ icalcomponent_remove_property(inner, prop);
+ icalproperty_free(prop);
+ }
+
+ prop = next;
+ }
+}
+
+void
+set_parent_child_relationship_to_component(icalcomponent *parent,
+ icalcomponent *child)
+{
+ icalproperty *child_related_to_parent =
+ icalproperty_new_relatedto(icalcomponent_get_uid(parent));
+ icalparameter *reltype_child =
+ icalparameter_new_reltype(ICAL_RELTYPE_PARENT);
+ icalproperty_add_parameter(child_related_to_parent, reltype_child);
+
+ icalcomponent *inner =
+ icalcomponent_get_first_component(child, ICAL_ANY_COMPONENT);
+ if (inner) {
+ icalcomponent_add_property(inner, child_related_to_parent);
+ }
+}
diff --git a/ical_extra.h b/ical_extra.h
@@ -0,0 +1,51 @@
+#ifndef ical_extra_h_INCLUDED
+#define ical_extra_h_INCLUDED
+#include "libical/ical.h"
+#include "mregion.h"
+#include "sys/stat.h"
+#include "uuid/uuid.h"
+#include <stdbool.h>
+
+icaltimetype
+get_last_modified(icalcomponent *component);
+
+bool
+is_directory_component(icalcomponent *component);
+
+// Owner: ctx
+icalcomponent *
+parse_ics_file(memory_region *mreg, const char *filename);
+
+icaltimetype
+get_ical_now();
+
+size_t
+get_entry_content_size(icalcomponent *component);
+
+char *
+create_new_unique_ics_uid(memory_region *mreg);
+
+icalcomponent *
+create_vjournal_directory(memory_region *mreg, const char *summary);
+
+icalcomponent *
+create_vjournal_entry(memory_region *mreg, const char *summary);
+
+const char *
+get_parent_uid(icalcomponent *component);
+
+void
+remove_parent_child_relationship_from_component(icalcomponent *parent,
+ icalcomponent *child);
+
+void
+set_parent_child_relationship_to_component(icalcomponent *parent,
+ icalcomponent *child);
+
+const icalproperty_class
+parse_ical_class(const char *input);
+
+const char *
+format_ical_class(const enum icalproperty_class iclass);
+
+#endif // ical_extra_h_INCLUDED
diff --git a/main.c b/main.c
@@ -1,8 +1,9 @@
-#include "fuse3/fuse_opt.h"
#define FUSE_USE_VERSION 31
#include "agenda_entry.h"
+#include "fuse3/fuse_opt.h"
#include "hashmap.h"
+#include "ical_extra.h"
#include "mregion.h"
#include "tree.h"
#include "util.h"
@@ -30,7 +31,7 @@
static pthread_mutex_t entries_mutex = PTHREAD_MUTEX_INITIALIZER;
static int
-agenda_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
+fuse_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
{
LOG("STAT %s", path);
@@ -100,7 +101,7 @@ cleanup_return:
}
static int
-agenda_readlink(const char *path, char *buf, size_t size)
+fuse_readlink(const char *path, char *buf, size_t size)
{
// TODO: Implement
LOG("READLINK path: %s", path);
@@ -108,9 +109,8 @@ agenda_readlink(const char *path, char *buf, size_t size)
}
static int
-agenda_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi,
- enum fuse_readdir_flags flags)
+fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset,
+ struct fuse_file_info *fi, enum fuse_readdir_flags flags)
{
LOG("READDIR %s", path);
@@ -144,7 +144,11 @@ agenda_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
st.st_mode = S_IFDIR | 0755;
}
- filler(buf, get_node_filename(mreg, child), &st, 0, 0);
+ if (filler(buf, get_node_filename(mreg, child), &st, 0, 0) !=
+ 0) {
+ status = -ENOMEM;
+ goto cleanup_return;
+ }
}
cleanup_return:
@@ -154,28 +158,34 @@ cleanup_return:
}
static int
-agenda_open(const char *path, struct fuse_file_info *fi)
+fuse_open(const char *path, struct fuse_file_info *fi)
{
+ LOG("OPEN %s", path);
+
memory_region *mreg = create_region();
pthread_mutex_lock(&entries_mutex);
+ int status = 0;
- LOG("Opening journal for %s", path);
const struct tree_node *node = get_node_by_path(mreg, path);
+ if (!node) {
+ status = -ENOENT;
+ }
pthread_mutex_unlock(&entries_mutex);
rfree_all(mreg);
- return node ? 0 : -ENOENT;
+
+ return status;
}
static int
-agenda_mkdir(const char *path, mode_t mode)
+fuse_mkdir(const char *path, mode_t mode)
{
+ LOG("MKDIR %s", path);
memory_region *mreg = create_region();
pthread_mutex_lock(&entries_mutex);
int status = 0;
- LOG("MKDIR %s", path);
status = create_directory_from_fuse_path(mreg, path);
pthread_mutex_unlock(&entries_mutex);
@@ -184,10 +194,10 @@ agenda_mkdir(const char *path, mode_t mode)
}
static int
-agenda_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+fuse_read(const char *path, char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
{
- LOG("READ on path %s", path);
+ LOG("READ %s", path);
memory_region *mreg = create_region();
pthread_mutex_lock(&entries_mutex);
@@ -205,8 +215,7 @@ agenda_read(const char *path, char *buf, size_t size, off_t offset,
}
// We now treat description as the full content
- const char *content = description;
- size_t content_len = strlen(content);
+ size_t content_len = strlen(description);
if (offset >= content_len) {
ret_code = 0;
@@ -214,12 +223,11 @@ agenda_read(const char *path, char *buf, size_t size, off_t offset,
}
if (offset + size > content_len) {
- LOG("Size is set");
size = content_len - offset;
}
if (size > 0) {
- memcpy(buf, content + offset, size);
+ memcpy(buf, description + offset, size);
}
ret_code = size;
@@ -231,8 +239,8 @@ cleanup_return:
}
static int
-agenda_write(const char *path, const char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+fuse_write(const char *path, const char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
{
LOG("WRITE %s, %zu, %zu", buf, size, offset);
@@ -266,7 +274,7 @@ cleanup_return:
// Aka remove or delete
static int
-agenda_unlink(const char *file)
+fuse_unlink(const char *file)
{
LOG("DELETE %s", file);
@@ -282,7 +290,7 @@ agenda_unlink(const char *file)
}
static int
-agenda_rmdir(const char *file)
+fuse_rmdir(const char *file)
{
LOG("DELETE %s", file);
@@ -298,7 +306,7 @@ agenda_rmdir(const char *file)
}
static int
-agenda_rename(const char *old, const char *new, unsigned int flags)
+fuse_rename(const char *old, const char *new, unsigned int flags)
{
memory_region *mreg = create_region();
@@ -313,7 +321,7 @@ agenda_rename(const char *old, const char *new, unsigned int flags)
}
static int
-agenda_create(const char *filename, mode_t mode, struct fuse_file_info *info)
+fuse_create(const char *filename, mode_t mode, struct fuse_file_info *info)
{
memory_region *mreg = create_region();
@@ -329,7 +337,7 @@ agenda_create(const char *filename, mode_t mode, struct fuse_file_info *info)
}
static int
-agenda_removexattr(const char *path, const char *header)
+fuse_removexattr(const char *path, const char *header)
{
LOG("REMOVEXATTR '%s' '%s'", path, header);
memory_region *mreg = create_region();
@@ -364,8 +372,8 @@ cleanup_return:
}
static int
-agenda_setxattr(const char *path, const char *header,
- const char *new_attributes, size_t s, int flags)
+fuse_setxattr(const char *path, const char *header, const char *new_attributes,
+ size_t s, int flags)
{
LOG("SETXATTR '%s' '%s' '%zu' '%s' '%d'", path, header, s,
new_attributes, flags);
@@ -412,7 +420,7 @@ cleanup_return:
}
static int
-agenda_listxattr(const char *path, char *list, size_t size)
+fuse_listxattr(const char *path, char *list, size_t size)
{
LOG("LISTXATTR %s %zu", list, size);
memory_region *mreg = create_region();
@@ -472,7 +480,7 @@ cleanup_return:
}
static int
-agenda_getxattr(const char *path, const char *header, char *buf, size_t s)
+fuse_getxattr(const char *path, const char *header, char *buf, size_t s)
{
LOG("GETXATTR '%s' '%s' '%zu'\n", path, header, s);
pthread_mutex_lock(&entries_mutex);
@@ -602,28 +610,28 @@ watch_vdir_changes(void *arg)
// Ignore for now
static int
-agenda_utimens(const char *path, const struct timespec tv[2],
- struct fuse_file_info *info)
+fuse_utimens(const char *path, const struct timespec tv[2],
+ struct fuse_file_info *info)
{
return 0;
}
-struct fuse_operations agenda_oper = {.getattr = agenda_getattr,
- .readdir = agenda_readdir,
- .open = agenda_open,
- .read = agenda_read,
- .utimens = agenda_utimens,
- .write = agenda_write,
- .create = agenda_create,
- .mkdir = agenda_mkdir,
- .unlink = agenda_unlink,
- .getxattr = agenda_getxattr,
- .setxattr = agenda_setxattr,
- .listxattr = agenda_listxattr,
- .removexattr = agenda_removexattr,
- .rmdir = agenda_rmdir,
- .readlink = agenda_readlink,
- .rename = agenda_rename};
+struct fuse_operations fuse_oper = {.getattr = fuse_getattr,
+ .readdir = fuse_readdir,
+ .open = fuse_open,
+ .read = fuse_read,
+ .utimens = fuse_utimens,
+ .write = fuse_write,
+ .create = fuse_create,
+ .mkdir = fuse_mkdir,
+ .unlink = fuse_unlink,
+ .getxattr = fuse_getxattr,
+ .setxattr = fuse_setxattr,
+ .listxattr = fuse_listxattr,
+ .removexattr = fuse_removexattr,
+ .rmdir = fuse_rmdir,
+ .readlink = fuse_readlink,
+ .rename = fuse_rename};
struct agendafs_config {
char *ics_directory;
@@ -653,13 +661,13 @@ agendafs_opt_proc(void *data, const char *arg, int key,
" -o vdir=STRING\n",
outargs->argv[0]);
fuse_opt_add_arg(outargs, "-h");
- fuse_main(outargs->argc, outargs->argv, &agenda_oper, NULL);
+ fuse_main(outargs->argc, outargs->argv, &fuse_oper, NULL);
exit(1);
case KEY_VERSION:
fprintf(stderr, "agendafs version %s\n", "v0.01 ALPHA");
fuse_opt_add_arg(outargs, "--version");
- fuse_main(outargs->argc, outargs->argv, &agenda_oper, NULL);
+ fuse_main(outargs->argc, outargs->argv, &fuse_oper, NULL);
exit(0);
}
return 1;
@@ -685,10 +693,14 @@ main(int argc, char *argv[])
" -o vdir=STRING\n",
argv[0]);
fuse_opt_add_arg(&args, "-h");
- fuse_main(args.argc, args.argv, &agenda_oper, NULL);
+ fuse_main(args.argc, args.argv, &fuse_oper, NULL);
exit(1);
}
+#ifdef DEBUG
+ fuse_opt_add_arg(&args, "-f");
+#endif
+
if (load_agendafs_environment(conf.ics_directory) != 0) {
fprintf(stderr, "Failed to load ICS directory\n");
exit(1);
@@ -703,7 +715,7 @@ main(int argc, char *argv[])
}
load_root_node_tree();
- int ret = fuse_main(args.argc, args.argv, &agenda_oper, NULL);
+ int ret = fuse_main(args.argc, args.argv, &fuse_oper, NULL);
LOG("Cleaning up");
pthread_cancel(watcher_thread);
diff --git a/util.h b/util.h
@@ -3,8 +3,12 @@
#include <stdlib.h>
+#ifdef DEBUG
#define LOG(fmt, ...) \
fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
+#else
+#define LOG(fmt, ...)
+#endif
void *
reallocarray(void *, size_t, size_t);