Function: tramp-sh-handle-file-local-copy
tramp-sh-handle-file-local-copy is a byte-compiled function defined in
tramp-sh.el.gz.
Signature
(tramp-sh-handle-file-local-copy FILENAME)
Documentation
Like file-local-copy for Tramp files.
Source Code
;; Defined in /usr/src/emacs/lisp/net/tramp-sh.el.gz
(defun tramp-sh-handle-file-local-copy (filename)
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
(unless (file-exists-p (file-truename filename))
(tramp-compat-file-missing v filename))
(let* ((size (tramp-compat-file-attribute-size
(file-attributes (file-truename filename))))
(rem-enc (tramp-get-inline-coding v "remote-encoding" size))
(loc-dec (tramp-get-inline-coding v "local-decoding" size))
(tmpfile (tramp-compat-make-temp-file filename)))
(condition-case err
(cond
;; `copy-file' handles direct copy and out-of-band methods.
((or (tramp-local-host-p v)
(tramp-method-out-of-band-p v size))
(copy-file filename tmpfile 'ok-if-already-exists 'keep-time))
;; Use inline encoding for file transfer.
(rem-enc
(with-tramp-progress-reporter
v 3
(format-message
"Encoding remote file `%s' with `%s'" filename rem-enc)
(tramp-barf-unless-okay
v (format rem-enc (tramp-shell-quote-argument localname))
"Encoding remote file failed"))
(with-tramp-progress-reporter
v 3 (format-message
"Decoding local file `%s' with `%s'" tmpfile loc-dec)
(if (functionp loc-dec)
;; If local decoding is a function, we call it. We
;; must disable multibyte, because
;; `uudecode-decode-region' doesn't handle it
;; correctly. Unset `file-name-handler-alist'.
;; Otherwise, epa-file gets confused.
(let (file-name-handler-alist
(coding-system-for-write 'binary)
(default-directory
tramp-compat-temporary-file-directory))
(with-temp-file tmpfile
(set-buffer-multibyte nil)
(insert-buffer-substring (tramp-get-buffer v))
(funcall loc-dec (point-min) (point-max))))
;; If tramp-decoding-function is not defined for this
;; method, we invoke tramp-decoding-command instead.
(let ((tmpfile2 (tramp-compat-make-temp-file filename)))
;; Unset `file-name-handler-alist'. Otherwise,
;; epa-file gets confused.
(let (file-name-handler-alist
(coding-system-for-write 'binary))
(with-current-buffer (tramp-get-buffer v)
(write-region
(point-min) (point-max) tmpfile2 nil 'no-message)))
(unwind-protect
(tramp-call-local-coding-command
loc-dec tmpfile2 tmpfile)
(delete-file tmpfile2)))))
;; Set proper permissions.
(set-file-modes tmpfile (tramp-default-file-modes filename))
;; Set local user ownership.
(tramp-set-file-uid-gid tmpfile))
;; Oops, I don't know what to do.
(t (tramp-error
v 'file-error "Wrong method specification for `%s'" method)))
;; Error handling.
((error quit)
(delete-file tmpfile)
(signal (car err) (cdr err))))
(run-hooks 'tramp-handle-file-local-copy-hook)
tmpfile)))