diff --git a/.vscode/settings.json b/.vscode/settings.json index 580d696ee..03ce42b1d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -204,7 +204,9 @@ "apps.h": "c", "download.h": "c", "stdlib.h": "c", - "update.h": "c" + "update.h": "c", + "launch.h": "c", + "untar.h": "c" }, "files.exclude": { "bundled": true, diff --git a/sources/core/apps/store/source/core/core.c b/sources/core/apps/store/source/core/core.c index 82f27ec58..b88db0c2f 100644 --- a/sources/core/apps/store/source/core/core.c +++ b/sources/core/apps/store/source/core/core.c @@ -5,13 +5,17 @@ #include #include "../apps/apps.h" +#include "../launch/launch.h" #include "../update/update.h" #include "../install/install.h" -#include "../uninstall/uninstall.h" +#include "../remove/remove.h" void print_help(){ printf("For help: ./store --help\n"); printf("To install an application: ./store --install [app name]\n"); + printf("To remove an application: ./store --remove [app name]\n"); + printf("To update an application: ./store --update [app name]\n"); + printf("To launch an application: ./store --launch [app name] [arguments]\n"); } int main(int argc, char *argv[]){ @@ -116,9 +120,13 @@ int main(int argc, char *argv[]){ }else if(!strcmp(argv[1], "--update") && argc == 3){ char* name = argv[2]; update_app(curl, name); - }else if(!strcmp(argv[1], "--uninstall") && argc == 3){ + }else if(!strcmp(argv[1], "--remove") && argc == 3){ char* name = argv[2]; - uninstall_app(name); + remove_app(name, true); + }else if(!strcmp(argv[1], "--launch") && argc >= 3){ + char* name = argv[2]; + // Keep the app name + launch_app(name, argc - 2, &argv[2]); }else{ print_help(); } diff --git a/sources/core/apps/store/source/install/install.c b/sources/core/apps/store/source/install/install.c index 9047bc49b..7a7ec45ee 100644 --- a/sources/core/apps/store/source/install/install.c +++ b/sources/core/apps/store/source/install/install.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -26,16 +27,13 @@ int install_app(CURL* curl, char* url, char* name, bool reinstall){ char* path_store = getenv("PATHSTORE"); create_dir_if_not_exist(path_store); - char* path_store_app = malloc(strlen(path_store) + sizeof((char)'/') + strlen(name) + sizeof((char)'/') + 1); - strcpy(path_store_app, path_store); - strcat(path_store_app, "/"); - strcat(path_store_app, name); - strcat(path_store_app, "/"); + char* path_store_app; + assert(asprintf(&path_store_app, "%s/%s/", path_store, name) >= 0); + create_dir_if_not_exist(path_store_app); - char* path_store_app_info_json = malloc(strlen(path_store_app) + strlen("app-info.json") + 1); - strcpy(path_store_app_info_json, path_store_app); - strcat(path_store_app_info_json, "app-info.json"); + char* path_store_app_info_json; + assert(asprintf(&path_store_app_info_json, "%sapp-info.json", path_store_app) >= 0); if(download_file(curl, url, path_store_app_info_json, reinstall)){ printf("Error: Aborting installation of %s!\n", name); diff --git a/sources/core/apps/store/source/launch/launch.c b/sources/core/apps/store/source/launch/launch.c new file mode 100644 index 000000000..bedb716a5 --- /dev/null +++ b/sources/core/apps/store/source/launch/launch.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "launch.h" + +static bool is_dir_exist(char* path){ + struct stat sb; + return (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)); +} + +static bool is_file_exists(char* path){ + struct stat sb; + return (stat(path, &sb) == 0); +} + +static int get_executable_path(char* app_info_path, char** relative_path){ + FILE* fp = fopen(app_info_path, "r"); + + if(fp != NULL){ + fseek(fp, 0, SEEK_END); + size_t size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + void* buffer = malloc(size); + int len = fread(buffer, 1, size, fp); + fclose(fp); + + cJSON* root = cJSON_Parse(buffer); + if(root != NULL){ + cJSON* executable_path = cJSON_GetObjectItem(root, "executable_path"); + if(executable_path != NULL){ + if(cJSON_IsString(executable_path) && (executable_path->valuestring != NULL)){ + *relative_path = malloc(strlen(executable_path->valuestring) + 1); + strcpy(*relative_path, executable_path->valuestring); + + cJSON_Delete(root); + free(buffer); + return 0; + } + } + cJSON_Delete(root); + } + + free(buffer); + return -1; + }else{ + return -1; + } +} + +int launch_app(char* name, int argc, char *argv[]){ + char* path_store = getenv("PATHSTORE"); + if(is_dir_exist(path_store)){ + char* path_store_app; + assert(asprintf(&path_store_app, "%s/%s/", path_store, name) >= 0); + + if(is_dir_exist(path_store_app)){ + char* path_store_app_info_json; + assert(asprintf(&path_store_app_info_json, "%sapp-info.json", path_store_app) >= 0); + + char* relative_path = NULL; + int result = get_executable_path(path_store_app_info_json, &relative_path); + free(path_store_app_info_json); + + if(!result){ + char* absolute_path = NULL; + assert(asprintf(&absolute_path, "%s%s", path_store_app, relative_path) >= 0); + + printf("Launching : %s\n", absolute_path); + int r = execve(absolute_path, argv, NULL); + printf("Error when launching : %s, error code : %d\n", absolute_path, r); + + free(relative_path); + free(absolute_path); + } + + printf("Error when launching : %d\n", name); + free(path_store_app); + + return -1; + } + + free(path_store_app); + } + + printf("Can't find the app named : %d\n", name); + + return -1; +} \ No newline at end of file diff --git a/sources/core/apps/store/source/launch/launch.h b/sources/core/apps/store/source/launch/launch.h new file mode 100644 index 000000000..1d4bb16c8 --- /dev/null +++ b/sources/core/apps/store/source/launch/launch.h @@ -0,0 +1,6 @@ +#ifndef LAUNCH_H +#define LAUNCH_H + +int launch_app(char* name, int argc, char *argv[]); + +#endif // LAUNCH_H \ No newline at end of file diff --git a/sources/core/apps/store/source/remove/remove.c b/sources/core/apps/store/source/remove/remove.c new file mode 100644 index 000000000..c3c8cb90b --- /dev/null +++ b/sources/core/apps/store/source/remove/remove.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "remove.h" + +#define MAX_REMOVE_DIR 256 + +static bool is_dir_exist(char* path){ + struct stat sb; + return (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)); +} + +static bool check_user_allow(char* name){ + char allow_remove[3]; + printf("%s > Would you like to remove it? (Y/N)\n", name); + fgets(allow_remove, sizeof(allow_remove), stdin); + allow_remove[strcspn(allow_remove, "\n")] = 0; + return (!strcmp("Y", allow_remove)); +} + +static int remove_directory(char* path){ + DIR* d = opendir(path); + if(!d){ + return -1; + } + + struct dirent* p; + int count = 0; + char* path_list[MAX_REMOVE_DIR]; + + while((p = readdir(d)) != NULL){ + int r; + char* buffer; + size_t path_len = strlen(path); + + + if(asprintf(&path_list[count], "%s%s", path, p->d_name) >= 0){ + count++; + if(count >= MAX_REMOVE_DIR){ + remove_directory(path); + break; + } + } + } + + closedir(d); + + for(int i = 0; i < count; i++){ + printf("Removing : %s\n", path_list[i]); + struct stat statbuf; + if(lstat(path_list[i], &statbuf) >= 0){ + if(S_ISDIR(statbuf.st_mode)) { + remove_directory(path_list[i]); + }else{ + remove(path_list[i]); + } + } + free(path_list[i]); + } + + printf("Removing : %s\n", path); + return rmdir(path); +} + +int remove_app(char* name, bool check_user){ + char* path_store = getenv("PATHSTORE"); + if(is_dir_exist(path_store)){ + char* path_store_app; + assert(asprintf(&path_store_app, "%s/%s/", path_store, name) >= 0); + + if(is_dir_exist(path_store_app)){ + bool do_remove = true; + + if(check_user){ + do_remove = check_user_allow(name); + } + + if(do_remove){ + printf("Removing %s\n", name); + remove_directory(path_store_app); + printf("Done remove %s\n", name); + return 0; + }else{ + printf("Cancel the removal of %s\n", name); + return -2; + } + } + } + + printf("Can't find : ' %s\n", name); + return -1; +} \ No newline at end of file diff --git a/sources/core/apps/store/source/remove/remove.h b/sources/core/apps/store/source/remove/remove.h new file mode 100644 index 000000000..20b35f165 --- /dev/null +++ b/sources/core/apps/store/source/remove/remove.h @@ -0,0 +1,6 @@ +#ifndef REMOVE_H +#define REMOVE_H + +int remove_app(char* name, bool check_user); + +#endif // REMOVE_H \ No newline at end of file diff --git a/sources/core/apps/store/source/uninstall/uninstall.c b/sources/core/apps/store/source/uninstall/uninstall.c deleted file mode 100644 index 80ca1279d..000000000 --- a/sources/core/apps/store/source/uninstall/uninstall.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "uninstall.h" - -static bool is_dir_exist(char* path){ - struct stat sb; - return (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)); -} - -static int delete(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf){ - return remove(fpath); -} - -int rmrf(char* path){ - return nftw(path, delete, 64, FTW_DEPTH | FTW_PHYS); -} - -int uninstall_app(char* name){ - printf("Uninstalling %s...\n", name); - char* path_store = getenv("PATHSTORE"); - if(is_dir_exist(path_store)){ - char* path_store_app = malloc(strlen(path_store) + sizeof((char)'/') + strlen(name) + sizeof((char)'/') + 1); - strcpy(path_store_app, path_store); - strcat(path_store_app, "/"); - strcat(path_store_app, name); - strcat(path_store_app, "/"); - - if(is_dir_exist(path_store_app)){ - printf("Done uninstall %s\n", name); - rmrf(path_store_app); - rmdir(path_store_app); - return 0; - } - } - - printf("Can't uninstall %s\n", name); - - return -1; -} \ No newline at end of file diff --git a/sources/core/apps/store/source/uninstall/uninstall.h b/sources/core/apps/store/source/uninstall/uninstall.h deleted file mode 100644 index 4189443f4..000000000 --- a/sources/core/apps/store/source/uninstall/uninstall.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef UNINSTALL_H -#define UNINSTALL_H - -int uninstall_app(char* name); - -#endif // UNINSTALL_H \ No newline at end of file diff --git a/sources/core/apps/store/source/update/update.c b/sources/core/apps/store/source/update/update.c index b55462e8c..b6bed1ece 100644 --- a/sources/core/apps/store/source/update/update.c +++ b/sources/core/apps/store/source/update/update.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,7 +9,7 @@ #include "update.h" #include "../install/install.h" -#include "../uninstall/uninstall.h" +#include "../remove/remove.h" static bool is_dir_exist(char* path){ struct stat sb; @@ -161,27 +162,25 @@ static int check_update(CURL* curl, char* app_info_path, char** url){ int update_app(CURL* curl, char* name){ char* path_store = getenv("PATHSTORE"); if(is_dir_exist(path_store)){ - char* path_store_app = malloc(strlen(path_store) + sizeof((char)'/') + strlen(name) + sizeof((char)'/') + 1); - strcpy(path_store_app, path_store); - strcat(path_store_app, "/"); - strcat(path_store_app, name); - strcat(path_store_app, "/"); + char* path_store_app; + assert(asprintf(&path_store_app, "%s/%s/", path_store, name) >= 0); if(is_dir_exist(path_store_app)){ - char* path_store_app_info_json = malloc(strlen(path_store_app) + strlen("app-info.json") + 1); - strcpy(path_store_app_info_json, path_store_app); - strcat(path_store_app_info_json, "app-info.json"); + char* path_store_app_info_json; + assert(asprintf(&path_store_app_info_json, "%sapp-info.json", path_store_app) >= 0); char* url = NULL; int result = check_update(curl, path_store_app_info_json, &url); + free(path_store_app_info_json); + if(result == 0){ printf("%s : is up-to-date\n", name); }else if(result == 1 && url != NULL){ printf("%s : is not up-to-date\n", name); printf("Updating...\n"); printf("Removing old files...\n"); - uninstall_app(name); + remove_app(name, false); printf("Installing new files...\n"); int r = install_app(curl, url, name, true); @@ -196,6 +195,8 @@ int update_app(CURL* curl, char* name){ }else{ printf("%s : is not installed\n", name); } + + free(path_store_app); }else{ printf("%s : is not installed\n", name); } diff --git a/sources/core/kernel/source/global/syscall.c b/sources/core/kernel/source/global/syscall.c index 19e857d71..bba6ebac0 100644 --- a/sources/core/kernel/source/global/syscall.c +++ b/sources/core/kernel/source/global/syscall.c @@ -564,8 +564,22 @@ static void syscall_handler_dir_read_entries(cpu_context_t* ctx){ } static void syscall_handler_dir_remove(cpu_context_t* ctx){ - log_warning("%s : syscall not implemented\n", __FUNCTION__); - SYSCALL_RETURN(ctx, -ENOSYS); + char* path = (char*)ARCH_CONTEXT_SYSCALL_ARG0(ctx); + size_t path_len = (size_t)ARCH_CONTEXT_SYSCALL_ARG1(ctx); + + if(path_len >= PATH_MAX){ + SYSCALL_RETURN(ctx, -EINVAL); + } + + if(vmm_check_memory(vmm_get_current_space(), (memory_range_t){path, path_len + 1})){ + SYSCALL_RETURN(ctx, -EINVAL); + } + + path[path_len] = '\0'; + + int error = d_remove(ARCH_CONTEXT_CURRENT_THREAD(ctx)->process->vfs_ctx, path); + + SYSCALL_RETURN(ctx, -error); } static void syscall_handler_dir_create(cpu_context_t* ctx){ @@ -585,12 +599,34 @@ static void syscall_handler_dir_create(cpu_context_t* ctx){ int error = d_create(ARCH_CONTEXT_CURRENT_THREAD(ctx)->process->vfs_ctx, path, mode); - SYSCALL_RETURN(ctx, error); + SYSCALL_RETURN(ctx, -error); } static void syscall_handler_unlink_at(cpu_context_t* ctx){ - log_warning("%s : syscall not implemented\n", __FUNCTION__); - SYSCALL_RETURN(ctx, -ENOSYS); + int dirfd = (int)ARCH_CONTEXT_SYSCALL_ARG0(ctx); + char* path = (char*)ARCH_CONTEXT_SYSCALL_ARG1(ctx); + size_t path_len = (size_t)ARCH_CONTEXT_SYSCALL_ARG2(ctx); + int flags = (int)ARCH_CONTEXT_SYSCALL_ARG3(ctx); + + if(path_len >= PATH_MAX){ + SYSCALL_RETURN(ctx, -EINVAL); + } + + if(vmm_check_memory(vmm_get_current_space(), (memory_range_t){path, path_len + 1})){ + SYSCALL_RETURN(ctx, -EINVAL); + } + + path[path_len] = '\0'; + + if(dirfd == AT_FDCWD){ + int error = f_remove(ARCH_CONTEXT_CURRENT_THREAD(ctx)->process->vfs_ctx, path); + + SYSCALL_RETURN(ctx, -error); + }else{ + // TODO + log_warning("%s : syscall not implemented\n", __FUNCTION__); + SYSCALL_RETURN(ctx, -ENOSYS); + } } static void syscall_handler_rename_at(cpu_context_t* ctx){ diff --git a/sources/core/libs/mlibc/sysdeps/kot/generic/filesystem.cpp b/sources/core/libs/mlibc/sysdeps/kot/generic/filesystem.cpp index 5d58c920d..e8ff28461 100644 --- a/sources/core/libs/mlibc/sysdeps/kot/generic/filesystem.cpp +++ b/sources/core/libs/mlibc/sysdeps/kot/generic/filesystem.cpp @@ -154,7 +154,7 @@ namespace mlibc{ } int sys_rmdir(const char *path){ - auto result = do_syscall(SYS_DIR_REMOVE, AT_FDCWD, path, AT_REMOVEDIR); + auto result = do_syscall(SYS_DIR_REMOVE, path, strlen(path)); if(result < 0){ return -result; @@ -174,7 +174,7 @@ namespace mlibc{ } int sys_unlinkat(int dirfd, const char *path, int flags){ - auto result = do_syscall(SYS_UNLINK_AT, AT_FDCWD, path, AT_REMOVEDIR); + auto result = do_syscall(SYS_UNLINK_AT, dirfd, path, strlen(path), flags); if(result < 0){ return -result; diff --git a/sources/core/modules/fat32/source/core.c b/sources/core/modules/fat32/source/core.c index 0aaf21d41..1eaa2e2ac 100644 --- a/sources/core/modules/fat32/source/core.c +++ b/sources/core/modules/fat32/source/core.c @@ -712,15 +712,16 @@ static int fat_update_entry_with_path_from_root(fat_context_t* ctx, const char* static int fat_add_entry_with_path(fat_context_t* ctx, fat_short_entry_t* dir, const char* path, fat_short_entry_t* entry, bool use_lfn,void* cluster_buffer){ char* entry_name; - dir = fat_find_last_directory(ctx, dir, path, cluster_buffer, &entry_name); + fat_short_entry_t* dir_tmp = fat_find_last_directory(ctx, dir, path, cluster_buffer, &entry_name); - if(dir == NULL){ + if(dir_tmp == NULL){ return ENOENT; } /* Remove dir from the cluster_buffer */ - fat_short_entry_t dir_tmp = *dir; - dir = &dir_tmp; + fat_short_entry_t dir_tmp_buf; + memcpy(&dir_tmp_buf, dir_tmp, sizeof(fat_short_entry_t)); + dir = &dir_tmp_buf; uint32_t base_cluster = fat_get_cluster_entry(ctx, dir); @@ -774,22 +775,23 @@ static int fat_add_entry_with_path_from_root(fat_context_t* ctx, const char* pat static int fat_remove_entry_with_path(fat_context_t* ctx, fat_short_entry_t* dir, const char* path, void* cluster_buffer){ char* entry_name; - dir = fat_find_last_directory(ctx, dir, path, cluster_buffer, &entry_name); + fat_short_entry_t* dir_tmp = fat_find_last_directory(ctx, dir, path, cluster_buffer, &entry_name); - if(dir == NULL){ + if(dir_tmp == NULL){ return ENOENT; } /* Remove dir from the cluster_buffer */ - fat_short_entry_t dir_tmp = *dir; - dir = &dir_tmp; + fat_short_entry_t dir_tmp_buf; + memcpy(&dir_tmp_buf, dir_tmp, sizeof(fat_short_entry_t)); + dir = &dir_tmp_buf; uint32_t base_cluster = fat_get_cluster_entry(ctx, dir); uint32_t sfn_index; uint32_t lfn_index; - int err = fat_find_entry_info_with_path_from_root(ctx, path, cluster_buffer, NULL, &sfn_index, &lfn_index); + int err = fat_find_entry_info_with_path(ctx, dir, path, cluster_buffer, NULL, &sfn_index, &lfn_index); if(err){ return err; @@ -808,7 +810,7 @@ static int fat_remove_entry_with_path(fat_context_t* ctx, fat_short_entry_t* dir uint64_t alignement_source = first_index_to_move * ENTRY_SIZE; uint64_t alignement_destination = first_index_to_remove * ENTRY_SIZE; - uint64_t size_to_copy = fat_get_dir_size(ctx, dir, cluster_buffer) - alignement_source; + uint64_t size_to_copy = fat_get_dir_size(ctx, dir, cluster_buffer) - (alignement_source - alignement_destination); void* buffer_to_copy = malloc(size_to_copy); uint64_t size_read_tmp; @@ -816,6 +818,9 @@ static int fat_remove_entry_with_path(fat_context_t* ctx, fat_short_entry_t* dir uint64_t size_write_tmp; assert(!fat_write_cluster_chain(ctx, base_cluster, alignement_destination, size_to_copy, &size_write_tmp, buffer_to_copy, WRITE_CLUSTER_CHAIN_FLAG_EOC | WRITE_CLUSTER_CHAIN_FLAG_FWZ)); + + free(buffer_to_copy); + return 0; } @@ -845,35 +850,37 @@ static int fat_clear_entry_data_with_path_from_root(fat_context_t* ctx, const ch static int fat_remove_and_clear_entry_with_path(fat_context_t* ctx, fat_short_entry_t* dir, const char* path, void* cluster_buffer){ - char* entry_name; + char* entry_name_tmp; - fat_short_entry_t* dir_parent = fat_find_last_directory(ctx, dir, path, cluster_buffer, &entry_name); + fat_short_entry_t* dir_parent_tmp = fat_find_last_directory(ctx, dir, path, cluster_buffer, &entry_name_tmp); + char* entry_name = malloc(strlen(entry_name_tmp) + 1); + strcpy(entry_name, entry_name_tmp); - if(dir_parent == NULL){ - free(cluster_buffer); + if(dir_parent_tmp == NULL){ return ENOENT; } /* Remove dir from the cluster_buffer */ - fat_short_entry_t dir_parent_tmp = *dir_parent; - dir_parent = &dir_parent_tmp; + fat_short_entry_t dir_parent; + memcpy(&dir_parent, dir_parent_tmp, sizeof(fat_short_entry_t)); - fat_short_entry_t* entry = fat_find_entry_with_path(ctx, dir_parent, entry_name, cluster_buffer); + fat_short_entry_t* entry_tmp = fat_find_entry_with_path(ctx, &dir_parent, entry_name, cluster_buffer); - if(entry == NULL){ - free(cluster_buffer); + if(entry_tmp == NULL){ + free(entry_name); return ENOENT; } /* Remove entry from the cluster_buffer */ - fat_short_entry_t entry_tmp = *entry; - entry = &entry_tmp; + fat_short_entry_t entry; + memcpy(&entry, entry_tmp, sizeof(fat_short_entry_t)); - fat_clear_entry_data(ctx, entry, cluster_buffer); + assert(!fat_remove_entry_with_path(ctx, &dir_parent, entry_name, cluster_buffer)); - assert(!fat_remove_entry_with_path(ctx, dir_parent, entry_name, cluster_buffer)); + fat_clear_entry_data(ctx, &entry, cluster_buffer); + free(entry_name); return 0; } @@ -895,7 +902,8 @@ static int fat_rename_entry_with_path(fat_context_t* ctx, fat_short_entry_t* old } /* Remove entry from the cluster_buffer */ - fat_short_entry_t entry_tmp = *entry; + fat_short_entry_t entry_tmp; + memcpy(&entry_tmp, entry, sizeof(fat_short_entry_t)); entry = &entry_tmp; char* new_entry_name = strrchr(new_path, '/'); @@ -965,11 +973,19 @@ static int fat_create_file(fat_context_t* ctx, const char* path, void* cluster_b int fat_remove_file(fat_context_t* ctx, const char* path){ void* cluster_buffer = malloc(ctx->cluster_size); - int err = fat_remove_and_clear_entry_with_path_from_root(ctx, path, cluster_buffer); + fat_short_entry_t* dir = fat_find_entry_with_path_from_root(ctx, path, cluster_buffer); - free(cluster_buffer); + if(!dir->attributes.directory){ + int err = fat_remove_and_clear_entry_with_path_from_root(ctx, path, cluster_buffer); - return err; + free(cluster_buffer); + + return err; + }else{ + free(cluster_buffer); + + return EISDIR; + } } fat_file_internal_t* fat_open_file(fat_context_t* ctx, const char* path, int flags, mode_t mode, int* error){ @@ -1135,25 +1151,31 @@ int fat_create_dir(fat_context_t* ctx, const char* path, mode_t mode){ int fat_remove_dir(fat_context_t* ctx, const char* path){ void* cluster_buffer = malloc(ctx->cluster_size); - fat_short_entry_t* dir = fat_find_entry_with_path_from_root(ctx, path, cluster_buffer); + fat_short_entry_t* dir_tmp = fat_find_entry_with_path_from_root(ctx, path, cluster_buffer); - /* Remove dir from the cluster_buffer */ - fat_short_entry_t dir_tmp = *dir; - dir = &dir_tmp; + if(dir_tmp->attributes.directory){ + /* Remove dir from the cluster_buffer */ + fat_short_entry_t dir; + memcpy(&dir, dir_tmp, sizeof(fat_short_entry_t)); - if(fat_get_cluster_entry(ctx, dir) == ctx->bpb->root_cluster_number){ - return EACCES; // can't delete root dir - }else{ - if(fat_get_dir_size(ctx, dir, cluster_buffer) > DIR_MINIMUM_SIZE){ - return ENOTEMPTY; + if(fat_get_cluster_entry(ctx, &dir) == ctx->bpb->root_cluster_number){ + return EACCES; // can't delete root dir + }else{ + if(fat_get_dir_size(ctx, &dir, cluster_buffer) > DIR_MINIMUM_SIZE * ENTRY_SIZE){ + return ENOTEMPTY; + } } - } - int err = fat_remove_and_clear_entry_with_path_from_root(ctx, path, cluster_buffer); + int err = fat_remove_and_clear_entry_with_path_from_root(ctx, path, cluster_buffer); - free(cluster_buffer); + free(cluster_buffer); - return err; + return err; + }else{ + free(cluster_buffer); + + return ENOTDIR; + } } fat_directory_internal_t* fat_open_dir(fat_context_t* ctx, const char* path, int* error){