agendafs
A filesystem for your calendar.
git clone git://mccd.space/agendafscommit cca40f2c0bba3c84fb88b5c5dfe8562321e0ebc5
parent 40c4af71c6ca4926fc7da0b37030ea58f5f6f961
Author: Marc Coquand <marc@coquand.email>
Date: Tue, 3 Jun 2025 11:23:29 +0100
Fix time bug
Diffstat:
| M | main.c | | | 85 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
1 file changed, 44 insertions(+), 41 deletions(-)
diff --git a/main.c b/main.c
@@ -31,6 +31,8 @@ regex_t regex_dtstamp, regex_lastmod, regex_fuse_file;
time_t INVALID_TIME = (time_t)-1;
+icaltimezone *local_ical_time;
+
#define ENOTJOURNAL 1001
typedef struct {
@@ -232,19 +234,6 @@ get_entry_from_fuse_path(const char *path)
return entry;
}
-time_t
-icaltime_to_time_t(icaltimetype tt)
-{
- struct tm t = {.tm_year = tt.year - 1900,
- .tm_mon = tt.month - 1,
- .tm_mday = tt.day,
- .tm_hour = tt.hour,
- .tm_min = tt.minute,
- .tm_sec = tt.second,
- .tm_isdst = -1};
- return mktime(&t);
-}
-
char *
read_stream(char *s, size_t size, void *d)
{
@@ -293,20 +282,16 @@ parse_ics_to_journal_entry(const char *filename, journal_entry *entry)
return 0;
}
-// Dynamically create a time string using format
char *
time_string(icaltimetype t, const char *format)
{
- time_t time_val = icaltime_to_time_t(t);
- struct tm tm_info;
- if (!localtime_r(&time_val, &tm_info)) {
- return NULL;
- }
- size_t buf_size = 64;
- char *buffer = xmalloc(buf_size);
+ char *buffer = xmalloc(64);
+ time_t tme = icaltime_as_timet(t);
+ struct tm tm_info;
+ localtime_r(&tme, &tm_info);
- strftime(buffer, buf_size, format, &tm_info);
+ strftime(buffer, 64, format, &tm_info);
return buffer;
}
@@ -503,7 +488,7 @@ journal_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
if (last_modified_prop) {
icaltimetype ical_lastmodified =
icalproperty_get_lastmodified(last_modified_prop);
- lastmodified = icaltime_to_time_t(ical_lastmodified);
+ lastmodified = icaltime_as_timet(ical_lastmodified);
}
else {
lastmodified = time(NULL);
@@ -569,12 +554,20 @@ journal_read(const char *path, char *buf, size_t size, off_t offset,
goto unlock_and_return;
}
+ const char *summary = icalcomponent_get_summary(entry->component);
+ if (summary == NULL) {
+ summary = "";
+ }
+ const char *description =
+ icalcomponent_get_description(entry->component);
+ if (description == NULL) {
+ description = "";
+ }
+
// Calculate required length for full content
char *full_content = NULL;
size_t needed_len =
- asprintf(&full_content, "%s\n---\n%s",
- icalcomponent_get_summary(entry->component),
- icalcomponent_get_description(entry->component));
+ asprintf(&full_content, "%s\n---\n%s", summary, description);
if (needed_len == -1) {
LOG("Out of memory");
exit(1);
@@ -601,6 +594,14 @@ unlock_and_return:
return ret_code;
}
+icaltimetype
+get_now()
+{
+ struct icaltimetype now_tt = icaltime_from_timet_with_zone(
+ time(NULL), 0, icaltimezone_get_utc_timezone());
+ return now_tt;
+}
+
size_t
parse_entry_content(journal_entry *entry, const char *buf, size_t size)
{
@@ -624,19 +625,6 @@ parse_entry_content(journal_entry *entry, const char *buf, size_t size)
return -EINVAL;
}
- icalproperty *prop = icalcomponent_get_first_property(
- entry->component, ICAL_LASTMODIFIED_PROPERTY);
- if (!prop) {
- prop = icalproperty_new_lastmodified(icaltime_null_time());
- icalcomponent_add_property(entry->component, prop);
- }
- else {
- time_t now = time(NULL);
- struct icaltimetype now_tt =
- icaltime_from_timet_with_zone(now, 0, NULL);
- icalproperty_set_lastmodified(prop, now_tt);
- }
-
icalcomponent_set_summary(entry->component, summary);
icalcomponent_set_description(entry->component, description);
free(copy);
@@ -646,6 +634,17 @@ parse_entry_content(journal_entry *entry, const char *buf, size_t size)
size_t
write_entry_to_ical_file(const journal_entry *entry, const char *filepath)
{
+ // Always set last modified to the time we write
+ icalproperty *prop = icalcomponent_get_first_property(
+ entry->component, ICAL_LASTMODIFIED_PROPERTY);
+ if (!prop) {
+ prop = icalproperty_new_lastmodified(get_now());
+ icalcomponent_add_property(entry->component, prop);
+ }
+ else {
+ icalproperty_set_lastmodified(prop, get_now());
+ }
+
char *ical_str = icalcomponent_as_ical_string_r(entry->component);
FILE *f = fopen(filepath, "w");
@@ -769,8 +768,8 @@ do_journal_entry_rename(time_t new_created_at, const char *old, const char *new)
journal_entry *new_entry = copy_journal_entry(old_entry);
free(new_entry->filename);
new_entry->filename = strdup(new_basename);
- struct icaltimetype created_at_ical =
- icaltime_from_timet_with_zone(new_created_at, 0, NULL);
+ struct icaltimetype created_at_ical = icaltime_from_timet_with_zone(
+ new_created_at, 0, icaltimezone_get_utc_timezone());
icalcomponent_set_dtstamp(new_entry->component, created_at_ical);
@@ -1092,6 +1091,10 @@ main(int argc, char *argv[])
{
pthread_t watcher_thread;
+ tzset();
+ const char *tzid = getenv("TZ");
+ local_ical_time = icaltimezone_get_builtin_timezone(tzid);
+
if (load_caldavfs_environment() != 0) {
fprintf(stderr, "Failed to load ICS directory\n");
exit(1);