diff options
-rw-r--r-- | src/bootstrap/tar.c | 18 | ||||
-rw-r--r-- | src/libc/include/string.h | 2 | ||||
-rw-r--r-- | src/libc/string/string.c | 9 |
3 files changed, 25 insertions, 4 deletions
diff --git a/src/bootstrap/tar.c b/src/bootstrap/tar.c index 2020fe0..678f54f 100644 --- a/src/bootstrap/tar.c +++ b/src/bootstrap/tar.c @@ -60,18 +60,28 @@ static char tar_type(void *meta) { return *(char*)(meta + 156); } +#include <stdio.h> static void *tar_open(const char *path, int len, void *base, size_t base_len) { + void *res; if (len <= 0) return NULL; - path += 1; // skip the leading slash - len -= 1; + if (*path == '/') { + 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) + if (len == 0) { return (void*)root_fakemeta; + } - return tar_find(path, len, base, base_len); + res = tar_find(path, len, base, base_len); + if (res && tar_type(res) == '1') { /* hard link */ + _klogf("hard link to %s", res+157); + res = tar_find(res + 157, strnlen(res + 157, 100), base, base_len); + } + return res; } static void tar_dirbuild(struct dirbuild *db, const char *meta, void *base, size_t base_len) { diff --git a/src/libc/include/string.h b/src/libc/include/string.h index d9d2b74..8b04b39 100644 --- a/src/libc/include/string.h +++ b/src/libc/include/string.h @@ -24,4 +24,6 @@ char *strncat(char *restrict dst, const char *restrict src, size_t n); char *stpncpy(char *restrict dst, const char *restrict src, size_t n); char *strdup(const char *s); +size_t strnlen(const char *s, size_t len); + char *strerror(int errnum); diff --git a/src/libc/string/string.c b/src/libc/string/string.c index ac1c757..014be4a 100644 --- a/src/libc/string/string.c +++ b/src/libc/string/string.c @@ -115,6 +115,15 @@ char *strdup(const char *s) { return buf; } +size_t strnlen(const char *s, size_t len) { + for (size_t i = 0; i < len; i++) { + if (!s[i]) { + return i; + } + } + return len; +} + /* strings.h */ int strcasecmp(const char *s1, const char *s2) { return strncasecmp(s1, s2, ~0); |