aboutsummaryrefslogtreecommitdiff
path: root/src/fileutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileutils.c')
-rw-r--r--src/fileutils.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/fileutils.c b/src/fileutils.c
new file mode 100644
index 0000000..ea57550
--- /dev/null
+++ b/src/fileutils.c
@@ -0,0 +1,82 @@
+#include "fileutils.h"
+#include "alloc.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+const char* get_home_dir() {
+ const char *home_dir = getenv("HOME");
+ if(!home_dir) {
+ struct passwd *pw = getpwuid(getuid());
+ home_dir = pw->pw_dir;
+ }
+ return home_dir;
+}
+
+int file_get_content(const char *filepath, char **data, long *size) {
+ int result = 0;
+ FILE *file = fopen(filepath, "rb");
+ if(!file) {
+ int err = -errno;
+ perror(filepath);
+ return err;
+ }
+
+ fseek(file, 0, SEEK_END);
+ *size = ftell(file);
+ if(*size == -1) {
+ fprintf(stderr, "Failed to tell the size of file %s, is it not a file?\n", filepath);
+ result = -1;
+ goto cleanup;
+ }
+ fseek(file, 0, SEEK_SET);
+
+ *data = alloc_or_crash(*size);
+ if((long)fread(*data, 1, *size, file) != *size) {
+ fprintf(stderr, "Failed to read all bytes in file %s\n", filepath);
+ result = -1;
+ goto cleanup;
+ }
+
+ cleanup:
+ fclose(file);
+ return result;
+}
+
+int create_directory_recursive(char *path) {
+ int path_len = strlen(path);
+ char *p = path;
+ char *end = path + path_len;
+ for(;;) {
+ char *slash_p = strchr(p, '/');
+
+ // Skips first '/', we don't want to try and create the root directory
+ if(slash_p == path) {
+ ++p;
+ continue;
+ }
+
+ if(!slash_p)
+ slash_p = end;
+
+ char prev_char = *slash_p;
+ *slash_p = '\0';
+ int err = mkdir(path, S_IRWXU);
+ *slash_p = prev_char;
+
+ if(err == -1 && errno != EEXIST)
+ return err;
+
+ if(slash_p == end)
+ break;
+ else
+ p = slash_p + 1;
+ }
+ return 0;
+}