summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
Diffstat (limited to 'avr')
-rw-r--r--avr/cmd_fat.c165
1 files changed, 164 insertions, 1 deletions
diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c
index 063ebfb..c4d17b3 100644
--- a/avr/cmd_fat.c
+++ b/avr/cmd_fat.c
@@ -21,10 +21,11 @@ uint32_t fat_time(const struct tm * timeptr);
#include "timer.h"
#include "debug.h"
#include "env.h"
+#include "getopt-min.h"
#define DEBUG_FA 0 /* set to 1 to debug */
#define DEBUG_LS 1 /* set to 1 to debug */
-#define DEBUG_RM 1 /* set to 1 to debug */
+#define DEBUG_RM 0 /* set to 1 to debug */
#define debug_fa(fmt, args...) \
debug_cond(DEBUG_FA, fmt, ##args)
@@ -202,6 +203,23 @@ char *path_split(char *p)
return ps;
}
+command_ret_t do_mkdir(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
+{
+ int ret = CMD_RET_SUCCESS;
+ FRESULT res;
+
+ if (argc < 1)
+ return CMD_RET_USAGE;
+
+ for (uint8_t i = 1; i < argc; i++) {
+ if ((res = f_mkdir(argv[i])) != FR_OK) {
+ ret = CMD_RET_FAILURE;
+ cmd_error(0, res, PSTR("cannot create directory '%s'"), argv[i]);
+ }
+ }
+ return ret;
+}
+
/*
* ls path - Directory listing
*
@@ -275,6 +293,137 @@ 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);
+
+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)
+#define F_FLAG (1<<3) // overwrite existing file ignoring write protection
+#define P_FLAG (1<<4) // preserve attributes and timestamps
+#define V_FLAG (1<<5) // explain what is being done
+
+char* splitpath(const char* path)
+{
+ char* fs = strrchr(path, '/');
+ char* bs = strrchr(path, '\\');
+ if (fs > bs) {
+ *fs = '\0';
+ return fs + 1;
+ } else if (bs != NULL) {
+ *bs = '\0';
+ return bs + 1;
+ }
+ return NULL;
+}
+
+FRESULT ff_remove(const TCHAR *file, const TCHAR *dest UNUSED)
+{
+ FRESULT res = FR_OK;
+
+ debug_rm("==== ff_remove: '%s'\n", file);
+
+ if (!(cmd_flags & N_FLAG)) {
+ if ((res = f_unlink(file)) == FR_OK) {
+ if (cmd_flags & V_FLAG)
+ 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);
+ }
+
+ return res;
+}
+
+void ff_iterate(fatfunc_t fatfunc, int count, char* const file[], char* dest)
+{
+ FRESULT res = 0;
+ DIR dir;
+ FILINFO finfo;
+ char srcpath[PATH_MAX], destpath[PATH_MAX];
+
+ uint8_t dest_is_dir = dest != NULL && f_stat(dest, &finfo) == FR_OK && finfo.fattrib & AM_DIR;
+ for (uint8_t i = 0; i < count; i++) {
+ char* pattern = NULL;
+ strcpy(srcpath, file[i]);
+ char* p1 = path_split(srcpath);
+
+ if (p1 != NULL) {
+ 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;
+ if (*p1++ != '/')
+ *(p1++) = '/';
+ } else {
+ 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);
+
+ }
+ res = 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[])
+{
+
+ cmd_flags = 0;
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("nv"))) != -1) {
+ switch (opt) {
+ case 'n':
+ cmd_flags |= N_FLAG;
+ break;
+ case 'v':
+ cmd_flags |= V_FLAG;
+ break;
+ default:
+ return CMD_RET_USAGE;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ debug_rm("==== do_rm: argc, argv[0]: %d, '%s'\n", argc, argv[0]);
+
+ if (argc < 1)
+ return CMD_RET_USAGE;
+
+ ff_iterate(ff_remove, argc, argv, NULL);
+
+ return CMD_RET_SUCCESS;
+}
/*
* tst path - for debugging: test access with different functions
@@ -584,6 +733,11 @@ CMD_TBL_ITEM(
"path"
),
CMD_TBL_ITEM(
+ mkdir, CONFIG_SYS_MAXARGS, 0, do_mkdir,
+ "Create the DIRECTORY(ies), if they do not already exist.",
+ "DIRECTORY..."
+),
+CMD_TBL_ITEM(
ls, 2, CTBL_RPT|CTBL_SUBCMDAUTO, do_ls,
"Directory listing",
"path"
@@ -594,6 +748,15 @@ CMD_TBL_ITEM(
"[path [pattern]]"
),
CMD_TBL_ITEM(
+ rm, CONFIG_SYS_MAXARGS, 0, do_rm,
+ "Remove FILE(s)",
+ "[OPTION]... [FILE]...\n"
+ //" -i prompt before removal\n"
+ " -v explain what is being done\n"
+ "\n"
+ "rm removes directories, if they are empty."
+),
+CMD_TBL_ITEM(
load, 5, 0, do_rw,
"load binary file from a dos filesystem",
"<d:/path/filename> <addr> [bytes [pos]]\n"