A file-browser/include/file_access.h => file-browser/include/file_access.h +159 -0
@@ 0,0 1,159 @@
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+typedef enum {
+ TYPE_FOLDER,
+ TYPE_FILE,
+ TYPE_OTHER,
+ TYPE_UNKNOWN,
+} filetype_t;
+
+typedef enum {
+ FA_LOCAL, // root fs
+ FA_EXTERN, // not mounted device to be mounted when opened
+ FA_TEMP,
+ FA_COUNT,
+} fileaccess_type_t;
+
+typedef struct {
+ uint8_t owner : 3;
+ uint8_t group : 3;
+ uint8_t other : 3;
+} file_permissions_t;
+
+typedef struct {
+ char *path;
+ filetype_t type;
+
+ // stats
+ uint64_t size;
+ uint64_t modify_date;
+ uint64_t create_date;
+ file_permissions_t permissions;
+ char *owner;
+ char *group_owner;
+} file_t;
+
+typedef struct {
+ char *path;
+ file_t *files;
+ uint32_t files_count;
+} directory_t;
+
+typedef enum {
+ FILOPER_SUCCESS,
+ FILOPER_PERMISSIONS,
+ FILOPER_DOES_NOT_EXIST,
+ FILOPER_USED,
+ FILOPER_UNKNOWN,
+} file_operation_error_t;
+
+typedef struct {
+ bool error;
+ union {
+ file_operation_error_t error;
+ pid_t pid;
+ } payload;
+} pid_or_error_t;
+
+typedef struct {
+ bool error;
+ union {
+ file_operation_error_t error;
+ directory_t *directory;
+ } payload;
+} directory_or_error_t;
+
+typedef struct fileaccess_t fileaccess_t;
+
+typedef struct {
+ const fileaccess_t *fileaccess;
+ void *state;
+} fileaccess_state_t;
+
+typedef fileaccess_state_t (*init_state_fn)(void *data);
+typedef bool (*deinit_state_fn)(fileaccess_state_t state);
+
+typedef directory_or_error_t (*list_directory_fn)(fileaccess_state_t state,
+ char *path);
+typedef directory_or_error_t (*list_root_fn)(fileaccess_state_t state);
+
+typedef directory_or_error_t (*create_directory_fn)(fileaccess_state_t state,
+ char *path);
+typedef file_operation_error_t (*close_directory_fn)(fileaccess_state_t state,
+ directory_t *directory);
+
+typedef file_operation_error_t (*get_mime_type_fn)(fileaccess_state_t state,
+ file_t *file, char *mime);
+typedef pid_or_error_t (*execute_file_fn)(fileaccess_state_t state,
+ file_t *file, char *args);
+
+typedef file_operation_error_t (*delete_directory_fn)(fileaccess_state_t state,
+ directory_t *directory);
+typedef file_operation_error_t (*delete_file_fn)(fileaccess_state_t state,
+ directory_t *directory);
+
+struct fileaccess_t {
+ fileaccess_type_t type;
+
+ init_state_fn init;
+ deinit_state_fn deinit;
+
+ list_directory_fn list_directory;
+ list_root_fn list_root;
+
+ create_directory_fn create_directory;
+ close_directory_fn close_directory;
+
+ get_mime_type_fn get_mime_type;
+ execute_file_fn execute_file;
+
+ delete_directory_fn delete_directory;
+ delete_file_fn delete_file;
+};
+
+typedef struct fileaccess_connector_t fileaccess_connector_t;
+typedef file_operation_error_t (*file_copy_fn)(
+ fileaccess_connector_t *connector, void *first_state, void *second_state,
+ file_t *file, char *destination);
+typedef file_operation_error_t (*file_move_fn)(
+ fileaccess_connector_t *connector, void *first_state, void *second_state,
+ file_t *file, char *destination);
+
+struct fileaccess_connector_t {
+ const fileaccess_t *first;
+ const fileaccess_t *second;
+
+ file_copy_fn copy;
+ file_move_fn move;
+};
+
+extern const fileaccess_t
+ local_file_access; // state is root directory descriptor
+extern const fileaccess_t
+ extern_file_access; // state is mount directory descriptor
+extern const fileaccess_t
+ temp_file_access; // state is /tmp directory descriptor
+
+extern const fileaccess_connector_t connectors[FA_COUNT*FA_COUNT];
+
+fileaccess_state_t fileaccess_init(const fileaccess_t *fileaccess, void *data);
+bool fileaccess_deinit(fileaccess_state_t state);
+
+directory_or_error_t fileaccess_directory_list(fileaccess_state_t state,
+ char *path);
+
+directory_or_error_t fileaccess_root_list(fileaccess_state_t state);
+
+directory_or_error_t fileaccess_directory_create(fileaccess_state_t state,
+ char *path);
+file_operation_error_t fileaccess_directory_close(fileaccess_state_t state,
+ directory_t *directory);
+
+file_operation_error_t fileaccess_file_get_mimetype(fileaccess_state_t state,
+ file_t *file,
+ /*out*/ char *mime);
+
+pid_or_error_t fileaccess_file_execute(fileaccess_state_t state, file_t *file,
+ char *args);
A file-browser/include/path.h => file-browser/include/path.h +4 -0
@@ 0,0 1,4 @@
+#include <string.h>
+#include <stdbool.h>
+
+char *path_join(char *base, char *relative);
A file-browser/src/file_access.c => file-browser/src/file_access.c +40 -0
@@ 0,0 1,40 @@
+#include "file_access.h"
+#include <string.h>
+
+fileaccess_state_t fileaccess_init(const fileaccess_t *fileaccess, void *data) {
+ return fileaccess->init(data);
+}
+
+bool fileaccess_deinit(fileaccess_state_t state) {
+ return state.fileaccess->deinit(state);
+}
+
+directory_or_error_t fileaccess_directory_list(fileaccess_state_t state,
+ char *path) {
+ return state.fileaccess->list_directory(state, path);
+}
+
+directory_or_error_t fileaccess_root_list(fileaccess_state_t state) {
+ return state.fileaccess->list_root(state);
+}
+
+directory_or_error_t fileaccess_directory_create(fileaccess_state_t state,
+ char *path) {
+ return state.fileaccess->create_directory(state, path);
+}
+
+file_operation_error_t fileaccess_directory_close(fileaccess_state_t state,
+ directory_t *directory) {
+ return state.fileaccess->close_directory(state, directory);
+}
+
+file_operation_error_t fileaccess_file_get_mimetype(fileaccess_state_t state,
+ file_t *file,
+ /*out*/ char *mime) {
+ return state.fileaccess->get_mime_type(state, file, mime);
+}
+
+pid_or_error_t fileaccess_file_execute(fileaccess_state_t state, file_t *file,
+ char *args) {
+ return state.fileaccess->execute_file(state, file, args);
+}
A file-browser/src/path.c => file-browser/src/path.c +27 -0
@@ 0,0 1,27 @@
+#include "path.h"
+#include <stdlib.h>
+#include <string.h>
+
+char *path_join(char *base, char *relative) {
+ size_t base_len = strlen(base);
+ size_t relative_len = strlen(relative);
+
+ while (base[base_len - 1] == '/' && base_len > 0) {
+ base_len--;
+ }
+
+ while (relative[0] == '/' && relative_len > 0) {
+ relative_len--;
+ relative++;
+ }
+
+ size_t new_len = base_len + relative_len + 1; // length of the string
+ char *out = malloc((new_len + 1) * sizeof(out)); // length of the string plus one for \0
+ out[new_len] = '\0';
+ out[base_len] = '/';
+
+ memcpy(out, base, base_len);
+ memcpy(out + base_len + 1, relative, relative_len);
+
+ return out;
+}