GNU bug report logs - #19274
tar-mode.el: allow for adding new archive members

Previous Next

Package: emacs;

Reported by: Ivan Shmakov <ivan <at> siamics.net>

Date: Thu, 4 Dec 2014 21:19:02 UTC

Severity: wishlist

Tags: patch

Fixed in version 25.1

Done: Ivan Shmakov <ivan <at> siamics.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 19274 in the body.
You can then email your comments to 19274 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Thu, 04 Dec 2014 21:19:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Ivan Shmakov <ivan <at> siamics.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 04 Dec 2014 21:19:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: submit <at> debbugs.gnu.org
Subject: tar-mode.el: allow for adding new archive members 
Date: Thu, 04 Dec 2014 21:17:54 +0000
[Message part 1 (text/plain, inline)]
Package:  emacs
Severity: wishlist

	Please consider the patch MIMEd.

	* tar-mode.el: Allow for adding new archive members.
	(tar--pad-to, tar--put-at, tar-header-serialize): New functions.
	(tar-current-position): Split from tar-current-descriptor.
	(tar-current-descriptor): Use it.
	(tar-new-entry): New command.
	(tar-mode-map): Bind it.

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A
[Message part 2 (text/diff, inline)]
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -369,6 +369,58 @@
 	string)
   (tar-parse-octal-integer string))
 
+(defun tar--pad-to (pos)
+  (make-string (+ pos (- (point)) (point-min)) 0))
+
+(defun tar--put-at (pos val)
+  (when val
+    (insert (tar--pad-to pos) val)))
+
+(defun tar-header-serialize (header &optional update-checksum)
+  (with-temp-buffer
+    (set-buffer-multibyte nil)
+    (let ((encoded-name
+	   (encode-coding-string (tar-header-name header)
+				 tar-file-name-coding-system)))
+      (unless (< (length encoded-name) 99)
+	;; FIXME: implement it
+	(error "Long file name support is not implemented"))
+      (insert encoded-name))
+    (insert (tar--pad-to tar-mode-offset)
+	    (format "%6o\0 " (logand #o777777 (tar-header-mode header)))
+	    (format "%6o\0 " (logand #o777777 (tar-header-uid  header)))
+	    (format "%6o\0 " (logand #o777777 (tar-header-gid  header))))
+    (insert (tar--pad-to tar-size-offset)
+	    (format "%11o " (tar-header-size header)))
+    (insert (tar--pad-to tar-time-offset)
+	    (tar-octal-time (tar-header-date header))
+	    " ")
+    ;; omit tar-header-checksum (tar-chk-offset) for now
+    (tar--put-at   tar-linkp-offset (tar-header-link-type header))
+    (tar--put-at   tar-link-offset  (tar-header-link-name header))
+    (when (tar-header-magic header)
+      (tar--put-at tar-magic-offset (tar-header-magic header))
+      (tar--put-at tar-uname-offset (tar-header-uname header))
+      (tar--put-at tar-gname-offset (tar-header-gname header))
+      (let ((dmaj (tar-header-dmaj header))
+	    (dmin (tar-header-dmin header)))
+	(tar--put-at tar-dmaj-offset
+		     (and dmaj (format "%7o\0" (logand #o7777777 dmaj))))
+	(tar--put-at tar-dmin-offset
+		     (and dmin (format "%7o\0" (logand #o7777777 dmin))))))
+    (tar--put-at 512 "")
+    (let ((ck (tar-header-block-checksum (buffer-string))))
+      (goto-char (+ (point-min) tar-chk-offset))
+      (delete-char 8)
+      (insert (format "%6o\0 " ck))
+      (when update-checksum
+	(setf (tar-header-checksum header) ck))
+      (tar-header-block-check-checksum (buffer-string)
+				       (tar-header-checksum header)
+				       (tar-header-name header)))
+    ;; .
+    (buffer-string)))
+
 
 (defun tar-header-block-checksum (string)
   "Compute and return a tar-acceptable checksum for this block."
@@ -547,6 +599,7 @@ defvar tar-mode-map
     (define-key map "p" 'tar-previous-line)
     (define-key map "\^P" 'tar-previous-line)
     (define-key map [up] 'tar-previous-line)
+    (define-key map "I" 'tar-new-entry)
     (define-key map "R" 'tar-rename-entry)
     (define-key map "u" 'tar-unflag)
     (define-key map "v" 'tar-view)
@@ -731,10 +784,14 @@
   (interactive "p")
   (tar-next-line (- arg)))
 
+(defun tar-current-position ()
+  "Return the `tar-parse-info' index for the current line."
+  (count-lines (point-min) (line-beginning-position)))
+
 (defun tar-current-descriptor (&optional noerror)
   "Return the tar-descriptor of the current line, or signals an error."
   ;; I wish lines had plists, like in ZMACS...
-  (or (nth (count-lines (point-min) (line-beginning-position))
+  (or (nth (tar-current-position)
 	   tar-parse-info)
       (if noerror
 	  nil
@@ -948,6 +1005,45 @@
 	(write-region start end to-file nil nil nil t)))
     (message "Copied tar entry %s to %s" name to-file)))
 
+(defun tar-new-entry (filename &optional index)
+  "Insert a new empty regular file before point."
+  (interactive "*sNew file name: ")
+  (let* ((buffer  (current-buffer))
+	 (index   (or index (tar-current-position)))
+	 (d-list  (and (not (zerop index))
+		       (nthcdr (+ -1 index) tar-parse-info)))
+	 (pos     (if d-list
+		      (tar-header-data-end (car d-list))
+		    (point-min)))
+	 (new-descriptor
+	  (make-tar-header
+	   nil
+	   filename
+	   #o644 0 0 0
+	   (current-time)
+	   nil				; checksum
+	   nil nil
+	   nil nil nil nil nil)))
+    ;; update the data buffer; fill the missing descriptor fields
+    (with-current-buffer tar-data-buffer
+      (goto-char pos)
+      (insert (tar-header-serialize new-descriptor t))
+      (setf  (tar-header-data-start new-descriptor)
+	     (copy-marker (point) nil)))
+    ;; update tar-parse-info
+    (if d-list
+	(setcdr d-list     (cons new-descriptor (cdr d-list)))
+      (setq tar-parse-info (cons new-descriptor
+				 tar-parse-info)))
+    ;; update the listing buffer
+    (save-excursion
+      (goto-char (point-min))
+      (forward-line index)
+      (let ((inhibit-read-only t))
+	(insert (tar-header-block-summarize new-descriptor) ?\n)))
+    ;; .
+    index))
+
 (defun tar-flag-deleted (p &optional unflag)
   "In Tar mode, mark this sub-file to be deleted from the tar file.
 With a prefix argument, mark that many files."

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Fri, 05 Dec 2014 02:11:02 GMT) Full text and rfc822 format available.

Message #8 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Ivan Shmakov <ivan <at> siamics.net>
Cc: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Thu, 04 Dec 2014 21:10:18 -0500
> 	* tar-mode.el: Allow for adding new archive members.
> 	(tar--pad-to, tar--put-at, tar-header-serialize): New functions.
> 	(tar-current-position): Split from tar-current-descriptor.
> 	(tar-current-descriptor): Use it.
> 	(tar-new-entry): New command.
> 	(tar-mode-map): Bind it.

Thanks, looks good, please install (with appropriate etc/NEWS entry).
See nitpicks below,


        Stefan


> +    ;; omit tar-header-checksum (tar-chk-offset) for now

Please capitalize and punctuate your comments.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Fri, 05 Dec 2014 20:21:01 GMT) Full text and rfc822 format available.

Message #11 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Fri, 05 Dec 2014 20:20:24 +0000
>>>>> Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

[…]

 >> + ;; omit tar-header-checksum (tar-chk-offset) for now

 > Please capitalize and punctuate your comments.

	Even the one-line ones?

	Given that I have some time to improve this patch, could someone
	please suggest a good place to add a menu entry for
	tar-new-entry in tar-mode-map?  (I never use Emacs’ menus
	myself, so I’m rather clueless on this.)

	BTW, I wonder if it makes sense to split the make-tar-header
	form (with all the nil’s there) off tar-new-entry into a new
	(tar-new-regular-file-header filename &optional size time)
	function?  I guess that’d ease the creation of Tar archives from
	Emacs Lisp code; (and I already imagine some uses to that.)

	I’ll also write a proper docstring for tar-header-serialize, so
	to make it clear this function is part of the module’s external
	interface.

PS.  you know you may be a mathematician if your sentences start with a
	lower-case letter and end with a semicolon;

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 05:10:01 GMT) Full text and rfc822 format available.

Message #14 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Sat, 06 Dec 2014 00:09:56 -0500
>>> + ;; omit tar-header-checksum (tar-chk-offset) for now
>> Please capitalize and punctuate your comments.
> 	Even the one-line ones?

Yes, we do that for all comments, since this poor little sentence would
feel disrespected otherwise.

> 	BTW, I wonder if it makes sense to split the make-tar-header
> 	form (with all the nil’s there) off tar-new-entry into a new
> 	(tar-new-regular-file-header filename &optional size time)
> 	function?  I guess that’d ease the creation of Tar archives from
> 	Emacs Lisp code; (and I already imagine some uses to that.)

BTW, if you're interested in hacking on tar-mode, I keep dreaming of
plugging it into file-name-handler-alist so you can just visit
/foo/bar.tar.gz/somefile, use dired on it, ...


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 19:18:02 GMT) Full text and rfc822 format available.

Message #17 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Sat, 06 Dec 2014 19:17:16 +0000
[Message part 1 (text/plain, inline)]
>>>>> Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

	Please consider the revised patch MIMEd.

	* tar-mode.el: Allow for adding new archive members.
	(tar-new-regular-file-header, tar--pad-to, tar--put-at)
	(tar-header-serialize): New functions.
	(tar-current-position): Split from tar-current-descriptor.
	(tar-current-descriptor): Use it.
	(tar-new-entry): New command.
	(tar-mode-map): Bind it.

[…]

 >> BTW, I wonder if it makes sense to split the make-tar-header form
 >> (with all the nil’s there) off tar-new-entry into a new
 >> (tar-new-regular-file-header filename &optional size time) function?

	(Done.)

 >> I guess that’d ease the creation of Tar archives from Emacs Lisp
 >> code; (and I already imagine some uses to that.)

 > BTW, if you're interested in hacking on tar-mode, I keep dreaming of
 > plugging it into file-name-handler-alist so you can just visit
 > /foo/bar.tar.gz/somefile, use dired on it, ...

	I’m not all that familiar with file-name-handler-alist, but I
	guess I could check it out.  (Although at this point I’m simply
	interested in creating Tar archives from the contents of Emacs
	buffers, – without having them saved into files, that is.)

	Curiously, what would be the sensible behavior for Emacs when
	the copy of the Tar archive kept in the *tar-data* buffer
	happens to differ to the on-disk state of the respective file?

-- 
FSF associate member #7257  np. Вселенская большая любовь — Гражданская Оборона
[Message part 2 (text/diff, inline)]
--- a/etc/NEWS	2014-11-27 11:36:08 +0000
+++ b/etc/NEWS	2014-12-06 19:03:35 +0000
@@ -340,6 +340,9 @@
 `tildify-ignored-environments-alist' variables (as well as a few
 helper functions) obsolete.
 
+** tar-mode: new `tar-new-entry' command, allowing for new members to
+be added to the archive.
+
 ** Obsolete packages
 
 ---
--- a/lisp/tar-mode.el	2014-08-28 19:18:24 +0000
+++ b/lisp/tar-mode.el	2014-12-06 19:04:02 +0000
@@ -50,9 +50,6 @@
 ;;
 ;; o  chmod should understand "a+x,og-w".
 ;;
-;; o  It's not possible to add a NEW file to a tar archive; not that
-;;    important, but still...
-;;
 ;; o  The code is less efficient that it could be - in a lot of places, I
 ;;    pull a 512-character string out of the buffer and parse it, when I could
 ;;    be parsing it in place, not garbaging a string.  Should redo that.
@@ -369,6 +366,83 @@ write-date, checksum, link-type, and link-name."
 	string)
   (tar-parse-octal-integer string))
 
+(defun tar-new-regular-file-header (filename &optional size time)
+  "Return a Tar header for a regular file.
+The header will lack a proper checksum; use `tar-header-block-checksum'
+to compute one, or request `tar-header-serialize' to do that.
+
+Other tar-mode facilities may also require the data-start header
+field to be set to a valid value.
+
+If SIZE is not given or nil, it defaults to 0.
+If TIME is not given or nil, assume now."
+  (make-tar-header
+   nil
+   filename
+   #o644 0 0 (or size 0)
+   (or time (current-time))
+   nil				; checksum
+   nil nil
+   nil nil nil nil nil))
+
+(defun tar--pad-to (pos)
+  (make-string (+ pos (- (point)) (point-min)) 0))
+
+(defun tar--put-at (pos val)
+  (when val
+    (insert (tar--pad-to pos) val)))
+
+(defun tar-header-serialize (header &optional update-checksum)
+  "Return the serialization of a Tar HEADER as a string.
+This function calls `tar-header-block-check-checksum' to ensure the
+checksum is correct.
+
+When UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed
+checksum before doing the check."
+  (with-temp-buffer
+    (set-buffer-multibyte nil)
+    (let ((encoded-name
+	   (encode-coding-string (tar-header-name header)
+				 tar-file-name-coding-system)))
+      (unless (< (length encoded-name) 99)
+	;; FIXME: implement it
+	(error "Long file name support is not implemented"))
+      (insert encoded-name))
+    (insert (tar--pad-to tar-mode-offset)
+	    (format "%6o\0 " (logand #o777777 (tar-header-mode header)))
+	    (format "%6o\0 " (logand #o777777 (tar-header-uid  header)))
+	    (format "%6o\0 " (logand #o777777 (tar-header-gid  header))))
+    (insert (tar--pad-to tar-size-offset)
+	    (format "%11o " (tar-header-size header)))
+    (insert (tar--pad-to tar-time-offset)
+	    (tar-octal-time (tar-header-date header))
+	    " ")
+    ;; omit tar-header-checksum (tar-chk-offset) for now
+    (tar--put-at   tar-linkp-offset (tar-header-link-type header))
+    (tar--put-at   tar-link-offset  (tar-header-link-name header))
+    (when (tar-header-magic header)
+      (tar--put-at tar-magic-offset (tar-header-magic header))
+      (tar--put-at tar-uname-offset (tar-header-uname header))
+      (tar--put-at tar-gname-offset (tar-header-gname header))
+      (let ((dmaj (tar-header-dmaj header))
+	    (dmin (tar-header-dmin header)))
+	(tar--put-at tar-dmaj-offset
+		     (and dmaj (format "%7o\0" (logand #o7777777 dmaj))))
+	(tar--put-at tar-dmin-offset
+		     (and dmin (format "%7o\0" (logand #o7777777 dmin))))))
+    (tar--put-at 512 "")
+    (let ((ck (tar-header-block-checksum (buffer-string))))
+      (goto-char (+ (point-min) tar-chk-offset))
+      (delete-char 8)
+      (insert (format "%6o\0 " ck))
+      (when update-checksum
+	(setf (tar-header-checksum header) ck))
+      (tar-header-block-check-checksum (buffer-string)
+				       (tar-header-checksum header)
+				       (tar-header-name header)))
+    ;; .
+    (buffer-string)))
+
 
 (defun tar-header-block-checksum (string)
   "Compute and return a tar-acceptable checksum for this block."
@@ -547,6 +621,7 @@ MODE should be an integer which is a file mode value."
     (define-key map "p" 'tar-previous-line)
     (define-key map "\^P" 'tar-previous-line)
     (define-key map [up] 'tar-previous-line)
+    (define-key map "I" 'tar-new-entry)
     (define-key map "R" 'tar-rename-entry)
     (define-key map "u" 'tar-unflag)
     (define-key map "v" 'tar-view)
@@ -731,10 +806,14 @@ tar-file's buffer."
   (interactive "p")
   (tar-next-line (- arg)))
 
+(defun tar-current-position ()
+  "Return the `tar-parse-info' index for the current line."
+  (count-lines (point-min) (line-beginning-position)))
+
 (defun tar-current-descriptor (&optional noerror)
   "Return the tar-descriptor of the current line, or signals an error."
   ;; I wish lines had plists, like in ZMACS...
-  (or (nth (count-lines (point-min) (line-beginning-position))
+  (or (nth (tar-current-position)
 	   tar-parse-info)
       (if noerror
 	  nil
@@ -948,6 +1027,37 @@ the current tar-entry."
 	(write-region start end to-file nil nil nil t)))
     (message "Copied tar entry %s to %s" name to-file)))
 
+(defun tar-new-entry (filename &optional index)
+  "Insert a new empty regular file before point."
+  (interactive "*sFile name: ")
+  (let* ((buffer  (current-buffer))
+	 (index   (or index (tar-current-position)))
+	 (d-list  (and (not (zerop index))
+		       (nthcdr (+ -1 index) tar-parse-info)))
+	 (pos     (if d-list
+		      (tar-header-data-end (car d-list))
+		    (point-min)))
+	 (new-descriptor
+	  (tar-new-regular-file-header filename)))
+    ;; Update the data buffer; fill the missing descriptor fields.
+    (with-current-buffer tar-data-buffer
+      (goto-char pos)
+      (insert (tar-header-serialize new-descriptor t))
+      (setf  (tar-header-data-start new-descriptor)
+	     (copy-marker (point) nil)))
+    ;; Update tar-parse-info.
+    (if d-list
+	(setcdr d-list     (cons new-descriptor (cdr d-list)))
+      (setq tar-parse-info (cons new-descriptor tar-parse-info)))
+    ;; Update the listing buffer.
+    (save-excursion
+      (goto-char (point-min))
+      (forward-line index)
+      (let ((inhibit-read-only t))
+	(insert (tar-header-block-summarize new-descriptor) ?\n)))
+    ;; .
+    index))
+
 (defun tar-flag-deleted (p &optional unflag)
   "In Tar mode, mark this sub-file to be deleted from the tar file.
 With a prefix argument, mark that many files."

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 19:34:02 GMT) Full text and rfc822 format available.

Message #20 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Ivan Shmakov <ivan <at> siamics.net>
Cc: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Sat, 06 Dec 2014 21:33:29 +0200
> From: Ivan Shmakov <ivan <at> siamics.net>
> Date: Sat, 06 Dec 2014 19:17:16 +0000
> 
> --- a/etc/NEWS	2014-11-27 11:36:08 +0000
> +++ b/etc/NEWS	2014-12-06 19:03:35 +0000
> @@ -340,6 +340,9 @@
>  `tildify-ignored-environments-alist' variables (as well as a few
>  helper functions) obsolete.
>  
> +** tar-mode: new `tar-new-entry' command, allowing for new members to
> +be added to the archive.

How about adding the necessary bits to the Emacs manual?

> +(defun tar-header-serialize (header &optional update-checksum)
> +  "Return the serialization of a Tar HEADER as a string.
> +This function calls `tar-header-block-check-checksum' to ensure the
> +checksum is correct.
> +
> +When UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed

Not "when", "if".  "When" has an implicit timing reference, which is
not what you mean here.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 19:46:02 GMT) Full text and rfc822 format available.

Message #23 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Sat, 06 Dec 2014 19:45:26 +0000
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>>>> From: Ivan Shmakov  Date: Sat, 06 Dec 2014 19:17:16 +0000

[…]

 >> ** tar-mode: new `tar-new-entry' command, allowing for new members
 >> to be added to the archive.

 > How about adding the necessary bits to the Emacs manual?

	Sure; what’s the respective .texi file?  (Somehow, I failed to
	find one.)

[…]

 >> When UPDATE-CHECKSUM is non-nil, update HEADER with the
 >> newly-computed

 > Not "when", "if".  "When" has an implicit timing reference, which is
 > not what you mean here.

	ACK.

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 19:57:01 GMT) Full text and rfc822 format available.

Message #26 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Ivan Shmakov <ivan <at> siamics.net>
Cc: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Sat, 06 Dec 2014 21:56:18 +0200
> From: Ivan Shmakov <ivan <at> siamics.net>
> Date: Sat, 06 Dec 2014 19:45:26 +0000
> 
> >>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
> >>>>> From: Ivan Shmakov  Date: Sat, 06 Dec 2014 19:17:16 +0000
> 
> […]
> 
>  >> ** tar-mode: new `tar-new-entry' command, allowing for new members
>  >> to be added to the archive.
> 
>  > How about adding the necessary bits to the Emacs manual?
> 
> 	Sure; what’s the respective .texi file?  (Somehow, I failed to
> 	find one.)

"fgrep tar-mode doc/emacs/*.texi blames misc.texi.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 20:05:01 GMT) Full text and rfc822 format available.

Message #29 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Sat, 06 Dec 2014 20:04:46 +0000
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>>>> From: Ivan Shmakov  Date: Sat, 06 Dec 2014 19:45:26 +0000
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:

[…]

 >>> How about adding the necessary bits to the Emacs manual?

 >> Sure; what’s the respective .texi file?  (Somehow, I failed to find
 >> one.)

 > "fgrep tar-mode doc/emacs/*.texi blames misc.texi.

	For me, it only finds ‘tar-mode’ in ‘wordstar-mode’:

$ grep -F -- tar-mode doc/emacs/*.texi 
doc/emacs/ack.texi:@file{tar-mode.el}, which provides simple viewing and editing commands
doc/emacs/misc.texi:@findex wordstar-mode
doc/emacs/misc.texi:@kbd{M-x wordstar-mode} provides a major mode with WordStar-like
$ 

	(And the same for -r --include=\*.texi over doc/ as a whole.)

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 20:16:01 GMT) Full text and rfc822 format available.

Message #32 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Ivan Shmakov <ivan <at> siamics.net>
Cc: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Sat, 06 Dec 2014 22:15:19 +0200
> From: Ivan Shmakov <ivan <at> siamics.net>
> Date: Sat, 06 Dec 2014 20:04:46 +0000
> 
> >>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
> >>>>> From: Ivan Shmakov  Date: Sat, 06 Dec 2014 19:45:26 +0000
> >>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> […]
> 
>  >>> How about adding the necessary bits to the Emacs manual?
> 
>  >> Sure; what’s the respective .texi file?  (Somehow, I failed to find
>  >> one.)
> 
>  > "fgrep tar-mode doc/emacs/*.texi blames misc.texi.
> 
> 	For me, it only finds ‘tar-mode’ in ‘wordstar-mode’:

You are right, sorry.  Try this instead:

  fgrep -w Tar doc/emacs/*.texi




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 20:51:01 GMT) Full text and rfc822 format available.

Message #35 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Sat, 06 Dec 2014 20:50:36 +0000
[Message part 1 (text/plain, inline)]
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>>>> From: Ivan Shmakov  Date: Sat, 06 Dec 2014 20:04:46 +0000
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:

[…]

 >>> "fgrep tar-mode doc/emacs/*.texi blames misc.texi.

 >> For me, it only finds ‘tar-mode’ in ‘wordstar-mode’:

 > You are right, sorry.  Try this instead:

 >   fgrep -w Tar doc/emacs/*.texi 

	Now, it makes me wonder if there should be an @findex tar-mode
	along with the @cindices?  (And @findex archive-mode, too.)

	Otherwise, does the patch MIMEd look sane?

	TIA.

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A
[Message part 2 (text/diff, inline)]
--- a/doc/emacs/files.texi	2014-06-08 07:41:27 +0000
+++ b/doc/emacs/files.texi	2014-12-06 20:44:44 +0000
@@ -1689,6 +1689,14 @@ likewise.  @kbd{v} extracts a file into a buffer in View mode
 another window, so you could edit the file and operate on the archive
 simultaneously.
 
+  The @kbd{I} key adds a new (regular) file to the archive.  The file
+is initially empty, but can readily be edited using the commands
+above.  The command inserts the new file on the line above the current
+one, so that using it on the topmost line of the Tar buffer makes the
+new file the first one in the archive, and using it on the last line
+(the one after the line describing the last file) makes it the last
+one.
+
   @kbd{d} marks a file for deletion when you later use @kbd{x}, and
 @kbd{u} unmarks a file, as in Dired.  @kbd{C} copies a file from the
 archive to disk and @kbd{R} renames a file within the archive.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sat, 06 Dec 2014 23:14:02 GMT) Full text and rfc822 format available.

Message #38 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Sat, 06 Dec 2014 18:13:52 -0500
> 	Please consider the revised patch MIMEd.

Looks good, thanks,


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sun, 07 Dec 2014 16:22:01 GMT) Full text and rfc822 format available.

Message #41 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Ivan Shmakov <ivan <at> siamics.net>
Cc: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Sun, 07 Dec 2014 18:20:06 +0200
> From: Ivan Shmakov <ivan <at> siamics.net>
> Date: Sat, 06 Dec 2014 20:50:36 +0000
> 
>  >   fgrep -w Tar doc/emacs/*.texi 
> 
> 	Now, it makes me wonder if there should be an @findex tar-mode
> 	along with the @cindices?  (And @findex archive-mode, too.)

What, just to help us search for it?  These functions are never
mentioned in that node.

But I don't mind adding the index entries.

(In general, the best way of doing this search is to take note of the
node you are reading in Info, and then search for the corresponding
@node line.)

> 	Otherwise, does the patch MIMEd look sane?

Yes, with one comment; see below.

> +  The @kbd{I} key adds a new (regular) file to the archive.  The file
> +is initially empty, but can readily be edited using the commands
> +above.  The command inserts the new file on the line above the current
> +one, so that using it on the topmost line of the Tar buffer makes the
> +new file the first one in the archive, and using it on the last line
> +(the one after the line describing the last file) makes it the last
> +one.

Instead of the complicated description of "the last line, which is one
line after the last file's line", I'd simply say "at the end of the
buffer".  This is simpler and much more clear, especially to
non-native speakers who might have problems with long and complex
sentences.

Otherwise, it's fine.  Thanks.  (Don't forget to mark the NEWS entry
with "+++" together with installing this change.)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sun, 07 Dec 2014 17:48:02 GMT) Full text and rfc822 format available.

Message #44 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Sun, 07 Dec 2014 17:47:30 +0000
[Message part 1 (text/plain, inline)]
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>>>> From: Ivan Shmakov  Date: Sat, 06 Dec 2014 20:50:36 +0000

 >>> fgrep -w Tar doc/emacs/*.texi

 >> Now, it makes me wonder if there should be an @findex tar-mode along
 >> with the @cindices?  (And @findex archive-mode, too.)

 > What, just to help us search for it?  These functions are never
 > mentioned in that node.

 > But I don't mind adding the index entries.

	I guess my idea of a better Emacs manual includes documenting
	all the command names alongside their respective default
	bindings.  Looks like it warrants a separate bug report, though.

 > (In general, the best way of doing this search is to take note of the
 > node you are reading in Info, and then search for the corresponding
 > @node line.)

	In this particular case, I should have tried the command below.

$ grep -irE --include=\*.texi -- '\<tar\>' doc/ 

[…]

 >> The command inserts the new file on the line above the current one,
 >> so that using it on the topmost line of the Tar buffer makes the new
 >> file the first one in the archive, and using it on the last line
 >> (the one after the line describing the last file) makes it the last
 >> one.

 > Instead of the complicated description of "the last line, which is
 > one line after the last file's line", I'd simply say "at the end of
 > the buffer".  This is simpler and much more clear, especially to
 > non-native speakers who might have problems with long and complex
 > sentences.

	Indeed, that’s much better.  Does it make sense to also simplify
	the head of the sentence as follows?  (I believe that “lines”
	are rather just an implementation detail here.)

- The command inserts the new file on the line above the current one,
+ The command inserts the new file before the current one,

 > Otherwise, it's fine.  Thanks.  (Don't forget to mark the NEWS entry
 > with "+++" together with installing this change.)

	Meanwhile, I’ve also simplified tar-header-serialize a bit (at
	the cost of adding a couple of lines to tar--put-at) – and
	hopefully made it more readable at the same time.

	The (once again) revised patch is MIMEd.

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A
[Message part 2 (text/diff, inline)]
--- a/etc/NEWS	2014-11-27 11:36:08 +0000
+++ b/etc/NEWS	2014-12-07 17:31:11 +0000
@@ -340,6 +340,10 @@
 `tildify-ignored-environments-alist' variables (as well as a few
 helper functions) obsolete.
 
++++
+** tar-mode: new `tar-new-entry' command, allowing for new members to
+be added to the archive.
+
 ** Obsolete packages
 
 ---
--- a/doc/emacs/files.texi	2014-06-08 07:41:27 +0000
+++ b/doc/emacs/files.texi	2014-12-07 17:35:34 +0000
@@ -1689,6 +1689,13 @@ @node File Archives
 another window, so you could edit the file and operate on the archive
 simultaneously.
 
+  The @kbd{I} key adds a new (regular) file to the archive.  The file
+is initially empty, but can readily be edited using the commands
+above.  The command inserts the new file on the line above the current
+one, so that using it on the topmost line of the Tar buffer makes the
+new file the first one in the archive, and using it at the end of the
+buffer makes it the last one.
+
   @kbd{d} marks a file for deletion when you later use @kbd{x}, and
 @kbd{u} unmarks a file, as in Dired.  @kbd{C} copies a file from the
 archive to disk and @kbd{R} renames a file within the archive.
--- a/lisp/tar-mode.el	2014-08-28 19:18:24 +0000
+++ b/lisp/tar-mode.el	2014-12-07 17:44:40 +0000
@@ -50,9 +50,6 @@
 ;;
 ;; o  chmod should understand "a+x,og-w".
 ;;
-;; o  It's not possible to add a NEW file to a tar archive; not that
-;;    important, but still...
-;;
 ;; o  The code is less efficient that it could be - in a lot of places, I
 ;;    pull a 512-character string out of the buffer and parse it, when I could
 ;;    be parsing it in place, not garbaging a string.  Should redo that.
@@ -369,6 +366,80 @@
 	string)
   (tar-parse-octal-integer string))
 
+(defun tar-new-regular-file-header (filename &optional size time)
+  "Return a Tar header for a regular file.
+The header will lack a proper checksum; use `tar-header-block-checksum'
+to compute one, or request `tar-header-serialize' to do that.
+
+Other tar-mode facilities may also require the data-start header
+field to be set to a valid value.
+
+If SIZE is not given or nil, it defaults to 0.
+If TIME is not given or nil, assume now."
+  (make-tar-header
+   nil
+   filename
+   #o644 0 0 (or size 0)
+   (or time (current-time))
+   nil				; checksum
+   nil nil
+   nil nil nil nil nil))
+
+(defun tar--pad-to (pos)
+  (make-string (+ pos (- (point)) (point-min)) 0))
+
+(defun tar--put-at (pos val &optional fmt mask)
+  (when val
+    (insert (tar--pad-to pos)
+	    (if fmt
+		(format fmt (if mask (logand mask val) val))
+	      val))))
+
+(defun tar-header-serialize (header &optional update-checksum)
+  "Return the serialization of a Tar HEADER as a string.
+This function calls `tar-header-block-check-checksum' to ensure the
+checksum is correct.
+
+If UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed
+checksum before doing the check."
+  (with-temp-buffer
+    (set-buffer-multibyte nil)
+    (let ((encoded-name
+	   (encode-coding-string (tar-header-name header)
+				 tar-file-name-coding-system)))
+      (unless (< (length encoded-name) 99)
+	;; FIXME: Implement it.
+	(error "Long file name support is not implemented"))
+      (insert encoded-name))
+    (tar--put-at tar-mode-offset (tar-header-mode header) "%6o\0 " #o777777)
+    (tar--put-at tar-uid-offset  (tar-header-uid  header) "%6o\0 " #o777777)
+    (tar--put-at tar-gid-offset  (tar-header-gid  header) "%6o\0 " #o777777)
+    (tar--put-at tar-size-offset (tar-header-size header) "%11o ")
+    (insert (tar--pad-to tar-time-offset)
+	    (tar-octal-time (tar-header-date header))
+	    " ")
+    ;; Omit tar-header-checksum (tar-chk-offset) for now.
+    (tar--put-at   tar-linkp-offset (tar-header-link-type header))
+    (tar--put-at   tar-link-offset  (tar-header-link-name header))
+    (when (tar-header-magic header)
+      (tar--put-at tar-magic-offset (tar-header-magic header))
+      (tar--put-at tar-uname-offset (tar-header-uname header))
+      (tar--put-at tar-gname-offset (tar-header-gname header))
+      (tar--put-at tar-dmaj-offset (tar-header-dmaj header) "%7o\0" #o7777777)
+      (tar--put-at tar-dmin-offset (tar-header-dmin header) "%7o\0" #o7777777))
+    (tar--put-at 512 "")
+    (let ((ck (tar-header-block-checksum (buffer-string))))
+      (goto-char (+ (point-min) tar-chk-offset))
+      (delete-char 8)
+      (insert (format "%6o\0 " ck))
+      (when update-checksum
+	(setf (tar-header-checksum header) ck))
+      (tar-header-block-check-checksum (buffer-string)
+				       (tar-header-checksum header)
+				       (tar-header-name header)))
+    ;; .
+    (buffer-string)))
+
 
 (defun tar-header-block-checksum (string)
   "Compute and return a tar-acceptable checksum for this block."
@@ -547,6 +618,7 @@ defvar tar-mode-map
     (define-key map "p" 'tar-previous-line)
     (define-key map "\^P" 'tar-previous-line)
     (define-key map [up] 'tar-previous-line)
+    (define-key map "I" 'tar-new-entry)
     (define-key map "R" 'tar-rename-entry)
     (define-key map "u" 'tar-unflag)
     (define-key map "v" 'tar-view)
@@ -731,10 +803,14 @@
   (interactive "p")
   (tar-next-line (- arg)))
 
+(defun tar-current-position ()
+  "Return the `tar-parse-info' index for the current line."
+  (count-lines (point-min) (line-beginning-position)))
+
 (defun tar-current-descriptor (&optional noerror)
   "Return the tar-descriptor of the current line, or signals an error."
   ;; I wish lines had plists, like in ZMACS...
-  (or (nth (count-lines (point-min) (line-beginning-position))
+  (or (nth (tar-current-position)
 	   tar-parse-info)
       (if noerror
 	  nil
@@ -948,6 +1024,37 @@
 	(write-region start end to-file nil nil nil t)))
     (message "Copied tar entry %s to %s" name to-file)))
 
+(defun tar-new-entry (filename &optional index)
+  "Insert a new empty regular file before point."
+  (interactive "*sFile name: ")
+  (let* ((buffer  (current-buffer))
+	 (index   (or index (tar-current-position)))
+	 (d-list  (and (not (zerop index))
+		       (nthcdr (+ -1 index) tar-parse-info)))
+	 (pos     (if d-list
+		      (tar-header-data-end (car d-list))
+		    (point-min)))
+	 (new-descriptor
+	  (tar-new-regular-file-header filename)))
+    ;; Update the data buffer; fill the missing descriptor fields.
+    (with-current-buffer tar-data-buffer
+      (goto-char pos)
+      (insert (tar-header-serialize new-descriptor t))
+      (setf  (tar-header-data-start new-descriptor)
+	     (copy-marker (point) nil)))
+    ;; Update tar-parse-info.
+    (if d-list
+	(setcdr d-list     (cons new-descriptor (cdr d-list)))
+      (setq tar-parse-info (cons new-descriptor tar-parse-info)))
+    ;; Update the listing buffer.
+    (save-excursion
+      (goto-char (point-min))
+      (forward-line index)
+      (let ((inhibit-read-only t))
+	(insert (tar-header-block-summarize new-descriptor) ?\n)))
+    ;; .
+    index))
+
 (defun tar-flag-deleted (p &optional unflag)
   "In Tar mode, mark this sub-file to be deleted from the tar file.
 With a prefix argument, mark that many files."

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sun, 07 Dec 2014 18:00:03 GMT) Full text and rfc822 format available.

Message #47 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Ivan Shmakov <ivan <at> siamics.net>
Cc: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members
Date: Sun, 07 Dec 2014 19:58:01 +0200
> From: Ivan Shmakov <ivan <at> siamics.net>
> Date: Sun, 07 Dec 2014 17:47:30 +0000
> 
>  > (In general, the best way of doing this search is to take note of the
>  > node you are reading in Info, and then search for the corresponding
>  > @node line.)
> 
> 	In this particular case, I should have tried the command below.
> 
> $ grep -irE --include=\*.texi -- '\<tar\>' doc/ 

What I meant is this:

  fgrep "@node File Archives" doc/emacs/*.texi

>  > Instead of the complicated description of "the last line, which is
>  > one line after the last file's line", I'd simply say "at the end of
>  > the buffer".  This is simpler and much more clear, especially to
>  > non-native speakers who might have problems with long and complex
>  > sentences.
> 
> 	Indeed, that’s much better.  Does it make sense to also simplify
> 	the head of the sentence as follows?  (I believe that “lines”
> 	are rather just an implementation detail here.)
> 
> - The command inserts the new file on the line above the current one,
> + The command inserts the new file before the current one,

Yes, that's better.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#19274; Package emacs. (Sun, 07 Dec 2014 18:08:02 GMT) Full text and rfc822 format available.

Message #50 received at 19274 <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274 <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Sun, 07 Dec 2014 18:07:34 +0000
[Message part 1 (text/plain, inline)]
>>>>> Eli Zaretskii <eliz <at> gnu.org> writes:
>>>>> From: Ivan Shmakov  Date: Sun, 07 Dec 2014 17:47:30 +0000

[…]

 >> Does it make sense to also simplify the head of the sentence as
 >> follows?  (I believe that “lines” are rather just an implementation
 >> detail here.)

 >> - The command inserts the new file on the line above the current
 >>   one,
 >> + The command inserts the new file before the current one,

 > Yes, that's better.

	The revised patch for doc/emacs/files.texi is MIMEd.  (The rest
	remains the same [1].)

[1] news:871tobl5cd.fsf <at> violet.siamics.net
    http://permalink.gmane.org/gmane.emacs.bugs/96948

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A
[Message part 2 (text/diff, inline)]
--- a/doc/emacs/files.texi	2014-06-08 07:41:27 +0000
+++ b/doc/emacs/files.texi	2014-12-07 18:05:31 +0000
@@ -1689,6 +1689,13 @@ @node File Archives
 another window, so you could edit the file and operate on the archive
 simultaneously.
 
+  The @kbd{I} key adds a new (regular) file to the archive.  The file
+is initially empty, but can readily be edited using the commands
+above.  The command inserts the new file before the current one, so
+that using it on the topmost line of the Tar buffer makes the new file
+the first one in the archive, and using it at the end of the buffer
+makes it the last one.
+
   @kbd{d} marks a file for deletion when you later use @kbd{x}, and
 @kbd{u} unmarks a file, as in Dired.  @kbd{C} copies a file from the
 archive to disk and @kbd{R} renames a file within the archive.

Added tag(s) patch. Request was from Ivan Shmakov <ivan <at> siamics.net> to control <at> debbugs.gnu.org. (Mon, 29 Dec 2014 09:02:02 GMT) Full text and rfc822 format available.

Reply sent to Ivan Shmakov <ivan <at> siamics.net>:
You have taken responsibility. (Tue, 27 Jan 2015 22:05:02 GMT) Full text and rfc822 format available.

Notification sent to Ivan Shmakov <ivan <at> siamics.net>:
bug acknowledged by developer. (Tue, 27 Jan 2015 22:05:02 GMT) Full text and rfc822 format available.

Message #57 received at 19274-done <at> debbugs.gnu.org (full text, mbox):

From: Ivan Shmakov <ivan <at> siamics.net>
To: 19274-done <at> debbugs.gnu.org
Subject: Re: bug#19274: tar-mode.el: allow for adding new archive members 
Date: Tue, 27 Jan 2015 22:04:18 +0000
[Message part 1 (text/plain, inline)]
Version: 25.1

>>>>> Ivan Shmakov <ivan <at> siamics.net> writes:

[…]

 > The revised patch for doc/emacs/files.texi is MIMEd.  (The rest
 > remains the same [1].)

 > [1] news:871tobl5cd.fsf <at> violet.siamics.net
 >     http://permalink.gmane.org/gmane.emacs.bugs/96948

	Pushed; closing.

-- 
FSF associate member #7257  http://boycottsystemd.org/  … 3013 B6A0 230E 334A
[Message part 2 (text/plain, inline)]
commit a56eab8259568ea1389e972623e46359e73c0233

    Allow for adding new members to Tar archives.

    * lisp/tar-mode.el: Allow for adding new archive members.
    (tar-new-regular-file-header, tar--pad-to, tar--put-at)
    (tar-header-serialize): New functions.
    (tar-current-position): Split from tar-current-descriptor.
    (tar-current-descriptor): Use it.
    (tar-new-entry): New command.
    (tar-mode-map): Bind it.
    * doc/emacs/files.texi (File Archives): Document "I" for tar-new-entry.
    * etc/NEWS: Mention the new tar-new-entry command.

    Fixes: debbugs:19274

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 25 Feb 2015 12:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 9 years and 34 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.