? tramp-xemacs-merge.diff
Index: ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/ChangeLog,v
retrieving revision 1.40
diff -u -r1.40 ChangeLog
--- ChangeLog	2004/10/18 06:59:08	1.40
+++ ChangeLog	2004/12/23 23:54:20
@@ -1,3 +1,7 @@
+2004-12-23  Michael Albinus  <michael.albinus@gmx.de>
+
+	* Makefile (AUTHOR_VERSION): Bump to 2.0.46.
+
 2004-10-18  Norbert Koch  <viteno@xemacs.org>
 
 	* Makefile (VERSION): XEmacs package 1.20 released.
Index: ChangeLog.upstream
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/ChangeLog.upstream,v
retrieving revision 1.5
diff -u -r1.5 ChangeLog.upstream
--- ChangeLog.upstream	2004/10/17 17:55:41	1.5
+++ ChangeLog.upstream	2004/12/23 23:54:21
@@ -1,3 +1,19 @@
+2004-12-16  Michael Albinus  <michael.albinus@gmx.de>
+
+	Version 2.0.46 released.
+
+	* configure.ac: Bump version.
+
+2004-10-17  Michael Albinus  <michael.albinus@gmx.de>
+
+	* Makefile.XEmacs, package-info.in: Synchronize with XEmacs CVS
+	repository.
+
+2004-10-14  Michael Albinus  <michael.albinus@gmx.de>
+
+	* configure.ac: Bump version (to 2.0.46-pre).  Update merge
+	version to 2.0.45.
+
 2004-10-12  Michael Albinus  <michael.albinus@gmx.de>
 
 	Version 2.0.45 released.
Index: Makefile
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/Makefile,v
retrieving revision 1.40
diff -u -r1.40 Makefile
--- Makefile	2004/10/18 06:59:09	1.40
+++ Makefile	2004/12/23 23:54:21
@@ -18,7 +18,7 @@
 # Boston, MA 02111-1307, USA.
 
 VERSION = 1.20
-AUTHOR_VERSION = 2.0.45
+AUTHOR_VERSION = 2.0.46
 MAINTAINER = Kai Großjohann <kai.grossjohann@gmx.net>
 PACKAGE = tramp
 PKG_TYPE = regular
Index: lisp/ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/lisp/ChangeLog,v
retrieving revision 1.21
diff -u -r1.21 ChangeLog
--- lisp/ChangeLog	2004/10/24 16:42:56	1.21
+++ lisp/ChangeLog	2004/12/23 23:54:30
@@ -1,8 +1,100 @@
-2004-10-24  Michael Albinus  <michael.albinus@gmx.de>
+2004-12-23  Michael Albinus  <michael.albinus@gmx.de>
 
+	* tramp.el (tramp-file-name-for-operation): Mark `shell-command'
+	as magic for Emacs only.
+	(tramp-wait-for-output): Fix error in deleting region.  From Kai
+	Grossjohann <kai.grossjohann@gmx.net>.
+
+	* tramp-vc.el (tramp-vc-do-command, tramp-vc-do-command-new)
+	(tramp-vc-simple-command): Call `tramp-handle-shell-command' but
+	`shell-command', because it isn't magic in XEmacs.  Reported by
+	Adrian Aichner <adrian@xemacs.org>.
+
+
+2004-12-22  Michael Albinus  <michael.albinus@gmx.de>
+
+	* tramp-smb.el (tramp-smb-file-name-handler-alist): Add entry for
+	`substitute-in-file-name.
+	(tramp-smb-handle-substitute-in-file-name): New defun.
+	(tramp-smb-advice-PC-do-completion): Delete advice.
+
+2004-07-06  Kai Grossjohann  <kgrossjo@eu.uu.net>
+
+	Sync with trunk (Michael Albinus <michael.albinus@gmx.de>).
+
+	* tramp.el (tramp-handle-file-newer-than-file-p): Reverse logic.
+	From Andrew J. Korty <ajk@iu.edu>.
+
+2004-12-16  Michael Albinus  <michael.albinus@gmx.de>
+
+	Version 2.0.46 released.
+
+2004-12-05  Michael Albinus  <michael.albinus@gmx.de>
+
+	* tramp.el (tramp-maybe-send-perl-script): Change order of
+	parameters wrt Tramp convention.
+	(tramp-handle-file-attributes-with-perl)
+	(tramp-handle-directory-files-and-attributes): Apply it.
+
+2004-11-26  Lars Hansen  <larsh@math.ku.dk>
+
+	Sync with Emacs CVS (Michael Albinus <michael.albinus@gmx.de>).
+	
+	* tramp.el (tramp-handle-directory-files-and-attributes): New function.
+	(tramp-perl-directory-files-and-attributes): New constant.
+	(tramp-file-name-handler-alist): Delete file-directory-files, add
+	directory-files-and-attributes.
+	(tramp-perl-file-attributes): Surround uid and gid by double
+	quotes. Change parameter id-format from nonnumeric.
+	(tramp-convert-file-attributes): New function.
+	(tramp-handle-file-attributes): Use it.
+	(tramp-maybe-send-perl-script): New function.
+	(tramp-handle-file-attributes-with-perl): Use it. Don't convert
+	file mode. Change parameter id-format from nonnumeric.
+	(tramp-handle-file-attributes-with-ls): Change parameter id-format
+	from nonnumeric.
+	(tramp-post-connection): Don't send tramp-perl-file-attributes
+	script. Reset connection property "perl-scripts".
+	(tramp-handle-insert-directory): Run real handler when ls-lisp is
+	in use.
+
+2004-12-04  Michael Albinus  <michael.albinus@gmx.de>
+
+	* tramp.el (tramp-do-copy-or-rename-file-out-of-band): Check for
+	existence of `copy-program'.  Reported by Zack Weinberg
+	<zack@codesourcery.com>.
+
+2004-11-06  Richard M. Stallman  <rms@gnu.org>
+
+	* tramp.el (tramp group): Add :version.
+
+2004-11-05  Kai Grossjohann  <kgrossjo@eu.uu.net>
+
+	* tramp.el (tramp-coding-commands): Additionally try "uudecode -o
+	/dev/stdout" before trying "uudecode -o -".  Suggested by Han
+	Boetes.
+	(tramp-uudecode): Mention `uudecode -o /dev/stdout'.
+
+2004-10-23  Kai Grossjohann  <kai.grossjohann@gmx.net>
+
+	* tramp-vc.el (vc-do-command): Do not advise it if
+	process-file is fboundp.
+	* tramp.el (tramp-file-name-handler-alist): Add entry for
+	process-file.
+	(tramp-handle-process-file): New function.
+	(tramp-file-name-for-operation): Support process-file.
+
+2004-10-17  Michael Albinus  <michael.albinus@gmx.de>
+
+	* tramp-smb.el (tramp-smb-advice-PC-do-completion): Make the
+	advice less fragile.  Surround temporary redefinition of
+	`substitute-in-file-name' with `unwind-protect'.  Suggested by
+	Matt Hodges <MPHodges@member.fsf.org>.
+
+2004-10-15  John Paul Wallington  <jpw@gnu.org>
+
 	* tramp.el (top): Set `edebug-form-spec' property directly rather
-	than calling `def-edebug-spec'.  From John Paul Wallington
-	<jpw@gnu.org>.
+	than calling `def-edebug-spec'.
 
 2004-10-12  Michael Albinus  <michael.albinus@gmx.de>
 
@@ -77,6 +169,9 @@
 	implementation clarifies.
 
 2004-07-17  Kai Grossjohann  <kai.grossjohann@gmx.net>
+
+	* tramp.el (tramp-handle-verify-visited-file-modtime): New
+	docstring.  From Luc Teirlinck.
 
 	Version 2.0.43 released.
 
Index: lisp/tramp-smb.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/lisp/tramp-smb.el,v
retrieving revision 1.3
diff -u -r1.3 tramp-smb.el
--- lisp/tramp-smb.el	2004/10/17 17:55:51	1.3
+++ lisp/tramp-smb.el	2004/12/23 23:54:33
@@ -1105,9 +1105,11 @@
 	;; Do `PC-do-completion' without substitution
 	(let* (save)
 	  (fset 'save (symbol-function 'substitute-in-file-name))
-	  (fset 'substitute-in-file-name (symbol-function 'identity))
-	  ad-do-it
-	  (fset 'substitute-in-file-name (symbol-function 'save)))
+ 	  (unwind-protect
+ 	      (progn
+ 		(fset 'substitute-in-file-name (symbol-function 'identity))
+ 		ad-do-it)
+ 	    (fset 'substitute-in-file-name (symbol-function 'save))))
 
 	;; Expand "$"
 	(let* ((beg (or (and (functionp 'minibuffer-prompt-end) ; Emacs 21
Index: lisp/tramp-vc.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/lisp/tramp-vc.el,v
retrieving revision 1.11
diff -u -r1.11 tramp-vc.el
--- lisp/tramp-vc.el	2004/09/22 19:09:52	1.11
+++ lisp/tramp-vc.el	2004/12/23 23:54:34
@@ -217,6 +217,7 @@
 ;; Daniel Pittman <daniel@danann.net>
 ;;-(if (fboundp 'vc-call-backend)
 ;;-    () ;; This is the new VC for which we don't have an appropriate advice yet
+(unless (fboundp 'process-file)
 (if (fboundp 'vc-call-backend)
     (defadvice vc-do-command
       (around tramp-advice-vc-do-command
@@ -242,7 +243,7 @@
           (setq ad-return-value
                 (apply 'tramp-vc-do-command buffer okstatus command 
                        (or file (buffer-file-name)) last flags))
-        ad-do-it))))
+        ad-do-it)))))
 ;;-)
 
 
Index: lisp/tramp.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/lisp/tramp.el,v
retrieving revision 1.21
diff -u -r1.21 tramp.el
--- lisp/tramp.el	2004/10/24 16:42:56	1.21
+++ lisp/tramp.el	2004/12/23 23:54:52
@@ -159,7 +159,8 @@
 
 (defgroup tramp nil
   "Edit remote files with a combination of rsh and rcp or similar programs."
-:group 'files)
+:group 'files
+:version "21.4")
 
 (defcustom tramp-verbose 9
   "*Verbosity level for tramp.el.  0 means be silent, 10 is most verbose."
@@ -1535,8 +1536,9 @@
 rm -f /tmp/tramp.$$
 }"
   "Shell function to implement `uudecode' to standard output.
-Many systems support `uudecode -o -' for this or `uudecode -p', but
-some systems don't, and for them we have this shell function.")
+Many systems support `uudecode -o /dev/stdout' or `uudecode -o -'
+for this or `uudecode -p', but some systems don't, and for them
+we have this shell function.")
 
 ;; Perl script to implement `file-attributes' in a Lisp `read'able
 ;; output.  If you are hacking on this, note that you get *no* output
@@ -1545,20 +1547,92 @@
 ;; The device number is returned as "-1", because there will be a virtual
 ;; device number set in `tramp-handle-file-attributes'
 (defconst tramp-perl-file-attributes "\
-\($f, $n) = @ARGV;
-@s = lstat($f);
-if (($s[2] & 0170000) == 0120000) { $l = readlink($f); $l = \"\\\"$l\\\"\"; }
-elsif (($s[2] & 0170000) == 040000) { $l = \"t\"; }
-else { $l = \"nil\" };
-$u = ($n eq \"nil\") ? $s[4] : getpwuid($s[4]);
-$g = ($n eq \"nil\") ? $s[5] : getgrgid($s[5]);
-printf(\"(%s %u %s %s (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) -1)\\n\",
-$l, $s[3], $u, $g, $s[8] >> 16 & 0xffff, $s[8] & 0xffff,
-$s[9] >> 16 & 0xffff, $s[9] & 0xffff, $s[10] >> 16 & 0xffff, $s[10] & 0xffff,
-$s[7], $s[2], $s[1] >> 16 & 0xffff, $s[1] & 0xffff);"
+@stat = lstat($ARGV[0]);
+if (($stat[2] & 0170000) == 0120000)
+{
+    $type = readlink($ARGV[0]);
+    $type = \"\\\"$type\\\"\";
+}
+elsif (($stat[2] & 0170000) == 040000)
+{
+    $type = \"t\";
+}
+else
+{
+    $type = \"nil\"
+};
+$uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
+$gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
+printf(
+    \"(%s %u %s %s (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) -1)\\n\",
+    $type,
+    $stat[3],
+    $uid,
+    $gid,
+    $stat[8] >> 16 & 0xffff,
+    $stat[8] & 0xffff,
+    $stat[9] >> 16 & 0xffff,
+    $stat[9] & 0xffff,
+    $stat[10] >> 16 & 0xffff,
+    $stat[10] & 0xffff,
+    $stat[7],
+    $stat[2],
+    $stat[1] >> 16 & 0xffff,
+    $stat[1] & 0xffff
+);"
   "Perl script to produce output suitable for use with `file-attributes'
 on the remote file system.")
 
+(defconst tramp-perl-directory-files-and-attributes "\
+chdir($ARGV[0]);
+opendir(DIR,\".\");
+@list = readdir(DIR);
+closedir(DIR);
+$n = scalar(@list);
+printf(\"(\\n\");
+for($i = 0; $i < $n; $i++)
+{
+    $filename = $list[$i];
+    @stat = lstat($filename);
+    if (($stat[2] & 0170000) == 0120000)
+    {
+        $type = readlink($filename);
+        $type = \"\\\"$type\\\"\";
+    }
+    elsif (($stat[2] & 0170000) == 040000)
+    {
+        $type = \"t\";
+    }
+    else
+    {
+        $type = \"nil\"
+    };
+    $uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
+    $gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
+    printf(
+        \"(\\\"%s\\\" %s %u %s %s (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) (%u %u))\\n\",
+        $filename,
+        $type,
+        $stat[3],
+        $uid,
+        $gid,
+        $stat[8] >> 16 & 0xffff,
+        $stat[8] & 0xffff,
+        $stat[9] >> 16 & 0xffff,
+        $stat[9] & 0xffff,
+        $stat[10] >> 16 & 0xffff,
+        $stat[10] & 0xffff,
+        $stat[7],
+        $stat[2],
+        $stat[1] >> 16 & 0xffff,
+        $stat[1] & 0xffff,
+        $stat[0] >> 16 & 0xffff,
+        $stat[0] & 0xffff);
+}
+printf(\")\\n\");"
+  "Perl script implementing `directory-files-attributes' as Lisp `read'able
+output.")
+
 ;; ;; These two use uu encoding.
 ;; (defvar tramp-perl-encode "%s -e'\
 ;; print qq(begin 644 xxx\n);
@@ -1757,8 +1831,8 @@
     (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
     (file-attributes . tramp-handle-file-attributes)
     (file-modes . tramp-handle-file-modes)
-    (file-directory-files . tramp-handle-file-directory-files)
     (directory-files . tramp-handle-directory-files)
+    (directory-files-and-attributes . tramp-handle-directory-files-and-attributes)
     (file-name-all-completions . tramp-handle-file-name-all-completions)
     (file-name-completion . tramp-handle-file-name-completion)
     (add-name-to-file . tramp-handle-add-name-to-file)
@@ -1770,6 +1844,7 @@
     (delete-file . tramp-handle-delete-file)
     (directory-file-name . tramp-handle-directory-file-name)
     (shell-command . tramp-handle-shell-command)
+    (process-file . tramp-handle-process-file)
     (insert-directory . tramp-handle-insert-directory)
     (expand-file-name . tramp-handle-expand-file-name)
     (file-local-copy . tramp-handle-file-local-copy)
@@ -2166,26 +2241,21 @@
 ;; Daniel Pittman <daniel@danann.net>
 (defun tramp-handle-file-attributes (filename &optional id-format)
   "Like `file-attributes' for tramp files."
-  (let ((nonnumeric (and id-format (equal id-format 'string)))
-	result)
+  (when (file-exists-p filename)
+    ;; file exists, find out stuff
+    (unless id-format (setq id-format 'integer))
     (with-parsed-tramp-file-name filename nil
-      (when (file-exists-p filename)
-	;; file exists, find out stuff
-	(save-excursion
-	  (if (tramp-get-remote-perl multi-method method user host)
-	      (setq result
-		    (tramp-handle-file-attributes-with-perl
-		     multi-method method user host localname nonnumeric))
-	    (setq result
-		  (tramp-handle-file-attributes-with-ls
-		   multi-method method user host localname nonnumeric)))
-	  ;; set virtual device number
-	  (setcar (nthcdr 11 result)
-		  (tramp-get-device multi-method method user host)))))
-    result))
+      (save-excursion
+        (tramp-convert-file-attributes
+         multi-method method user host
+         (if (tramp-get-remote-perl multi-method method user host)
+             (tramp-handle-file-attributes-with-perl multi-method method user host
+                                                     localname id-format)
+           (tramp-handle-file-attributes-with-ls multi-method method user host
+                                                 localname id-format)))))))
 
 (defun tramp-handle-file-attributes-with-ls
-  (multi-method method user host localname &optional nonnumeric)
+  (multi-method method user host localname &optional id-format)
   "Implement `file-attributes' for tramp files using the ls(1) command."
   (let (symlinkp dirp
 		 res-inode res-filemodes res-numlinks
@@ -2198,7 +2268,7 @@
      multi-method method user host
      (format "%s %s %s"
 	     (tramp-get-ls-command multi-method method user host)
-	     (if nonnumeric "-ild" "-ildn")
+	     (if (eq id-format 'integer) "-ildn" "-ild")
 	     (tramp-shell-quote-argument localname)))
     (tramp-wait-for-output)
     ;; parse `ls -l' output ...
@@ -2225,7 +2295,7 @@
     ;; ... uid and gid
     (setq res-uid (read (current-buffer)))
     (setq res-gid (read (current-buffer)))
-    (unless nonnumeric
+    (when (eq id-format 'integer)
       (unless (numberp res-uid) (setq res-uid -1))
       (unless (numberp res-gid) (setq res-gid -1)))
     ;; ... size
@@ -2270,33 +2340,20 @@
      )))
 
 (defun tramp-handle-file-attributes-with-perl
-  (multi-method method user host localname &optional nonnumeric)
-  "Implement `file-attributes' for tramp files using a Perl script.
-
-The Perl command is sent to the remote machine when the connection
-is initially created and is kept cached by the remote shell."
+  (multi-method method user host localname &optional id-format)
+  "Implement `file-attributes' for tramp files using a Perl script."
   (tramp-message-for-buffer multi-method method user host 10
 			    "file attributes with perl: %s"
 			    (tramp-make-tramp-file-name
 			     multi-method method user host localname))
-  (tramp-send-command
-   multi-method method user host
-   (format "tramp_file_attributes %s %s"
-	   (tramp-shell-quote-argument localname) nonnumeric))
+  (tramp-maybe-send-perl-script multi-method method user host
+				tramp-perl-file-attributes
+                                "tramp_file_attributes")
+  (tramp-send-command multi-method method user host
+                      (format "tramp_file_attributes %s %s"
+                              (tramp-shell-quote-argument localname) id-format))
   (tramp-wait-for-output)
-  (let ((result (read (current-buffer))))
-    (setcar (nthcdr 8 result)
-	    (tramp-file-mode-from-int (nth 8 result)))
-    result))
-
-(defun tramp-get-device (multi-method method user host)
-  "Returns the virtual device number.
-If it doesn't exist, generate a new one."
-  (let ((string (tramp-make-tramp-file-name multi-method method user host "")))
-    (unless (assoc string tramp-devices)
-      (add-to-list 'tramp-devices
-		   (list string (length tramp-devices))))
-    (list -1 (nth 1 (assoc string tramp-devices)))))
+  (read (current-buffer)))
 
 (defun tramp-handle-set-visited-file-modtime (&optional time-list)
   "Like `set-visited-file-modtime' for tramp files."
@@ -2336,7 +2393,12 @@
 ;; This function makes the same assumption as
 ;; `tramp-handle-set-visited-file-modtime'.
 (defun tramp-handle-verify-visited-file-modtime (buf)
-  "Like `verify-visited-file-modtime' for tramp files."
+  "Like `verify-visited-file-modtime' for tramp files.
+At the time `verify-visited-file-modtime' calls this function, we
+already know that the buffer is visiting a file and that
+`visited-file-modtime' does not return 0.  Do not call this
+function directly, unless those two cases are already taken care
+of."
   (with-current-buffer buf
     ;; There is no file visiting the buffer, or the buffer has no
     ;; recorded last modification time.
@@ -2438,7 +2500,7 @@
 		 (fa2 (file-attributes file2)))
 	     (if (and (not (equal (nth 5 fa1) '(0 0)))
 		      (not (equal (nth 5 fa2) '(0 0))))
-		 (> 0 (tramp-time-diff (nth 5 fa1) (nth 5 fa2)))
+		 (> 0 (tramp-time-diff (nth 5 fa2) (nth 5 fa1)))
 	       ;; If one of them is the dont-know value, then we can
 	       ;; still try to run a shell command on the remote host.
 	       ;; However, this only works if both files are Tramp
@@ -2624,6 +2686,38 @@
 		  (push item result)))))))
       result)))
 
+(defun tramp-handle-directory-files-and-attributes
+  (directory &optional full match nosort id-format)
+  "Like `directory-files-and-attributes' for tramp files."
+  (when (tramp-handle-file-exists-p directory)
+    (save-excursion
+      (setq directory (tramp-handle-expand-file-name directory))
+      (with-parsed-tramp-file-name directory nil
+        (tramp-maybe-send-perl-script multi-method method user host
+				      tramp-perl-directory-files-and-attributes
+                                      "tramp_directory_files_and_attributes")
+        (tramp-send-command multi-method method user host
+                            (format "tramp_directory_files_and_attributes %s %s"
+                                    (tramp-shell-quote-argument localname)
+                                    (or id-format 'integer)))
+        (tramp-wait-for-output)
+        (let* ((root (cons nil (read (current-buffer))))
+               (cell root))
+          (while (cdr cell)
+            (if (and match (not (string-match match (caadr cell))))
+                ;; Remove from list
+                (setcdr cell (cddr cell))
+              ;; Include in list
+              (setq cell (cdr cell))
+              (let ((l (car cell)))
+                (tramp-convert-file-attributes multi-method method user host
+                                               (cdr l))
+                ;; If FULL, make file name absolute
+                (when full (setcar l (concat directory "/" (car l)))))))
+          (if nosort
+              (cdr root)
+            (sort (cdr root) (lambda (x y) (string< (car x) (car y))))))))))
+
 ;; This function should return "foo/" for directories and "bar" for
 ;; files.  We use `ls -ad' to get a list of files (including
 ;; directories), and `find . -type d \! -name . -prune' to get a list
@@ -3006,6 +3100,12 @@
 
     ;; Use an asynchronous process.  By this, password can be handled.
     (save-excursion
+
+      ;; Check for program.
+      (when (and (fboundp 'executable-find)
+		 (not (executable-find copy-program)))
+	(error "Cannot find copy program: %s" copy-program))
+
       (set-buffer trampbuf)
       (setq tramp-current-multi-method multi-method
 	    tramp-current-method method
@@ -3087,7 +3187,7 @@
     (tramp-wait-for-output 120)
     ;; Make sure that it worked...
     (and (file-exists-p filename)
-	 (error "Failed to recusively delete %s" filename))))
+	 (error "Failed to recursively delete %s" filename))))
 	 
 (defun tramp-handle-dired-call-process (program discard &rest arguments)
   "Like `dired-call-process' for tramp files."
@@ -3182,83 +3282,87 @@
 (defun tramp-handle-insert-directory
   (filename switches &optional wildcard full-directory-p)
   "Like `insert-directory' for tramp files."
-  ;; For the moment, we assume that the remote "ls" program does not
-  ;; grok "--dired".  In the future, we should detect this on
-  ;; connection setup.
-  (when (string-match "^--dired\\s-+" switches)
-    (setq switches (replace-match "" nil t switches)))
-  (setq filename (expand-file-name filename))
-  (with-parsed-tramp-file-name filename nil
-    (tramp-message-for-buffer
-     multi-method method user host 10
-     "Inserting directory `ls %s %s', wildcard %s, fulldir %s"
-     switches filename (if wildcard "yes" "no")
-     (if full-directory-p "yes" "no"))
-    (when wildcard
-      (setq wildcard (file-name-nondirectory localname))
-      (setq localname (file-name-directory localname)))
-    (when (listp switches)
-      (setq switches (mapconcat 'identity switches " ")))
-    (unless full-directory-p
-      (setq switches (concat "-d " switches)))
-    (when wildcard
-      (setq switches (concat switches " " wildcard)))
-    (save-excursion
-      ;; If `full-directory-p', we just say `ls -l FILENAME'.
-      ;; Else we chdir to the parent directory, then say `ls -ld BASENAME'.
-      (if full-directory-p
-	  (tramp-send-command
-	   multi-method method user host
-	   (format "%s %s %s"
-		   (tramp-get-ls-command multi-method method user host)
-		   switches
-		   (if wildcard
-		       localname
-		     (tramp-shell-quote-argument (concat localname ".")))))
-	(tramp-barf-unless-okay
-	 multi-method method user host
-	 (format "cd %s" (tramp-shell-quote-argument
-			  (file-name-directory localname)))
-	 nil 'file-error
-	 "Couldn't `cd %s'"
-	 (tramp-shell-quote-argument (file-name-directory localname)))
-	(tramp-send-command
-	 multi-method method user host
-	 (format "%s %s %s"
-		 (tramp-get-ls-command multi-method method user host)
-		 switches
-		 (if wildcard
-		     localname
-		   (tramp-shell-quote-argument
-		    (file-name-nondirectory localname))))))
-      (sit-for 1)			;needed for rsh but not ssh?
-      (tramp-wait-for-output))
-    ;; The following let-binding is used by code that's commented
-    ;; out.  Let's leave the let-binding in for a while to see
-    ;; that the commented-out code is really not needed.  Commenting-out
-    ;; happened on 2003-03-13.
-    (let ((old-pos (point)))
-      (insert-buffer-substring
-       (tramp-get-buffer multi-method method user host))
-      ;; On XEmacs, we want to call (exchange-point-and-mark t), but
-      ;; that doesn't exist on Emacs, so we use this workaround instead.
-      ;; Since zmacs-region-stays doesn't exist in Emacs, this ought to
-      ;; be safe.  Thanks to Daniel Pittman <daniel@danann.net>.
-      ;;     (let ((zmacs-region-stays t))
-      ;;       (exchange-point-and-mark))
+  (if (and (boundp 'ls-lisp-use-insert-directory-program)
+           (not ls-lisp-use-insert-directory-program))
+      (tramp-run-real-handler 'insert-directory
+                              (list filename switches wildcard full-directory-p))
+    ;; For the moment, we assume that the remote "ls" program does not
+    ;; grok "--dired".  In the future, we should detect this on
+    ;; connection setup.
+    (when (string-match "^--dired\\s-+" switches)
+      (setq switches (replace-match "" nil t switches)))
+    (setq filename (expand-file-name filename))
+    (with-parsed-tramp-file-name filename nil
+      (tramp-message-for-buffer
+       multi-method method user host 10
+       "Inserting directory `ls %s %s', wildcard %s, fulldir %s"
+       switches filename (if wildcard "yes" "no")
+       (if full-directory-p "yes" "no"))
+      (when wildcard
+        (setq wildcard (file-name-nondirectory localname))
+        (setq localname (file-name-directory localname)))
+      (when (listp switches)
+        (setq switches (mapconcat 'identity switches " ")))
+      (unless full-directory-p
+        (setq switches (concat "-d " switches)))
+      (when wildcard
+        (setq switches (concat switches " " wildcard)))
       (save-excursion
-	(tramp-send-command multi-method method user host "cd")
-	(tramp-wait-for-output))
-      ;; For the time being, the XEmacs kludge is commented out.
-      ;; Please test it on various XEmacs versions to see if it works.
-;;       ;; Another XEmacs specialty follows.  What's the right way to do
-;;       ;; it?
-;;       (when (and (featurep 'xemacs)
-;; 		 (eq major-mode 'dired-mode))
-;; 	(save-excursion
-;; 	  (require 'dired)
-;; 	  (dired-insert-set-properties old-pos (point))))
-      )))
+        ;; If `full-directory-p', we just say `ls -l FILENAME'.
+        ;; Else we chdir to the parent directory, then say `ls -ld BASENAME'.
+        (if full-directory-p
+            (tramp-send-command
+             multi-method method user host
+             (format "%s %s %s"
+                     (tramp-get-ls-command multi-method method user host)
+                     switches
+                     (if wildcard
+                         localname
+                       (tramp-shell-quote-argument (concat localname ".")))))
+          (tramp-barf-unless-okay
+           multi-method method user host
+           (format "cd %s" (tramp-shell-quote-argument
+                            (file-name-directory localname)))
+           nil 'file-error
+           "Couldn't `cd %s'"
+           (tramp-shell-quote-argument (file-name-directory localname)))
+          (tramp-send-command
+           multi-method method user host
+           (format "%s %s %s"
+                   (tramp-get-ls-command multi-method method user host)
+                   switches
+                   (if wildcard
+                       localname
+                     (tramp-shell-quote-argument
+                      (file-name-nondirectory localname))))))
+        (sit-for 1)			;needed for rsh but not ssh?
+        (tramp-wait-for-output))
+      ;; The following let-binding is used by code that's commented
+      ;; out.  Let's leave the let-binding in for a while to see
+      ;; that the commented-out code is really not needed.  Commenting-out
+      ;; happened on 2003-03-13.
+      (let ((old-pos (point)))
+        (insert-buffer-substring
+         (tramp-get-buffer multi-method method user host))
+        ;; On XEmacs, we want to call (exchange-point-and-mark t), but
+        ;; that doesn't exist on Emacs, so we use this workaround instead.
+        ;; Since zmacs-region-stays doesn't exist in Emacs, this ought to
+        ;; be safe.  Thanks to Daniel Pittman <daniel@danann.net>.
+        ;;     (let ((zmacs-region-stays t))
+        ;;       (exchange-point-and-mark))
+        (save-excursion
+          (tramp-send-command multi-method method user host "cd")
+          (tramp-wait-for-output))
+        ;; For the time being, the XEmacs kludge is commented out.
+        ;; Please test it on various XEmacs versions to see if it works.
+        ;;       ;; Another XEmacs specialty follows.  What's the right way to do
+        ;;       ;; it?
+        ;;       (when (and (featurep 'xemacs)
+        ;; 		 (eq major-mode 'dired-mode))
+        ;; 	(save-excursion
+        ;; 	  (require 'dired)
+        ;; 	  (dired-insert-set-properties old-pos (point))))
+        ))))
 
 ;; Continuation of kluge to pacify byte-compiler.
 ;;(eval-when-compile
@@ -3468,6 +3572,18 @@
     (tramp-run-real-handler 'shell-command
 			    (list command output-buffer error-buffer))))
 
+(defun tramp-handle-process-file (program &optional infile buffer display &rest args)
+  "Like `process-file' for Tramp files."
+  (when infile (error "Implementation does not handle input from file"))
+  (when (and (numberp buffer) (zerop buffer))
+    (error "Implementation does not handle immediate return"))
+  (when (consp buffer) (error "Implementation does not handle error files"))
+  (shell-command 
+   (mapconcat 'tramp-shell-quote-argument
+              (cons program args)
+              " ")
+   buffer))
+
 ;; File Editing.
 
 (defsubst tramp-make-temp-file ()
@@ -3958,7 +4074,11 @@
      (if (bufferp (nth 0 args)) (nth 0 args) (current-buffer))))
    ; COMMAND
    ((member operation
-	    (list 'dired-call-process 'shell-command
+	    (list 'dired-call-process-command
+                  ; Emacs only
+		  'shell
+                  ; Post Emacs 21.3 only
+                  'process-file
 	          ; XEmacs only
 		  'dired-print-file 'dired-shell-call-process))
     default-directory)
@@ -4661,6 +4781,29 @@
 
 ;;; Internal Functions:
 
+(defun tramp-maybe-send-perl-script (multi-method method user host script name)
+  "Define in remote shell function NAME implemented as perl SCRIPT.
+Only send the definition if it has not already been done.
+Function may have 0-3 parameters."
+  (let ((remote-perl (tramp-get-remote-perl multi-method method user host)))
+    (unless remote-perl (error "No remote perl"))
+    (let ((perl-scripts (tramp-get-connection-property "perl-scripts" nil
+                                                       multi-method method user host)))
+      (unless (memq name perl-scripts)
+        (with-current-buffer (tramp-get-buffer multi-method method user host)
+          (tramp-message 5 (concat "Sending the Perl script `" name "'..."))
+          (tramp-send-string multi-method method user host
+                             (concat name
+                                     " () {\n"
+                                     remote-perl
+                                     " -e '"
+                                     script
+                                     "' \"$1\" \"$2\" \"$3\" 2>/dev/null\n}"))
+          (tramp-wait-for-output)
+          (tramp-set-connection-property "perl-scripts" (cons name perl-scripts)
+                                         multi-method method user host)
+          (tramp-message 5 (concat "Sending the Perl script `" name "'...done.")))))))
+
 (defun tramp-set-auto-save ()
   (when (and (buffer-file-name)
              (tramp-tramp-file-p (buffer-file-name))
@@ -5841,6 +5984,7 @@
   (tramp-wait-for-output)
   ;; Find a `perl'.
   (erase-buffer)
+  (tramp-set-connection-property "perl-scripts" nil multi-method method user host)
   (let ((tramp-remote-perl
 	 (or (tramp-find-executable multi-method method user host
 				    "perl5" tramp-remote-path nil)
@@ -5849,48 +5993,37 @@
     (when tramp-remote-perl
       (tramp-set-connection-property "perl" tramp-remote-perl
 				     multi-method method user host)
-      ;; Set up stat in Perl if we can.
-      (when tramp-remote-perl
-	(tramp-message 5 "Sending the Perl `file-attributes' implementation.")
-	(tramp-send-string
-	 multi-method method user host
-	 (concat "tramp_file_attributes () {\n"
-		 tramp-remote-perl
-		 " -e '" tramp-perl-file-attributes "'"
-		 " \"$1\" \"$2\" 2>/dev/null\n"
-		 "}"))
-	(tramp-wait-for-output)
-	(unless (tramp-method-out-of-band-p multi-method method user host)
-	  (tramp-message 5 "Sending the Perl `mime-encode' implementations.")
-	  (tramp-send-string
-	   multi-method method user host
-	   (concat "tramp_encode () {\n"
-		   (format tramp-perl-encode tramp-remote-perl)
-		   " 2>/dev/null"
-		   "\n}"))
-	  (tramp-wait-for-output)
-	  (tramp-send-string
-	   multi-method method user host
-	   (concat "tramp_encode_with_module () {\n"
-		   (format tramp-perl-encode-with-module tramp-remote-perl)
-		   " 2>/dev/null"
-		   "\n}"))
-	  (tramp-wait-for-output)
-	  (tramp-message 5 "Sending the Perl `mime-decode' implementations.")
-	  (tramp-send-string
-	   multi-method method user host
-	   (concat "tramp_decode () {\n"
-		   (format tramp-perl-decode tramp-remote-perl)
-		   " 2>/dev/null"
-		   "\n}"))
-	  (tramp-wait-for-output)
-	  (tramp-send-string
-	   multi-method method user host
-	   (concat "tramp_decode_with_module () {\n"
-		   (format tramp-perl-decode-with-module tramp-remote-perl)
-		   " 2>/dev/null"
-		   "\n}"))
-	  (tramp-wait-for-output)))))
+      (unless (tramp-method-out-of-band-p multi-method method user host)
+        (tramp-message 5 "Sending the Perl `mime-encode' implementations.")
+        (tramp-send-string
+         multi-method method user host
+         (concat "tramp_encode () {\n"
+                 (format tramp-perl-encode tramp-remote-perl)
+                 " 2>/dev/null"
+                 "\n}"))
+        (tramp-wait-for-output)
+        (tramp-send-string
+         multi-method method user host
+         (concat "tramp_encode_with_module () {\n"
+                 (format tramp-perl-encode-with-module tramp-remote-perl)
+                 " 2>/dev/null"
+                 "\n}"))
+        (tramp-wait-for-output)
+        (tramp-message 5 "Sending the Perl `mime-decode' implementations.")
+        (tramp-send-string
+         multi-method method user host
+         (concat "tramp_decode () {\n"
+                 (format tramp-perl-decode tramp-remote-perl)
+                 " 2>/dev/null"
+                 "\n}"))
+        (tramp-wait-for-output)
+        (tramp-send-string
+         multi-method method user host
+         (concat "tramp_decode_with_module () {\n"
+                 (format tramp-perl-decode-with-module tramp-remote-perl)
+                 " 2>/dev/null"
+                 "\n}"))
+        (tramp-wait-for-output))))
   ;; Find ln(1)
   (erase-buffer)
   (let ((ln (tramp-find-executable multi-method method user host
@@ -5954,6 +6087,8 @@
      base64-encode-region base64-decode-region)
     ("recode data..base64" "recode base64..data"
      base64-encode-region base64-decode-region)
+    ("uuencode xxx" "uudecode -o /dev/stdout"
+     tramp-uuencode-region uudecode-decode-region)
     ("uuencode xxx" "uudecode -o -"
      tramp-uuencode-region uudecode-decode-region)
     ("uuencode xxx" "uudecode -p"
@@ -6203,7 +6338,7 @@
       (save-excursion
 	(goto-char start-point)
 	(when (looking-at (regexp-quote tramp-last-cmd))
-	  (delete-region (point) (forward-line 1)))))
+	  (delete-region (point) (progn (forward-line 1) (point))))))
     ;; Add output to debug buffer if appropriate.
     (when tramp-debug-buffer
       (append-to-buffer
@@ -6397,6 +6532,26 @@
          (t (error "Tenth char `%c' must be one of `xtT-'"
                    other-execute-or-sticky)))))))
 
+(defun tramp-convert-file-attributes (multi-method method user host attr)
+  "Convert file-attributes ATTR generated by perl script or ls.
+Convert file mode bits to string and set virtual device number.
+Return ATTR."
+  (unless (stringp (nth 8 attr))
+    ;; Convert file mode bits to string.
+    (setcar (nthcdr 8 attr) (tramp-file-mode-from-int (nth 8 attr))))
+  ;; Set virtual device number.
+  (setcar (nthcdr 11 attr)
+          (tramp-get-device multi-method method user host))
+  attr)
+
+(defun tramp-get-device (multi-method method user host)
+  "Returns the virtual device number.
+If it doesn't exist, generate a new one."
+  (let ((string (tramp-make-tramp-file-name multi-method method user host "")))
+    (unless (assoc string tramp-devices)
+      (add-to-list 'tramp-devices
+		   (list string (length tramp-devices))))
+    (list -1 (nth 1 (assoc string tramp-devices)))))
 
 (defun tramp-file-mode-from-int (mode)
   "Turn an integer representing a file mode into an ls(1)-like string."
Index: lisp/trampver.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/lisp/trampver.el,v
retrieving revision 1.5
diff -u -r1.5 trampver.el
--- lisp/trampver.el	2004/10/17 17:55:52	1.5
+++ lisp/trampver.el	2004/12/23 23:54:52
@@ -30,7 +30,7 @@
 ;; are auto-frobbed from configure.ac, so you should edit that file and run
 ;; "autoconf && ./configure" to change them.
 
-(defconst tramp-version "2.0.45"
+(defconst tramp-version "2.0.46"
   "This version of Tramp.")
 
 (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org"
Index: texi/ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/texi/ChangeLog,v
retrieving revision 1.22
diff -u -r1.22 ChangeLog
--- texi/ChangeLog	2004/10/17 17:56:01	1.22
+++ texi/ChangeLog	2004/12/23 23:54:54
@@ -1,3 +1,7 @@
+2004-12-16  Michael Albinus  <michael.albinus@gmx.de>
+
+	Version 2.0.46 released.
+
 2004-10-17  Michael Albinus  <michael.albinus@gmx.de>
 
 	* tramp.texi (bottom): Add arch-tag.  It was lost, somehow.
Index: texi/trampver.texi
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/tramp/texi/trampver.texi,v
retrieving revision 1.5
diff -u -r1.5 trampver.texi
--- texi/trampver.texi	2004/10/17 17:56:01	1.5
+++ texi/trampver.texi	2004/12/23 23:55:00
@@ -4,7 +4,7 @@
 @c In the Tramp CVS, the version number is auto-frobbed from
 @c configure.ac, so you should edit that file and run
 @c "autoconf && ./configure" to change the version number.
-@set trampver 2.0.45
+@set trampver 2.0.46
 
 @c Other flags from configuration
 @set prefix /usr/local
