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

9f2b7d5e6af2504c7db07dde94cecf1cbb67ed7a — František Boháček 3 years ago 74c0cff
feat: add file executing
A file-browser/include/file_open.h => file-browser/include/file_open.h +11 -0
@@ 0,0 1,11 @@
#ifndef __FILE_OPEN_H__
#define __FILE_OPEN_H__

#include <stdbool.h>
#include "file_access.h"
#include "options.h"

file_operation_error_t file_open(file_t *file, exec_options_t *options,
                                 fileaccess_state_t state);

#endif // __FILE_OPEN_H__

M file-browser/src/file_execute.c => file-browser/src/file_execute.c +2 -1
@@ 4,6 4,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

executing_file_error_t executing_file_execute(char *path, char *args) {
  executing_file_error_t ret;


@@ 15,7 16,7 @@ executing_file_error_t executing_file_execute(char *path, char *args) {
  }

  if (pid == 0) {
    execl(path, args, (char*)NULL);
    execl(path, path, args, (char*)NULL);
    exit(errno);
  }


A file-browser/src/file_open.c => file-browser/src/file_open.c +72 -0
@@ 0,0 1,72 @@
#include "file_open.h"
#include "file_access.h"
#include <linux/limits.h>
#include <sys/stat.h>
#include <unistd.h>
#include "nonblocking_io.h"
#include "serialize_lock.h"

static void file_prepare_before_open() {
  serialize_unlock();
}

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

  if (serialize_lock(1) <= 0) {
      serialize_lock(0);
  }
}

file_operation_error_t file_open(file_t *file, exec_options_t *options, fileaccess_state_t state) {
  executing_file_t executing;
  if (file->permissions & S_IXUSR) {
    // executable
    file_prepare_before_open();
    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;
    }
    
    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;
    }

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

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

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

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

    executing = executing_or_error.file;
  } else {
    return FILOPER_UNKNOWN;
  }

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

M file-browser/src/local_file_access.c => file-browser/src/local_file_access.c +12 -9
@@ 4,6 4,7 @@
#include "path.h"
#include <errno.h>
#include <ftw.h>
#include <linux/limits.h>
#include <magic.h>
#include <stdio.h>
#include <stdlib.h>


@@ 77,9 78,11 @@ static file_operation_error_t file_get_information(void *malloced,
directory_or_error_t local_fileaccess_directory_list(fileaccess_state_t state,
                                                     char *path) {
  directory_or_error_t ret;
  char full_path[path_join_memory_size(state.payload.local.path, path)];
  char full_path[PATH_MAX];
  path_join((char *)state.payload.local.path, path, full_path);

  realpath(full_path, full_path);

  DIR *dirptr = opendir(full_path);
  if (dirptr == NULL) {
    ret.error = true;


@@ 87,9 90,13 @@ directory_or_error_t local_fileaccess_directory_list(fileaccess_state_t state,
    return ret;
  }

  char show_path[PATH_MAX];
  realpath(path, show_path);

  uint32_t files_count = 0;
  uint64_t size = directory_get_needed_bytes(path, &files_count, dirptr);
  uint64_t files_offset = sizeof(directory_t) + strlen(path) + 1;

  uint64_t files_offset = sizeof(directory_t) + strlen(show_path) + 1;
  uint64_t names_offset = files_count * sizeof(file_t) + files_offset;
  directory_t *directory = malloc(size);
  void *malloced = directory;


@@ 103,7 110,7 @@ directory_or_error_t local_fileaccess_directory_list(fileaccess_state_t state,
  directory->path = malloced + sizeof(directory_t);
  directory->files = malloced + files_offset;
  directory->files_count = 0;
  strcpy(directory->path, path);
  strcpy(directory->path, show_path);

  struct dirent * dir;
  errno = 0;


@@ 208,14 215,10 @@ local_fileaccess_file_get_mime_type(fileaccess_state_t state, file_t *file,
  const char *data = magic_file(magic, full_path);
  if (data == NULL) {
    error = file_operation_error_from_errno(errno);
  } else {
    strcpy(mime, data);
  }

  uint16_t i = 0;
  while (*data != '\0') {
    mime[i++] = *data;
  }
  mime[i] = '\0';

  magic_close(magic);
  return error;
}

Do not follow this link