From 4a24b06e4435a27e4aa584700e401e713cde314c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Wed, 23 Jun 2021 10:04:54 +0200 Subject: [PATCH] feat: add directory list --- file-browser/include/file_access.h | 37 +++---- file-browser/include/local_file_access.h | 2 +- file-browser/src/local_file_access.c | 131 ++++++++++++++++++++++- 3 files changed, 147 insertions(+), 23 deletions(-) diff --git a/file-browser/include/file_access.h b/file-browser/include/file_access.h index e23e61274a89dfb2fa1005137d7cecb7f0190d06..afa5c3617451e46264dc61abc93cd29febc9e8a2 100644 --- a/file-browser/include/file_access.h +++ b/file-browser/include/file_access.h @@ -6,11 +6,13 @@ #include #include "file_execute.h" +typedef struct directory_t directory_t; + typedef enum { - TYPE_FOLDER, - TYPE_FILE, - TYPE_OTHER, - TYPE_UNKNOWN, + FT_FOLDER, + FT_FILE, + FT_OTHER, + FT_UNKNOWN, } filetype_t; typedef enum { @@ -21,29 +23,24 @@ typedef enum { } fileaccess_type_t; typedef struct { - uint8_t owner : 3; - uint8_t group : 3; - uint8_t other : 3; -} file_permissions_t; - -typedef struct { - char *path; + char *name; + directory_t *directory; filetype_t type; // stats uint64_t size; - uint64_t modify_date; - uint64_t create_date; - file_permissions_t permissions; - char *owner; - char *group_owner; + time_t modify_time; + + mode_t permissions; + uid_t uid; + gid_t gid; } file_t; -typedef struct { +struct directory_t { char *path; file_t *files; uint32_t files_count; -} directory_t; +}; typedef enum { FILOPER_SUCCESS, @@ -142,8 +139,8 @@ extern const fileaccess_t extern const fileaccess_t temp_file_access; // state is /tmp directory descriptor -extern uint8_t connectors_count; -extern const fileaccess_connector_t connectors[(FA_COUNT-1)*FA_COUNT]; +extern uint8_t fileaccess_connectors_count; +extern fileaccess_connector_t fileaccess_connectors[(FA_COUNT-1)*FA_COUNT]; fileaccess_state_t fileaccess_init(const fileaccess_t *fileaccess, void *data); bool fileaccess_deinit(fileaccess_state_t state); diff --git a/file-browser/include/local_file_access.h b/file-browser/include/local_file_access.h index d9c1d985f228ac95d3ede7c5bbc936e31da24d76..f8e1eee16eb7150512c558c98a2ee3288524dd20 100644 --- a/file-browser/include/local_file_access.h +++ b/file-browser/include/local_file_access.h @@ -15,7 +15,7 @@ file_operation_error_t local_fileaccess_directory_delete(fileaccess_state_t stat file_operation_error_t local_fileaccess_directory_close(fileaccess_state_t state, directory_t *directory); file_operation_error_t local_fileaccess_file_get_mime_type(fileaccess_state_t state, file_t *file, char *mime); -pid_or_error_t local_fileaccess_file_execute(fileaccess_state_t state, file_t *file, char *args); +executing_file_or_error_t local_fileaccess_file_execute(fileaccess_state_t state, file_t *file, char *args); file_operation_error_t local_fileaccess_file_delete(fileaccess_state_t state, char *path); #endif // __LOCAL_FILE_ACCESS_H__ diff --git a/file-browser/src/local_file_access.c b/file-browser/src/local_file_access.c index 4c89237ba15d6a050da124aeaacd8336a9dac05b..3013f5b6b856de1bd3f27efd065222ad35cf7197 100644 --- a/file-browser/src/local_file_access.c +++ b/file-browser/src/local_file_access.c @@ -6,13 +6,29 @@ #include #include #include +#include #include +#include #define ROOT "/" static int nfw_callback(const char *fpath, const struct stat *sb, int typeflag); static int delete_file(const char *path); static int delete_directory(const char *path); +static char *file_get_full_path(fileaccess_state_t state, + directory_t *directory, file_t *file) { + char *base_path = path_join((char*)state.state, directory->path); + + if (base_path == NULL) { + return NULL; + } + + char *full_path = path_join(base_path, file->name); + free(base_path); + + return full_path; +} + static int delete_directory(const char *path) { int err = ftw(path, nfw_callback, 5); if (err != 1) { @@ -54,6 +70,51 @@ bool local_fileaccess_deinit_state(fileaccess_state_t data) { return true; } +static file_operation_error_t file_get_information(void **malloced, + uint64_t *offset, uint64_t *bytes_malloced, + fileaccess_state_t state, + file_t file) { + size_t name_len = strlen(file.name); + bytes_malloced += sizeof(file_t) + name_len + 1; + void *new = realloc(*malloced, *bytes_malloced); + if (new == NULL) { + free(*malloced); + return FILOPER_UNKNOWN; + } + *malloced = new; + + char *full_path = file_get_full_path(state, file.directory, &file); + if (full_path == NULL) { + free(new); + return FILOPER_UNKNOWN; + } + + // load info + struct stat stats; + int status = stat(full_path, &stats); + free(full_path); + + if (status == -1) { + free(new); + return file_operation_error_from_errno(errno); + } + + file.size = stats.st_size; + file.gid = stats.st_gid; + file.uid = stats.st_uid; + file.permissions = stats.st_mode; + + file_t *stored = new + *offset; + *stored = file; + *offset += sizeof(file_t); + + strcpy(new + *offset, file.name); + stored->name = new + *offset; + *offset += name_len + 1; + + return FILOPER_SUCCESS; +} + directory_or_error_t local_fileaccess_directory_list(fileaccess_state_t state, char *path) { directory_or_error_t ret; @@ -64,7 +125,72 @@ directory_or_error_t local_fileaccess_directory_list(fileaccess_state_t state, return ret; } + uint64_t malloc_offset = sizeof(directory_t) + strlen(path) + 1; + uint64_t bytes_malloced = sizeof(directory_t) + strlen(path) + 1; + directory_t *directory = malloc(malloc_offset); + void *malloced = directory; + + if (directory == NULL) { + ret.error = true; + ret.payload.error = FILOPER_UNKNOWN; + free(full_path); + return ret; + } + + directory->path = malloced + sizeof(directory_t); + strcpy(directory->path, path); + + + DIR *dirptr = opendir(full_path); free(full_path); + if (dirptr == NULL) { + ret.error = true; + ret.payload.error = file_operation_error_from_errno(errno); + free(malloced); + return ret; + } + + struct dirent * dir; + errno = 0; + while ((dir = readdir(dirptr)) != NULL) { + file_t file; + file.directory = directory; + file.name = dir->d_name; + + switch(dir->d_type) { + case DT_DIR: + file.type = FT_FOLDER; + break; + case DT_REG: + file.type = FT_FILE; + break; + case DT_UNKNOWN: + file.type = FT_UNKNOWN; + break; + default: + file.type = FT_OTHER; + break; + } + + ret.payload.error = file_get_information(&malloced, &malloc_offset, + &bytes_malloced, state, file); + if (ret.payload.error != FILOPER_SUCCESS) { + ret.error = true; + free(malloced); + return ret; + } + + directory->files_count++; + } + + if (errno != 0) { + ret.error = true; + ret.payload.error = file_operation_error_from_errno(errno); + } else { + ret.error = false; + ret.payload.directory = directory; + } + return ret; } @@ -127,7 +253,7 @@ local_fileaccess_file_get_mime_type(fileaccess_state_t state, file_t *file, magic_t magic = magic_open(MAGIC_MIME_TYPE); magic_load(magic, NULL); - char *full_path = path_join((char *)state.state, file->path); + char *full_path = file_get_full_path(state, file->directory, file); if (full_path == NULL) { return FILOPER_UNKNOWN; } @@ -151,7 +277,7 @@ local_fileaccess_file_get_mime_type(fileaccess_state_t state, file_t *file, executing_file_or_error_t local_fileaccess_file_execute(fileaccess_state_t state, file_t *file, char *args) { executing_file_or_error_t ret; - char *full_path = path_join((char *)state.state, file->path); + char *full_path = file_get_full_path(state, file->directory, file); // TODO: check permissions if (full_path == NULL) { @@ -165,6 +291,7 @@ executing_file_or_error_t local_fileaccess_file_execute(fileaccess_state_t state ret.error = true; ret.payload.error = FILOPER_UNKNOWN; } else { + ret.error = false; ret.payload.file = efile.file; }