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

6eb081d8a15f03b5a185fc1cd2e5619e24186570 — František Boháček 4 years ago 8f5fd84
fix: rework file opening mechanism so mime is checked first
1 files changed, 87 insertions(+), 37 deletions(-)

M file-browser/src/file_open.c
M file-browser/src/file_open.c => file-browser/src/file_open.c +87 -37
@@ 1,6 1,7 @@
#include "file_open.h"
#include "file_access.h"
#include <linux/limits.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "nonblocking_io.h"


@@ 10,7 11,7 @@ static void file_prepare_before_open() {
  serialize_unlock();
}

static void file_prepare_after_open() {
static void file_prepare_after_close() {
  struct termios old;
  file_set_nonblocking(STDIN_FILENO, &old);



@@ 19,54 20,103 @@ static void file_prepare_after_open() {
  }
}

file_operation_error_t file_open(file_t *file, exec_options_t *options, fileaccess_state_t state) {
  executing_file_t executing;
static void file_execute(executing_file_t *executing) {
  executing_file_wait(executing);
  file_prepare_after_close();
}

static bool file_open_mime(file_t *file, exec_options_t *options,
                           fileaccess_state_t state, char *base_mime,
                           file_operation_error_t *error) {
  if (options == NULL) {
    return false;
  }

  char mime[256];
  if (base_mime != NULL) {
    strcpy(mime, base_mime);
  } else {
    *error = fileaccess_file_get_mimetype(state, file, mime);

    if (*error != FILOPER_SUCCESS) {
      return true;
    }
  }

  char *program = exec_options_get_program(options, mime);
  if (program == NULL) {
    return false;
  }

  char local_path[PATH_MAX];
  *error =
      fileaccess_file_get_local_path(state, file, local_path);

  if (*error != FILOPER_SUCCESS) {
    return true;
  }

  file_prepare_before_open();
  executing_file_error_t executing_or_error =
      executing_file_execute(program, local_path);

  if (executing_or_error.error != FILOPER_SUCCESS) {
    return executing_or_error.error;
  }

  file_execute(&executing_or_error.file);

  return true;
}

static bool file_open_text(file_t *file, exec_options_t *options,
                           fileaccess_state_t state,
                           file_operation_error_t *error) {
  return file_open_mime(file, options, state, "text", error);
}

static bool file_open_executable(file_t *file, exec_options_t *options,
                                 fileaccess_state_t state,
                                 file_operation_error_t *error) {
  if (file->permissions & S_IXUSR) {
    // executable
    file_prepare_before_open();
    executing_file_or_error_t executing_or_error = fileaccess_file_execute(state, file, "");
    executing_file_or_error_t executing_or_error =
        fileaccess_file_execute(state, file, "");
    if (executing_or_error.error) {
      file_prepare_after_open();
      return executing_or_error.payload.error;
      *error = executing_or_error.error;
      return true;
    }
    
    executing = executing_or_error.payload.file;
  } else if (options != NULL) {
    char mime[256];
    fileaccess_file_get_mimetype(state, file, mime);

    char *program = exec_options_get_program(options, mime);

    if (program == NULL) {
      program = exec_options_get_program(options, "text");
    }

    if (program == NULL) {
      return FILOPER_SUCCESS;
    }
    file_execute(&executing_or_error.payload.file);
    return true;
  }

    char local_path[PATH_MAX];
    file_operation_error_t error = fileaccess_file_get_local_path(state, file, local_path);
  return false;
}

    if (error != FILOPER_SUCCESS) {
      return error;
    }
file_operation_error_t file_open(file_t *file, exec_options_t *options, fileaccess_state_t state) {
  file_operation_error_t error = FILOPER_SUCCESS;

    file_prepare_before_open();
    executing_file_error_t executing_or_error = executing_file_execute(program, local_path);
  // 1. try mime
  if (file_open_mime(file, options, state, NULL, &error)) {
    return error;
  }

    if (executing_or_error.error != FILOPER_SUCCESS) {
      file_prepare_after_open();
      return executing_or_error.error;
    }
  if (error != FILOPER_SUCCESS) {
    return error;
  }
  // 2. is executable? execute it
  if (file_open_executable(file, options, state, &error)) {
    return error;
  }

    executing = executing_or_error.file;
  } else {
    return FILOPER_UNKNOWN;
  if (error != FILOPER_SUCCESS) {
    return error;
  }
  // 3. text mime
  file_open_text(file, options, state, &error);

  executing_file_wait(&executing);
  file_prepare_after_open();
  // TODO: figure out return data?
  return FILOPER_SUCCESS;
  return error;
}