@@ 6,11 6,13 @@
#include <sys/types.h>
#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);
@@ 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__
@@ 6,13 6,29 @@
#include <magic.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
+#include <dirent.h>
#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;
}