It was already mentioned in Dec 2016 here:
https://lists.suckless.org/dev/1612/30852.html
but never fixed since.

*Extracting* long paths was added in May 2022 here:
https://lists.suckless.org/hackers/2205/18321.html
but not *archiving*.

Next thing to do should be supporting links while archiving.
---
 tar.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/tar.c b/tar.c
index d3a9f3b..aa81caf 100644
--- a/tar.c
+++ b/tar.c
@@ -187,6 +187,9 @@ archive(const char *path)
        size_t chksum, i;
        ssize_t l, r;
        int fd = -1;
+       size_t path_len;
+       char tmp_prefix[PATH_MAX];
+       char *bsname;
 
        if (lstat(path, &st) < 0) {
                weprintf("lstat %s:", path);
@@ -201,7 +204,25 @@ archive(const char *path)
 
        h = (struct header *)b;
        memset(b, 0, sizeof(b));
-       estrlcpy(h->name,    path,                        sizeof(h->name));
+
+       path_len = strlen(path);
+       if (path_len > 100 - 1) {
+               // Cover case where path name is too long (in which case we need
+               // to split it to prefix and name).
+               bsname = basename((char *)path);
+               strncpy(tmp_prefix, path, PATH_MAX);
+               dirname(tmp_prefix);
+               // Could still be too long to fit in the struct.
+               if (strlen(bsname) >= sizeof(h->name) ||
+                   strlen(tmp_prefix) >= sizeof(h->prefix)) {
+                       eprintf("filename too long: %s\n", path);
+               } else {
+                       estrlcpy(h->name, bsname, sizeof(h->name));
+                       estrlcpy(h->prefix, tmp_prefix, sizeof(h->prefix));
+               }
+       } else
+               estrlcpy(h->name, path, sizeof(h->name));
+
        putoctal(h->mode,    (unsigned)st.st_mode & 0777, sizeof(h->mode));
        putoctal(h->uid,     (unsigned)st.st_uid,         sizeof(h->uid));
        putoctal(h->gid,     (unsigned)st.st_gid,         sizeof(h->gid));
-- 
2.34.1


Reply via email to