From 2fefa213c4e309992f43da3abb2b8a9bbf505faf Mon Sep 17 00:00:00 2001 From: Jesus Garcia Date: Mon, 22 Nov 2021 11:12:27 -0500 Subject: [PATCH] Added Copy Command --- src/cli/cli.c | 3 +- src/cli/dos_cmds.c | 83 ++++++++++++++++++++++++++++++++++++++++++ src/cli/dos_cmds.h | 5 +++ src/dev/fsys.c | 2 +- src/include/syscalls.h | 4 +- 5 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/cli/cli.c b/src/cli/cli.c index c59d33c..afd9239 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -56,7 +56,8 @@ const t_cli_command g_cli_commands[] = { { "HELP", "HELP : print this helpful message", cmd_help }, { "CD", "CD : sets the current directory", cmd_cd }, { "CLS", "CLS : clear the screen", cmd_cls }, - { "DASM", "DASM [] : print a memory disassembly", mem_cmd_dasm}, + { "COPY", "COPY : Copies files to destination", cmd_copy }, + { "DASM", "DASM [] : print a memory disassembly", mem_cmd_dasm }, { "DEL", "DEL : delete a file or directory", cmd_del }, { "DIR", "DIR : print directory listing", cmd_dir }, { "DISKFILL", "DISKFILL ", cmd_diskfill }, diff --git a/src/cli/dos_cmds.c b/src/cli/dos_cmds.c index f04aa9e..09860b5 100644 --- a/src/cli/dos_cmds.c +++ b/src/cli/dos_cmds.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "syscalls.h" @@ -142,6 +143,88 @@ short cmd_del(short screen, int argc, char * argv[]) { } } +short cmd_copy(short screen, int argc, char * argv[]) { + FRESULT find_result; + FRESULT result; + DIR dir; /* Directory object */ + FILINFO src_info; /* File information */ + FILINFO dst_info; + FIL src_file; + FIL dst_file; + + BYTE buffer[4096]; /* File copy buffer */ + UINT br, bw; /* File read/write count */ + + char path[MAX_PATH_LEN]; + + bool is_directory = false; + bool is_append_file = false; + + TRACE("cmd_copy"); + + if (argc > 2) { + strcpy(path, argv[2]); + + result = f_stat(argv[2], &dst_info); + if (result == FR_OK) { + is_directory = dst_info.fattrib & AM_DIR; + } else if (result == FR_NO_FILE) { + is_directory = false; + } else { + goto error; + } + + find_result = f_findfirst(&dir, &src_info, "", argv[1]); + + while (find_result == FR_OK && src_info.fname[0]) { + if (strcmp(src_info.fname, path) == 0) goto skip; // Skip copying file to self. + + result = f_open(&src_file, src_info.fname, FA_READ); + if (result != FR_OK) goto error; + + if (is_directory) { + sprintf(path, "%s/%s", dst_info.fname, src_info.fname); + result = f_open(&dst_file, path, FA_WRITE | FA_CREATE_ALWAYS); + } else if (is_append_file) { + result = f_open(&dst_file, path, FA_WRITE | FA_OPEN_APPEND); + } else { + result = f_open(&dst_file, path, FA_WRITE | FA_CREATE_ALWAYS); + } + if (result != FR_OK) goto error; + + print(screen, (is_append_file) ? "Appending " : "Copying "); + print(screen, src_info.fname); + print(screen, " to "); + print(screen, path); + print(screen, "\n"); + + /* Copy source to destination */ + for (;;) { + result = f_read(&src_file, buffer, sizeof buffer, &br); /* Read a chunk of data from the source file */ + if (br == 0) break; /* error or eof */ + result = f_write(&dst_file, buffer, br, &bw); /* Write it to the destination file */ + if (bw < br) break; /* error or disk full */ + } + + f_close(&src_file); + f_close(&dst_file); + +skip: + find_result = f_findnext(&dir, &src_info); + is_append_file = true; // If copying more than one file to a file, then open for append. + } + f_closedir(&dir); + return 0; + +error: + err_print(screen, "Unable to copy file(s)", result); + f_close(&src_file); + f_close(&dst_file); + return result; + } +} + + /* * Change the directory */ diff --git a/src/cli/dos_cmds.h b/src/cli/dos_cmds.h index 4dafecd..d701294 100644 --- a/src/cli/dos_cmds.h +++ b/src/cli/dos_cmds.h @@ -25,6 +25,11 @@ extern short cmd_mkdir(short screen, int argc, char * argv[]); */ extern short cmd_del(short screen, int argc, char * argv[]); +/* + * Copies file(s) to destination + */ +extern short cmd_copy(short screen, int argc, char * argv[]); + /* * Set the current working directory */ diff --git a/src/dev/fsys.c b/src/dev/fsys.c index 0fb24ec..16d9763 100644 --- a/src/dev/fsys.c +++ b/src/dev/fsys.c @@ -456,7 +456,7 @@ short fsys_set_cwd(const char * path) { short fsys_get_cwd(char * path, short size) { FRESULT result; - result = f_getcwd(path); + result = f_getcwd(path, size); if (result == FR_OK) { return 0; } else { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index d2bd79f..b6e47cb 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -572,7 +572,7 @@ extern short sys_fsys_rename(const char * old_path, const char * new_path); * Returns: * 0 on success, negative number on failure. */ -extern short sys_fsys_setcwd(const char * path); +extern short sys_fsys_set_cwd(const char * path); /** * Get the current working drive and directory @@ -584,7 +584,7 @@ extern short sys_fsys_setcwd(const char * path); * Returns: * 0 on success, negative number on failure. */ -extern short sys_fsys_getcwd(char * path, short size); +extern short sys_fsys_get_cwd(char * path, short size); /* * Load a file into memory at the designated destination address.