CE Add copy command
This commit is contained in:
100
ce/interp.c
100
ce/interp.c
@@ -203,6 +203,94 @@ static void cat (struct context* context, char** file_paths, size_t files_count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void copy (struct context* context, const char* path_a, const char* path_b) {
|
||||||
|
char volume[VOLUME_MAX];
|
||||||
|
const char* path;
|
||||||
|
int ret;
|
||||||
|
struct strbuf strbuf;
|
||||||
|
memset (&strbuf, 0, sizeof (strbuf));
|
||||||
|
|
||||||
|
if (!path_parse (path_a, volume, &path)) {
|
||||||
|
cprintf (context, "ERROR bad path '%s'\n", path_a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct filereader fr;
|
||||||
|
if ((ret = filereader_init (&fr, volume, path)) < 0) {
|
||||||
|
cprintf (context, "ERROR could not initialize filereader for '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t chunk_size = 1024;
|
||||||
|
char* buffer = arena_malloc (&arena, chunk_size);
|
||||||
|
|
||||||
|
size_t chunks = fr.file_size / chunk_size;
|
||||||
|
size_t rem = fr.file_size % chunk_size;
|
||||||
|
|
||||||
|
for (size_t chunk = 0; chunk < chunks; chunk++) {
|
||||||
|
if ((ret = filereader_read (&fr, (uint8_t*)buffer, chunk_size)) < 0) {
|
||||||
|
filereader_fini (&fr);
|
||||||
|
cprintf (context, "ERROR filereader failed to read from '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf_append_n (&strbuf, buffer, chunk_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rem > 0) {
|
||||||
|
if ((ret = filereader_read (&fr, (uint8_t*)buffer, rem)) < 0) {
|
||||||
|
filereader_fini (&fr);
|
||||||
|
cprintf (context, "ERROR filereader failed to read from '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf_append_n (&strbuf, buffer, rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
filereader_fini (&fr);
|
||||||
|
|
||||||
|
if (!(path_parse (path_b, volume, &path))) {
|
||||||
|
cprintf (context, "ERROR bad path '%s'\n", path_b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fw_flags = FW_CREATE_FILE | FW_TRUNCATE;
|
||||||
|
|
||||||
|
struct filewriter fw;
|
||||||
|
if ((ret = filewriter_init (&fw, volume, path, fw_flags)) < 0) {
|
||||||
|
cprintf (context, "ERROR could not initialize filewriter for '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strbuf.count == 0) {
|
||||||
|
filewriter_fini (&fw);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk_size = 1024;
|
||||||
|
chunks = (strbuf.count - 1) / chunk_size;
|
||||||
|
rem = (strbuf.count - 1) % chunk_size;
|
||||||
|
|
||||||
|
for (size_t chunk = 0; chunk < chunks; chunk++) {
|
||||||
|
if ((ret = filewriter_write (&fw, (uint8_t*)&strbuf.items[chunk * chunk_size], chunk_size)) <
|
||||||
|
0) {
|
||||||
|
filewriter_fini (&fw);
|
||||||
|
cprintf (context, "ERROR filewriter failed to write to '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rem > 0) {
|
||||||
|
if ((ret = filewriter_write (&fw, (uint8_t*)&strbuf.items[chunks * chunk_size], rem)) < 0) {
|
||||||
|
filewriter_fini (&fw);
|
||||||
|
cprintf (context, "ERROR filewriter failed to write to '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filewriter_fini (&fw);
|
||||||
|
}
|
||||||
|
|
||||||
static void ls (struct context* context, const char* path_string) {
|
static void ls (struct context* context, const char* path_string) {
|
||||||
struct desc desc;
|
struct desc desc;
|
||||||
char volume[VOLUME_MAX];
|
char volume[VOLUME_MAX];
|
||||||
@@ -344,6 +432,7 @@ static void help (struct context* context) {
|
|||||||
cprintf (context, "procinfo\n");
|
cprintf (context, "procinfo\n");
|
||||||
cprintf (context, "quit\n");
|
cprintf (context, "quit\n");
|
||||||
cprintf (context, "stall <milliseconds>\n");
|
cprintf (context, "stall <milliseconds>\n");
|
||||||
|
cprintf (context, "copy <path A> <path B>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmd_write_proc_ctx {
|
struct cmd_write_proc_ctx {
|
||||||
@@ -390,7 +479,7 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context, bool run_
|
|||||||
} else if (strcmp (cmd->name, "cat") == 0) {
|
} else if (strcmp (cmd->name, "cat") == 0) {
|
||||||
cat (context, cmd->args, cmd->arg_count);
|
cat (context, cmd->args, cmd->arg_count);
|
||||||
} else if (strcmp (cmd->name, "ls") == 0) {
|
} else if (strcmp (cmd->name, "ls") == 0) {
|
||||||
if (cmd->args[0] != NULL)
|
if (cmd->arg_count == 1)
|
||||||
ls (context, cmd->args[0]);
|
ls (context, cmd->args[0]);
|
||||||
else
|
else
|
||||||
cprintf (context, "ERROR No directory path provided\n");
|
cprintf (context, "ERROR No directory path provided\n");
|
||||||
@@ -403,7 +492,7 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context, bool run_
|
|||||||
} else if (strcmp (cmd->name, "rm") == 0) {
|
} else if (strcmp (cmd->name, "rm") == 0) {
|
||||||
rm (context, cmd->args, cmd->arg_count);
|
rm (context, cmd->args, cmd->arg_count);
|
||||||
} else if (strcmp (cmd->name, "edit") == 0) {
|
} else if (strcmp (cmd->name, "edit") == 0) {
|
||||||
if (cmd->args[0] != NULL)
|
if (cmd->arg_count == 1)
|
||||||
edit (context, cmd->args[0]);
|
edit (context, cmd->args[0]);
|
||||||
else
|
else
|
||||||
cprintf (context, "ERROR No file path provided\n");
|
cprintf (context, "ERROR No file path provided\n");
|
||||||
@@ -412,7 +501,7 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context, bool run_
|
|||||||
} else if (strcmp (cmd->name, "cls") == 0) {
|
} else if (strcmp (cmd->name, "cls") == 0) {
|
||||||
cls (context);
|
cls (context);
|
||||||
} else if (strcmp (cmd->name, "mkvol") == 0) {
|
} else if (strcmp (cmd->name, "mkvol") == 0) {
|
||||||
if ((cmd->args[0] != NULL) && (cmd->args[1] != NULL) && (cmd->args[2] != NULL))
|
if (cmd->arg_count == 3)
|
||||||
mkvol (context, cmd->args[0], cmd->args[1], cmd->args[2]);
|
mkvol (context, cmd->args[0], cmd->args[1], cmd->args[2]);
|
||||||
else
|
else
|
||||||
cprintf (context, "ERROR No volume key, filesystem type or device key provided\n");
|
cprintf (context, "ERROR No volume key, filesystem type or device key provided\n");
|
||||||
@@ -425,6 +514,11 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context, bool run_
|
|||||||
} else {
|
} else {
|
||||||
cprintf (context, "ERROR stall requires a timeout argument\n");
|
cprintf (context, "ERROR stall requires a timeout argument\n");
|
||||||
}
|
}
|
||||||
|
} else if (strcmp (cmd->name, "copy") == 0) {
|
||||||
|
if (cmd->arg_count == 2)
|
||||||
|
copy (context, cmd->args[0], cmd->args[1]);
|
||||||
|
else
|
||||||
|
cprintf (context, "ERROR copy requires source and destination\n");
|
||||||
} else {
|
} else {
|
||||||
char volume[VOLUME_MAX];
|
char volume[VOLUME_MAX];
|
||||||
const char* path;
|
const char* path;
|
||||||
|
|||||||
@@ -22,3 +22,8 @@ void strbuf_append_str (struct strbuf* strbuf, const char* s) {
|
|||||||
while (*s)
|
while (*s)
|
||||||
strbuf_append (strbuf, *s++);
|
strbuf_append (strbuf, *s++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strbuf_append_n (struct strbuf* strbuf, const char* s, size_t n) {
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
strbuf_append (strbuf, s[i]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,4 +12,6 @@ void strbuf_append (struct strbuf* strbuf, char c);
|
|||||||
|
|
||||||
void strbuf_append_str (struct strbuf* strbuf, const char* s);
|
void strbuf_append_str (struct strbuf* strbuf, const char* s);
|
||||||
|
|
||||||
|
void strbuf_append_n (struct strbuf* strbuf, const char* s, size_t n);
|
||||||
|
|
||||||
#endif // _STRBUF_H
|
#endif // _STRBUF_H
|
||||||
|
|||||||
Reference in New Issue
Block a user