Function: tramp-crypt-do-copy-or-rename-file

tramp-crypt-do-copy-or-rename-file is a byte-compiled function defined in tramp-crypt.el.gz.

Signature

(tramp-crypt-do-copy-or-rename-file OP FILENAME NEWNAME &optional OK-IF-ALREADY-EXISTS KEEP-DATE PRESERVE-UID-GID PRESERVE-EXTENDED-ATTRIBUTES)

Documentation

Copy or rename a remote file.

OP must be copy or rename and indicates the operation to perform. FILENAME specifies the file to copy or rename, NEWNAME is the name of the new file (for copy) or the new name of the file (for rename). OK-IF-ALREADY-EXISTS means don't barf if NEWNAME exists already. KEEP-DATE means to make sure that NEWNAME has the same timestamp as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep the uid and gid if both files are on the same host. PRESERVE-EXTENDED-ATTRIBUTES is ignored.

This function is invoked by tramp-crypt-handle-copy-file and tramp-crypt-handle-rename-file. It is an error if OP is neither of copy and rename. FILENAME and NEWNAME must be absolute file names.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp-crypt.el.gz
(defun tramp-crypt-do-copy-or-rename-file
  (op filename newname &optional ok-if-already-exists keep-date
   preserve-uid-gid preserve-extended-attributes)
  "Copy or rename a remote file.
OP must be `copy' or `rename' and indicates the operation to perform.
FILENAME specifies the file to copy or rename, NEWNAME is the name of
the new file (for copy) or the new name of the file (for rename).
OK-IF-ALREADY-EXISTS means don't barf if NEWNAME exists already.
KEEP-DATE means to make sure that NEWNAME has the same timestamp
as FILENAME.  PRESERVE-UID-GID, when non-nil, instructs to keep
the uid and gid if both files are on the same host.
PRESERVE-EXTENDED-ATTRIBUTES is ignored.

This function is invoked by `tramp-crypt-handle-copy-file' and
`tramp-crypt-handle-rename-file'.  It is an error if OP is
neither of `copy' and `rename'.  FILENAME and NEWNAME must be
absolute file names."
  ;; FILENAME and NEWNAME are already expanded.
  (unless (memq op '(copy rename))
    (error "Unknown operation `%s', must be `copy' or `rename'" op))

  (setq filename (file-truename filename))
  (let ((t1 (tramp-crypt-file-name-p filename))
	(t2 (tramp-crypt-file-name-p newname))
	(encrypt-filename (tramp-crypt-encrypt-file-name filename))
	(encrypt-newname (tramp-crypt-encrypt-file-name newname))
	(msg-operation (if (eq op 'copy) "Copying" "Renaming")))

    (if (file-directory-p filename)
	(progn
	  (copy-directory filename newname keep-date t)
	  (when (eq op 'rename)
	    (delete-directory filename 'recursive)))

      (with-parsed-tramp-file-name (if t1 filename newname) nil
	(tramp-barf-if-file-missing v filename
	  (when (and (not ok-if-already-exists) (file-exists-p newname))
	    (tramp-error v 'file-already-exists newname))
	  (when (and (file-directory-p newname)
		     (not (directory-name-p newname)))
	    (tramp-error v 'file-error "File is a directory %s" newname))

	  (with-tramp-progress-reporter
	      v 0 (format "%s %s to %s" msg-operation filename newname)
	    (if (and t1 t2 (string-equal t1 t2))
		;; Both files are on the same encrypted remote directory.
		(let (tramp-crypt-enabled)
		  (if (eq op 'copy)
		      (copy-file
		       encrypt-filename encrypt-newname ok-if-already-exists
		       keep-date preserve-uid-gid preserve-extended-attributes)
		    (rename-file
		     encrypt-filename encrypt-newname ok-if-already-exists)))

	      (let* ((tmpdir (tramp-compat-make-temp-file filename 'dir))
		     (tmpfile1
		      (expand-file-name
		       (file-name-nondirectory encrypt-filename) tmpdir))
		     (tmpfile2
		      (expand-file-name
		       (file-name-nondirectory encrypt-newname) tmpdir))
		     tramp-crypt-enabled)
		(cond
		 ;; Source and target file are on an encrypted remote directory.
		 ((and t1 t2)
		  (if (eq op 'copy)
		      (copy-file
		       encrypt-filename encrypt-newname ok-if-already-exists
		       keep-date preserve-uid-gid preserve-extended-attributes)
		    (rename-file
		     encrypt-filename encrypt-newname ok-if-already-exists)))
		 ;; Source file is on an encrypted remote directory.
		 (t1
		  (if (eq op 'copy)
		      (copy-file
		       encrypt-filename tmpfile1 t keep-date preserve-uid-gid
		       preserve-extended-attributes)
		    (rename-file encrypt-filename tmpfile1 t))
		  (tramp-crypt-decrypt-file t1 tmpfile1 tmpfile2)
		  (rename-file tmpfile2 newname ok-if-already-exists))
		 ;; Target file is on an encrypted remote directory.
		 (t2
		  (if (eq op 'copy)
		      (copy-file
		       filename tmpfile1 t keep-date preserve-uid-gid
		       preserve-extended-attributes)
		    (rename-file filename tmpfile1 t))
		  (tramp-crypt-encrypt-file t2 tmpfile1 tmpfile2)
		  (rename-file tmpfile2 encrypt-newname ok-if-already-exists)))
		(delete-directory tmpdir 'recursive)))))))

    (when (and t1 (eq op 'rename))
      (with-parsed-tramp-file-name filename v1
	(tramp-flush-file-properties v1 v1-localname)))

    (when t2
      (with-parsed-tramp-file-name newname v2
	(tramp-flush-file-properties v2 v2-localname)))))