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.
78 lines
1.6 KiB
78 lines
1.6 KiB
#include "src/app/cat.h"
|
|
#include "src/fs.h"
|
|
#include "src/memory.h"
|
|
#include "src/string.h"
|
|
#include "src/util.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
static stream_t *stream_in;
|
|
static stream_t *stream_out;
|
|
|
|
#define WRITE_S(s) stream_out->write(stream_out, s, sizeof(s) - 1);
|
|
#define WRITE_D(s) stream_out->write(stream_out, s, string_length(s));
|
|
|
|
void cat(stream_t *stdin, stream_t *stdout, uint8_t argc, char **argv) {
|
|
stream_in = stdin;
|
|
stream_out = stdout;
|
|
|
|
if (argc != 2) {
|
|
WRITE_S("cat: requires a single path\n");
|
|
return;
|
|
}
|
|
|
|
char *path_components[16];
|
|
uint64_t path_length = string_split(argv[1], '/', 16, path_components);
|
|
if (!string_empty(path_components[0])) {
|
|
WRITE_S("cat: relative paths not supported\n");
|
|
return;
|
|
}
|
|
|
|
fs_node_t *root = fs_mount();
|
|
|
|
fs_node_t *prev = NUL;
|
|
fs_node_t *curr = root;
|
|
uint8_t i = 1;
|
|
while (i < path_length) {
|
|
if (string_empty(path_components[i])) {
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
if (!curr->is_dir) {
|
|
WRITE_S("cat: can not navigate into a file\n");
|
|
fs_close(curr);
|
|
return;
|
|
}
|
|
|
|
prev = curr;
|
|
curr = fs_open_by(curr, path_components[i]);
|
|
if (prev != root) {
|
|
fs_close(prev);
|
|
}
|
|
|
|
if (!curr) {
|
|
WRITE_S("cat: invalid path\n");
|
|
return;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
if (curr->is_dir) {
|
|
WRITE_S("cat: can not print a directory\n");
|
|
if (curr != root) {
|
|
fs_close(curr);
|
|
}
|
|
return;
|
|
}
|
|
|
|
char *content = memory_allocate(curr->size + 1);
|
|
fs_read(curr, 0, curr->size, content);
|
|
stream_out->write(stream_out, content, curr->size);
|
|
memory_free(content);
|
|
fs_close(curr);
|
|
|
|
fs_unmount(root);
|
|
|
|
stream_in = stream_out = NUL;
|
|
}
|
|
|