aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2019-02-15 23:03:10 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2019-02-15 23:03:10 +0100
commit377ccdb9f2e2c13c371c78f4c1ca261908a656de (patch)
treefa0789a6e6c5413249cf277e7954e2c20113f6a4
parentMove fold function. (diff)
downloadcalp-377ccdb9f2e2c13c371c78f4c1ca261908a656de.tar.gz
calp-377ccdb9f2e2c13c371c78f4c1ca261908a656de.tar.xz
Fix pending fixes in calendar.c.
-rw-r--r--calendar.c177
-rw-r--r--calendar.h33
2 files changed, 114 insertions, 96 deletions
diff --git a/calendar.c b/calendar.c
index de06276a..d0476583 100644
--- a/calendar.c
+++ b/calendar.c
@@ -1,136 +1,121 @@
#include "calendar.h"
-/*
- * These three are only for some FD hacks.
- */
-#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
-#include <unistd.h>
-#include "macro.h"
#include "parse.h"
#include "err.h"
-/*
- * Returns 0 if file has no extersion
- *
- * TODO this looks from the first point, it should look from the last
- * point.
- */
-int get_extension(const char* filename, char* ext, ssize_t max_len) {
- int ext_idx = -1;
- ext[0] = '\0';
- for (char* c = (char*) filename; *c != '\0'; c++) {
- if (*c == '.') {
- ext_idx = 0;
- continue;
- }
- if (ext_idx >= 0) {
- ext[ext_idx++] = *c;
- if (ext_idx == max_len) break;
- }
+int read_vcalendar(vcomponent* cal, char* path) {
+
+ struct stat statbuf;
+ if (stat (path, &statbuf) != 0) {
+ fprintf(stderr,
+ "Error stating file or directory, errno = %i\npath = [%s]\n",
+ errno, path);
+ }
+
+ int type = statbuf.st_mode & 0777000;
+ int chmod = statbuf.st_mode & 0777;
+ INFO_F("file has mode 0%o, with chmod = 0%o", type, chmod);
+
+ switch (type) {
+ case S_IFREG: handle_file(cal, path); break;
+ case S_IFDIR: handle_dir (cal, path); break;
+ case S_IFLNK:
+ ERR("Found symlink, can't be bothered to check it further.");
+ break;
+
+ default: ;
}
- ext[ext_idx] = '\0';
- return (ext_idx == -1)
- ? 0
- : ext_idx;
+
+ return 0;
}
-/*
- * TODO merge the code for files and dirs.
- */
+int handle_file(vcomponent* cal, char* path) {
+ INFO("Parsing a single file");
-int parse_dir(vcomponent* cal, char* path) {
- DIR* dir = opendir(path);
- struct dirent* d;
- while ((d = readdir(dir)) != NULL) {
+ char* resolved_path = realpath(path, NULL);
+ open_ics (resolved_path, cal);
+ free (resolved_path);
- /* Check that it's a regular file */
- if (d->d_type != DT_REG) continue;
+ return 0;
+}
- /* Check that we have an ICS file */
- char* fname = d->d_name;
- char ext[10];
- int has_ext = get_extension(fname, ext, 9);
- if (! has_ext || strcmp(ext, "ics") != 0) continue;
+int handle_dir(vcomponent* cal, char* path) {
+ INFO("Parsing a directory");
+ DIR* dir = opendir(path);
- /* We now assume that it's a good file, and start parsing it */
+ /* Buffer for holding search path and filename */
+ char buf[PATH_MAX];
+ strcpy(buf, path);
+ int path_len = strlen(path) + 1;
- int fd = openat(dirfd(dir), fname, O_RDONLY);
+ /* Slash to guarantee we have at least one */
+ buf[path_len - 1] = '/';
- FILE* f = fdopen(fd, "r");
- if (f == NULL) {
- fprintf(stderr, "Error opening file [%s], errno = %i\n",
- fname, errno);
- exit (1);
- }
+ struct dirent* d;
+ while ((d = readdir(dir)) != NULL) {
+ /* Check that it's a regular file */
+ if (d->d_type != DT_REG) continue;
- // TODO complete path
- parse_file(fname, f, cal);
+ /* Append filename with currentt searchpath */
+ strcat(buf, d->d_name);
+ char* resolved_path = realpath(buf, NULL);
+ /* Remove file part from combined path */
+ buf[path_len] = '\0';
- fclose(f);
+ open_ics (resolved_path, cal);
+
+ free (resolved_path);
}
closedir(dir);
-
return 0;
}
-int read_vcalendar(vcomponent* cal, char* path) {
+int get_extension(const char* filename, char* ext, ssize_t max_len) {
+ int ext_idx = -1;
+ ext[0] = '\0';
+ for (int i = 0; filename[i] != '\0'; i++) {
+ if (filename[i] == '.') ext_idx = i + 1;
+ if (filename[i] == '/') ext_idx = -1;
+ }
- struct stat statbuf;
- if (stat (path, &statbuf) != 0) {
- fprintf(stderr,
- "Error opening file or directory, errno = %i\npath = [%s]\n",
- errno, path);
+ if (ext_idx == -1) return 0;
+
+ int ext_len = 0;
+ for (int i = 0; i < max_len; i++, ext_len++) {
+ char c = filename[i + ext_idx];
+ if (c == '\0') break;
+ ext[i] = c;
}
+ ext[ext_len] = '\0';
+ return ext_len;
+}
- int type = statbuf.st_mode & 0777000;
- int chmod = statbuf.st_mode & 0777;
- INFO_F("file has mode 0%o, with chmod = 0%o", type, chmod);
+int check_ext (const char* path, const char* ext) {
+ char buf[10];
+ int has_ext = get_extension(path, buf, 9);
- switch (type) {
- case S_IFREG:
- INFO("Parsing a single file");
-
- char ext[10];
- int has_ext = get_extension(path, ext, 9);
- if (! has_ext || strcmp(ext, "ics") != 0) {
- fprintf(stderr, "File doesn't have .ics extension. [%s]\n", ext);
- exit(1);
- }
-
- FILE* f = fopen(path, "r");
- if (f == NULL) {
- fprintf(stderr, "Error opening file [%s], errno = %i\n",
- path, errno);
- exit (1);
- }
-
- // TODO absolute path
- parse_file(path, f, cal);
- fclose(f);
- break;
+ return has_ext && strcmp(buf, ext) == 0;
+}
- case S_IFDIR:
- INFO("Parsing a directory");
- parse_dir (cal, path);
- break;
+int open_ics (char* resolved_path, vcomponent* cal) {
+ puts(resolved_path);
+ if (! check_ext(resolved_path, "ics") ) return 2;
- case S_IFLNK:
- ERR("Found symlink, can't be bothered to check it further.");
- break;
+ FILE* f = fopen(resolved_path, "r");
- default:
- ;
- }
+ if (f == NULL) return 1;
+ parse_file(resolved_path, f, cal);
+ fclose(f);
return 0;
}
+
diff --git a/calendar.h b/calendar.h
index c7484d05..20b78a9f 100644
--- a/calendar.h
+++ b/calendar.h
@@ -3,6 +3,39 @@
#include "vcal.h"
+/*
+ * Reads all ics flies in path into the given vcomponent. The
+ * component is assumed to be a abstract ROOT element, whose first
+ * component will most likely become a VCALENDAR.
+ *
+ * path should either be a single .ics file (vcalendar), or a
+ * directory directly containing .ics files (vdir).
+ */
int read_vcalendar(vcomponent* cal, char* path);
+/*
+ * Gets extension from filename. Writes output to ext.
+ * Assumes that the extension is the text between the last dot and
+ * the end of the string, and that no slashes can occur between the
+ * dot and the end.
+ *
+ * Returns the length of the extension, 0 if no extension.
+ */
+int get_extension(const char* filename, char* ext, ssize_t max_len);
+
+/* Returns 1 if path has extension ext, 0 otherwise */
+int check_ext (const char* path, const char* ext);
+
+/* Handle a lone ics file */
+int handle_file(vcomponent* cal, char* path);
+
+/* Handle a directory of ics files */
+int handle_dir(vcomponent* cal, char* path);
+
+/*
+ * Helper for opening a single ICS file. Handles file internally, and
+ * writes output to cal.
+ */
+int open_ics (char* resolved_path, vcomponent* cal);
+
#endif /* CALENDAR_H */