summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
Diffstat (limited to 'avr')
-rw-r--r--avr/cmd_fat.c190
-rw-r--r--avr/strerror.c3
2 files changed, 150 insertions, 43 deletions
diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c
index c4d17b3..c97fd79 100644
--- a/avr/cmd_fat.c
+++ b/avr/cmd_fat.c
@@ -24,8 +24,9 @@ uint32_t fat_time(const struct tm * timeptr);
#include "getopt-min.h"
#define DEBUG_FA 0 /* set to 1 to debug */
-#define DEBUG_LS 1 /* set to 1 to debug */
+#define DEBUG_LS 0 /* set to 1 to debug */
#define DEBUG_RM 0 /* set to 1 to debug */
+#define DEBUG_CP 0 /* set to 1 to debug */
#define debug_fa(fmt, args...) \
debug_cond(DEBUG_FA, fmt, ##args)
@@ -33,12 +34,15 @@ uint32_t fat_time(const struct tm * timeptr);
debug_cond(DEBUG_LS, fmt, ##args)
#define debug_rm(fmt, args...) \
debug_cond(DEBUG_RM, fmt, ##args)
+#define debug_cp(fmt, args...) \
+ debug_cond(DEBUG_CP, fmt, ##args)
/* TODO: use memory size test function (z80_memsize_detect() ) */
-#define MAX_MEMORY CONFIG_SYS_RAMSIZE_MAX
-#define BUFFER_SIZE FF_MAX_SS
-#define PATH_MAX CONFIG_SYS_MAX_PATHLEN
+#define MAX_MEMORY CONFIG_SYS_RAMSIZE_MAX
+#define BUFFER_SIZE FF_MAX_SS
+#define CPY_BUF_SIZE (2*FF_MAX_SS)
+#define PATH_MAX CONFIG_SYS_MAX_PATHLEN
/*
@@ -293,8 +297,10 @@ command_ret_t do_ls(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc,
return CMD_RET_SUCCESS;
}
-typedef FRESULT (*fatfunc_t)(const TCHAR* path_old, const TCHAR* path_new);
+typedef void (*fatfunc_t)(const TCHAR* path_old, const TCHAR* path_new);
+
+command_ret_t exit_val;
uint8_t cmd_flags;
#define I_FLAG (1<<1) // prompt before overwrite (overrides a previous -n option)
#define N_FLAG (1<<2) // do not overwrite an existing file (overrides a previous -i option)
@@ -316,7 +322,57 @@ char* splitpath(const char* path)
return NULL;
}
-FRESULT ff_remove(const TCHAR *file, const TCHAR *dest UNUSED)
+/*
+ * Copy File
+*/
+FRESULT copy_file(const TCHAR* src, const TCHAR* dst)
+{
+ FIL fsrc, fdst;
+ FRESULT res;
+
+ /* File copy buffer */
+ uint8_t *buffer = (uint8_t *) malloc(CPY_BUF_SIZE);
+ if (buffer == NULL) {
+ res = (FRESULT) ENOMEM;
+ } else {
+
+ /* Open source file */
+ res = f_open(&fsrc, src, FA_READ);
+ if (res == FR_OK) {
+
+ /* Create destination file */
+ res = f_open(&fdst, dst, FA_WRITE | FA_CREATE_NEW);
+ if (res == FR_OK) {
+ UINT br, bw; /* File read/write count */
+
+ /* Copy source to destination */
+ for (;;) {
+ res = f_read(&fsrc, buffer, CPY_BUF_SIZE, &br); /* Read a chunk of source file */
+ if (res || br == 0)
+ break; /* error or eof */
+ res = f_write(&fdst, buffer, br, &bw); /* Write it to the destination file */
+ if (res != FR_OK)
+ break;
+ if (bw < br) {
+ res = (FRESULT) EFULL; /* disk full */
+ break;
+ }
+ }
+
+debug_cp("==== copy() res: %d, br: %d, bw: %d\n", res, br, bw);
+ f_close(&fdst);
+ if (res != FR_OK)
+ f_unlink(dst);
+ }
+ f_close(&fsrc);
+ }
+ free(buffer);
+ }
+
+ return res;
+}
+
+void ff_remove(const TCHAR *file, const TCHAR *dest UNUSED)
{
FRESULT res = FR_OK;
@@ -325,15 +381,31 @@ FRESULT ff_remove(const TCHAR *file, const TCHAR *dest UNUSED)
if (!(cmd_flags & N_FLAG)) {
if ((res = f_unlink(file)) == FR_OK) {
if (cmd_flags & V_FLAG)
- printf_P(PSTR("removed '%s'\n"), file);
+ printf_P(PSTR("removed: '%s'\n"), file);
} else {
cmd_error(0, res, PSTR("cannot remove '%s'"), file);
}
} else {
- printf_P(PSTR("not removed '%s'\n"), file);
+ printf_P(PSTR("not removed: '%s'\n"), file);
}
- return res;
+ exit_val = (res != FR_OK);
+ return;
+}
+
+void ff_copy(const TCHAR* path_old, const TCHAR* path_new)
+{
+ FRESULT res;
+
+ debug_cp("==== ff_copy: '%s' --> '%s'\n", path_old, path_new);
+
+ if (cmd_flags & V_FLAG)
+ printf_P(PSTR("'%s' -> '%s'\n"), path_old, path_new);
+ if ((res = copy_file(path_old, path_new)) != FR_OK)
+ cmd_error(0, res, PSTR("error copying '%s' to '%s'"), path_old, path_new);
+
+ exit_val = (res != FR_OK);
+ return;
}
void ff_iterate(fatfunc_t fatfunc, int count, char* const file[], char* dest)
@@ -353,9 +425,6 @@ void ff_iterate(fatfunc_t fatfunc, int count, char* const file[], char* dest)
pattern = (char *) malloc(strlen(p1)+1);
strcpy(pattern, p1);
}
-
- debug_rm("### iter1 srcpath, pattern: '%s', '%s'\n", srcpath, pattern ? pattern : "<NULL>");
-
if (pattern != NULL) {
res = f_findfirst(&dir, &finfo, srcpath, pattern);
p1 = srcpath+strlen(srcpath)-1;
@@ -365,39 +434,36 @@ void ff_iterate(fatfunc_t fatfunc, int count, char* const file[], char* dest)
res = f_findfirst(&dir, &finfo, ".", file[i]);
p1 = srcpath;
}
- if (finfo.fname[0] == 0)
- cmd_error(0, res, PSTR("cannot remove '%s': no such file or directory"), file[i]);
-
-
- while (res == FR_OK && finfo.fname[0] != 0) {
- strcpy(p1, finfo.fname);
-
- debug_rm("### iter3 srcpath: '%s'\n", srcpath);
-
- if (dest != NULL) {
- strcpy(destpath, dest);
- if (dest_is_dir) {
- strcat_P(destpath, PSTR("/"));
- strcat(destpath, finfo.fname);
- }
- }
- fatfunc(srcpath, destpath);
- res = f_findnext(&dir, &finfo);
- debug_rm("### iter4 res, .fname: %d, '%s'\n", res, finfo.fname);
+ if ((res != FR_OK) || (finfo.fname[0] == 0)) {
+ cmd_error(0, res, PSTR("'%s': no such file or directory"), file[i]);
+ exit_val = CMD_RET_FAILURE;
+ } else {
- }
- res = f_closedir(&dir);
+ while (res == FR_OK && finfo.fname[0] != 0) {
+ strcpy(p1, finfo.fname);
+ if (dest != NULL) {
+ strcpy(destpath, dest);
+ if (dest_is_dir) {
+ strcat_P(destpath, PSTR("/"));
+ strcat(destpath, finfo.fname);
+ }
+ }
+ fatfunc(srcpath, destpath);
+ res = f_findnext(&dir, &finfo);
+ }
+ if (res != FR_OK)
+ cmd_error(CMD_RET_FAILURE, res, PSTR("error enumerating files"));
+ }
+ f_closedir(&dir);
free(pattern);
}
- if (res != FR_OK)
- cmd_error(CMD_RET_FAILURE, res, PSTR("error enumerating files"));
- //printf_P(PSTR("error enumerating files: %S\n"), ffw_error(res));
}
command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
{
-
+ exit_val = CMD_RET_SUCCESS;
cmd_flags = 0;
+
int opt;
while ((opt = getopt(argc, argv, PSTR("nv"))) != -1) {
switch (opt) {
@@ -422,7 +488,36 @@ command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc,
ff_iterate(ff_remove, argc, argv, NULL);
- return CMD_RET_SUCCESS;
+ return exit_val;
+}
+
+command_ret_t do_cp(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
+{
+ exit_val = CMD_RET_SUCCESS;
+ cmd_flags = 0;
+
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("v"))) != -1) {
+ switch (opt) {
+ case 'v':
+ cmd_flags |= V_FLAG;
+ break;
+ default:
+ return CMD_RET_USAGE;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ debug_cp("==== do_rm: argc, argv[0]: %d, '%s'\n", argc, argv[0]);
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ ff_iterate(ff_copy, argc - 1, argv, argv[argc - 1]);
+
+ return exit_val;
}
/*
@@ -749,13 +844,24 @@ CMD_TBL_ITEM(
),
CMD_TBL_ITEM(
rm, CONFIG_SYS_MAXARGS, 0, do_rm,
- "Remove FILE(s)",
+ "Remove FILE(s) or empty DIRECTORY(ies)",
"[OPTION]... [FILE]...\n"
//" -i prompt before removal\n"
- " -v explain what is being done\n"
- "\n"
- "rm removes directories, if they are empty."
+ " -n do not remove\n"
+ " -v explain what is being done"
+),
+CMD_TBL_ITEM(
+ cp, CONFIG_SYS_MAXARGS, 0, do_cp,
+ "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.",
+ "[OPTION]... SOURCE... DEST\n"
+// " -f overwrite existing file ignoring write protection\n"
+// " this option is ignored when the -n option is also used\n"
+// " -i prompt before overwrite (overrides a previous -n option)\n"
+// " -n do not overwrite an existing file (overrides a previous -i option)\n"
+// " -p preserve attributes and timestamps\n"
+ " -v explain what is being done"
),
+
CMD_TBL_ITEM(
load, 5, 0, do_rw,
"load binary file from a dos filesystem",
diff --git a/avr/strerror.c b/avr/strerror.c
index 199504a..f5850f7 100644
--- a/avr/strerror.c
+++ b/avr/strerror.c
@@ -10,7 +10,7 @@
static const FLASH char * const FLASH error_strings[] = {
FSTR("Unknown error"),
- FSTR("Not enough memory"), /* 101 */
+ FSTR("Not enough memory"), /* 101 */
FSTR("Interrupt"), /* 102 */
FSTR("Bus timeout"), /* 103 */
FSTR("Unexpected argument"), /* 104 */
@@ -22,6 +22,7 @@ static const FLASH char * const FLASH error_strings[] = {
FSTR("CPU is running"), /* 110 */
FSTR("Invalid argument"), /* 111 */
FSTR("Unexpected EOF"), /* 112 */
+ FSTR("Disk full"), /* 113 */
};