aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2007-08-28 20:09:58 +0000
committerMichael Albinus2007-08-28 20:09:58 +0000
commit8d60099b8054d1c10b3fcbd23e6bf8370da2b27e (patch)
tree7ad8b92050f9adb0ab4506496c6326952d23d7bf
parentaff2ba04077cf2a35a6b11888dacc24294327069 (diff)
downloademacs-8d60099b8054d1c10b3fcbd23e6bf8370da2b27e.tar.gz
emacs-8d60099b8054d1c10b3fcbd23e6bf8370da2b27e.zip
* net/tramp.el (tramp-handle-set-file-times): Flush the file
properties. (tramp-set-file-uid-gid, tramp-get-local-uid) (tramp-get-local-gid): New defuns. (tramp-handle-copy-file): Handle new parameter PRESERVE-UID-GID. (tramp-do-copy-or-rename-file): New parameter PRESERVE-UID-GID. Improve fast track. (tramp-do-copy-or-rename-file-directly): Sync parameter list with the other tramp-do-copy-or-rename-file-* functions. Major rewrite. (tramp-handle-file-local-copy, tramp-handle-insert-file-contents) (tramp-handle-write-region): Improve fast track. (tramp-handle-file-remote-p): IDENTIFICATION can also be 'localname. (tramp-maybe-open-connection): Let `process-adaptive-read-buffering' be nil.
-rw-r--r--lisp/ChangeLog19
-rw-r--r--lisp/net/tramp.el608
2 files changed, 393 insertions, 234 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index d07d9f1b125..ef5ac4d84f9 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,22 @@
12007-08-28 Michael Albinus <michael.albinus@gmx.de>
2
3 * net/tramp.el (tramp-handle-set-file-times): Flush the file
4 properties.
5 (tramp-set-file-uid-gid, tramp-get-local-uid)
6 (tramp-get-local-gid): New defuns.
7 (tramp-handle-copy-file): Handle new parameter PRESERVE-UID-GID.
8 (tramp-do-copy-or-rename-file): New parameter PRESERVE-UID-GID.
9 Improve fast track.
10 (tramp-do-copy-or-rename-file-directly): Sync parameter list with
11 the other tramp-do-copy-or-rename-file-* functions. Major
12 rewrite.
13 (tramp-handle-file-local-copy, tramp-handle-insert-file-contents)
14 (tramp-handle-write-region): Improve fast track.
15 (tramp-handle-file-remote-p): IDENTIFICATION can also be
16 'localname.
17 (tramp-maybe-open-connection): Let `process-adaptive-read-buffering'
18 be nil.
19
12007-08-28 Ivan Kanis <apple@kanis.eu> 202007-08-28 Ivan Kanis <apple@kanis.eu>
2 21
3 * time.el: New feature to display several time zones in a buffer. 22 * time.el: New feature to display several time zones in a buffer.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 85f9287fca8..affeac31c33 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2506,6 +2506,7 @@ of."
2506 (zerop 2506 (zerop
2507 (if (file-remote-p filename) 2507 (if (file-remote-p filename)
2508 (with-parsed-tramp-file-name filename nil 2508 (with-parsed-tramp-file-name filename nil
2509 (tramp-flush-file-property v localname)
2509 (let ((time (if (or (null time) (equal time '(0 0))) 2510 (let ((time (if (or (null time) (equal time '(0 0)))
2510 (current-time) 2511 (current-time)
2511 time)) 2512 time))
@@ -2527,6 +2528,7 @@ of."
2527 (format-time-string "%Y%m%d%H%M.%S" time t) 2528 (format-time-string "%Y%m%d%H%M.%S" time t)
2528 (format-time-string "%Y%m%d%H%M.%S" time)) 2529 (format-time-string "%Y%m%d%H%M.%S" time))
2529 (tramp-shell-quote-argument localname))))) 2530 (tramp-shell-quote-argument localname)))))
2531
2530 ;; We handle also the local part, because in older Emacsen, 2532 ;; We handle also the local part, because in older Emacsen,
2531 ;; without `set-file-times', this function is an alias for this. 2533 ;; without `set-file-times', this function is an alias for this.
2532 ;; We are local, so we don't need the UTC settings. 2534 ;; We are local, so we don't need the UTC settings.
@@ -2535,6 +2537,34 @@ of."
2535 (format-time-string "%Y%m%d%H%M.%S" time) 2537 (format-time-string "%Y%m%d%H%M.%S" time)
2536 (tramp-shell-quote-argument filename))))) 2538 (tramp-shell-quote-argument filename)))))
2537 2539
2540(defun tramp-set-file-uid-gid (filename &optional uid gid)
2541 "Set the ownership for FILENAME.
2542If UID and GID are provided, these values are used; otherwise uid
2543and gid of the corresponding user is taken. Both parameters must be integers."
2544 ;; CCC: Modern Unices allow chown only for root. So we might need
2545 ;; another implementation, see `dired-do-chown'. OTOH, it is
2546 ;; mostly working with su(do)? when it is needed, so it shall
2547 ;; succeed in the majority of cases.
2548 (if (file-remote-p filename)
2549 (with-parsed-tramp-file-name filename nil
2550 (let ((uid (or (and (integerp uid) uid)
2551 (tramp-get-remote-uid v 'integer)))
2552 (gid (or (and (integerp gid) gid)
2553 (tramp-get-remote-gid v 'integer))))
2554 (tramp-send-command
2555 v (format
2556 "chown %d:%d %s" uid gid
2557 (tramp-shell-quote-argument localname)))))
2558
2559 ;; We handle also the local part, because there doesn't exist
2560 ;; `set-file-uid-gid'.
2561 (let ((uid (or (and (integerp uid) uid) (tramp-get-local-uid 'integer)))
2562 (gid (or (and (integerp gid) gid) (tramp-get-local-uid 'integer)))
2563 (default-directory (tramp-temporary-file-directory)))
2564 (call-process
2565 "chown" nil nil nil
2566 (format "%d:%d" uid gid) (tramp-shell-quote-argument filename)))))
2567
2538;; Simple functions using the `test' command. 2568;; Simple functions using the `test' command.
2539 2569
2540(defun tramp-handle-file-executable-p (filename) 2570(defun tramp-handle-file-executable-p (filename)
@@ -2840,7 +2870,7 @@ of."
2840 (buffer-name)))))) 2870 (buffer-name))))))
2841 2871
2842(defun tramp-handle-copy-file 2872(defun tramp-handle-copy-file
2843 (filename newname &optional ok-if-already-exists keep-date) 2873 (filename newname &optional ok-if-already-exists keep-date preserve-uid-gid)
2844 "Like `copy-file' for Tramp files." 2874 "Like `copy-file' for Tramp files."
2845 ;; Check if both files are local -- invoke normal copy-file. 2875 ;; Check if both files are local -- invoke normal copy-file.
2846 ;; Otherwise, use tramp from local system. 2876 ;; Otherwise, use tramp from local system.
@@ -2850,9 +2880,10 @@ of."
2850 (if (or (tramp-tramp-file-p filename) 2880 (if (or (tramp-tramp-file-p filename)
2851 (tramp-tramp-file-p newname)) 2881 (tramp-tramp-file-p newname))
2852 (tramp-do-copy-or-rename-file 2882 (tramp-do-copy-or-rename-file
2853 'copy filename newname ok-if-already-exists keep-date) 2883 'copy filename newname ok-if-already-exists keep-date preserve-uid-gid)
2854 (tramp-run-real-handler 2884 (tramp-run-real-handler
2855 'copy-file (list filename newname ok-if-already-exists keep-date)))) 2885 'copy-file
2886 (list filename newname ok-if-already-exists keep-date preserve-uid-gid))))
2856 2887
2857(defun tramp-handle-rename-file 2888(defun tramp-handle-rename-file
2858 (filename newname &optional ok-if-already-exists) 2889 (filename newname &optional ok-if-already-exists)
@@ -2865,19 +2896,20 @@ of."
2865 (if (or (tramp-tramp-file-p filename) 2896 (if (or (tramp-tramp-file-p filename)
2866 (tramp-tramp-file-p newname)) 2897 (tramp-tramp-file-p newname))
2867 (tramp-do-copy-or-rename-file 2898 (tramp-do-copy-or-rename-file
2868 'rename filename newname ok-if-already-exists t) 2899 'rename filename newname ok-if-already-exists t t)
2869 (tramp-run-real-handler 2900 (tramp-run-real-handler
2870 'rename-file (list filename newname ok-if-already-exists)))) 2901 'rename-file (list filename newname ok-if-already-exists))))
2871 2902
2872(defun tramp-do-copy-or-rename-file 2903(defun tramp-do-copy-or-rename-file
2873 (op filename newname &optional ok-if-already-exists keep-date) 2904 (op filename newname &optional ok-if-already-exists keep-date preserve-uid-gid)
2874 "Copy or rename a remote file. 2905 "Copy or rename a remote file.
2875OP must be `copy' or `rename' and indicates the operation to perform. 2906OP must be `copy' or `rename' and indicates the operation to perform.
2876FILENAME specifies the file to copy or rename, NEWNAME is the name of 2907FILENAME specifies the file to copy or rename, NEWNAME is the name of
2877the new file (for copy) or the new name of the file (for rename). 2908the new file (for copy) or the new name of the file (for rename).
2878OK-IF-ALREADY-EXISTS means don't barf if NEWNAME exists already. 2909OK-IF-ALREADY-EXISTS means don't barf if NEWNAME exists already.
2879KEEP-DATE means to make sure that NEWNAME has the same timestamp 2910KEEP-DATE means to make sure that NEWNAME has the same timestamp
2880as FILENAME. 2911as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
2912the uid and gid if both files are on the same host.
2881 2913
2882This function is invoked by `tramp-handle-copy-file' and 2914This function is invoked by `tramp-handle-copy-file' and
2883`tramp-handle-rename-file'. It is an error if OP is neither of `copy' 2915`tramp-handle-rename-file'. It is an error if OP is neither of `copy'
@@ -2905,7 +2937,9 @@ and `rename'. FILENAME and NEWNAME must be absolute file names."
2905 ;; directly. 2937 ;; directly.
2906 ((tramp-equal-remote filename newname) 2938 ((tramp-equal-remote filename newname)
2907 (tramp-do-copy-or-rename-file-directly 2939 (tramp-do-copy-or-rename-file-directly
2908 op v1 v1-localname v2-localname keep-date)) 2940 op filename newname
2941 ok-if-already-exists keep-date preserve-uid-gid))
2942
2909 ;; If both source and target are Tramp files, 2943 ;; If both source and target are Tramp files,
2910 ;; both are using the same copy-program, then we 2944 ;; both are using the same copy-program, then we
2911 ;; can invoke rcp directly. Note that 2945 ;; can invoke rcp directly. Note that
@@ -2917,6 +2951,7 @@ and `rename'. FILENAME and NEWNAME must be absolute file names."
2917 tramp-copy-size-limit)) 2951 tramp-copy-size-limit))
2918 (tramp-do-copy-or-rename-file-out-of-band 2952 (tramp-do-copy-or-rename-file-out-of-band
2919 op filename newname keep-date)) 2953 op filename newname keep-date))
2954
2920 ;; No shortcut was possible. So we copy the 2955 ;; No shortcut was possible. So we copy the
2921 ;; file first. If the operation was `rename', we go 2956 ;; file first. If the operation was `rename', we go
2922 ;; back and delete the original file (if the copy was 2957 ;; back and delete the original file (if the copy was
@@ -2933,20 +2968,29 @@ and `rename'. FILENAME and NEWNAME must be absolute file names."
2933 ;; One file is a Tramp file, the other one is local. 2968 ;; One file is a Tramp file, the other one is local.
2934 ((or t1 t2) 2969 ((or t1 t2)
2935 (with-parsed-tramp-file-name (if t1 filename newname) nil 2970 (with-parsed-tramp-file-name (if t1 filename newname) nil
2936 ;; If the Tramp file has an out-of-band method, the corresponding 2971 (cond
2937 ;; copy-program can be invoked. 2972 ;; Fast track on local machine.
2938 (if (and (tramp-method-out-of-band-p v) 2973 ((tramp-local-host-p v)
2939 (> (nth 7 (file-attributes filename)) 2974 (tramp-do-copy-or-rename-file-directly
2940 tramp-copy-size-limit)) 2975 op filename newname
2941 (tramp-do-copy-or-rename-file-out-of-band 2976 ok-if-already-exists keep-date preserve-uid-gid))
2942 op filename newname keep-date) 2977
2943 ;; Use the generic method via a Tramp buffer. 2978 ;; If the Tramp file has an out-of-band method, the corresponding
2944 (tramp-do-copy-or-rename-file-via-buffer 2979 ;; copy-program can be invoked.
2945 op filename newname keep-date)))) 2980 ((and (tramp-method-out-of-band-p v)
2981 (> (nth 7 (file-attributes filename))
2982 tramp-copy-size-limit))
2983 (tramp-do-copy-or-rename-file-out-of-band
2984 op filename newname keep-date))
2985
2986 ;; Use the inline method via a Tramp buffer.
2987 (t (tramp-do-copy-or-rename-file-via-buffer
2988 op filename newname keep-date)))))
2946 2989
2947 (t 2990 (t
2948 ;; One of them must be a Tramp file. 2991 ;; One of them must be a Tramp file.
2949 (error "Tramp implementation says this cannot happen"))) 2992 (error "Tramp implementation says this cannot happen")))
2993
2950 ;; When newname did exist, we have wrong cached values. 2994 ;; When newname did exist, we have wrong cached values.
2951 (when t2 2995 (when t2
2952 (with-parsed-tramp-file-name newname nil 2996 (with-parsed-tramp-file-name newname nil
@@ -2977,53 +3021,132 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
2977 (delete-file filename)))) 3021 (delete-file filename))))
2978 3022
2979(defun tramp-do-copy-or-rename-file-directly 3023(defun tramp-do-copy-or-rename-file-directly
2980 (op vec localname1 localname2 keep-date) 3024 (op filename newname ok-if-already-exists keep-date preserve-uid-gid)
2981 "Invokes `cp' or `mv' on the remote system. 3025 "Invokes `cp' or `mv' on the remote system.
2982OP must be one of `copy' or `rename', indicating `cp' or `mv', 3026OP must be one of `copy' or `rename', indicating `cp' or `mv',
2983respectively. VEC specifies the connection. LOCALNAME1 and 3027respectively. FILENAME specifies the file to copy or rename,
2984LOCALNAME2 specify the two arguments of `cp' or `mv'. If 3028NEWNAME is the name of the new file (for copy) or the new name of
2985KEEP-DATE is non-nil, preserve the time stamp when copying." 3029the file (for rename). Both files must reside on the same host.
2986 ;; CCC: What happens to the timestamp when renaming? 3030KEEP-DATE means to make sure that NEWNAME has the same timestamp
2987 (let ((cmd (cond ((and (eq op 'copy) keep-date) "cp -f -p") 3031as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
2988 ((eq op 'copy) "cp -f") 3032the uid and gid from FILENAME."
2989 ((eq op 'rename) "mv -f") 3033 (with-parsed-tramp-file-name (if t1 filename newname) nil
2990 (t (tramp-error 3034 (let* ((cmd (cond ((and (eq op 'copy) preserve-uid-gid) "cp -f -p")
2991 vec 'file-error 3035 ((eq op 'copy) "cp -f")
2992 "Unknown operation `%s', must be `copy' or `rename'" 3036 ((eq op 'rename) "mv -f")
2993 op))))) 3037 (t (tramp-error
2994 (tramp-send-command 3038 vec 'file-error
2995 vec 3039 "Unknown operation `%s', must be `copy' or `rename'"
2996 (format "%s %s %s" 3040 op))))
2997 cmd 3041 (t1 (tramp-tramp-file-p filename))
2998 (tramp-shell-quote-argument localname1) 3042 (t2 (tramp-tramp-file-p newname))
2999 (tramp-shell-quote-argument localname2))) 3043 (localname1
3000 (with-current-buffer (tramp-get-buffer vec) 3044 (if t1 (tramp-handle-file-remote-p filename 'localname) filename))
3001 (goto-char (point-min)) 3045 (localname2
3002 (unless 3046 (if t2 (tramp-handle-file-remote-p newname 'localname) newname))
3003 (or 3047 (prefix (tramp-handle-file-remote-p (if t1 filename newname)))
3004 (and (eq op 'copy) keep-date 3048 (tmpfile (tramp-make-temp-file localname1)))
3005 ;; Mask cp -f error. 3049
3006 (re-search-forward tramp-operation-not-permitted-regexp nil t)) 3050 (cond
3007 (zerop (tramp-send-command-and-check vec nil))) 3051 ;; Both files are on a remote host, with same user.
3008 (tramp-error-with-buffer 3052 ((and t1 t2)
3009 nil vec 'file-error 3053 (tramp-send-command
3010 "Copying directly failed, see buffer `%s' for details." 3054 v
3011 (buffer-name)))) 3055 (format "%s %s %s" cmd
3012 ;; Set the mode. 3056 (tramp-shell-quote-argument localname1)
3013 ;; CCC: Maybe `chmod --reference=localname1 localname2' could be used 3057 (tramp-shell-quote-argument localname2)))
3014 ;; where available? 3058 (with-current-buffer (tramp-get-buffer v)
3015 (unless (or (eq op 'rename) keep-date) 3059 (goto-char (point-min))
3016 (set-file-modes 3060 (unless
3017 (tramp-make-tramp-file-name 3061 (or
3018 (tramp-file-name-method vec) 3062 (and keep-date
3019 (tramp-file-name-user vec) 3063 ;; Mask cp -f error.
3020 (tramp-file-name-host vec) 3064 (re-search-forward
3021 localname2) 3065 tramp-operation-not-permitted-regexp nil t))
3022 (file-modes (tramp-make-tramp-file-name 3066 (zerop (tramp-send-command-and-check v nil)))
3023 (tramp-file-name-method vec) 3067 (tramp-error-with-buffer
3024 (tramp-file-name-user vec) 3068 nil v 'file-error
3025 (tramp-file-name-host vec) 3069 "Copying directly failed, see buffer `%s' for details."
3026 localname1)))))) 3070 (buffer-name)))))
3071
3072 ;; We are on the local host.
3073 ((or t1 t2)
3074 (cond
3075 ;; We can do it directly.
3076 ((and (file-readable-p localname1)
3077 (file-writable-p (file-name-directory localname2)))
3078 (if (eq op 'copy)
3079 (copy-file
3080 localname1 localname2 ok-if-already-exists
3081 keep-date preserve-uid-gid)
3082 (rename-file localname1 localname2 ok-if-already-exists)))
3083
3084 ;; We can do it directly with `tramp-send-command'
3085 ((and (file-readable-p (concat prefix localname1))
3086 (file-writable-p
3087 (file-name-directory (concat prefix localname2))))
3088 (tramp-do-copy-or-rename-file-directly
3089 op (concat prefix localname1) (concat prefix localname2)
3090 ok-if-already-exists keep-date t)
3091 ;; We must change the ownership to the local user.
3092 (tramp-set-file-uid-gid
3093 (concat prefix localname2)
3094 (tramp-get-local-uid 'integer)
3095 (tramp-get-local-gid 'integer)))
3096
3097 ;; We need a temporary file in between.
3098 (t
3099 ;; Create the temporary file.
3100 (cond
3101 (t1
3102 (tramp-send-command
3103 v (format
3104 "%s %s %s" cmd
3105 (tramp-shell-quote-argument localname1)
3106 (tramp-shell-quote-argument tmpfile)))
3107 ;; We must change the ownership as remote user.
3108 (tramp-set-file-uid-gid
3109 (concat prefix tmpfile)
3110 (tramp-get-local-uid 'integer)
3111 (tramp-get-local-gid 'integer)))
3112 (t2
3113 (if (eq op 'copy)
3114 (copy-file
3115 localname1 tmpfile ok-if-already-exists
3116 keep-date preserve-uid-gid)
3117 (rename-file localname1 tmpfile ok-if-already-exists))
3118 ;; We must change the ownership as local user.
3119 (tramp-set-file-uid-gid
3120 tmpfile
3121 (tramp-get-remote-uid v 'integer)
3122 (tramp-get-remote-gid v 'integer))))
3123
3124 ;; Move the temporary file to its destination.
3125 (cond
3126 (t2
3127 (tramp-send-command
3128 v (format
3129 "%s %s %s" cmd
3130 (tramp-shell-quote-argument tmpfile)
3131 (tramp-shell-quote-argument localname2))))
3132 (t1
3133 (if (eq op 'copy)
3134 (copy-file
3135 tmpfile localname2 ok-if-already-exists
3136 keep-date preserve-uid-gid)
3137 (rename-file tmpfile localname2 ok-if-already-exists))))
3138
3139 ;; Remove temporary file.
3140 (when (eq op 'copy) (delete-file tmpfile))))))
3141
3142 ;; Set the time and mode. Mask possible errors.
3143 ;; Won't be applied for 'rename.
3144 (condition-case nil
3145 (when (and keep-date (not preserve-uid-gid))
3146 (set-file-times newname (nth 5 (file-attributes filename)))
3147 (set-file-modes newname (file-modes filename)))
3148 (error)))))
3149
3027 3150
3028(defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date) 3151(defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date)
3029 "Invoke rcp program to copy. 3152 "Invoke rcp program to copy.
@@ -3669,22 +3792,17 @@ beginning of local filename are not substituted."
3669 (with-parsed-tramp-file-name filename nil 3792 (with-parsed-tramp-file-name filename nil
3670 (let ((rem-enc (tramp-get-remote-coding v "remote-encoding")) 3793 (let ((rem-enc (tramp-get-remote-coding v "remote-encoding"))
3671 (loc-dec (tramp-get-local-coding v "local-decoding")) 3794 (loc-dec (tramp-get-local-coding v "local-decoding"))
3672 tmpfil) 3795 (tmpfil (tramp-make-temp-file filename)))
3673 (unless (file-exists-p filename) 3796 (unless (file-exists-p filename)
3674 (tramp-error 3797 (tramp-error
3675 v 'file-error 3798 v 'file-error
3676 "Cannot make local copy of non-existing file `%s'" filename)) 3799 "Cannot make local copy of non-existing file `%s'" filename))
3677 (setq tmpfil (tramp-make-temp-file filename))
3678 3800
3679 (cond 3801 (cond
3680 ;; Fast track on local machine. 3802 ;; `copy-file' handles direct copy and out-of-band methods.
3681 ((tramp-local-host-p v) 3803 ((or (tramp-local-host-p v)
3682 (tramp-do-copy-or-rename-file-directly 'copy v localname tmpfil t) 3804 (and (tramp-method-out-of-band-p v)
3683 (tramp-send-command v (format "chown %s %s" (user-login-name) tmpfil))) 3805 (> (nth 7 (file-attributes filename)) tramp-copy-size-limit)))
3684
3685 ;; `copy-file' handles out-of-band methods.
3686 ((and (tramp-method-out-of-band-p v)
3687 (> (nth 7 (file-attributes filename)) tramp-copy-size-limit))
3688 (copy-file filename tmpfil t t)) 3806 (copy-file filename tmpfil t t))
3689 3807
3690 ;; Use inline encoding for file transfer. 3808 ;; Use inline encoding for file transfer.
@@ -3723,7 +3841,9 @@ beginning of local filename are not substituted."
3723 (delete-file tmpfil2))) 3841 (delete-file tmpfil2)))
3724 (tramp-message v 5 "Decoding remote file %s...done" filename) 3842 (tramp-message v 5 "Decoding remote file %s...done" filename)
3725 ;; Set proper permissions. 3843 ;; Set proper permissions.
3726 (set-file-modes tmpfil (file-modes filename)))) 3844 (set-file-modes tmpfil (file-modes filename))
3845 ;; Set local user ownership.
3846 (tramp-set-file-uid-gid tmpfil)))
3727 3847
3728 ;; Oops, I don't know what to do. 3848 ;; Oops, I don't know what to do.
3729 (t (tramp-error 3849 (t (tramp-error
@@ -3743,6 +3863,7 @@ beginning of local filename are not substituted."
3743 ((eq identification 'method) method) 3863 ((eq identification 'method) method)
3744 ((eq identification 'user) user) 3864 ((eq identification 'user) user)
3745 ((eq identification 'host) host) 3865 ((eq identification 'host) host)
3866 ((eq identification 'localname) localname)
3746 (t (tramp-make-tramp-file-name method user host ""))))))) 3867 (t (tramp-make-tramp-file-name method user host "")))))))
3747 3868
3748(defun tramp-handle-insert-file-contents 3869(defun tramp-handle-insert-file-contents
@@ -3750,43 +3871,51 @@ beginning of local filename are not substituted."
3750 "Like `insert-file-contents' for Tramp files." 3871 "Like `insert-file-contents' for Tramp files."
3751 (barf-if-buffer-read-only) 3872 (barf-if-buffer-read-only)
3752 (setq filename (expand-file-name filename)) 3873 (setq filename (expand-file-name filename))
3753 (with-parsed-tramp-file-name filename nil 3874 (let (coding-system-used result)
3754 (if (not (file-exists-p filename)) 3875 (with-parsed-tramp-file-name filename nil
3755 (progn 3876
3756 (when visit 3877 (if (not (file-exists-p filename))
3757 (setq buffer-file-name filename) 3878 (progn
3758 (set-visited-file-modtime) 3879 (when visit
3759 (set-buffer-modified-p nil)) 3880 (setq buffer-file-name filename)
3760 (tramp-error 3881 (set-visited-file-modtime)
3761 v 'file-error "File %s not found on remote host" filename) 3882 (set-buffer-modified-p nil))
3762 (list (expand-file-name filename) 0)) 3883 (tramp-error
3763 ;; `insert-file-contents-literally' takes care to avoid calling 3884 v 'file-error "File %s not found on remote host" filename)
3764 ;; jka-compr. By let-binding inhibit-file-name-operation, we 3885 (list (expand-file-name filename) 0))
3765 ;; propagate that care to the file-local-copy operation. 3886
3766 (let ((local-copy 3887 (if (and (tramp-local-host-p v)
3767 (let ((inhibit-file-name-operation 3888 (file-readable-p localname))
3768 (when (eq inhibit-file-name-operation 3889 ;; Short track: if we are on the local host, we can run directly.
3769 'insert-file-contents) 3890 (insert-file-contents localname visit beg end replace)
3770 'file-local-copy))) 3891
3771 (file-local-copy filename))) 3892 ;; `insert-file-contents-literally' takes care to avoid calling
3772 coding-system-used result) 3893 ;; jka-compr. By let-binding inhibit-file-name-operation, we
3773 (tramp-message v 4 "Inserting local temp file `%s'..." local-copy) 3894 ;; propagate that care to the file-local-copy operation.
3774 (setq result (insert-file-contents local-copy nil beg end replace)) 3895 (let ((local-copy
3896 (let ((inhibit-file-name-operation
3897 (when (eq inhibit-file-name-operation
3898 'insert-file-contents)
3899 'file-local-copy)))
3900 (file-local-copy filename))))
3901 (tramp-message v 4 "Inserting local temp file `%s'..." local-copy)
3902 (setq result (insert-file-contents local-copy nil beg end replace))
3903 ;; Now `last-coding-system-used' has right value. Remember it.
3904 (when (boundp 'last-coding-system-used)
3905 (setq coding-system-used (symbol-value 'last-coding-system-used)))
3906 (tramp-message v 4 "Inserting local temp file `%s'...done" local-copy)
3907 (delete-file local-copy)
3908 (when (boundp 'last-coding-system-used)
3909 (set 'last-coding-system-used coding-system-used))))
3910
3775 (when visit 3911 (when visit
3912 (setq buffer-read-only (file-writable-p filename))
3776 (setq buffer-file-name filename) 3913 (setq buffer-file-name filename)
3777 (set-visited-file-modtime) 3914 (set-visited-file-modtime)
3778 (set-buffer-modified-p nil)) 3915 (set-buffer-modified-p nil))
3779 ;; Now `last-coding-system-used' has right value. Remember it.
3780 (when (boundp 'last-coding-system-used)
3781 (setq coding-system-used (symbol-value 'last-coding-system-used)))
3782 (tramp-message v 4 "Inserting local temp file `%s'...done" local-copy)
3783 (delete-file local-copy)
3784 (when (boundp 'last-coding-system-used)
3785 (set 'last-coding-system-used coding-system-used))
3786 (list (expand-file-name filename) 3916 (list (expand-file-name filename)
3787 (cadr result)))))) 3917 (cadr result))))))
3788 3918
3789
3790(defun tramp-handle-find-backup-file-name (filename) 3919(defun tramp-handle-find-backup-file-name (filename)
3791 "Like `find-backup-file-name' for Tramp files." 3920 "Like `find-backup-file-name' for Tramp files."
3792 (with-parsed-tramp-file-name filename nil 3921 (with-parsed-tramp-file-name filename nil
@@ -3892,10 +4021,12 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
3892 ;; (string= lockname filename)) 4021 ;; (string= lockname filename))
3893 ;; (error 4022 ;; (error
3894 ;; "tramp-handle-write-region: LOCKNAME must be nil or equal FILENAME")) 4023 ;; "tramp-handle-write-region: LOCKNAME must be nil or equal FILENAME"))
4024
3895 ;; XEmacs takes a coding system as the seventh argument, not `confirm' 4025 ;; XEmacs takes a coding system as the seventh argument, not `confirm'
3896 (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename)) 4026 (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename))
3897 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) 4027 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename))
3898 (tramp-error v 'file-error "File not overwritten"))) 4028 (tramp-error v 'file-error "File not overwritten")))
4029
3899 (let ((rem-dec (tramp-get-remote-coding v "remote-decoding")) 4030 (let ((rem-dec (tramp-get-remote-coding v "remote-decoding"))
3900 (loc-enc (tramp-get-local-coding v "local-encoding")) 4031 (loc-enc (tramp-get-local-coding v "local-encoding"))
3901 (modes (save-excursion (file-modes filename))) 4032 (modes (save-excursion (file-modes filename)))
@@ -3910,146 +4041,148 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
3910 ;; use an encoding function, but currently we use it always 4041 ;; use an encoding function, but currently we use it always
3911 ;; because this makes the logic simpler. 4042 ;; because this makes the logic simpler.
3912 (tmpfil (tramp-make-temp-file filename))) 4043 (tmpfil (tramp-make-temp-file filename)))
3913 ;; We say `no-message' here because we don't want the visited file 4044
3914 ;; modtime data to be clobbered from the temp file. We call 4045 (if (and (tramp-local-host-p v)
3915 ;; `set-visited-file-modtime' ourselves later on. 4046 (file-writable-p (file-name-directory localname)))
3916 (tramp-run-real-handler 4047 ;; Short track: if we are on the local host, we can run directly.
3917 'write-region 4048 (if confirm
3918 (if confirm ; don't pass this arg unless defined for backward compat. 4049 (write-region
3919 (list start end tmpfil append 'no-message lockname confirm) 4050 start end localname append 'no-message lockname confirm)
3920 (list start end tmpfil append 'no-message lockname))) 4051 (write-region start end localname append 'no-message lockname))
3921 ;; Now, `last-coding-system-used' has the right value. Remember it. 4052
3922 (when (boundp 'last-coding-system-used) 4053 ;; We say `no-message' here because we don't want the visited file
3923 (setq coding-system-used (symbol-value 'last-coding-system-used))) 4054 ;; modtime data to be clobbered from the temp file. We call
3924 ;; The permissions of the temporary file should be set. If 4055 ;; `set-visited-file-modtime' ourselves later on.
3925 ;; filename does not exist (eq modes nil) it has been renamed to 4056 (tramp-run-real-handler
3926 ;; the backup file. This case `save-buffer' handles 4057 'write-region
3927 ;; permissions. 4058 (if confirm ; don't pass this arg unless defined for backward compat.
3928 (when modes (set-file-modes tmpfil modes)) 4059 (list start end tmpfil append 'no-message lockname confirm)
3929 4060 (list start end tmpfil append 'no-message lockname)))
3930 ;; This is a bit lengthy due to the different methods possible for 4061 ;; Now, `last-coding-system-used' has the right value. Remember it.
3931 ;; file transfer. First, we check whether the method uses an rcp 4062 (when (boundp 'last-coding-system-used)
3932 ;; program. If so, we call it. Otherwise, both encoding and 4063 (setq coding-system-used (symbol-value 'last-coding-system-used)))
3933 ;; decoding command must be specified. However, if the method 4064 ;; The permissions of the temporary file should be set. If
3934 ;; _also_ specifies an encoding function, then that is used for 4065 ;; filename does not exist (eq modes nil) it has been renamed to
3935 ;; encoding the contents of the tmp file. 4066 ;; the backup file. This case `save-buffer' handles
3936 (cond ;; Fast track on local machine. 4067 ;; permissions.
3937 ((tramp-local-host-p v) 4068 (when modes (set-file-modes tmpfil modes))
3938 (tramp-do-copy-or-rename-file-directly 4069
3939 'rename v tmpfil localname t)) 4070 ;; This is a bit lengthy due to the different methods possible for
3940 4071 ;; file transfer. First, we check whether the method uses an rcp
3941 ;; `copy-file' handles out-of-band methods 4072 ;; program. If so, we call it. Otherwise, both encoding and
3942 ((and (tramp-method-out-of-band-p v) 4073 ;; decoding command must be specified. However, if the method
3943 (integerp start) 4074 ;; _also_ specifies an encoding function, then that is used for
3944 (> (- end start) tramp-copy-size-limit)) 4075 ;; encoding the contents of the tmp file.
3945 (rename-file tmpfil filename t)) 4076 (cond
3946 4077 ;; `rename-file' handles direct copy and out-of-band methods.
3947 ;; Use inline file transfer 4078 ((or (tramp-local-host-p v)
3948 (rem-dec 4079 (and (tramp-method-out-of-band-p v)
3949 ;; Encode tmpfil 4080 (integerp start)
3950 (tramp-message v 5 "Encoding region...") 4081 (> (- end start) tramp-copy-size-limit)))
3951 (unwind-protect 4082 (rename-file tmpfil filename t))
3952 (with-temp-buffer 4083
3953 ;; Use encoding function or command. 4084 ;; Use inline file transfer
3954 (if (and (symbolp loc-enc) (fboundp loc-enc)) 4085 (rem-dec
3955 (progn 4086 ;; Encode tmpfil
3956 (tramp-message 4087 (tramp-message v 5 "Encoding region...")
3957 v 5 "Encoding region using function `%s'..." 4088 (unwind-protect
3958 (symbol-name loc-enc)) 4089 (with-temp-buffer
3959 (let ((coding-system-for-read 'binary)) 4090 ;; Use encoding function or command.
3960 (insert-file-contents-literally tmpfil)) 4091 (if (and (symbolp loc-enc) (fboundp loc-enc))
3961 ;; CCC. The following `let' is a workaround for 4092 (progn
3962 ;; the base64.el that comes with pgnus-0.84. If 4093 (tramp-message
3963 ;; both of the following conditions are 4094 v 5 "Encoding region using function `%s'..."
3964 ;; satisfied, it tries to write to a local file 4095 (symbol-name loc-enc))
3965 ;; in default-directory, but at this point, 4096 (let ((coding-system-for-read 'binary))
3966 ;; default-directory is remote. 4097 (insert-file-contents-literally tmpfil))
3967 ;; (CALL-PROCESS-REGION can't write to remote 4098 ;; CCC. The following `let' is a workaround for
3968 ;; files, it seems.) The file in question is a 4099 ;; the base64.el that comes with pgnus-0.84. If
3969 ;; tmp file anyway. 4100 ;; both of the following conditions are
3970 (let ((default-directory 4101 ;; satisfied, it tries to write to a local file
3971 (tramp-temporary-file-directory))) 4102 ;; in default-directory, but at this point,
3972 (funcall loc-enc (point-min) (point-max)))) 4103 ;; default-directory is remote.
3973 4104 ;; (CALL-PROCESS-REGION can't write to remote
3974 (tramp-message 4105 ;; files, it seems.) The file in question is a
3975 v 5 "Encoding region using command `%s'..." loc-enc) 4106 ;; tmp file anyway.
3976 (unless (equal 0 (tramp-call-local-coding-command
3977 loc-enc tmpfil t))
3978 (tramp-error
3979 v 'file-error
3980 (concat "Cannot write to `%s', local encoding"
3981 " command `%s' failed")
3982 filename loc-enc)))
3983
3984 ;; Send buffer into remote decoding command which
3985 ;; writes to remote file. Because this happens on the
3986 ;; remote host, we cannot use the function.
3987 (goto-char (point-max))
3988 (unless (bolp) (newline))
3989 (tramp-message
3990 v 5 "Decoding region into remote file %s..." filename)
3991 (tramp-send-command
3992 v
3993 (format
3994 "%s >%s <<'EOF'\n%sEOF"
3995 rem-dec
3996 (tramp-shell-quote-argument localname)
3997 (buffer-string)))
3998 (tramp-barf-unless-okay
3999 v nil
4000 (concat "Couldn't write region to `%s',"
4001 " decode using `%s' failed")
4002 filename rem-dec)
4003 ;; When `file-precious-flag' is set, the region is
4004 ;; written to a temporary file. Check that the
4005 ;; checksum is equal to that from the local tmpfil.
4006 (when file-precious-flag
4007 (erase-buffer)
4008 (and
4009 ;; cksum runs locally
4010 (let ((default-directory 4107 (let ((default-directory
4011 (tramp-temporary-file-directory))) 4108 (tramp-temporary-file-directory)))
4012 (zerop (call-process "cksum" tmpfil t))) 4109 (funcall loc-enc (point-min) (point-max))))
4013 ;; cksum runs remotely 4110
4014 (zerop 4111 (tramp-message
4015 (tramp-send-command-and-check 4112 v 5 "Encoding region using command `%s'..." loc-enc)
4016 v 4113 (unless (equal 0 (tramp-call-local-coding-command
4017 (format 4114 loc-enc tmpfil t))
4018 "cksum <%s" 4115 (tramp-error
4019 (tramp-shell-quote-argument localname)))) 4116 v 'file-error
4020 ;; ... they are different 4117 "Cannot write to `%s', local encoding command `%s' failed"
4021 (not 4118 filename loc-enc)))
4022 (string-equal 4119
4023 (buffer-string) 4120 ;; Send buffer into remote decoding command which
4024 (with-current-buffer (tramp-get-buffer v) 4121 ;; writes to remote file. Because this happens on the
4025 (buffer-string)))) 4122 ;; remote host, we cannot use the function.
4026 (tramp-error 4123 (goto-char (point-max))
4027 v 'file-error 4124 (unless (bolp) (newline))
4028 (concat "Couldn't write region to `%s'," 4125 (tramp-message
4029 " decode using `%s' failed") 4126 v 5 "Decoding region into remote file %s..." filename)
4030 filename rem-dec))) 4127 (tramp-send-command
4031 (tramp-message 4128 v
4032 v 5 "Decoding region into remote file %s...done" filename) 4129 (format
4033 (tramp-flush-file-property v localname)) 4130 "%s >%s <<'EOF'\n%sEOF"
4034 4131 rem-dec
4035 ;; Save exit. 4132 (tramp-shell-quote-argument localname)
4036 (delete-file tmpfil))) 4133 (buffer-string)))
4037 4134 (tramp-barf-unless-okay
4038 ;; That's not expected. 4135 v nil
4039 (t 4136 "Couldn't write region to `%s', decode using `%s' failed"
4040 (tramp-error 4137 filename rem-dec)
4041 v 'file-error 4138 ;; When `file-precious-flag' is set, the region is
4042 (concat "Method `%s' should specify both encoding and " 4139 ;; written to a temporary file. Check that the
4043 "decoding command or an rcp program") 4140 ;; checksum is equal to that from the local tmpfil.
4044 method))) 4141 (when file-precious-flag
4142 (erase-buffer)
4143 (and
4144 ;; cksum runs locally
4145 (let ((default-directory (tramp-temporary-file-directory)))
4146 (zerop (call-process "cksum" tmpfil t)))
4147 ;; cksum runs remotely
4148 (zerop
4149 (tramp-send-command-and-check
4150 v
4151 (format "cksum <%s" (tramp-shell-quote-argument localname))))
4152 ;; ... they are different
4153 (not
4154 (string-equal
4155 (buffer-string)
4156 (with-current-buffer (tramp-get-buffer v) (buffer-string))))
4157 (tramp-error
4158 v 'file-error
4159 (concat "Couldn't write region to `%s',"
4160 " decode using `%s' failed")
4161 filename rem-dec)))
4162 (tramp-message
4163 v 5 "Decoding region into remote file %s...done" filename)
4164 (tramp-flush-file-property v localname))
4165
4166 ;; Save exit.
4167 (delete-file tmpfil)))
4168
4169 ;; That's not expected.
4170 (t
4171 (tramp-error
4172 v 'file-error
4173 (concat "Method `%s' should specify both encoding and "
4174 "decoding command or an rcp program")
4175 method))))
4045 4176
4046 (when (or (eq visit t) (stringp visit)) 4177 (when (or (eq visit t) (stringp visit))
4047 (set-visited-file-modtime 4178 (set-visited-file-modtime
4048 ;; We must pass modtime explicitely, because filename can be different 4179 ;; We must pass modtime explicitely, because filename can be different
4049 ;; from (buffer-file-name), f.e. if `file-precious-flag' is set. 4180 ;; from (buffer-file-name), f.e. if `file-precious-flag' is set.
4050 (nth 5 (file-attributes filename)))) 4181 (nth 5 (file-attributes filename))))
4182 ;; Set the ownership.
4183 (tramp-set-file-uid-gid filename)
4051 ;; Make `last-coding-system-used' have the right value. 4184 ;; Make `last-coding-system-used' have the right value.
4052 (when (boundp 'last-coding-system-used) 4185 (when coding-system-used
4053 (set 'last-coding-system-used coding-system-used)) 4186 (set 'last-coding-system-used coding-system-used))
4054 (when (or (eq visit t) (null visit) (stringp visit)) 4187 (when (or (eq visit t) (null visit) (stringp visit))
4055 (tramp-message v 0 "Wrote %s" filename)) 4188 (tramp-message v 0 "Wrote %s" filename))
@@ -5917,6 +6050,7 @@ connection if a previous connection has died for some reason."
5917 (let* ((target-alist (tramp-compute-multi-hops vec)) 6050 (let* ((target-alist (tramp-compute-multi-hops vec))
5918 (process-environment (copy-sequence process-environment)) 6051 (process-environment (copy-sequence process-environment))
5919 (process-connection-type tramp-process-connection-type) 6052 (process-connection-type tramp-process-connection-type)
6053 (process-adaptive-read-buffering nil)
5920 (coding-system-for-read nil) 6054 (coding-system-for-read nil)
5921 ;; This must be done in order to avoid our file name handler. 6055 ;; This must be done in order to avoid our file name handler.
5922 (p (let ((default-directory (tramp-temporary-file-directory))) 6056 (p (let ((default-directory (tramp-temporary-file-directory)))
@@ -6705,6 +6839,12 @@ necessary only. This function will be used in file name completion."
6705 ;; The command might not always return a number. 6839 ;; The command might not always return a number.
6706 (if (and (equal id-format 'integer) (not (integerp res))) -1 res)))) 6840 (if (and (equal id-format 'integer) (not (integerp res))) -1 res))))
6707 6841
6842(defun tramp-get-local-uid (id-format)
6843 (if (equal id-format 'integer) (user-uid) (user-login-name)))
6844
6845(defun tramp-get-local-gid (id-format)
6846 (nth 3 (file-attributes "~/" id-format)))
6847
6708;; Some predefined connection properties. 6848;; Some predefined connection properties.
6709(defun tramp-get-remote-coding (vec prop) 6849(defun tramp-get-remote-coding (vec prop)
6710 ;; Local coding handles properties like remote coding. So we could 6850 ;; Local coding handles properties like remote coding. So we could