From: "David Glasser" <glasser@davidglasser.net>
To: emacs-devel@gnu.org
Subject: [PATCH] support filename prefixes and 100-character filenames in tar-mode.el
Date: Fri, 11 Apr 2008 10:51:55 -0700 [thread overview]
Message-ID: <1ea387f60804111051o5e51d86akf34f5d80c4f2fd35@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 3268 bytes --]
I noticed this morning that when opening a tarball containing a file
with a long filename in tar-mode, the entry for that file didn't list
the full filename; it only listed some suffix of the filename. I did
some digging and found that newish tar standards (among others)
support a "prefix" field in the tar header block to overcome tar
format limitations; however, tar-mode doesn't support it.
You should be able to test this by opening the attached tarball. The
correct output should look something like:
drwxr-x--- glasser/eng 0 foo1
drwxr-x--- glasser/eng 0 foo1/foo2
drwxr-x--- glasser/eng 0 foo1/foo2/foo3
drwxr-x--- glasser/eng 0 foo1/foo2/foo3/foo4
drwxr-x--- glasser/eng 0 foo1/foo2/foo3/foo4/foo5
drwxr-x--- glasser/eng 0 foo1/foo2/foo3/foo4/foo5/foo6
drwxr-x--- glasser/eng 0 foo1/foo2/foo3/foo4/foo5/foo6/foo7
drwxr-x--- glasser/eng 0 foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8
drwxr-x--- glasser/eng 0 foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14/foo15
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14/foo15/foo16
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14/foo15/foo16/foo17
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14/foo15/foo16/foo17/foo18
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14/foo15/foo16/foo17/foo18/foo19
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14/foo15/foo16/foo17/foo18/foo19/foo20
drwxr-x--- glasser/eng 0
foo1/foo2/foo3/foo4/foo5/foo6/foo7/foo8/foo9/foo10/foo11/foo12/foo13/foo14/foo15/foo16/foo17/foo18/foo19/foo20/foo21
Without my patch at all, the bottom few look like they aren't inside foo1/foo2/.
With all of the patch except for the change in the initial
initialization of name-end, the results look correct, except the
penultimate line ends in "foo2" instead of "foo20"; that is because
the name field here fill the entire field with no nulls, but the code
previously assumed there would be at least one null. (It's possible
that similar adjustments are required for the initial values of
link-end, gname-end, and uname-end.)
Let me know if this is a significant enough change that papers are necessary.
Also, please note that until an hour ago I had no idea what the TAR
format looked like!
--dave
--
David Glasser | glasser@davidglasser.net | http://www.davidglasser.net/
[-- Attachment #2: tar-prefix.patch.txt --]
[-- Type: text/plain, Size: 3686 bytes --]
Index: tar-mode.el
===================================================================
*** tar-mode.el (revision 200)
--- tar-mode.el (working copy)
*************** This information is useful, but it takes
*** 197,203 ****
(defconst tar-gname-offset (+ tar-uname-offset 32))
(defconst tar-dmaj-offset (+ tar-gname-offset 32))
(defconst tar-dmin-offset (+ tar-dmaj-offset 8))
! (defconst tar-end-offset (+ tar-dmin-offset 8))
(defun tar-header-block-tokenize (string)
"Return a `tar-header' structure.
--- 197,204 ----
(defconst tar-gname-offset (+ tar-uname-offset 32))
(defconst tar-dmaj-offset (+ tar-gname-offset 32))
(defconst tar-dmin-offset (+ tar-dmaj-offset 8))
! (defconst tar-prefix-offset (+ tar-dmin-offset 8))
! (defconst tar-end-offset (+ tar-prefix-offset 155))
(defun tar-header-block-tokenize (string)
"Return a `tar-header' structure.
*************** write-date, checksum, link-type, and lin
*** 207,219 ****
(;(some 'plusp string) ; <-- oops, massive cycle hog!
(or (not (= 0 (aref string 0))) ; This will do.
(not (= 0 (aref string 101))))
! (let* ((name-end (1- tar-mode-offset))
(link-end (1- tar-magic-offset))
(uname-end (1- tar-gname-offset))
(gname-end (1- tar-dmaj-offset))
(link-p (aref string tar-linkp-offset))
(magic-str (substring string tar-magic-offset (1- tar-uname-offset)))
! (uname-valid-p (or (string= "ustar " magic-str) (string= "GNUtar " magic-str)))
name linkname
(nulsexp "[^\000]*\000"))
(when (string-match nulsexp string tar-name-offset)
--- 208,221 ----
(;(some 'plusp string) ; <-- oops, massive cycle hog!
(or (not (= 0 (aref string 0))) ; This will do.
(not (= 0 (aref string 101))))
! (let* ((name-end tar-mode-offset)
(link-end (1- tar-magic-offset))
(uname-end (1- tar-gname-offset))
(gname-end (1- tar-dmaj-offset))
(link-p (aref string tar-linkp-offset))
(magic-str (substring string tar-magic-offset (1- tar-uname-offset)))
! (uname-valid-p (or (string= "ustar " magic-str) (string= "GNUtar " magic-str)
! (string= "ustar\0000" magic-str)))
name linkname
(nulsexp "[^\000]*\000"))
(when (string-match nulsexp string tar-name-offset)
*************** write-date, checksum, link-type, and lin
*** 229,234 ****
--- 231,242 ----
nil
(- link-p ?0)))
(setq linkname (substring string tar-link-offset link-end))
+ (when (and uname-valid-p
+ (string-match nulsexp string tar-prefix-offset)
+ (> (match-end 0) (1+ tar-prefix-offset)))
+ (setq name (concat (substring string tar-prefix-offset
+ (1- (match-end 0)))
+ "/" name)))
(if default-enable-multibyte-characters
(setq name
(decode-coding-string name
*************** write-date, checksum, link-type, and lin
*** 255,261 ****
(and uname-valid-p (substring string tar-uname-offset uname-end))
(and uname-valid-p (substring string tar-gname-offset gname-end))
(tar-parse-octal-integer string tar-dmaj-offset tar-dmin-offset)
! (tar-parse-octal-integer string tar-dmin-offset tar-end-offset)
)))
(t 'empty-tar-block)))
--- 263,269 ----
(and uname-valid-p (substring string tar-uname-offset uname-end))
(and uname-valid-p (substring string tar-gname-offset gname-end))
(tar-parse-octal-integer string tar-dmaj-offset tar-dmin-offset)
! (tar-parse-octal-integer string tar-dmin-offset tar-prefix-offset)
)))
(t 'empty-tar-block)))
[-- Attachment #3: test.tar.gz --]
[-- Type: application/x-gzip, Size: 437 bytes --]
next reply other threads:[~2008-04-11 17:51 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-11 17:51 David Glasser [this message]
2008-04-13 22:23 ` [PATCH] support filename prefixes and 100-character filenames in tar-mode.el Juri Linkov
2008-04-14 1:48 ` David Glasser
2008-04-15 22:35 ` Juri Linkov
2008-04-15 23:17 ` David Glasser
2008-04-16 23:17 ` Juri Linkov
2008-04-16 23:32 ` David Glasser
2008-04-17 9:21 ` Juri Linkov
2008-04-17 13:34 ` Chong Yidong
2008-04-22 20:51 ` Juri Linkov
2008-04-22 21:20 ` David Glasser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1ea387f60804111051o5e51d86akf34f5d80c4f2fd35@mail.gmail.com \
--to=glasser@davidglasser.net \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.