From 646dcc582e2d4996596b7df2bfedeccb19f9e200 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Tue, 9 Nov 2021 21:38:07 +0100
Subject: init/tar: add (bad) support for reading the root dir

---
 src/init/tar.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/init/tar.c b/src/init/tar.c
index ef3af2c..8db3cd8 100644
--- a/src/init/tar.c
+++ b/src/init/tar.c
@@ -11,6 +11,10 @@ static int tar_size(void *sector);
 static void *tar_find(const char *path, size_t path_len, void *base, size_t base_len);
 static int oct_parse(char *str, size_t len);
 
+
+static const char *root_fakemeta = ""; /* see comment in tar_open */
+
+
 void tar_driver(void *base) {
 	static char buf[BUF_SIZE];
 	struct fs_wait_response res;
@@ -34,10 +38,16 @@ void tar_driver(void *base) {
 static int tar_open(const char *path, int len, void *base, size_t base_len) {
 	void *ptr;
 
-	if (len <= 1) return -1;
+	if (len <= 0) return -1;
 	path += 1; // skip the leading slash
 	len  -= 1;
 
+	/* TAR archives don't (seem to) contain an entry for the root dir, so i'm
+	 * returning a fake one. this isn't a full entry because i'm currently too
+	 * lazy to create a full one - thus, it has to be special cased in tar_read */
+	if (len == 0)
+		return root_fakemeta;
+
 	ptr = tar_find(path, len, base, ~0);
 	if (!ptr) return -1;
 	return (int)ptr;
@@ -52,6 +62,8 @@ static int tar_read(struct fs_wait_response *res, void *base, size_t base_len) {
 	static char buf[BUF_SIZE]; // TODO reuse a single buffer
 	size_t buf_pos = 0;
 
+	if (meta == root_fakemeta) type = '5'; /* see comment in tar_open() */
+
 	switch (type) {
 		case '\0':
 		case '0': /* normal files */
-- 
cgit v1.2.3