Teach `package-install-file' to install previously rejected tarballs Whilst Emacs can open the varieties of tarballs with no problem, the package management functions depended on a particular table layout in the tarball to calculate the directory for the package. For example, with BSD tar: `tar cf ...` would generate a rejected tarball, and `tar cof ...` would generate an accepted one. * lisp/emacs-lisp/package.el (package-untar-buffer): Compare against the header name from the tarball rather than the filesystem expanded form. (package-tar-file-info): Also allow the first entry to be a plain directory name without trailing path separator. --- lisp/emacs-lisp/package.el | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 4268f7d27a..cc371fbc50 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -926,11 +926,12 @@ package-untar-buffer (let ((regexp (concat "\\`" (regexp-quote (expand-file-name dir)) "/")) (case-fold-search (file-name-case-insensitive-p dir))) (dolist (tar-data tar-parse-info) - (let ((name (expand-file-name (tar-header-name tar-data)))) + (let* ((header-name (tar-header-name tar-data)) + (name (expand-file-name header-name))) (or (string-match regexp name) ;; Tarballs created by some utilities don't list ;; directories with a trailing slash (Bug#13136). - (and (string-equal dir name) + (and (string-equal dir header-name) (eq (tar-header-link-type tar-data) 5)) (error "Package does not untar cleanly into directory %s/" dir))))) (tar-untar-buffer)) @@ -1192,8 +1193,10 @@ package-tar-file-info "Find package information for a tar file. The return result is a `package-desc'." (cl-assert (derived-mode-p 'tar-mode)) - (let* ((dir-name (file-name-directory - (tar-header-name (car tar-parse-info)))) + (let* ((header-name (tar-header-name (car tar-parse-info))) + (dir-name (or (file-name-directory header-name) + ;; Some tar utilities generate a plain directory name first + (file-name-as-directory header-name))) (desc-file (package--description-file dir-name)) (tar-desc (tar-get-file-descriptor (concat dir-name desc-file)))) (unless tar-desc 2.38.0