commit 9af7199750e539d4bd0fbe9464c7cd38e09c1706
parent d5f4cba15457120d1a87029ff1a05d47a98226fd
Author: erai <erai@omiltem.net>
Date: Mon, 27 May 2024 13:00:42 -0400
add xxd command
Diffstat:
M | bootstrap.sh | | | 2 | +- |
M | build.sh | | | 6 | ++++-- |
A | cat.c | | | 59 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | lib.c | | | 74 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | xxd.c | | | 56 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 194 insertions(+), 3 deletions(-)
diff --git a/bootstrap.sh b/bootstrap.sh
@@ -11,4 +11,4 @@ gcc -Wall -Wextra -Wno-unused -pedantic -std=c99 ./cc0.c -o cc0
cmp cc1 cc2 || echo mismatch
-sh ./build.sh
+sh -e ./build.sh
diff --git a/build.sh b/build.sh
@@ -6,8 +6,8 @@ GENLEX="genlex.c"
BOOT="pxe.asm"
SSHD="chacha20.c poly1305.c sha256.c sha512.c ed25519.c sshd.c"
KERNEL="kernel.c"
-SHELL="echo.c cmp.c rm.c ls.c mv.c mkdir.c cpio.c vi.c sh.c"
-BIN="echo cmp rm ls mv mkdir cpio sh vi sshd init cc1 cc2"
+SHELL="echo.c cmp.c rm.c ls.c cat.c xxd.c mv.c mkdir.c cpio.c vi.c sh.c"
+BIN="echo cmp rm ls cat xxd mv mkdir cpio sh vi sshd init cc1 cc2 build.sh cc3.l"
ALL="${LIBS} ${CC} ${GENLEX} ${BOOT} ${SSHD} ${KERNEL} ${SHELL} ${BIN}"
./cc1 ${LIBS} ${CC} -o cc2
@@ -21,6 +21,8 @@ ALL="${LIBS} ${CC} ${GENLEX} ${BOOT} ${SSHD} ${KERNEL} ${SHELL} ${BIN}"
./cc2 ${LIBS} mv.c -o mv
./cc2 ${LIBS} mkdir.c -o mkdir
./cc2 ${LIBS} ls.c -o ls
+./cc2 ${LIBS} cat.c -o cat
+./cc2 ${LIBS} xxd.c -o xxd
./cc2 ${LIBS} cpio.c -o cpio
./cc2 ${LIBS} sh.c -o sh
./cc2 ${LIBS} sshd.c -o sshd
diff --git a/cat.c b/cat.c
@@ -0,0 +1,59 @@
+docat(fd: int, buf: *byte) {
+ var n: int;
+ var m: int;
+ var k: int;
+ loop {
+ n = read(fd, buf, 4096);
+ if n == 0 {
+ return;
+ }
+
+ if n < 0 {
+ die("read failed");
+ }
+
+ m = 0;
+ loop {
+ if m == n {
+ break;
+ }
+
+ k = write(1, &buf[m], n - m);
+ if k < 0 {
+ die("write failed");
+ }
+
+ m = m + k;
+ }
+ }
+}
+
+main(argc: int, argv: **byte, envp: **byte) {
+ var fd: int;
+ var i: int;
+ var a: alloc;
+ var buf: *byte;
+
+ setup_alloc(&a);
+
+ buf = alloc(&a, 4096);
+
+ if argc == 1 {
+ docat(0, buf);
+ } else {
+ i = 1;
+ loop {
+ if i >= argc {
+ break;
+ }
+
+ fd = open(argv[i], 0, 0);
+
+ docat(fd, buf);
+
+ close(fd);
+
+ i = i + 1;
+ }
+ }
+}
diff --git a/lib.c b/lib.c
@@ -155,6 +155,80 @@ fdputd(fd: int, n: int) {
fdputc(fd, '0' + a);
}
+xxd_line(line: *byte, offset: int, data: *byte, len: int) {
+ var i: int;
+ var j: int;
+ var d: *byte;
+ d = "0123456789abcdef";
+
+ i = 0;
+
+ line[i] = d[(offset >> 28) & 15];
+ line[i + 1] = d[(offset >> 24) & 15];
+ line[i + 2] = d[(offset >> 20) & 15];
+ line[i + 3] = d[(offset >> 16) & 15];
+ line[i + 4] = d[(offset >> 12) & 15];
+ line[i + 5] = d[(offset >> 8) & 15];
+ line[i + 6] = d[(offset >> 4) & 15];
+ line[i + 7] = d[offset & 15];
+ line[i + 8] = ':':byte;
+ line[i + 9] = ' ':byte;
+
+ i = i + 10;
+
+ j = 0;
+ loop {
+ if j == 16 {
+ break;
+ }
+
+ if j < len {
+ line[i] = d[(data[j]:int >> 4) & 15];
+ line[i + 1] = d[data[j]:int & 15];
+ } else {
+ line[i] = ' ':byte;
+ line[i + 1] = ' ':byte;
+ }
+
+ if j + 1 < len {
+ line[i + 2] = d[(data[j]:int >> 4) & 15];
+ line[i + 3] = d[data[j]:int & 15];
+ } else {
+ line[i + 2] = ' ':byte;
+ line[i + 3] = ' ':byte;
+ }
+
+ line[i + 4] = ' ':byte;
+
+ j = j + 2;
+ i = i + 5;
+ }
+
+ line[i] = ' ':byte;
+ i = i + 1;
+
+ j = 0;
+ loop {
+ if j == 16 || j >= len {
+ break;
+ }
+
+ if data[j]:int >= 0x20 && data[j]:int < 0x80 {
+ line[i] = data[j];
+ } else {
+ line[i] = '.':byte;
+ }
+
+ j = j + 1;
+ i = i + 1;
+ }
+
+ line[i] = '\n':byte;
+ i = i + 1;
+
+ line[i] = 0:byte;
+}
+
fdxxd(fd: int, data: *byte, len: int) {
var i: int;
var j: int;
diff --git a/xxd.c b/xxd.c
@@ -0,0 +1,56 @@
+doxxd(fd: int, buf: *byte) {
+ var n: int;
+ var m: int;
+ var ret: int;
+
+ m = 0;
+ loop {
+ n = 0;
+ loop {
+ ret = read(fd, buf, 16 - n);
+ if ret == 0 {
+ break;
+ }
+
+ if ret < 0 {
+ die("read failed");
+ }
+
+ n = n + ret;
+
+ if n == 16 {
+ break;
+ }
+ }
+
+ xxd_line(&buf[16], m, buf, n);
+ fdputs(1, &buf[16]);
+
+ if n < 16 {
+ break;
+ }
+
+ m = m + n;
+ }
+}
+
+main(argc: int, argv: **byte, envp: **byte) {
+ var fd: int;
+ var i: int;
+ var a: alloc;
+ var buf: *byte;
+
+ setup_alloc(&a);
+
+ buf = alloc(&a, 4096);
+
+ if argc == 1 {
+ doxxd(0, buf);
+ } else if argc == 2 {
+ fd = open(argv[1], 0, 0);
+ doxxd(fd, buf);
+ close(fd);
+ } else {
+ die("usage: xxd [file]");
+ }
+}