(put 'tar-superior-buffer 'permanent-local t)
(put 'tar-superior-descriptor 'permanent-local t)
\f
-;;; First, duplicate some Common Lisp functions; I used to just (require 'cl)
-;;; but "cl.el" was messing some people up (also it's really big).
-
(defmacro tar-setf (form val)
"A mind-numbingly simple implementation of setf."
(let ((mform (macroexpand form (and (boundp 'byte-compile-macro-environment)
((eq (car mform) 'cdr)
(list 'setcdr (nth 1 mform) val))
(t (error "don't know how to setf %s" form)))))
-
-(defmacro tar-dolist (control &rest body)
- "syntax: (dolist (var-name list-expr &optional return-value) &body body)"
- (let ((var (car control))
- (init (car (cdr control)))
- (val (car (cdr (cdr control)))))
- (list 'let (list (list '_dolist_iterator_ init))
- (list 'while '_dolist_iterator_
- (cons 'let
- (cons (list (list var '(car _dolist_iterator_)))
- (append body
- (list (list 'setq '_dolist_iterator_
- (list 'cdr '_dolist_iterator_)))))))
- val)))
-
-(defmacro tar-dotimes (control &rest body)
- "syntax: (dolist (var-name count-expr &optional return-value) &body body)"
- (let ((var (car control))
- (n (car (cdr control)))
- (val (car (cdr (cdr control)))))
- (list 'let (list (list '_dotimes_end_ n)
- (list var 0))
- (cons 'while
- (cons (list '< var '_dotimes_end_)
- (append body
- (list (list 'setq var (list '1+ var))))))
- val)))
-
\f
;;; down to business.
(defun tar-parse-octal-integer-safe (string)
(let ((L (length string)))
(if (= L 0) (error "empty string"))
- (tar-dotimes (i L)
+ (dotimes (i L)
(if (or (< (aref string i) ?0)
(> (aref string i) ?7))
(error "`%c' is not an octal digit"))))
(if (not (= desired-checksum (tar-header-block-checksum hblock)))
(progn (beep) (message "Invalid checksum for file %s!" file-name))))
-(defun tar-header-block-recompute-checksum (hblock)
- "Modifies the given string to have a valid checksum field."
- (let* ((chk (tar-header-block-checksum hblock))
- (chk-string (format "%6o" chk))
- (l (length chk-string)))
- (aset hblock 154 0)
- (aset hblock 155 32)
- (tar-dotimes (i l) (aset hblock (- 153 i) (aref chk-string (- l i 1)))))
- hblock)
-
(defun tar-clip-time-string (time)
(let ((str (current-time-string time)))
- (concat (substring str 4 16) (substring str 19 24))))
+ (concat " " (substring str 4 16) (substring str 19 24))))
-(defun tar-grind-file-mode (mode string start)
- "Store `-rw--r--r--' indicating MODE into STRING beginning at START.
+(defun tar-grind-file-mode (mode)
+ "Construct a `-rw--r--r--' string indicating MODE.
MODE should be an integer which is a file mode value."
- (aset string start (if (zerop (logand 256 mode)) ?- ?r))
- (aset string (+ start 1) (if (zerop (logand 128 mode)) ?- ?w))
- (aset string (+ start 2) (if (zerop (logand 64 mode)) ?- ?x))
- (aset string (+ start 3) (if (zerop (logand 32 mode)) ?- ?r))
- (aset string (+ start 4) (if (zerop (logand 16 mode)) ?- ?w))
- (aset string (+ start 5) (if (zerop (logand 8 mode)) ?- ?x))
- (aset string (+ start 6) (if (zerop (logand 4 mode)) ?- ?r))
- (aset string (+ start 7) (if (zerop (logand 2 mode)) ?- ?w))
- (aset string (+ start 8) (if (zerop (logand 1 mode)) ?- ?x))
- (if (zerop (logand 1024 mode)) nil (aset string (+ start 2) ?s))
- (if (zerop (logand 2048 mode)) nil (aset string (+ start 5) ?s))
- string)
+ (string
+ (if (zerop (logand 256 mode)) ?- ?r)
+ (if (zerop (logand 128 mode)) ?- ?w)
+ (if (zerop (logand 1024 mode)) (if (zerop (logand 64 mode)) ?- ?x) ?s)
+ (if (zerop (logand 32 mode)) ?- ?r)
+ (if (zerop (logand 16 mode)) ?- ?w)
+ (if (zerop (logand 2048 mode)) (if (zerop (logand 8 mode)) ?- ?x) ?s)
+ (if (zerop (logand 4 mode)) ?- ?r)
+ (if (zerop (logand 2 mode)) ?- ?w)
+ (if (zerop (logand 1 mode)) ?- ?x)))
(defun tar-header-block-summarize (tar-hblock &optional mod-p)
- "Returns a line similar to the output of `tar -vtf'."
+ "Return a line similar to the output of `tar -vtf'."
(let ((name (tar-header-name tar-hblock))
(mode (tar-header-mode tar-hblock))
(uid (tar-header-uid tar-hblock))
(size (tar-header-size tar-hblock))
(time (tar-header-date tar-hblock))
(ck (tar-header-checksum tar-hblock))
- (link-p (tar-header-link-type tar-hblock))
- (link-name (tar-header-link-name tar-hblock))
- )
- (let* ((left 11)
- (namew 8)
- (groupw 8)
- (sizew 8)
- (datew (if tar-mode-show-date 18 0))
- (slash (1- (+ left namew)))
- (lastdigit (+ slash groupw sizew))
- (datestart (+ lastdigit 2))
- (namestart (+ datestart datew))
- (multibyte (or (multibyte-string-p name)
- (multibyte-string-p link-name)))
- ;; If multibyte, we can't use optimized method of aset,
- ;; instead we must use concat.
- (string (make-string (if multibyte
- namestart
- (+ namestart
- (length name)
- (if link-p (+ 5 (length link-name)) 0)))
- 32))
- (type (tar-header-link-type tar-hblock)))
- (aset string 0 (if mod-p ?* ? ))
- (aset string 1
+ (type (tar-header-link-type tar-hblock))
+ (link-name (tar-header-link-name tar-hblock)))
+ (format "%c%c%s%8s/%-8s%7s%s %s%s"
+ (if mod-p ?* ? )
(cond ((or (eq type nil) (eq type 0)) ?-)
- ((eq type 1) ?l) ; link
- ((eq type 2) ?s) ; symlink
- ((eq type 3) ?c) ; char special
- ((eq type 4) ?b) ; block special
- ((eq type 5) ?d) ; directory
- ((eq type 6) ?p) ; FIFO/pipe
- ((eq type 20) ?*) ; directory listing
- ((eq type 29) ?M) ; multivolume continuation
- ((eq type 35) ?S) ; sparse
- ((eq type 38) ?V) ; volume header
- ))
- (tar-grind-file-mode mode string 2)
- (setq uid (if (= 0 (length uname)) (int-to-string uid) uname))
- (setq gid (if (= 0 (length gname)) (int-to-string gid) gname))
- (setq size (int-to-string size))
- (setq time (tar-clip-time-string time))
- (tar-dotimes (i (min (1- namew) (length uid))) (aset string (- slash i) (aref uid (- (length uid) i 1))))
- (aset string (1+ slash) ?/)
- (tar-dotimes (i (min (1- groupw) (length gid))) (aset string (+ (+ slash 2) i) (aref gid i)))
- (tar-dotimes (i (min sizew (length size))) (aset string (- lastdigit i) (aref size (- (length size) i 1))))
- (if tar-mode-show-date
- (tar-dotimes (i (length time)) (aset string (+ datestart i) (aref time i))))
- (if multibyte
- (setq string (concat string name))
- (tar-dotimes (i (length name)) (aset string (+ namestart i) (aref name i))))
- (if (or (eq link-p 1) (eq link-p 2))
- (if multibyte
- (setq string (concat string
- (if (= link-p 1) " ==> " " --> ")
- link-name))
- (tar-dotimes (i 3) (aset string (+ namestart 1 (length name) i) (aref (if (= link-p 1) "==>" "-->") i)))
- (tar-dotimes (i (length link-name)) (aset string (+ namestart 5 (length name) i) (aref link-name i)))))
- (put-text-property namestart (length string)
- 'mouse-face 'highlight string)
- string)))
-
+ ((eq type 1) ?l) ; link
+ ((eq type 2) ?s) ; symlink
+ ((eq type 3) ?c) ; char special
+ ((eq type 4) ?b) ; block special
+ ((eq type 5) ?d) ; directory
+ ((eq type 6) ?p) ; FIFO/pipe
+ ((eq type 20) ?*) ; directory listing
+ ((eq type 29) ?M) ; multivolume continuation
+ ((eq type 35) ?S) ; sparse
+ ((eq type 38) ?V) ; volume header
+ (t ?\ )
+ )
+ (tar-grind-file-mode mode)
+ (if (= 0 (length uname)) uid uname)
+ (if (= 0 (length gname)) gid gname)
+ size
+ (if tar-mode-show-date (tar-clip-time-string time) "")
+ (propertize name 'mouse-face 'highlight)
+ (if (or (eq type 1) (eq type 2))
+ (concat (if (= type 1) " ==> " " --> ") link-name)
+ ""))))
(defun tar-summarize-buffer ()
"Parse the contents of the tar file in the current buffer.
(summaries nil))
;; Collect summary lines and insert them all at once since tar files
;; can be pretty big.
- (tar-dolist (tar-desc (reverse tar-parse-info))
+ (dolist (tar-desc (reverse tar-parse-info))
(setq summaries
(cons (tar-header-block-summarize (tar-desc-tokens tar-desc))
(cons "\n"
(insert-buffer-substring tar-buffer start end)
(set-buffer-multibyte t))
(insert-buffer-substring tar-buffer start end))
- (goto-char 0)
+ (goto-char (point-min))
(setq buffer-file-name
;; `:' is not allowed on Windows
(expand-file-name (concat tarname "!" name)))
(and set-auto-coding-function
(save-excursion
(funcall set-auto-coding-function
- name (point-max)))))
+ name (- (point-max) (point))))))
(multibyte enable-multibyte-characters)
(detected (detect-coding-region
1 (min 16384 (point-max)) t)))
(unwind-protect
(let ((coding-system-for-write 'no-conversion))
(set-buffer-multibyte nil)
- (write-region start end to-file))
+ (write-region start end to-file nil nil nil t))
(set-buffer-multibyte multibyte)))
(message "Copied tar entry %s to %s" name to-file)))
With a prefix argument, mark that many files."
(interactive "p")
(beginning-of-line)
- (tar-dotimes (i (if (< p 0) (- p) p))
+ (dotimes (i (if (< p 0) (- p) p))
(if (tar-current-descriptor unflag) ; barf if we're not on an entry-line.
(progn
(delete-char 1)
;; iteration over the files that remain, or only iterate up to
;; the next file to be deleted.
(let ((data-length (- data-end data-start)))
- (tar-dolist (desc following-descs)
+ (dolist (desc following-descs)
(tar-setf (tar-desc-data-start desc)
(- (tar-desc-data-start desc) data-length))))
))
(multibyte enable-multibyte-characters))
(set-buffer-multibyte nil)
(save-excursion
- (goto-char 0)
+ (goto-char (point-min))
(while (not (eobp))
(if (looking-at "D")
(progn (tar-expunge-internal)
"Remove the stars at the beginning of each line."
(interactive)
(save-excursion
- (goto-char 1)
+ (goto-char (point-min))
(while (< (position-bytes (point)) tar-header-offset)
(if (not (eq (following-char) ?\ ))
(progn (delete-char 1) (insert " ")))
;; update the data pointer of this and all following files...
(tar-setf (tar-header-size tokens) subfile-size)
(let ((difference (- subfile-size-pad size-pad)))
- (tar-dolist (desc following-descs)
+ (dolist (desc following-descs)
(tar-setf (tar-desc-data-start desc)
(+ (tar-desc-data-start desc) difference))))
;;
;; alter the descriptor-line...
;;
(let ((position (- (length tar-parse-info) (length head))))
- (goto-char 1)
+ (goto-char (point-min))
(next-line position)
(beginning-of-line)
(let ((p (point))