+/*
+ * pwd - Print current directory of the current drive.
+ *
+ */
+command_ret_t do_pwd(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
+{
+ FRESULT res;
+ TCHAR buf[PATH_MAX];
+
+ res = f_getcwd(buf, PATH_MAX); /* Get current directory path */
+
+ if (res != FR_OK)
+ cmd_error(CMD_RET_FAILURE, res, NULL);
+
+ puts(buf);
+
+ return CMD_RET_SUCCESS;
+}
+
+
+/*
+ * cd - Change the current/working directory.
+ *
+ */
+command_ret_t do_cd(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
+{
+ TCHAR *path;
+ FRESULT res = FR_OK;
+
+ if (argc < 2) {
+ path = getenv_str(PSTR(ENV_HOME));
+ if (path == NULL) {
+ cmd_error(CMD_RET_FAILURE, 0, PSTR("\"%S\" not set"), PSTR(ENV_HOME));
+ }
+ } else
+ path = argv[1];
+
+ if (strlen(path) > 1 && path[1] == ':')
+ res = f_chdrive(path);
+
+ if (res == FR_OK)
+ res = f_chdir(path);
+
+ if (res != FR_OK)
+ cmd_error(CMD_RET_FAILURE, res, NULL);
+
+ return CMD_RET_SUCCESS;
+}
+
+
+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
+ *
+ */
+command_ret_t do_ls(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
+{
+ FATFS *fs;
+ DIR dir; /* Directory object */
+ FILINFO finfo;
+ unsigned long p1;
+ unsigned int s1, s2;
+ FRESULT res = FR_OK;
+ char buf[PATH_MAX];
+ char *path = buf;
+ char *pattern;
+
+
+ memset(buf, 0, PATH_MAX);
+ if (argc < 2) {
+ buf[0] = '.';
+ } else {
+ strncpy(path, argv[1], PATH_MAX-1);
+ }
+ pattern = path_split(path);
+ debug_ls("### path, pattern: '%s', '%s'\n", path[0] ? path : "<NULL>", pattern ? pattern : "<NULL>");
+
+ if (pattern == NULL) {
+ res = f_opendir(&dir, path);
+ if (res == FR_NO_PATH || res == FR_INVALID_NAME) {
+ pattern = path;
+ path = ".";
+ } else if (res != FR_OK) {
+ cmd_error(CMD_RET_FAILURE, res, PSTR("'%s'"), path);
+ }
+ }
+ debug_ls("### path, pattern: '%s', '%s'\n", path, pattern ? pattern : "<NULL>");
+
+ if (pattern == NULL || *pattern == '\0')
+ pattern = "*";
+
+ debug_ls("### path, pattern: '%s', '%s'\n", path, pattern ? pattern : "<NULL>");
+
+ res = f_findfirst(&dir, &finfo, path, pattern);
+
+ p1 = s1 = s2 = 0;
+ for(;;) {
+ if (res != FR_OK)
+ cmd_error(CMD_RET_FAILURE, res, NULL);
+ if (!finfo.fname[0])
+ break;
+ if (finfo.fattrib & AM_DIR) {
+ s2++;
+ } else {
+ s1++; p1 += finfo.fsize;
+ }
+ print_dirent(&finfo);
+ if (check_abort())
+ break;
+ res = f_findnext(&dir, &finfo);
+ }
+
+ if (res == FR_OK) {
+ printf_P(PSTR("%4u File(s),%10lu bytes total\n%4u Dir(s)"), s1, p1, s2);
+ if (f_getfree(path, (DWORD*)&p1, &fs) == FR_OK)
+ printf_P(PSTR(", %10luK bytes free\n"), p1 * fs->csize / 2);
+ }
+
+ if (res)
+ cmd_error(CMD_RET_FAILURE, res, NULL);
+
+ return CMD_RET_SUCCESS;
+}
+