+(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)))
+