You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
404 lines
7.4 KiB
404 lines
7.4 KiB
#include <ctype.h>
|
|
#include <inttypes.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <console.h>
|
|
#include <flash.h>
|
|
#include <ftl.h>
|
|
#include <macros.h>
|
|
#include <mufs.h>
|
|
#include <shell.h>
|
|
|
|
#include <shell/mufs.h>
|
|
#include <shell/progress.h>
|
|
|
|
extern struct flash_dev *flash;
|
|
struct mufs *mufs = NULL;
|
|
|
|
int shell_mount(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
if (!flash) {
|
|
fprintf(con->fp, "error: no flash device probed.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs) {
|
|
mufs_unmount(mufs);
|
|
mufs = NULL;
|
|
}
|
|
|
|
if (!(mufs = mufs_mount(flash))) {
|
|
fprintf(con->fp, "error: unable to mount the filesystem.\n");
|
|
return -1;
|
|
}
|
|
|
|
flash = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_unmount(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "no mufs filesystem currently active\n");
|
|
return -1;
|
|
}
|
|
|
|
if (flash)
|
|
flash_release(flash);
|
|
|
|
flash = mufs->dev;
|
|
mufs->dev = NULL;
|
|
|
|
mufs_unmount(mufs);
|
|
mufs = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_format(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
if (!flash) {
|
|
fprintf(con->fp, "error: no flash device probed.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs_format(flash) < 0) {
|
|
fprintf(con->fp, "error: unable to format the flash device.\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_mkdir(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
if (argc < 1) {
|
|
fprintf(con->fp, "usage: mufs mkdir <path>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs_mkdir(mufs, argv[0]) < 0) {
|
|
fprintf(con->fp, "error: unable to create the directory\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_rmdir(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
if (argc < 1) {
|
|
fprintf(con->fp, "usage: mufs rmdir <path>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs_rmdir(mufs, argv[0]) < 0) {
|
|
fprintf(con->fp, "error: unable to remove the directory\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_stat(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
struct mufs_stat stat;
|
|
|
|
if (argc < 1) {
|
|
fprintf(con->fp, "usage: mufs stat <path>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs_stat(mufs, argv[0], &stat) < 0) {
|
|
fprintf(con->fp, "error: unable to stat the file\n");
|
|
return -1;
|
|
}
|
|
|
|
switch (stat.type) {
|
|
case MUFS_DIR: fprintf(con->fp, " type: directory\n"); break;
|
|
case MUFS_FILE: fprintf(con->fp, " type: file\n"); break;
|
|
default: return -1;
|
|
}
|
|
|
|
fprintf(con->fp, " file size: %" PRIu32 " bytes\n", stat.file_size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_cat(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
char data[256];
|
|
struct mufs_file *file;
|
|
size_t ret;
|
|
|
|
if (argc < 1) {
|
|
fprintf(con->fp, "usage: mufs cat <path>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!(file = mufs_open(mufs, argv[0], MUFS_READ))) {
|
|
fprintf(con->fp, "error: unable to open the file\n");
|
|
return -1;
|
|
}
|
|
|
|
while ((ret = mufs_read(file, data, sizeof data)) != 0) {
|
|
fwrite(data, sizeof *data, ret, con->fp);
|
|
}
|
|
|
|
mufs_close(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_write(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
char data[256];
|
|
struct mufs_file *file;
|
|
ssize_t ret;
|
|
|
|
if (argc < 1) {
|
|
fprintf(con->fp, "usage: mufs write <path>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!(file = mufs_open(mufs, argv[0], MUFS_WRITE))) {
|
|
fprintf(con->fp, "error: unable to open the file\n");
|
|
return -1;
|
|
}
|
|
|
|
if ((ret = console_read(con, data, sizeof data)) > 0)
|
|
mufs_write(file, data, ret);
|
|
|
|
mufs_close(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_append(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
char data[256];
|
|
struct mufs_file *file;
|
|
ssize_t ret;
|
|
|
|
if (argc < 1) {
|
|
fprintf(con->fp, "usage: mufs append <path>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!(file = mufs_open(mufs, argv[0], MUFS_WRITE | MUFS_APPEND))) {
|
|
fprintf(con->fp, "error: unable to open the file\n");
|
|
return -1;
|
|
}
|
|
|
|
if ((ret = console_read(con, data, sizeof data)) > 0)
|
|
mufs_write(file, data, ret);
|
|
|
|
mufs_close(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_mv(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
fprintf(con->fp, "usage: mufs mv <old> <new>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs_rename(mufs, argv[0], argv[1]) < 0) {
|
|
fprintf(con->fp, "error: unable to move the file\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_cp(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
struct mufs_stat stat;
|
|
struct mufs_file *in, *out;
|
|
char data[256];
|
|
size_t ret;
|
|
size_t count = 0;
|
|
size_t total;
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (argc < 2) {
|
|
fprintf(con->fp, "usage: mufs cp <src> <dst>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs_stat(mufs, argv[0], &stat) < 0) {
|
|
fprintf(con->fp, "error: unable to stat the file\n");
|
|
return -1;
|
|
}
|
|
|
|
if (stat.type != MUFS_FILE) {
|
|
fprintf(con->fp, "error: only able to copy files\n");
|
|
return -1;
|
|
}
|
|
|
|
total = stat.file_size;
|
|
|
|
if (!(in = mufs_open(mufs, argv[0], MUFS_READ))) {
|
|
fprintf(con->fp, "error: unable to open the file\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!(out = mufs_open(mufs, argv[1], MUFS_WRITE))) {
|
|
fprintf(con->fp, "error: unable to open the file\n");
|
|
goto err_close_in;
|
|
}
|
|
|
|
draw_progress(con->fp, count, total);
|
|
|
|
while (count < total) {
|
|
ret = mufs_read(in, data, sizeof data);
|
|
|
|
if (ret == 0)
|
|
break;
|
|
|
|
ret = mufs_write(out, data, ret);
|
|
|
|
if (ret == 0)
|
|
break;
|
|
|
|
count += ret;
|
|
draw_progress(con->fp, count, total);
|
|
}
|
|
|
|
fputc('\n', con->fp);
|
|
|
|
mufs_close(out);
|
|
mufs_close(in);
|
|
|
|
return 0;
|
|
|
|
err_close_in:
|
|
mufs_close(in);
|
|
return -1;
|
|
}
|
|
|
|
int shell_rm(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
if (argc < 1) {
|
|
fprintf(con->fp, "usage: mufs rm <path>\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (mufs_unlink(mufs, argv[0]) < 0) {
|
|
fprintf(con->fp, "error: unable to remove the file\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int shell_ls(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
struct mufs_dirent ent;
|
|
struct mufs_dir *dir;
|
|
const char *path = "";
|
|
|
|
if (argc >= 1) {
|
|
path = argv[0];
|
|
}
|
|
|
|
if (!mufs) {
|
|
fprintf(con->fp, "error: no file system mounted.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!(dir = mufs_opendir(mufs, path))) {
|
|
fprintf(con->fp, "error: unable to open the directory\n");
|
|
return -1;
|
|
}
|
|
|
|
while (mufs_readdir(dir, &ent) == 0) {
|
|
fprintf(con->fp, "%s\n", ent.path);
|
|
}
|
|
|
|
mufs_closedir(dir);
|
|
return 0;
|
|
}
|
|
|
|
static struct cmd mufs_cmds[] = {
|
|
{ "mount", NULL, shell_mount },
|
|
{ "umount", NULL, shell_unmount },
|
|
{ "format", NULL, shell_format },
|
|
{ "mkdir", NULL, shell_mkdir },
|
|
{ "rmdir", NULL, shell_rmdir },
|
|
{ "ls", NULL, shell_ls },
|
|
{ "stat", NULL, shell_stat },
|
|
{ "cat", NULL, shell_cat },
|
|
{ "write", NULL, shell_write },
|
|
{ "append", NULL, shell_append },
|
|
{ "mv", NULL, shell_mv, },
|
|
{ "cp", NULL, shell_cp, },
|
|
{ "rm", NULL, shell_rm, },
|
|
{ NULL, NULL, NULL },
|
|
};
|
|
|
|
int do_mufs_cmd(struct console *con, size_t argc, const char **argv)
|
|
{
|
|
return cmd_exec(mufs_cmds, con, argc, argv);
|
|
}
|
|
|