[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/lib/fs/shell.c b/src/bsp/lk/lib/fs/shell.c
new file mode 100644
index 0000000..1dbd6de
--- /dev/null
+++ b/src/bsp/lk/lib/fs/shell.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <err.h>
+#include <debug.h>
+#include <string.h>
+#include <stdio.h>
+#include <trace.h>
+#include <stdlib.h>
+#include <platform.h>
+#include <lib/console.h>
+#include <lib/fs.h>
+
+/* shell console hooks for manipulating the file system */
+
+#if WITH_LIB_CONSOLE
+
+static char *cwd = NULL;
+
+static void set_cwd(const char *path)
+{
+    if (!path) {
+        free(cwd);
+        cwd = NULL;
+        return;
+    }
+
+    size_t len = strlen(path) + 1;
+    char *new_cwd = realloc(cwd, len);
+    if (new_cwd) {
+        cwd = new_cwd;
+        memcpy(cwd, path, len);
+    }
+}
+
+static const char *get_cwd(void)
+{
+    if (!cwd)
+        return "/";
+    return cwd;
+}
+
+static char *prepend_cwd(char *path, size_t len, const char *arg)
+{
+    path[0] = '\0';
+
+    if (!arg || arg[0] != '/') {
+        strlcat(path, get_cwd(), len);
+        if (arg && path[strlen(path) - 1] != '/')
+            strlcat(path, "/", len);
+    }
+    if (arg) {
+        strlcat(path, arg, len);
+    }
+
+    return path;
+}
+
+static int cmd_ls(int argc, const cmd_args *argv)
+{
+    status_t status = NO_ERROR;
+
+    // construct the path
+    char *path = malloc(FS_MAX_PATH_LEN);
+    prepend_cwd(path, FS_MAX_PATH_LEN, (argc >= 2) ? argv[1].str : NULL);
+
+    dirhandle *dhandle;
+    status = fs_open_dir(path, &dhandle);
+    if (status < 0) {
+        printf("error %d opening dir '%s'\n", status, path);
+        goto err;
+    }
+
+    size_t pathlen = strlen(path);
+
+    status_t err;
+    struct dirent ent;
+    while ((err = fs_read_dir(dhandle, &ent)) >= 0) {
+        struct file_stat stat;
+        filehandle *handle;
+
+        // append our filename to the path
+        strlcat(path, "/", FS_MAX_PATH_LEN);
+        strlcat(path, ent.name, FS_MAX_PATH_LEN);
+
+        err = fs_open_file(path, &handle);
+
+        // restore the old path
+        path[pathlen] = '\0';
+
+        if (err < 0) {
+            printf("error %d opening file '%s'\n", err, path);
+            continue;
+        }
+
+        // stat the file
+        err = fs_stat_file(handle, &stat);
+        fs_close_file(handle);
+        if (err < 0) {
+            printf("error %d statting file\n", err);
+            continue;
+        }
+
+        printf("%c %16llu %s\n", stat.is_dir ? 'd' : ' ', stat.size, ent.name);
+    }
+
+    fs_close_dir(dhandle);
+
+err:
+    free(path);
+    return status;;
+}
+
+static int cmd_cd(int argc, const cmd_args *argv)
+{
+    if (argc < 2) {
+        set_cwd(NULL);
+    } else {
+        char *path = malloc(FS_MAX_PATH_LEN);
+        prepend_cwd(path, FS_MAX_PATH_LEN, (argc >= 2) ? argv[1].str : NULL);
+        fs_normalize_path(path);
+
+        if (strlen(path) == 0) {
+            set_cwd(NULL);
+        } else {
+            set_cwd(path);
+        }
+        free(path);
+    }
+    puts(get_cwd());
+
+    return 0;
+}
+
+static int cmd_pwd(int argc, const cmd_args *argv)
+{
+    puts(get_cwd());
+
+    return 0;
+}
+
+static int cmd_mkdir(int argc, const cmd_args *argv)
+{
+    if (argc < 2) {
+        printf("not enough arguments\n");
+        printf("usage: %s <path>\n", argv[0].str);
+        return -1;
+    }
+
+    char *path = malloc(FS_MAX_PATH_LEN);
+
+    int status = fs_make_dir(prepend_cwd(path, FS_MAX_PATH_LEN, argv[1].str));
+    if (status < 0) {
+        printf("error %d making directory '%s'\n", status, path);
+    }
+
+    free(path);
+    return status;
+}
+
+static int cmd_mkfile(int argc, const cmd_args *argv)
+{
+    if (argc < 2) {
+        printf("not enough arguments\n");
+        printf("usage: %s <path> [length]\n", argv[0].str);
+        return -1;
+    }
+
+    char *path = malloc(FS_MAX_PATH_LEN);
+    prepend_cwd(path, FS_MAX_PATH_LEN, argv[1].str);
+
+    filehandle *handle;
+    status_t status = fs_create_file(path, &handle, (argc >= 2) ? argv[2].u : 0);
+    if (status < 0) {
+        printf("error %d making file '%s'\n", status, path);
+        goto err;
+    }
+
+    fs_close_file(handle);
+
+err:
+    free(path);
+    return status;
+}
+
+static int cmd_rm(int argc, const cmd_args *argv)
+{
+    if (argc < 2) {
+        printf("not enough arguments\n");
+        printf("usage: %s <path>\n", argv[0].str);
+        return -1;
+    }
+
+    char *path = malloc(FS_MAX_PATH_LEN);
+    prepend_cwd(path, FS_MAX_PATH_LEN, argv[1].str);
+
+    status_t err = fs_remove_file(path);
+    if (err < 0) {
+        printf("error %d removing file '%s'\n", err, path);
+        return err;
+    }
+
+    return 0;
+}
+
+static int cmd_stat(int argc, const cmd_args *argv)
+{
+    if (argc < 2) {
+        printf("not enough arguments\n");
+        printf("usage: %s <path>\n", argv[0].str);
+        return -1;
+    }
+
+    int status;
+    struct file_stat stat;
+    filehandle *handle;
+
+    char *path = malloc(FS_MAX_PATH_LEN);
+    prepend_cwd(path, FS_MAX_PATH_LEN, argv[1].str);
+
+    status = fs_open_file(path, &handle);
+    if (status < 0) {
+        printf("error %d opening file '%s'\n", status, path);
+        goto err;
+    }
+
+    status = fs_stat_file(handle, &stat);
+
+    fs_close_file(handle);
+
+    if (status < 0) {
+        printf("error %d statting file\n", status);
+        goto err;
+    }
+
+    printf("stat successful:\n");
+    printf("\tis_dir: %d\n", stat.is_dir ? 1 : 0);
+    printf("\tsize: %lld\n", stat.size);
+
+
+err:
+    free(path);
+    return status;
+}
+
+static int cmd_cat(int argc, const cmd_args *argv)
+{
+    status_t status = NO_ERROR;
+
+    if (argc < 2) {
+        printf("not enough arguments\n");
+        printf("usage: %s <path>\n", argv[0].str);
+        return -1;
+    }
+
+    char *path = malloc(FS_MAX_PATH_LEN);
+    prepend_cwd(path, FS_MAX_PATH_LEN, argv[1].str);
+
+    filehandle *handle;
+    status = fs_open_file(path, &handle);
+    if (status < 0) {
+        printf("error %d opening file '%s'\n", status, path);
+        goto err;
+    }
+
+    char buf[64];
+    ssize_t read_len;
+    off_t offset = 0;
+    while ((read_len = fs_read_file(handle, buf, offset, sizeof(buf))) > 0) {
+        for (int i = 0; i < read_len; i++) {
+            putchar(buf[i]);
+        }
+
+        offset += read_len;
+    }
+
+    fs_close_file(handle);
+
+err:
+    free(path);
+    return status;
+}
+
+STATIC_COMMAND_START
+STATIC_COMMAND("ls", "dir listing", &cmd_ls)
+STATIC_COMMAND("cd", "change dir", &cmd_cd)
+STATIC_COMMAND("pwd", "print working dir", &cmd_pwd)
+STATIC_COMMAND("mkdir", "make dir", &cmd_mkdir)
+STATIC_COMMAND("mkfile", "make file", &cmd_mkfile)
+STATIC_COMMAND("rm", "remove file", &cmd_rm)
+STATIC_COMMAND("stat", "stat file", &cmd_stat)
+STATIC_COMMAND("cat", "cat file", &cmd_cat)
+STATIC_COMMAND_END(fs_shell);
+
+#endif
+