agendafs
A filesystem for your calendar.
git clone git://mccd.space/agendafscommit 0d8cbe2f7bc83e01e2bb86a8d8aa7ff86e2741b1
parent 9e874d9358fba49a4f306aab581044323cdb3bca
Author: Marc Coquand <marc@coquand.email>
Date: Sat, 31 May 2025 14:13:22 +0100
File name
Diffstat:
| M | main.c | | | 58 | +++++++++++++++++++++++++--------------------------------- |
1 file changed, 25 insertions(+), 33 deletions(-)
diff --git a/main.c b/main.c
@@ -13,10 +13,12 @@
#define ICS_DIR "./sample_ics"
const char *display_date_fmt = "%b %d, %Y at %H:%M";
+const char *date_title_fmt = "%Y%m%d-%H%M%S";
typedef struct
{
char *filename;
+ char *filename_original;
char *summary;
char *description;
time_t timestamp;
@@ -77,7 +79,7 @@ static int compile_regexes(regex_t *regex_summary, regex_t *regex_description, r
static char *extract_match(const char *content, regmatch_t match)
{
size_t len = match.rm_eo - match.rm_so;
- char *str = malloc(len + 1);
+ char *str = calloc(len + 1, sizeof(char));
if (!str) return NULL;
memcpy(str, content + match.rm_so, len);
str[len] = '\0';
@@ -138,7 +140,7 @@ static int parse_ics_file(const char *file_path, journal_entry *entry)
long file_size = ftell(file);
fseek(file, 0, SEEK_SET);
- char *file_content = malloc(file_size + 1);
+ char *file_content = calloc(file_size + 1, sizeof(char));
if (!file_content)
{
perror("Memory allocation failed");
@@ -160,7 +162,7 @@ static int parse_ics_file(const char *file_path, journal_entry *entry)
goto cleanup;
}
- // Extract SUMMARY
+ // SUMMARY
if (regexec(®ex_summary, file_content, 2, matches_summary, 0) != 0)
{
fprintf(stderr, "SUMMARY field not found in: %s\n", file_path);
@@ -175,7 +177,7 @@ static int parse_ics_file(const char *file_path, journal_entry *entry)
}
unescape_text(entry->summary);
- // Extract DESCRIPTION
+ // DESCRIPTION
if (regexec(®ex_description, file_content, 2, matches_description, 0) != 0)
{
fprintf(stderr, "DESCRIPTION field not found in: %s\n", file_path);
@@ -211,27 +213,8 @@ static int parse_ics_file(const char *file_path, journal_entry *entry)
entry->created_at = time(NULL);
}
- if (regexec(®ex_dtstamp, file_content, 2, matches_dtstamp, 0) == 0)
- {
- char *dtstamp_str = extract_match(file_content, matches_dtstamp[1]);
- if (!dtstamp_str)
- {
- perror("Memory allocation failed for DTSTAMP");
- goto cleanup;
- }
- entry->created_at = parse_datetime(dtstamp_str);
- free(dtstamp_str);
- if (entry->created_at == -1)
- {
- fprintf(stderr, "Failed to parse DTSTAMP in: %s\n", file_path);
- goto cleanup;
- }
- } else
- {
- entry->created_at = time(NULL);
- }
- // LAST-MODIFIED (timestamp)
+ // LAST-MODIFIED
if (regexec(®ex_lastmod, file_content, 2, matches_lastmod, 0) == 0)
{
char *lastmod_str = extract_match(file_content, matches_lastmod[1]);
@@ -249,7 +232,7 @@ static int parse_ics_file(const char *file_path, journal_entry *entry)
}
} else
{
- entry->timestamp = entry->created_at; // fallback
+ entry->timestamp = entry->created_at;
}
// Success and goto cleanup
@@ -282,10 +265,15 @@ static void load_journal_entries()
{
snprintf(filepath, sizeof(filepath), "%s/%s", ICS_DIR, entry->d_name);
journal_entry new_entry;
- new_entry.filename = strdup(entry->d_name);
+ new_entry.filename_original = strdup(entry->d_name);
if (parse_ics_file(filepath, &new_entry) == 0)
{
- entries = realloc(entries, sizeof(journal_entry) * (entry_count + 1));
+ char filename_time_str[64];
+ struct tm *tm_info = localtime(&new_entry.created_at);
+ strftime(filename_time_str, sizeof(filename_time_str), date_title_fmt, tm_info);
+ new_entry.filename = strdup(filename_time_str);
+
+ entries = realloc(entries, sizeof(journal_entry) * (entry_count + 1));
entries[entry_count] = new_entry;
entry_count++;
} else
@@ -315,6 +303,7 @@ static int journal_getattr(const char *path, struct stat *stbuf, struct fuse_fil
snprintf(entry_path, sizeof(entry_path), "/%s.txt", entries[i].filename);
if (strcmp(path, entry_path) == 0)
{
+ // S_IFREG = Regular file
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
struct tm *tm_info = localtime(&entries[i].timestamp);
@@ -323,22 +312,25 @@ static int journal_getattr(const char *path, struct stat *stbuf, struct fuse_fil
// Calculate the file size as in journal_read
int size = snprintf(NULL, 0, "%s\n%s\n---\n%s\n",
- entries[i].summary, timestamp_str, entries[i].description);
+ entries[i].summary, timestamp_str, entries[i].description);
stbuf->st_size = (off_t)size;
- // Set the times
- stbuf->st_mtime = entries[i].timestamp; // Use the timestamp as the modification time
- stbuf->st_ctime = entries[i].timestamp; // Set the change time to the same as the modification time
+ // Use the timestamp as the modification time
+ stbuf->st_mtime = entries[i].timestamp;
+
+ // Set the change time to the same as the modification time
+ stbuf->st_ctime = entries[i].timestamp;
+
// Access time is current time
stbuf->st_atime = time(NULL);
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)
@@ -392,7 +384,7 @@ static int journal_read(const char *path, char *buf, size_t size, off_t offset,
if (needed_len < 0)
return -EIO; // snprintf error
- char *full_content = malloc(needed_len + 1);
+ char *full_content = calloc(needed_len + 1, sizeof(char));
if (!full_content)
{
perror("Memory allocation failed");