*** /home/albinus/src/tramp/lisp/tramp.el.~2.785~ 2010-04-30 05:50:29.619245904 +0200 --- /home/albinus/src/tramp/lisp/tramp.el 2010-04-29 18:14:53.139400813 +0200 *************** *** 285,290 **** --- 285,297 ---- :group 'tramp :type 'string) + (defcustom tramp-inline-compress-start-size 4096 + "*The minimum size of compressing where inline transfer. + When inline transfer, compress transfered data of file + whose size is this value or above (up to `tramp-copy-size-limit')." + :group 'tramp + :type 'integer) + (defcustom tramp-copy-size-limit 10240 "*The maximum file size where inline copying is preferred over an out-of-the-band copy." :group 'tramp *************** *** 4722,4737 **** v 'file-error "Cannot make local copy of non-existing file `%s'" filename)) ! (let ((rem-enc (tramp-get-remote-coding v "remote-encoding")) ! (loc-dec (tramp-get-local-coding v "local-decoding")) ! (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 (nth 7 (file-attributes filename)))) (copy-file filename tmpfile t t)) ;; Use inline encoding for file transfer. --- 4729,4744 ---- v 'file-error "Cannot make local copy of non-existing file `%s'" filename)) ! (let* ((size (nth 7 (file-attributes 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 t t)) ;; Use inline encoding for file transfer. *************** *** 4739,4750 **** (save-excursion (tramp-message v 5 "Encoding remote file %s..." filename) (tramp-barf-unless-okay ! v ! (format "%s < %s" rem-enc (tramp-shell-quote-argument localname)) "Encoding remote file failed") (tramp-message v 5 "Encoding remote file %s...done" filename) ! (if (and (symbolp loc-dec) (fboundp loc-dec)) ;; If local decoding is a function, we call it. We ;; must disable multibyte, because ;; `uudecode-decode-region' doesn't handle it --- 4746,4756 ---- (save-excursion (tramp-message v 5 "Encoding remote file %s..." filename) (tramp-barf-unless-okay ! v (format rem-enc (tramp-shell-quote-argument localname)) "Encoding remote file failed") (tramp-message v 5 "Encoding remote file %s...done" filename) ! (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 *************** *** 5093,5116 **** 'write-region (list start end localname append 'no-message lockname confirm)) ! (let ((rem-dec (tramp-get-remote-coding v "remote-decoding")) ! (loc-enc (tramp-get-local-coding v "local-encoding")) ! (modes (save-excursion (tramp-default-file-modes filename))) ! ;; We use this to save the value of ! ;; `last-coding-system-used' after writing the tmp file. ! ;; At the end of the function, we set ! ;; `last-coding-system-used' to this saved value. This ! ;; way, any intermediary coding systems used while ! ;; talking to the remote shell or suchlike won't hose ! ;; this variable. This approach was snarfed from ! ;; ange-ftp.el. ! coding-system-used ! ;; Write region into a tmp file. This isn't really ! ;; needed if we use an encoding function, but currently ! ;; we use it always because this makes the logic ! ;; simpler. ! (tmpfile (or tramp-temp-buffer-file-name ! (tramp-compat-make-temp-file filename)))) ;; If `append' is non-nil, we copy the file locally, and let ;; the native `write-region' implementation do the job. --- 5099,5125 ---- 'write-region (list start end localname append 'no-message lockname confirm)) ! (let* ((size (or (and (stringp start) (length start)) ! (- (or end (point-max)) ! (or start (point-min))))) ! (rem-dec (tramp-get-inline-coding v "remote-decoding" size)) ! (loc-enc (tramp-get-inline-coding v "local-encoding" size)) ! (modes (save-excursion (tramp-default-file-modes filename))) ! ;; We use this to save the value of ! ;; `last-coding-system-used' after writing the tmp ! ;; file. At the end of the function, we set ! ;; `last-coding-system-used' to this saved value. This ! ;; way, any intermediary coding systems used while ! ;; talking to the remote shell or suchlike won't hose ! ;; this variable. This approach was snarfed from ! ;; ange-ftp.el. ! coding-system-used ! ;; Write region into a tmp file. This isn't really ! ;; needed if we use an encoding function, but currently ! ;; we use it always because this makes the logic ! ;; simpler. ! (tmpfile (or tramp-temp-buffer-file-name ! (tramp-compat-make-temp-file filename)))) ;; If `append' is non-nil, we copy the file locally, and let ;; the native `write-region' implementation do the job. *************** *** 5156,5163 **** (cond ;; `copy-file' handles direct copy and out-of-band methods. ((or (tramp-local-host-p v) ! (tramp-method-out-of-band-p ! v (nth 7 (file-attributes tmpfile)))) (if (and (not (stringp start)) (= (or end (point-max)) (point-max)) (= (or start (point-min)) (point-min)) --- 5165,5171 ---- (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)) (if (and (not (stringp start)) (= (or end (point-max)) (point-max)) (= (or start (point-min)) (point-min)) *************** *** 5185,5196 **** (tramp-message v 5 "Encoding region...") (unwind-protect (with-temp-buffer ;; Use encoding function or command. ! (if (and (symbolp loc-enc) (fboundp loc-enc)) (progn (tramp-message ! v 5 "Encoding region using function `%s'..." ! (symbol-name loc-enc)) (let ((coding-system-for-read 'binary)) (insert-file-contents-literally tmpfile)) ;; The following `let' is a workaround for the --- 5193,5204 ---- (tramp-message v 5 "Encoding region...") (unwind-protect (with-temp-buffer + (set-buffer-multibyte nil) ;; Use encoding function or command. ! (if (functionp loc-enc) (progn (tramp-message ! v 5 "Encoding region using function `%s'..." loc-enc) (let ((coding-system-for-read 'binary)) (insert-file-contents-literally tmpfile)) ;; The following `let' is a workaround for the *************** *** 5208,5215 **** (tramp-message v 5 "Encoding region using command `%s'..." loc-enc) ! (unless (equal 0 (tramp-call-local-coding-command ! loc-enc tmpfile t)) (tramp-error v 'file-error "Cannot write to `%s', local encoding command `%s' failed" --- 5216,5223 ---- (tramp-message v 5 "Encoding region using command `%s'..." loc-enc) ! (unless (zerop (tramp-call-local-coding-command ! loc-enc tmpfile t)) (tramp-error v 'file-error "Cannot write to `%s', local encoding command `%s' failed" *************** *** 5225,5232 **** (tramp-send-command v (format ! "%s >%s <<'EOF'\n%sEOF" ! rem-dec (tramp-shell-quote-argument localname) (buffer-string))) (tramp-barf-unless-okay --- 5233,5239 ---- (tramp-send-command v (format ! (concat rem-dec " <<'EOF'\n%sEOF") (tramp-shell-quote-argument localname) (buffer-string))) (tramp-barf-unless-okay *************** *** 7200,7205 **** --- 7207,7270 ---- (if (string-match "%s" cmd) (format cmd input) cmd) (if (stringp output) (concat "> " output) "")))) + (defconst tramp-inline-compress-commands + '(("gzip" "gzip -d") + ("bzip2" "bzip2 -d") + ("compress" "compress -d")) + "List of compress and decompress commands for inline transfer. + Each item is a list that looks like this: + + \(COMPRESS DECOMPRESS\) + + COMPRESS or DECOMPRESS are strings with the respective commands.") + + (defun tramp-find-inline-compress (vec) + "Find an inline transfer compress command that works. + Goes through the list `tramp-inline-compress-commands'." + (save-excursion + (let ((commands tramp-inline-compress-commands) + (magic "xyzzy") + item compress decompress + found) + (while (and commands (not found)) + (catch 'next + (setq item (pop commands) + compress (nth 0 item) + decompress (nth 1 item)) + (tramp-message + vec 5 + "Checking local compress command `%s', `%s' for sanity" + compress decompress) + (unless (zerop (tramp-call-local-coding-command + (format "echo %s | %s | %s" + magic compress decompress) nil nil)) + (throw 'next nil)) + (tramp-message + vec 5 + "Checking remote compress command `%s', `%s' for sanity" + compress decompress) + (unless (zerop (tramp-send-command-and-check + vec (format "echo %s | %s | %s" + magic compress decompress) t)) + (throw 'next nil)) + (setq found t))) + + ;; Did we find something? + (if found + (progn + ;; Set connection properties. + (tramp-message + vec 5 "Using inline transfer compress command `%s'" compress) + (tramp-set-connection-property vec "inline-compress" compress) + (tramp-message + vec 5 "Using inline transfer decompress command `%s'" decompress) + (tramp-set-connection-property vec "inline-decompress" decompress)) + + (tramp-set-connection-property vec "inline-compress" nil) + (tramp-set-connection-property vec "inline-decompress" nil) + (tramp-message + vec 2 "Couldn't find an inline transfer compress command"))))) + (defun tramp-compute-multi-hops (vec) "Expands VEC according to `tramp-default-proxies-alist'. Gateway hops are already opened." *************** *** 8080,8086 **** ;; Either the file size is large enough, or (in rare cases) there ;; does not exist a remote encoding. (or (> size tramp-copy-size-limit) ! (null (tramp-get-remote-coding vec "remote-encoding"))))) (defun tramp-local-host-p (vec) "Return t if this points to the local host, nil otherwise." --- 8145,8151 ---- ;; Either the file size is large enough, or (in rare cases) there ;; does not exist a remote encoding. (or (> size tramp-copy-size-limit) ! (null (tramp-get-inline-coding vec "remote-encoding" size))))) (defun tramp-local-host-p (vec) "Return t if this points to the local host, nil otherwise." *************** *** 8361,8387 **** (nth 3 (tramp-compat-file-attributes "~/" id-format))) ;; Some predefined connection properties. ! (defun tramp-get-remote-coding (vec prop) ! ;; Local coding handles properties like remote coding. So we could ! ;; call it without pain. ! (let ((ret (tramp-get-local-coding vec prop))) ;; The connection property might have been cached. So we must send ! ;; the script - maybe. ! (when (and ret (symbolp ret)) ! (let ((name (symbol-name ret))) (while (string-match (regexp-quote "-") name) (setq name (replace-match "_" nil t name))) ! (tramp-maybe-send-script vec (symbol-value ret) name) ! (setq ret name))) ! ;; Return the value. ! ret)) ! ! (defun tramp-get-local-coding (vec prop) ! (or ! (tramp-get-connection-property vec prop nil) ! (progn ! (tramp-find-inline-encoding vec) ! (tramp-get-connection-property vec prop nil)))) (defun tramp-get-method-parameter (method param) "Return the method parameter PARAM. --- 8426,8493 ---- (nth 3 (tramp-compat-file-attributes "~/" id-format))) ;; Some predefined connection properties. ! (defun tramp-get-inline-compress (vec prop size) ! (when (> size tramp-inline-compress-start-size) ! (with-connection-property vec prop ! (tramp-find-inline-compress vec) ! (tramp-get-connection-property vec prop nil)))) ! ! (defun tramp-get-inline-coding (vec prop size) ! "Return the coding command related to PROP. ! PROP is either `remote-encoding', `remode-decoding', ! `local-encoding' or `local-decoding'. ! ! SIZE is the length of the file to be coded. Depending on SIZE, ! compression might be applied. ! ! If no corresponding command is found, NIL is returned. ! Otherwise, either a string is returned which contains a `%s' mark ! to be used for the respective input or output file; or a Lisp ! function cell is returned to be applied on a buffer." ! (let ((coding ! (with-connection-property vec prop ! (tramp-find-inline-encoding vec) ! (tramp-get-connection-property vec prop nil))) ! (prop1 (if (string-match "encoding" prop) ! "inline-compress" "inline-decompress")) ! compress) ;; The connection property might have been cached. So we must send ! ;; the script to the remote side - maybe. ! (when (and coding (symbolp coding) (string-match "remote" prop)) ! (let ((name (symbol-name coding))) (while (string-match (regexp-quote "-") name) (setq name (replace-match "_" nil t name))) ! (tramp-maybe-send-script vec (symbol-value coding) name) ! (setq coding name))) ! (when coding ! ;; Check for the `compress' command. ! (setq compress (tramp-get-inline-compress vec prop1 size)) ! ;; Return the value. ! (cond ! ((and compress (symbolp coding)) ! (if (string-match "decompress" prop1) ! `(lambda (beg end) ! (,coding beg end) ! (apply ! 'call-process-region (point-min) (point-max) ! (car (split-string ,compress)) t t nil ! (cdr (split-string ,compress)))) ! `(lambda (beg end) ! (apply ! 'call-process-region beg end ! (car (split-string ,compress)) t t nil ! (cdr (split-string ,compress))) ! (,coding (point-min) (point-max))))) ! ((symbolp coding) ! coding) ! ((and compress (string-match "decoding" prop)) ! (format "(%s | %s >%%s)" coding compress)) ! (compress ! (format "(%s <%%s | %s)" compress coding)) ! ((string-match "decoding" prop) ! (format "%s >%%s" coding)) ! (t ! (format "%s <%%s" coding)))))) (defun tramp-get-method-parameter (method param) "Return the method parameter PARAM.