~ruther/CTU-FEE-B0B35APO-Semestral-project

7db45d6d9a6b4bb8f10fae9ce127d7cb350e046a — František Boháček 3 years ago d5a2044
feat: add structure for dynamic file access
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;
}

Do not follow this link