Commits

Anonymous committed cc9b866

Remove Tramp files not necessary for XEmacs package

  • Participants
  • Parent commits 7261fd4

Comments (0)

Files changed (10)

File Makefile.XEmacs

-# XEmacs Makefile for TRAMP
-
-# This file is part of XEmacs.
-
-# XEmacs is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2, or (at your option) any
-# later version.
-
-# XEmacs is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with XEmacs; see the file COPYING.  If not, write to
-# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-# Author: Stephen J. Turnbull <stephen@xemacs.org>
-# Created: 2001 November 10
-
-# This Makefile requires GNU make.
-
-# #### This Makefile is a newt.  But it's getting betta.
-
-#
-# packaging parameters
-#
-
-VERSION = 0.80
-AUTHOR_VERSION = 2.46
-MAINTAINER = Stephen J. Turnbull <stephen@xemacs.org>
-PACKAGE = tramp
-PKG_TYPE = regular
-
-# external files required
-# from core: cl custom
-# from xemacs-packages: compile vc timer shell advice efs dired reporter
-# from mule-packages:
-# not found: vc-rcs
-# copied to TRAMP from elsewhere
-#     format-spec from Gnus 5.8, also in tar ball (REQUIRE gnus)
-#     base64 by Kyle Jones for mimencode methods (REQUIRE mail-lib)
-REQUIRES = tramp xemacs-base vc fsf-compat efs dired mail-lib gnus
-CATEGORY = standard
-
-#
-# Definitions telling Make what to build and install.
-#
-
-TEXI_DIR = texi
-
-# These MUST be .elcs; bad things will happen (your sources will all
-# disappear when you clean!) if these are .els.
-ELCS = lisp/tramp-util.elc lisp/tramp.elc lisp/tramp-vc.elc lisp/trampcache.elc
-
-# EXTRA_OBJS get cleaned by make clean
-EXTRA_OBJS = lisp.ChangeLog $(TEXI_DIR).ChangeLog
-
-# EXTRA_SOURCES get copied into the package
-# #### Adding EXTRA_OBJS should happen in XEmacs.rules?
-# Don't put ChangeLog in here, that gets picked up automatically
-EXTRA_SOURCES = CONTRIBUTORS $(EXTRA_OBJS)
-
-# We should put the Lisp ChangeLog in with the Lisp files, the Texinfo
-# ChangeLog in man/tramp, the top-level ChangeLog in etc/tramp, and create
-# a README which also goes in etc/tramp.
-INFO_FILES = $(TEXI_DIR)/$(PACKAGE).info*
-TEXI_FILES = $(TEXI_DIR)/$(PACKAGE).texi
-MANUAL = $(PACKAGE)
-
-AUTOLOAD_PATH = lisp
-
-include ../../XEmacs.rules
-
-GENERATED += lisp/custom-load.elc
-
-#
-# targets
-#
-
-.PHONY: extra-objects mvtramp2 mvcompat
-
-all::	mvtramp2 mvcompat \
-	$(AUTOLOAD_PATH)/auto-autoloads.elc $(ELCS) \
-	$(AUTOLOAD_PATH)/custom-load.elc \
-	$(TEXI_DIR)/tramp.info \
-	extra-objects
-
-# Move hazmat out of the way.
-mvtramp2:
-	if [ -n "$(wildcard lisp/tramp2*.el*)" ]; then \
-	  if [ ! -e lisp/_tramp2 ]; then mkdir lisp/_tramp2; fi; \
-	  mv lisp/tramp2*.el* lisp/_tramp2; \
-	fi
-
-mvcompat:
-	if [ -n "$(wildcard lisp/base64.el*)" ]; then \
-	  if [ ! -e lisp/_compat ]; then mkdir lisp/_compat; fi; \
-	  mv lisp/base64.el* lisp/_compat; \
-	fi; \
-	if [ -n "$(wildcard lisp/format-spec.el*)" ]; then \
-	  if [ ! -e lisp/_compat ]; then mkdir lisp/_compat; fi; \
-	  mv lisp/format-spec.el* lisp/_compat; \
-	fi
-
-# #### Bogosity, but what to do is not obvious.
-extra-objects:
-	cp lisp/ChangeLog lisp.ChangeLog
-	cp $(TEXI_DIR)/ChangeLog $(TEXI_DIR).ChangeLog
-
-$(TEXI_DIR)/tramp.info: $(TEXI_DIR)/tramp.texi
-	(cd $(TEXI_DIR); $(MAKEINFO) -o tramp.info tramp.texi)
-
-# #### I don't know why you wouldn't be able to build a source package,
-# but that seems to be the case with a lot of packages with internal
-# structure (eg separate lisp and texinfo directories), so default to safe.
-# You can try substituting the active target below.
-# srckit: srckit-std
-srckit: 
-	@echo "You cannot build a source package for $(PACKAGE)"
-
-binkit: binkit-sourceinfo

File lisp/base64.el

-;;; base64.el,v --- Base64 encoding functions
-;; Author: Kyle E. Jones
-;; Created: 1997/03/12 14:37:09
-;; Version: 1.6
-;; Keywords: extensions
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Copyright (C) 1997 Kyle E. Jones
-;;;
-;;; This file is not part of GNU Emacs, but the same permissions apply.
-;;;
-;;; GNU Emacs is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2, or (at your option)
-;;; any later version.
-;;;
-;;; GNU Emacs is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;;; Boston, MA 02111-1307, USA.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(eval-when-compile (require 'cl))
-
-;; For non-MULE
-(if (not (fboundp 'char-int))
-    (defalias 'char-int 'identity))
-
-(defvar base64-alphabet
-  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
-
-(defvar base64-decoder-program nil
-  "*Non-nil value should be a string that names a MIME base64 decoder.
-The program should expect to read base64 data on its standard
-input and write the converted data to its standard output.")
-
-(defvar base64-decoder-switches nil
-  "*List of command line flags passed to the command named by
-base64-decoder-program.")
-
-(defvar base64-encoder-program nil
-  "*Non-nil value should be a string that names a MIME base64 encoder.
-The program should expect arbitrary data on its standard
-input and write base64 data to its standard output.")
-
-(defvar base64-encoder-switches nil
-  "*List of command line flags passed to the command named by
-base64-encoder-program.")
-
-(defconst base64-alphabet-decoding-alist
-  '(
-    ( ?A . 00) ( ?B . 01) ( ?C . 02) ( ?D . 03) ( ?E . 04) ( ?F . 05)
-    ( ?G . 06) ( ?H . 07) ( ?I . 08) ( ?J . 09) ( ?K . 10) ( ?L . 11)
-    ( ?M . 12) ( ?N . 13) ( ?O . 14) ( ?P . 15) ( ?Q . 16) ( ?R . 17)
-    ( ?S . 18) ( ?T . 19) ( ?U . 20) ( ?V . 21) ( ?W . 22) ( ?X . 23)
-    ( ?Y . 24) ( ?Z . 25) ( ?a . 26) ( ?b . 27) ( ?c . 28) ( ?d . 29)
-    ( ?e . 30) ( ?f . 31) ( ?g . 32) ( ?h . 33) ( ?i . 34) ( ?j . 35)
-    ( ?k . 36) ( ?l . 37) ( ?m . 38) ( ?n . 39) ( ?o . 40) ( ?p . 41)
-    ( ?q . 42) ( ?r . 43) ( ?s . 44) ( ?t . 45) ( ?u . 46) ( ?v . 47)
-    ( ?w . 48) ( ?x . 49) ( ?y . 50) ( ?z . 51) ( ?0 . 52) ( ?1 . 53)
-    ( ?2 . 54) ( ?3 . 55) ( ?4 . 56) ( ?5 . 57) ( ?6 . 58) ( ?7 . 59)
-    ( ?8 . 60) ( ?9 . 61) ( ?+ . 62) ( ?/ . 63)
-    ))
-
-(defvar base64-alphabet-decoding-vector
-  (let ((v (make-vector 123 nil))
-	(p base64-alphabet-decoding-alist))
-    (while p
-      (aset v (car (car p)) (cdr (car p)))
-      (setq p (cdr p)))
-    v))
-
-(defvar base64-binary-coding-system 'binary)
-
-(defun base64-run-command-on-region (start end output-buffer command
-					   &rest arg-list)
-  (let ((tempfile nil) status errstring default-process-coding-system 
-	(coding-system-for-write base64-binary-coding-system)
-	(coding-system-for-read base64-binary-coding-system))
-    (unwind-protect
-	(progn
-	  (setq tempfile (make-temp-name "base64"))
-	  (setq status
-		(apply 'call-process-region
-		       start end command nil
-		       (list output-buffer tempfile)
-		       nil arg-list))
-	  (cond ((equal status 0) t)
-		((zerop (save-excursion
-			  (set-buffer (find-file-noselect tempfile))
-			  (buffer-size)))
-		 t)
-		(t (save-excursion
-		     (set-buffer (find-file-noselect tempfile))
-		     (setq errstring (buffer-string))
-		     (kill-buffer nil)
-		     (cons status errstring)))))
-      (ignore-errors
-	(delete-file tempfile)))))
-
-(if (featurep 'xemacs)
-    (defalias 'base64-insert-char 'insert-char)
-  (defun base64-insert-char (char &optional count ignored buffer)
-    (if (or (null buffer) (eq buffer (current-buffer)))
-	(insert-char char count)
-      (with-current-buffer buffer
-	(insert-char char count))))
-  (setq base64-binary-coding-system 'no-conversion))
-
-(defun base64-decode-region (start end)
-  (interactive "r")
-  ;;(message "Decoding base64...")
-  (let ((work-buffer nil)
-	(done nil)
-	(counter 0)
-	(bits 0)
-	(lim 0) inputpos
-	(non-data-chars (concat "^=" base64-alphabet)))
-    (unwind-protect
-	(save-excursion
-	  (setq work-buffer (generate-new-buffer " *base64-work*"))
-	  (buffer-disable-undo work-buffer)
-	  (if base64-decoder-program
-	      (let* ((binary-process-output t) ; any text already has CRLFs
-		     (status (apply 'base64-run-command-on-region
-				    start end work-buffer
-				    base64-decoder-program
-				    base64-decoder-switches)))
-		(if (not (eq status t))
-		    (error "%s" (cdr status))))
-	    (goto-char start)
-	    (skip-chars-forward non-data-chars end)
-	    (while (not done)
-	      (setq inputpos (point))
-	      (cond
-	       ((> (skip-chars-forward base64-alphabet end) 0)
-		(setq lim (point))
-		(while (< inputpos lim)
-		  (setq bits (+ bits
-				(aref base64-alphabet-decoding-vector
-				      (char-int (char-after inputpos)))))
-		  (setq counter (1+ counter)
-			inputpos (1+ inputpos))
-		  (cond ((= counter 4)
-			 (base64-insert-char (lsh bits -16) 1 nil work-buffer)
-			 (base64-insert-char (logand (lsh bits -8) 255) 1 nil
-					     work-buffer)
-			 (base64-insert-char (logand bits 255) 1 nil
-					     work-buffer)
-			 (setq bits 0 counter 0))
-			(t (setq bits (lsh bits 6)))))))
-	      (cond
-	       ((or (= (point) end)
-		    (eq (char-after (point)) ?=))
-		(if (and (= (point) end) (> counter 1))
-		    (message 
-		     "at least %d bits missing at end of base64 encoding"
-		     (* (- 4 counter) 6)))
-		(setq done t)
-		(cond ((= counter 1)
-		       (error "at least 2 bits missing at end of base64 encoding"))
-		      ((= counter 2)
-		       (base64-insert-char (lsh bits -10) 1 nil work-buffer))
-		      ((= counter 3)
-		       (base64-insert-char (lsh bits -16) 1 nil work-buffer)
-		       (base64-insert-char (logand (lsh bits -8) 255)
-					   1 nil work-buffer))
-		      ((= counter 0) t)))
-	       (t (skip-chars-forward non-data-chars end)))))
-	  (or (markerp end) (setq end (set-marker (make-marker) end)))
-	  (goto-char start)
-	  (insert-buffer-substring work-buffer)
-	  (delete-region (point) end))
-      (and work-buffer (kill-buffer work-buffer))))
-  ;;(message "Decoding base64... done")
-  )
-
-(defun base64-encode-region (start end &optional no-line-break)
-  (interactive "r")
-  (message "Encoding base64...")
-  (let ((work-buffer nil)
-	(counter 0)
-	(cols 0)
-	(bits 0)
-	(alphabet base64-alphabet)
-	inputpos)
-    (unwind-protect
-	(save-excursion
-	  (setq work-buffer (generate-new-buffer " *base64-work*"))
-	  (buffer-disable-undo work-buffer)
-	  (if base64-encoder-program
-	      (let ((status (apply 'base64-run-command-on-region
-				   start end work-buffer
-				   base64-encoder-program
-				   base64-encoder-switches)))
-		(if (not (eq status t))
-		    (error "%s" (cdr status))))
-	    (setq inputpos start)
-	    (while (< inputpos end)
-	      (setq bits (+ bits (char-int (char-after inputpos))))
-	      (setq counter (1+ counter))
-	      (cond ((= counter 3)
-		     (base64-insert-char (aref alphabet (lsh bits -18)) 1 nil
-					 work-buffer)
-		     (base64-insert-char
-		      (aref alphabet (logand (lsh bits -12) 63))
-		      1 nil work-buffer)
-		     (base64-insert-char
-		      (aref alphabet (logand (lsh bits -6) 63))
-		      1 nil work-buffer)
-		     (base64-insert-char
-		      (aref alphabet (logand bits 63))
-		      1 nil work-buffer)
-		     (setq cols (+ cols 4))
-		     (cond ((and (= cols 72)
-				 (not no-line-break))
-			    (base64-insert-char ?\n 1 nil work-buffer)
-			    (setq cols 0)))
-		     (setq bits 0 counter 0))
-		    (t (setq bits (lsh bits 8))))
-	      (setq inputpos (1+ inputpos)))
-	    ;; write out any remaining bits with appropriate padding
-	    (if (= counter 0)
-		nil
-	      (setq bits (lsh bits (- 16 (* 8 counter))))
-	      (base64-insert-char (aref alphabet (lsh bits -18)) 1 nil
-				  work-buffer)
-	      (base64-insert-char (aref alphabet (logand (lsh bits -12) 63))
-				  1 nil work-buffer)
-	      (if (= counter 1)
-		  (base64-insert-char ?= 2 nil work-buffer)
-		(base64-insert-char (aref alphabet (logand (lsh bits -6) 63))
-				    1 nil work-buffer)
-		(base64-insert-char ?= 1 nil work-buffer)))
-	    (if (and (> cols 0)
-		     (not no-line-break))
-	    	(base64-insert-char ?\n 1 nil work-buffer)))
-	  (or (markerp end) (setq end (set-marker (make-marker) end)))
-	  (goto-char start)
-	  (insert-buffer-substring work-buffer)
-	  (delete-region (point) end))
-      (and work-buffer (kill-buffer work-buffer))))
-  (message "Encoding base64... done"))
-
-(defun base64-encode (string &optional no-line-break)
-  (save-excursion
-    (set-buffer (get-buffer-create " *base64-encode*"))
-    (erase-buffer)
-    (insert string)
-    (base64-encode-region (point-min) (point-max) no-line-break)
-    (skip-chars-backward " \t\r\n")
-    (delete-region (point-max) (point))
-    (prog1
-	(buffer-string)
-      (kill-buffer (current-buffer)))))
-
-(defun base64-decode (string)
-  (save-excursion
-    (set-buffer (get-buffer-create " *base64-decode*"))
-    (erase-buffer)
-    (insert string)
-    (base64-decode-region (point-min) (point-max))
-    (goto-char (point-max))
-    (skip-chars-backward " \t\r\n")
-    (delete-region (point-max) (point))
-    (prog1
-	(buffer-string)
-      (kill-buffer (current-buffer)))))
-
-(defalias 'base64-decode-string 'base64-decode)
-(defalias 'base64-encode-string 'base64-encode)
-
-(provide 'base64)

File lisp/format-spec.el

-;;; format-spec.el --- functions for formatting arbitrary formatting strings
-;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
-
-;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
-;; Keywords: tools
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-
-(defun format-spec (format specification)
-  "Return a string based on FORMAT and SPECIFICATION.
-FORMAT is a string containing `format'-like specs like \"bash %u %k\",
-while SPECIFICATION is an alist mapping from format spec characters
-to values."
-  (with-temp-buffer
-    (insert format)
-    (goto-char (point-min))
-    (while (search-forward "%" nil t)
-      (cond
-       ;; Quoted percent sign.
-       ((eq (char-after) ?%)
-	(delete-char 1))
-       ;; Valid format spec.
-       ((looking-at "\\([-0-9.]*\\)\\([a-zA-Z]\\)")
-	(let* ((num (match-string 1))
-	       (spec (string-to-char (match-string 2)))
-	       (val (cdr (assq spec specification))))
-	  (delete-region (1- (match-beginning 0)) (match-end 0))
-	  (unless val
-	    (error "Invalid format character: %s" spec))
-	  (insert (format (concat "%" num "s") val))))
-       ;; Signal an error on bogus format strings.
-       (t
-	(error "Invalid format string"))))
-    (buffer-string)))
-
-(defun format-spec-make (&rest pairs)
-  "Return an alist suitable for use in `format-spec' based on PAIRS.
-PAIRS is a list where every other element is a character and a value,
-starting with a character."
-  (let (alist)
-    (while pairs
-      (unless (cdr pairs)
-	(error "Invalid list of pairs"))
-      (push (cons (car pairs) (cadr pairs)) alist)
-      (setq pairs (cddr pairs)))
-    (nreverse alist)))
-
-(provide 'format-spec)
-
-;;; format-spec.el ends here

File lisp/tramp2-cache.el

-;;; tramp2-cache.el --- TRAMP2 cache management and access
-
-;; Copyright (C) 2001 by Daniel Pittman <daniel@localhost>
-
-;;; Commentary:
-
-;; This module provides remote caching support for tramp2 connections.
-
-;; Each cache is maintained as a buffer-local value in the actual connection
-;; buffer. This ensures that the cache is flushed when the connection is
-;; destroyed.
-
-;;; Code:
-(eval-when-compile
-  (require 'tramp2)
-  (make-variable-buffer-local 'tramp2-tilde-cache))
-
-(require 'tramp2-compat)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; tilde expansion caching.
-;;
-;; Because the user home directory is *very* unlikely to change during a
-;; single connection to the remote host, this is a good candidate for caching.
-(defun tramp2-tilde-expand (path name)
-  "Expand VALUE as a tilde expression for the connection of PATH.
-The result is cached and served from there, if possible."
-  (unless (char-equal ?~ (elt name 0))
-    (tramp2-error "Invalid tilde expression" name))
-  (tramp2-with-connection path
-    (or (tramp2-tilde-find name)
-	(tramp2-tilde-extract path name))))
-
-(defun tramp2-tilde-find (name)
-  "Find an entry in the tilde cache for this connection."
-  ;; Make sure we have a cache already...
-  (if (boundp 'tramp2-tilde-cache)
-      (cdr-safe (assoc name tramp2-tilde-cache))
-    (set (make-local-variable 'tramp2-tilde-cache) nil)))
-
-(defun tramp2-tilde-extract (path name)
-  "Expand a tilde expression on the remote machine and return it.
-The value is added to the local cache to avoid the overhead a second
-time."
-  (unless (= 0 (tramp2-run-command path (format "echo %s" name)))
-    (tramp2-error (format "Unable to expand %s" name)))
-  (tramp2-tilde-add name
-		    (file-name-as-directory (buffer-substring (tramp2-point-at-bol)
-							      (tramp2-point-at-eol)))))
-
-(defun tramp2-tilde-add (name value)
-  "Add an entry to the tramp2 tilde cache."
-  (setq tramp2-tilde-cache (nconc (list (cons name value)) tramp2-tilde-cache))
-  value)
-  
-
-(provide 'tramp2-cache)
-
-;;; tramp2-cache.el ends here

File lisp/tramp2-compat.el

-;;; tramp2-compat.el --- TRAMP2 Emacs/XEmacs compatibility routines.
-
-;; Copyright (C) 2001 by Daniel Pittman <daniel@localhost>
-
-;;; Commentary:
-
-;; This module contains code that allows XEmacs and Emacs to inter-operate
-;; politely. This is somewhat essential as it makes life easier for all of us.
-
-;; Why can't we all just get along?
-
-;;; Code:
-
-;; NOTE: *DON'T* require tramp2 here, even if we are byte-compiling.
-;; This will cause an infloop of dependencies...
-
-;; XEmacs provides `define-error' to make structured error handling easier for
-;; the average mortal. Emacs 20.7.2 doesn't. This makes it easier for all of
-;; us. :)
-(unless (fboundp 'define-error)
-  
-(defun define-error (error-sym doc-string &optional inherits-from)
-  "Define a new error, denoted by ERROR-SYM.
-DOC-STRING is an informative message explaining the error, and will be
-printed out when an unhandled error occurs.
-ERROR-SYM is a sub-error of INHERITS-FROM (which defaults to `error').
-
-\[`define-error' internally works by putting on ERROR-SYM an `error-message'
-property whose value is DOC-STRING, and an `error-conditions' property
-that is a list of ERROR-SYM followed by each of its super-errors, up
-to and including `error'.  You will sometimes see code that sets this up
-directly rather than calling `define-error', but you should *not* do this
-yourself.]"
-  (unless (symbolp error-sym)  (error 'wrong-type-argument (list 'symbolp error-sym)))
-  (unless (stringp doc-string) (error 'wrong-type-argument (list 'stringp doc-string)))
-
-  (put error-sym 'error-message doc-string)
-  (or inherits-from (setq inherits-from 'error))
-  (let ((conds (get inherits-from 'error-conditions)))
-    (or conds (signal 'error (list "Not an error symbol" error-sym)))
-    (put error-sym 'error-conditions (cons error-sym conds))))
-
-)
-
-
-;; A more useful error reporting tool. This works with both XEmacs and Emacs.
-(defun tramp2-error (&rest args)
-  (signal 'tramp2-file-error args))
-
-
-;; Finding the point at the start and end of the line.
-(cond
- ((fboundp 'point-at-eol)	(defalias 'tramp2-point-at-eol #'point-at-eol))
- ((fboundp 'line-end-position)	(defalias 'tramp2-point-at-eol #'line-end-position))
- (t (defalias 'tramp2-point-at-eol #'(lambda () (save-excursion (end-of-line) (point))))))
-
-(cond
- ((fboundp 'point-at-bol)	(defalias 'tramp2-point-at-bol #'point-at-bol))
- ((fboundp 'line-beginning-position)	(defalias 'tramp2-point-at-bol #'line-beginning-position))
- (t (defalias 'tramp2-point-at-bol #'(lambda () (save-excursion (beginning-of-line) (point))))))
-
-
-
-;; Work around the Emacs `accept-process-output' function which does not
-;; support floating point wait times.
-(if (catch 'done
-      (condition-case nil
-	  (accept-process-output nil 0.1)
-	(error (throw 'done t))
-	nil))
-    ;; Wrap the accept-process-input call...
-    (defsubst tramp2-accept-process-output (&optional process timeout-secs timeout-msecs)
-      "Call accept-process-output with only integer values for timeout."
-      (accept-process-output process timeout-secs
-			     (floor (* 1000 (- timeout-secs (floor timeout-secs))))))
-  (defalias 'tramp2-accept-process-output #'accept-process-output))
-   
-
-(provide 'tramp2-compat)
-
-;;; tramp2-compat.el ends here

File lisp/tramp2-enc.el

-;;; tramp2-enc.el --- Remote file transfer support for TRAMP2
-
-;; Copyright (C) 2001 Free Software Foundation, Inc.
-
-;;; Commentary:
-
-;; This file contains the support code for managing remote file encoding and
-;; decoding in TRAMP2.
-
-;; The test functions are called in an active tramp2 connection buffer and can
-;; use the `tramp-send-command' interface to run commands on the remote
-;; machine for testing the availablity of remote software.
-
-;; Note that using `tramp2-run-command' here is unadvisable as it will *not*
-;; do what you want. It will, rather, throw an ugly error at you. :)
-
-;; The send and fetch functions are called in the context of a fully setup
-;; connection and should transfer the data in the appropriate direction.
-
-;;; Code:
-(eval-when-compile
-  (require 'tramp2)
-  (defvar tramp2-base64-decode	nil)
-  (defvar tramp2-base64-encode	nil))
-
-(require 'base64)
-(require 'tramp2-util)
-
-
-(defconst tramp2-base64-test-value "hello world"
-  "Data used to test the remote base64 coder.")
-
-
-(defun tramp2-base64-supported-p ()
-  "Ensure that this buffer is configured for base64 encoding support."
-  (and (boundp 'tramp2-base64-decode) tramp2-base64-decode
-       (boundp 'tramp2-base64-encode) tramp2-base64-encode))
-
-(defun tramp2-base64-test (connect path)
-  "Determine if the connection for PATH supports BASE64 encoding."
-  ;; Test the coder for this connection, if any.
-  (tramp2-base64-test-coder (tramp2-find-value (tramp2-connect-user connect)
-							(tramp2-connect-host connect)
-							tramp2-base64-coder)))
-    
-
-(defun tramp2-base64-test-coder (coder)
-  "Test that CODER has valid and working encoder and decoder routines.
-This also sets the current buffer base64 encoding specific data to the
-valid encoder/decoder calls.
-
-We return `nil' if any part of the coder does not succeed."
-  (and (listp coder)
-       (let ((enc (car-safe (cdr-safe (assoc 'encoder coder))))
-	     (dec (car-safe (cdr-safe (assoc 'decoder coder))))
-	     one)
-	 (when (and enc dec)
-	   ;; Test the encoder first.
-	   (set (make-local-variable 'tramp2-base64-encode)
-		(if (stringp enc)
-		    (tramp2-base64-test-encoder enc)
-		  (catch 'found
-		    (while enc
-		      (setq one (car enc)
-			    enc (cdr enc))
-		      (when (tramp2-base64-test-encoder one)
-			(throw 'found one))))))
-	   ;; Test the decoder.
-	   (set (make-local-variable 'tramp2-base64-decode)
-		(if (stringp dec)
-		    (tramp2-base64-test-decoder dec)
-		  (catch 'found
-		    (while dec
-		      (setq one (car dec)
-			    dec (cdr dec))
-		      (when (tramp2-base64-test-decoder one)
-			(throw 'found one))))))
-	   ;; Ensure that we got valid coders...
-	   (and tramp2-base64-encode tramp2-base64-decode)))))
-
-(defun tramp2-base64-test-encoder (coder)
-  "Test that a base64 encoder works on the remote machine."
-  (and (stringp coder)
-       (save-match-data
-	 ;; Test that the command runs successfully...
-	 (and (= 0 (tramp2-send-command
-		    (format "echo %s | %s"
-			    (tramp2-shell-quote tramp2-base64-test-value)
-			    coder)))
-	      ;; Test that it's output decodes successfully...
-	      (base64-decode-region (point-min) (point-max))
-	      ;; Test that it's decoded output is what we put in...
-	      (goto-char (point-min))
-	      (looking-at (concat "^" tramp2-base64-test-value))))))
-    
-
-(defun tramp2-base64-test-decoder (coder)
-  "Test that a base64 decoder works on the remote machine."
-  (and (stringp coder)
-       (save-match-data
-	 ;; Test that the command runs successfully...
-	 (and (= 0 (tramp2-send-command
-		    (format "echo %s | %s"
-			    (tramp2-shell-quote
-			     (with-temp-buffer
-			       (insert tramp2-base64-test-value)
-			       (base64-encode-region (point-min) (point-max))
-			       (buffer-string)))
-			    coder)))
-	      ;; Test that the output is what we expected...
-	      (goto-char (point-min))
-	      (looking-at (concat "^" tramp2-base64-test-value))))))
-
-
-(defun tramp2-base64-write (source start end file append)
-  "Write the data in the SOURCE buffer from START to END to FILE
-on the remote machine. If APPEND, append to the file."
-  (unless (tramp2-base64-supported-p)
-    (tramp2-error "base64 send in non-base64 capable buffer!"))
-  (unless (tramp2-util-shell-write file
-				   tramp2-base64-decode
-				   append
-				   (tramp2-base64-encode source start end))
-    (tramp2-error (list "base64 send failed"
-					   (buffer-string)))))
-
-
-(defun tramp2-base64-read (start end file)
-  "Transfer the bytes from START to END of FILE to the local machine."
-  (unless (tramp2-base64-supported-p) 
-    (tramp2-error "base64 read in non-base64 capable buffer!"))
-  ;; We can just use the shell reader directly. Yay.
-  (tramp2-util-shell-read file
-			  tramp2-base64-encode
-			  #'base64-decode-region
-			  start
-			  end))
-
-
-(defun tramp2-base64-encode (source start end)
-  "Encode FILE (a local file) as base64 and return the base64 data
-as a string."
-  (with-temp-buffer
-    ;; This shouldn't fail silently. If it does, we need to catch the error
-    ;; a little more gracefully, I think.
-    (insert-buffer-substring source start end)
-    ;; Now, encode the buffer...
-    (base64-encode-region (point-min) (point-max))
-    ;; Return the encoded content as a string.
-    (buffer-string)))
-
-
-;; uuencode
-(defun tramp2-uuencode-test (connect path)
-  "Determine if the connection for PATH supports UUENCODE encoding."
-  (debug))
-
-(defun tramp2-uuencode-write (source start end file append)
-  "Write the data in the SOURCE buffer from START to END to FILE
-on the remote machine. If APPEND, append to the file."
-  (debug))
-
-(defun tramp2-uuencode-read (start end file)
-  "Transfer the bytes from START to END of FILE to the local machine."
-  (debug))
-
-
-(provide 'tramp2-enc)
-
-;; TODO:
-;; * Implement the `uuencode' based functionality.
-;;
-;; * Implement `scp' based transfer functionality.
-
-;;; tramp2-enc.el ends here

File lisp/tramp2-hack.el

-;;; tramp2-hack.el --- Hooks and hacks to allow better file-operation handling
-
-;; Copyright (C) 2001 Free Software Foundation, Inc.
-
-;;; Commentary:
-
-;; The code and routines in here ensure that we can hook into some operations
-;; that need specific support for tramp files but that don't, by default,
-;; provide the file-handler hooks for doing so.
-
-;; This code rudely installs it's hooks through the system when loaded. This
-;; violates policy but, hell, it's rude enough as it is. :)
-
-;; To make it possible for future versions of the routines hacked on in here
-;; to improve their support for file handlers, every hack should test that it
-;; is needed before it makes any system changes.
-
-;;; Code:
-(eval-when-compile
-  (require 'tramp2))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; `file-remote-p' does not use a file operation to test, it has hard-coded
-;; knowledge about efs and, presumably, ange-ftp. This should be fixed but,
-;; until then, we code around it.
-;;
-;; We do this by replacing the original version with one that uses a
-;; file-operation, then call the original only if that does nothing for us.
-(when (fboundp 'file-remote-p)
-  
-(let ((file-name-handler-alist '(("test-file" . (lambda (&rest args) (setq pass t)))))
-      (pass nil))
-  (file-remote-p "test-file")
-  (unless pass
-
-(or (fboundp 'tramp2-original-file-remote-p)
-    (fset 'tramp2-original-file-remote-p (symbol-function 'file-remote-p)))
-(defalias 'file-remote-p 'tramp2-sane-file-remote-p)
-    
-(defun tramp2-sane-file-remote-p (file)
-  "Determine if a file is remote.
-This uses the file operation `file-remote-p' to determine if the
-file is remote or not. This is much nicer than the original version
-which hard-coded the knowledge about remote file handlers.
-
-The original definition is called `tramp2-original-file-remote-p'."
-  (when allow-remote-paths
-    (let ((handler (find-file-name-handler file 'file-remote-p)))
-      (if handler
-	  (funcall handler 'file-remote-p file)
-	(tramp2-original-file-remote-p file)))))
-
-))
-
-)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; EFS and ange-ftp have some, er, issues with the tramp paths. Specifically,
-;; they treat our paths as their own which, unsurprisingly, does not work real
-;; well.
-;;
-;; Sometimes their handlers get through despite our best efforts. This
-;; requires us to hack around them, dammit.
-
-(defun tramp2-hack-efs-ftp-path ()
-  "Install the hacks for EFS ftp path handling."
-  (require 'advice)
-  
-  (defadvice efs-ftp-path (around tramp2-safe-efs-ftp-path activate)
-    "Cause efs-ftp-path to fail when the path is a TRAMP path."
-    (save-match-data
-      (unless (string-match tramp2-path-tag (ad-get-arg 0))
-	ad-do-it))))
-
-(if (fboundp 'efs-ftp-path)
-    (tramp2-hack-efs-ftp-path)
-  (eval-after-load "efs-cu" (tramp2-hack-efs-ftp-path)))
-
-
-
-(provide 'tramp2-hack)
-
-;;; tramp2-hack.el ends here

File lisp/tramp2-ops.el

-;;; tramp2-ops.el --- File operation handlers for TRAMP2
-
-;; Copyright (C) 2001 Free Software Foundation, Inc.
-
-;;; Commentary:
-
-;; This defines the file operation handlers for TRAMP2
-
-;; This is an example:
-
-;; (def-tramp-handler sample-operation (file other-file)
-;;   "This implements `sample-operation' for TRAMP2 files.
-
-;; The argument FILE is magical - if this is a string, it is parsed to
-;; a valid TRAMP2 path object. If it is already a path object, it is
-;; left untouched.
-
-;; This magic is based on the argument name. If you need to parse a
-;; second file-name, you must do it by hand, as this example shows.
-
-;; The handler is not run from the current buffer of the connection. If you
-;; need to get access to the output from a command, wrap your code in 
-;; `tramp2-with-connection'.
-
-;; When calling file operations from within a handler, you should call
-;; `tramp2-do-NAME' rather than NAME. This will call the internal handler and
-;; saves the overhead of parsing the path in every function. Failing to do
-;; this will result in an error at runtime, so do be careful.
-
-;; Use `tramp2-run-command' to execute a command on a remote machine
-;; suitable for a path."
-;;   (condition-case error
-;;       (let ((other-file (tramp2-path-parse other-file)))
-;;	 ;; Do things with the file here
-;; 	) 
-;;     (tramp2-file-error (t)))) ; not a valid tramp2 path
-
-;;; Code:
-(eval-when-compile
-  (require 'tramp2)
-  (defvar tramp2-file-attributes-sent-perl	nil))
-
-(require 'tramp2-cache)
-
-
-;; Demonstration handler for remote operations...
-(def-tramp-handler noop (file)
-  "A simple remote command handler that changes nothing in the
-remote system state."
-  (tramp2-run-command file "true"))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Vital hooks for supporting the Emacs file-handler model.
-(def-tramp-handler unhandled-file-name-directory (filename)
-  "Return a suitable local directory for tramp2 magic paths."
-  (tramp2-temp-dir))
-			   
-      
-(def-tramp-handler file-local-copy (file &optional buffer)
-  "Make a local copy of FILE, returning the name.
-If FILE is already local, return nil.
-
-BUFFER is specified and optional in Emacs 20.7.3 and XEmacs 22.2.
-It isn't /ever/ used by either of them, though, so it's an error
-to pass it to this function. *sigh*"
-  (when buffer
-    (tramp2-error "`file-local-copy' with BUFFER! " file))
-
-  ;; Right, return a local copy...
-  (debug)
-
-  ;; Well, OK, lie like a dog...
-  nil)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Simple file-name mangling operations.
-;; Note that these follow local system conventions regardless of the remote
-;; host they are connected to. This might want to change to allow the mangling
-;; function to be customised on a per-connection basis with `tramp2-find-value'.
-;;
-;; This would allow, for example, OS/2 or Win32 names to be mangled
-;; appropriately for those few legacy systems that we are obliged to deal
-;; with. :)
-(def-tramp-handler file-name-nondirectory (file)
-  "Return the name of the file without the directory part."
-  (file-name-nondirectory (tramp2-path-remote-file file)))
-
-(def-tramp-handler file-name-directory (file)
-  "Return the directory part of file."
-  ;; Return a stringified path with the same connect method but
-  ;; we remove the non-directory part from the remote file.
-  (tramp2-path-to-string
-   (tramp2-make-path (tramp2-path-connect file)
-		     (file-name-directory (tramp2-path-remote-file file)))))
-
-(def-tramp-handler file-name-as-directory (file)
-  "Return the path as a directory."
-  (tramp2-path-to-string
-   (tramp2-make-path (tramp2-path-connect file)
-		     (file-name-as-directory (tramp2-path-remote-file file)))))
-
-(def-tramp-handler directory-file-name (file)
-  "Return the name of the file that holds directory data for a tramp2 filename."
-  (tramp2-path-to-string
-   (tramp2-make-path (tramp2-path-connect file)
-		     (directory-file-name (tramp2-path-remote-file file)))))
-
-;; REVISIT: Test this when KEEP-BACKUP-VERSION is not nil. I think it's incorrect.
-(def-tramp-handler file-name-sans-versions (file &optional keep-backup-version)
-  "Return the filename sans backup versions or strings."
-  (tramp2-path-to-string
-   (tramp2-make-path (tramp2-path-connect file)
-		     (file-name-sans-versions (tramp2-path-remote-file file)
-					      keep-backup-version))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Complex file-name mangling operations.
-;; These operations require access to information on the remote system.
-(def-tramp-handler file-truename (file &optional dir)
-  "Return the canonical name of FILE, using the optional DIR
-as the directory to search from when FILE is relative.
-
-Since a TRAMP2 path can /never/ be relative to a directory, the
-DIR part is a no-op.
-
-From the function:
-Return the canonical name of FILENAME.
-Second arg DEFAULT is directory to start with if FILENAME is relative
- (does not start with slash); if DEFAULT is nil or missing,
- the current buffer's value of `default-directory' is used.
-No component of the resulting pathname will be a symbolic link, as
- in the realpath() function."
-  (when (tramp2-do-file-exists-p file)
-    (tramp2-with-connection file
-      ;; Now, walk through the link chain to the end...
-      (let ((link (tramp2-path-remote-file file))
-	    dest)
-	(while (stringp (setq dest (car (tramp2-do-file-attributes file))))
-	  (setq link (concat (file-name-directory link) dest))
-	  (setq file (tramp2-make-path (tramp2-path-connect file) link))))
-      ;; Return the truename of the file.
-      (tramp2-path-to-string file))))
-
-
-;; Note that PATH is not automatically parsed. This is because we might have
-;; been called because DIR, not PATH, was the tramp2 file.
-(def-tramp-handler expand-file-name (path &optional dir)
-  "Expand FILE (potentially from DIR)."
-  (let ((dir (tramp2-path-parse-safe dir)))
-    (if (and (not (tramp2-path-parse-safe path))
-	     dir
-	     (not (file-name-absolute-p path)))
-	;; Make the path relative...
-	(tramp2-make-path-relative path dir)
-      ;; Return the path unmodified...
-      (if (tramp2-path-p path)
-	  (tramp2-path-to-string path)
-	path))))
-
-
-
-(defun tramp2-make-path-relative (path directory)
-  "Make PATH, a string or TRAMP2 path object, relative to DIRECTORY,
-a tramp2 path object representing a directory.
-
-This returns the string version of the relative path."
-  (save-match-data
-    (let ((dir (file-name-as-directory (tramp2-path-remote-file directory))))
-      ;; Is the remote directory absolute?
-      (unless (file-name-absolute-p dir)
-	(setq dir (concat "~/" dir)))
-
-      ;; Now, make the path relative...
-      (setq path (concat dir path))
-      
-      ;; Expand any tilde sequence in the thing.
-      (while (string-match "~[^/]*/?" path)
-	(setq path (replace-match (tramp2-tilde-expand directory (match-string 0 path))
-				  t t path)))
-
-      ;; Now, remove /./ and /../ from the (full) path.
-      (while (string-match "/\\./" path)
-	(setq path (replace-match "/" t t path)))
-      (while (string-match "/[^/]+/\\.\\./" path)
-	(setq path (replace-match "/" t t path)))
-      ;; EFS claim that this is correct. *shrug*
-      (while (string-match "^\\(/+\\)\\.\\./" path)
-	(setq path (replace-match "\\1" t nil path)))
-
-      ;; Now, put together the result.
-      (tramp2-path-to-string (tramp2-make-path (tramp2-path-connect directory) path)))))
-
-
-
-(def-tramp-handler abbreviate-file-name (file &optional home-dir)
-  "Abbreviate the path passed in, including substituting user home
-directories, if needed."
-  (save-match-data
-    (let ((path (tramp2-path-remote-file file))
-	  (abbrevs (tramp2-find-value (tramp2-path-last-user file)
-				      (tramp2-path-last-host file)
-				      tramp2-directory-abbrev-alist)))
-      ;; The easy one, the directory hacks list...
-      (while abbrevs
-	(when (string-match (caar abbrevs) path)
-	  (setq path (replace-match (cdar abbrevs) nil nil path)))
-	(setq abbrevs (cdr abbrevs)))
-      ;; Now, the home directory hack?
-      (when home-dir
-	(let ((home-dir (concat
-			 (regexp-quote (substring (tramp2-tilde-expand file "~") 0 -1))
-			 "\\(" (string directory-sep-char) "\\|\\'\\)")))
-	  (when (string-match home-dir path)
-	    (setq path (replace-match "~\\1" nil nil path)))))
-      ;; Return the appropriate value...
-      (tramp2-path-to-string (tramp2-make-path (tramp2-path-connect file)
-					       path)))))
-
-
-(defconst tramp2-environment-match (concat "\\("
-					   ;; 2    2
-					   "\\($$\\)" "\\|"
-					   ;; 3            3  
-					   "\\(${[^}]+}\\)" "\\|"
-					   ;; 4             4
-					   "\\($[a-z0-9_]+\\)"
-					   "\\)")
-  "A regular expression matching environment variable substitutions
-in a path name.")
-
-(def-tramp-handler substitute-in-file-name (path)
-  "Replace environment variables in PATH with expanded versions.
-This works with the enviroment on the local machine and on the
-remote machine."
-  (save-match-data
-    (let ((file (tramp2-path-parse-safe path))
-	  (connect (car (split-string path "::")))
-	  (path   (cadr (split-string path "::"))))
-      ;; Substitute in the connect part first...
-      (while (string-match tramp2-environment-match connect)
-	(let ((name (cond ((match-string 2 connect) "$")
-			  ((match-string 3 connect)
-			   (substring (match-string 3 connect) 2 -1))
-			  ((match-string 4 connect)
-			   (substring (match-string 3 connect) 1))
-			  (t (tramp2-error
-				    "Badly formed environment value" name)))))
-	  (setq connect (replace-match (if (string-equal "$" name)
-					   name
-					 (tramp2-getenv file name))
-				       nil t connect)))
-	(setq file (tramp2-path-parse-safe (concat connect "::" path))))
-      ;; Now, make sure the path is still ours...
-      (if (null file)
-	  ;; Call the original, it's not ours any longer...
-	  (substitute-in-file-name (concat connect "::" path))
-	;; Right, now we process the path part of it...
-	(while (string-match tramp2-environment-match path)
-	  (let ((name (cond ((match-string 2 path) "$")
-			    ((match-string 3 path)
-			     (substring (match-string 3 path) 2 -1))
-			    ((match-string 4 path)
-			     (substring (match-string 4 path) 1))
-			    (t (tramp2-error
-				      "Badly formed environment value" name)))))
-	    (setq path (replace-match (if (string-equal "$" name)
-					  name
-					(tramp2-getenv file name))
-				      nil t path))))
-	;; Build up the full path expression...
-	(concat connect "::" path)))))
-      
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Simple tests for file properties.
-(defmacro tramp2-handle-file-test (file test)
-  "Use test(1) on the remote system to test the properties of a file."
-  `(= 0 (tramp2-run-command ,file (format "test %s %s"
- 					  ,test
-					  (tramp2-shell-quote
-					   (tramp2-path-remote-file ,file))))))
-
-(def-tramp-handler file-regular-p (file)
-  "Determine if a tramp2 file is a regular file."
-  (tramp2-handle-file-test file "-f"))
-  
-(def-tramp-handler file-symlink-p (file)
-  "Determine if a tramp2 file is a symlink."
-  (when (tramp2-handle-file-test file "-L")
-    (nth 0 (tramp2-do-file-attributes file))))
-
-(def-tramp-handler file-writable-p (file)
-  "Determine if a tramp2 file is writable."
-  (tramp2-handle-file-test file "-w"))
-
-(def-tramp-handler file-readable-p (file)
-  "Determine if a tramp2 file is readable."
-  (tramp2-handle-file-test file "-r"))
-
-(def-tramp-handler file-exists-p (file)
-  "Determine if a tramp2 file exists."
-  (tramp2-handle-file-test file "-e"))
-
-(def-tramp-handler file-directory-p (file)
-  "Determine if a tramp2 file is a directory."
-  (tramp2-handle-file-test file "-d"))
-
-
-(def-tramp-handler file-remote-p (path)
-  "Determine if a tramp2 file is on a remote machine. (hint: YES)"
-  t)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Complex tests for file properties.
-(def-tramp-handler file-attributes (file)
-  "Return the file attributes of a remote file."
-  ;; Select the particular implementation at runtime...
-  (tramp2-with-connection file
-    (if tramp2-perl
-	(tramp2-do-file-attributes-with-perl file)
-      (tramp2-do-file-attributes-with-ls file))))
-
-
-;; Perl script to implement `file-attributes' in a Lisp `read'able output.
-;; If you are hacking on this, note that you get *no* output unless this
-;; spits out a complete line, including the '\n' at the end.
-(defconst tramp2-perl-file-attributes
-  (concat
-   "$f = $ARGV[0];"
-   "@s = lstat($f) or exit 1;"
-   "if (($s[2] & 0170000) == 0120000) { $l = readlink($f); $l = \"\\\"$l\\\"\"; }"
-   "elsif (($s[2] & 0170000) == 040000) { $l = \"t\"; }"
-   "else { $l = \"nil\" };"
-   "@s = stat($f) or exit 1;"
-   "printf(\"(%s %u %u %u (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) (%u %u))\\n\","
-   "$l, $s[3], $s[4], $s[5], $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, $s[0] >> 16 & 0xffff, $s[0] & 0xffff);"
-   )
-  "Perl script to produce output suitable for use with `file-attributes' 
-  on the remote file system.") 
-
-
-; These values conform to `file-attributes' from XEmacs 21.2.
-; GNU Emacs and other tools not checked.
-(defconst tramp2-file-mode-type-map '((0  . "-") ; Normal file (SVID-v2 and XPG2)
-				      (1  . "p") ; fifo
-				      (2  . "c") ; character device
-				      (3  . "m") ; multiplexed character device (v7)
-				      (4  . "d") ; directory
-				      (5  . "?") ; Named special file (XENIX)
-				      (6  . "b") ; block device
-				      (7  . "?") ; multiplexed block device (v7)
-				      (8  . "-") ; regular file
-				      (9  . "n") ; network special file (HP-UX)
-				      (10 . "l") ; symlink
-				      (11 . "?") ; ACL shadow inode (Solaris, not userspace)
-				      (12 . "s") ; socket
-				      (13 . "D") ; door special (Solaris)
-				      (14 . "w")) ; whiteout (BSD)
-  "A list of file types returned from the `stat' system call.
-This is used to map a mode number to a permission string.")
-
-(defun tramp2-do-file-attributes-with-perl (file)
-  "stat(2) FILE on the remote machine using Perl and return the result."
-  ;; Do the Perl stat setup, falling back if we have to.
-  ;; This is retried *every* stat, because I am mean. :/
-  (unless (or (and (boundp 'tramp2-file-attributes-sent-perl)
-		   tramp2-file-attributes-sent-perl)
-	      (tramp2-do-file-attributes-setup-perl file))
-    ;; Fall-back to the ls version, ugly as it is.
-    (tramp2-message 5 (format "Falling back to `ls' for `file-attributes'."))
-    (tramp2-do-file-attributes-with-ls file))
-  
-  ;; Run the stat on the remote machine.
-  ;; If this fails, we know that the file does not exist.
-  (when (= 0 (tramp2-run-command
-	      file (format "tramp2_stat_file %s"
-			   (tramp2-shell-quote (tramp2-path-remote-file file)))))
-    (let ((result (read (current-buffer))))
-      (setcar (nthcdr 8 result)
-	      (tramp2-file-mode-from-int (nth 8 result)))
-      result)))
-
-(defun tramp2-do-file-attributes-setup-perl (file)
-  "Send the Perl implementation of stat(2) to the remote host."
-  (when (= 0 (tramp2-run-command 
-	      file
-	      (format "tramp2_stat_file () { %s -e '%s' \"$1\" 2>/dev/null; }"
-		      tramp2-perl
-		      tramp2-perl-file-attributes)))
-    (set (make-local-variable 'tramp2-file-attributes-sent-perl) t)))
-
-(defun tramp2-file-mode-from-int (mode)
-  "Turn an integer representing a file mode into an ls(1)-like string."
-  (let ((type	(cdr (assoc (logand (lsh mode -12) 15) tramp2-file-mode-type-map)))
-	(user	(logand (lsh mode -6) 7))
-	(group	(logand (lsh mode -3) 7))
-	(other	(logand (lsh mode -0) 7))
-	(suid	(> (logand (lsh mode -9) 4) 0))
-	(sgid	(> (logand (lsh mode -9) 2) 0))
-	(sticky	(> (logand (lsh mode -9) 1) 0)))
-    (setq user  (tramp2-file-mode-permissions user  suid "s"))
-    (setq group (tramp2-file-mode-permissions group sgid "s"))
-    (setq other (tramp2-file-mode-permissions other sticky "t"))
-    (concat type user group other)))
-
-(defun tramp2-file-mode-permissions (perm suid suid-text)
-  "Convert a permission bitset into a string.
-This is used internally by `tramp-file-mode-from-int'."
-  (let ((r (> (logand perm 4) 0))
-	(w (> (logand perm 2) 0))
-	(x (> (logand perm 1) 0)))
-    (concat (or (and r "r") "-")
-	    (or (and w "w") "-")
-	    (or (and suid x suid-text)	; suid, execute
-		(and suid (upcase suid-text)) ; suid, !execute
-		(and x "x") "-"))))
-
-
-;; REVISIT: Can more of the work here be done on the remote machine with,
-;; say, sed(1) or something like that?
-(defun tramp2-do-file-attributes-with-ls (file)
-  "stat(2) FILE on the remote machine using ls, then parse and return the result."
-  (debug))
-
-
-(def-tramp-handler verify-visited-file-modtime (buffer)
-  "Ensure that the file visited by BUFFER is up-to-date.
-We need to handle this as a file-operation handler because
-the default implementation uses stat(2) directly,
-not `file-attributes'.
-
-This follows the same process as the XEmacs C implementation -
-it tollerates a whole second of variance between the last change
-and what's recorded in the buffer."
-  (with-current-buffer buffer
-    (let ((file (tramp2-path-parse-safe buffer-file-name)))
-      (unless file
-	(tramp2-error "Buffer is not a tramp buffer" buffer-file-name))
-      ;; Right, stat the thing.
-      (let* ((mtime  (nth 5 (tramp2-do-file-attributes file)))
-	     (btime  (visited-file-modtime)))
-	(and (= (car mtime) (car btime))
-	     (< (abs (- (cdr btime) (nth 1 mtime))) 1))))))
-
-
-;; Note that /either/ file being ours causes this routine to be called.
-(def-tramp-handler file-newer-than-file-p (file1 file2)
-  "Test if one file is newer than the other.
-This could be optimised with test(1) on the remote system, if the
-two files share a remote system.
-
-Return t if file FILE1 is newer than file FILE2.
-If FILE1 does not exist, the answer is nil;
-otherwise, if FILE2 does not exist, the answer is t."
-  (let ((the-file (tramp2-path-parse-safe file1))
-	(other-file (tramp2-path-parse-safe file2)))
-    (if (and the-file other-file (tramp2-path-same-connection-p the-file other-file))
-	;; Handle the simple case of both files on the same connection...
-	(tramp2-handle-fast-file-newer-than-file-p the-file other-file)
-      ;; Do this using `file-attributes'. This is unreliable on a
-      ;; connection without a remote Perl, though.
-      (let ((m1 (nth 5 (file-attributes file1)))
-	    (m2 (nth 5 (file-attributes file2))))
-	(cond ((not m1) nil)
-	      ((not m2) t)
-	      (t        (or (> (car m1) (car m2))
-			    (> (cadr m1) (cadr m2)))))))))
-
-(defun tramp2-handle-fast-file-newer-than-file-p (the-file other-file)
-  "Test if one file is newer than the other.
-This is an optimized version of the routine that depends on
-both files being on the same remote host connection.
-
-Note that we /don't/ use the optimized version when the
-connection is different because we don't know that we can
-accurately test the files.
-
-Specifically, think of the case where we have root and user
-at the same host. If we try to stat as root, we can see *any*
-file. If we try it as user, we can't. Different behaviour and,
-so, if we use the wrong id..."
-  (tramp2-with-connection the-file
-    (unless (= 0 (tramp2-run-command the-file
-				     (format "tramp2_file_newer_than %s %s"
-					     (tramp2-shell-quote
-					      (tramp2-path-remote-file the-file))
-					     (tramp2-shell-quote
-					      (tramp2-path-remote-file other-file)))))
-      (tramp2-error "Testing file newer than file"
-	     (tramp2-path-remote-file the-file)
-	     (tramp2-path-remote-file other-file)))
-    ;; Read the result out of the buffer...
-    (goto-char (point-min))
-    (read (current-buffer))))
-
-  
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; File name completion and dired integration.
-(defconst tramp2-find-file-completions
-  (concat "( cd %s && "
-	  "%s -a %s 2>/dev/null | "
-	  "{ echo \\(; while read f; do "
-	  "if test -d \"$f\" 2>/dev/null; then "
-	  "echo \\\"$f/\\\"; else "
-	  "echo \\\"$f\\\"; fi; done; "
-	  "echo \\); }"
-	  " )")
-   
-  "A shell script that lists completions of a file-name pattern.
-This has the ls(1) command and the glob substituted into it.
-
-It outputs a `read'-able list of completions in the current directory.
-
-Substitions, in order, are:
-* Remote directory
-* ls command
-* glob to match")
-
-
-(def-tramp-handler file-name-all-completions (partial dir)
-  "Find all possible completions for PARTIAL in DIR."
-  (let ((dir (tramp2-path-parse dir)))
-    (tramp2-with-connection dir
-      (unless (= 0 (tramp2-run-command dir
-				       (format tramp2-find-file-completions
-					       (tramp2-shell-quote
-						(tramp2-path-remote-file dir))
-					       tramp2-ls
-					       (if (and partial
-							(> (length partial) 0))
-						   (concat "-d " (tramp2-shell-quote partial) "*")
-						 ""))))
-	(tramp2-error (format "Unable to complete file names in %s"
-					  (tramp2-path-remote-file dir))
-	       (buffer-string)))
-      ;; Now, parse out the results...
-      (goto-char (point-min))
-      (let ((full            (read (current-buffer)))
-	    (without-ignored nil))
-	;; Remove the trivial items from the list...
-	(setq full (delete "./" (delete "../" full)))
-
-	;; Now, set `without-ignored' to the value *after* excluding entries
-	;; that have ignored extensions.
-	(setq without-ignored (delete nil (mapcar #'tramp2-complete-ignore-files full)))
-
-	;; Return the better list
-	(if (> (length without-ignored) 0)
-	    without-ignored
-	  full)))))
-
-(defsubst tramp2-complete-ignore-files (file)
-  "If FILE is in `completion-ignored-extensions', return nil, else return FILE."
-  (if (string-equal "/" (substring file -1))
-      file
-    (unless (member t (mapcar #'(lambda (ext) (tramp2-complete-ignored-file-p file ext))
-			      completion-ignored-extensions))
-      file)))
-      
-
-(defsubst tramp2-complete-ignored-file-p (file ext)
-  "If FILE matches EXT at the end, return t, else nil."
-  (let ((len (length ext)))
-    (and (> (length file) len)
-	 (string-equal ext (substring file (- len))))))
-
-
-(def-tramp-handler file-name-completion (partial dir)
-  "Find completions for PARTIAL in DIR."
-  (try-completion partial
-		  (mapcar (lambda (x) (cons x nil))
-			  (file-name-all-completions partial dir))))
-  
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; File reading and writing. The exciting stuff. :)
-(def-tramp-handler write-region (start end file &optional append visit lockname silly-emacs)
-  "Write a region of the current buffer to a tramp2 file.
-This behaves like `write-region' for tramp2 files.
-
-This routine operates correctly, without surprises, on both
-XEmacs and Emacs, with regard the 7th (SILLY-EMACS) argument.
-
-LOCKNAME (and file locking) are ignored by this routine.
-
-Version specific information:
-
-In Emacs, argument 7 SILLY-EMACS is CONFIRM.
-In XEmacs, argument 7 SILLY-EMACS is CODING-SYSTEM.
-
-Specifically, from documentation for `write-region':
-
-Write current region into specified file.
-By default the file's existing contents are replaced by the specified region.
-When called from a program, takes three arguments:
-START, END and FILENAME.  START and END are buffer positions.
-Optional fourth argument APPEND if non-nil means
-  append to existing file contents (if any).
-Optional fifth argument VISIT if t means
-  set last-save-file-modtime of buffer to this file's modtime
-  and mark buffer not modified.
-If VISIT is a string, it is a second file name;
-  the output goes to FILENAME, but the buffer is marked as visiting VISIT.
-  VISIT is also the file name to lock and unlock for clash detection.
-If VISIT is neither t nor nil nor a string,
-  that means do not print the \"Wrote file\" message.
-The optional sixth arg LOCKNAME, if non-nil, specifies the name to 
-  use for locking and unlocking, overriding FILENAME and VISIT. 
-Kludgy feature: if START is a string, then that string is written 
-to the file, instead of any buffer contents, and END is ignored. 
-
-XEmacs specific documentation:
-
-Optional seventh argument CODING-SYSTEM specifies the coding system 
-  used to encode the text when it is written out, and defaults to 
-  the value of `buffer-file-coding-system' in the current buffer. 
-  Interactively, with a prefix arg, you will be prompted for the 
-  coding system.
-
-Emacs specific documentation:
-
-The optional seventh arg CONFIRM, if non-nil, says ask for confirmation
-  before overwriting an existing file."
-  ;; Handle the basic argument lossage. Dammit.
-  (when (or (featurep 'xemacs)
-	    (and (not (null silly-emacs))
-		 (file-exists-p file)
-		 (yes-or-no-p (format "File %s on host %s exists, overwrite? "
-				      (tramp2-path-remote-file file)
-				      (tramp2-connect-host (last (tramp2-path-connect file)))))))
-    (tramp2-write-region-internal start end file
-				  append visit lockname
-				  (and (featurep 'xemacs)
-				       silly-emacs))))
-
-(defun tramp2-write-region-internal (start end file append visit lockname coding-system)
-  "Internal handler for `write-region' once the Emacs/XEmacs lossage
-is dealt with.
-
-Locking, and LOCKNAME specifically, are ignored."
-  ;; Do we need to generate a special buffer?
-  (if (stringp start)
-      (with-temp-buffer
-	(insert start)
-	(tramp2-write (point-min) (point-max) file append))
-    (tramp2-write (point-min) (point-max) file append)))
-  
-
-(def-tramp-handler insert-file-contents (file &optional visit start end replace)
-  "Handle insertion of file content from the remote machine.
-
-This actually copes with REPLACE, even though that requires C-level
-support (at least on XEmacs). This is done through the wonders of
-temporary files. Feel good yet?
-
-Specifically, from documentation for `insert-file-contents':
-
-Insert contents of file FILENAME after point.
-Returns list of absolute file name and length of data inserted.
-If second argument VISIT is non-nil, the buffer's visited filename
-and last save file modtime are set, and it is marked unmodified.
-If visiting and the file does not exist, visiting is completed
-before the error is signaled.
-
-The optional third and fourth arguments START and END
-specify what portion of the file to insert.
-If VISIT is non-nil, START and END must be nil.
-If optional fifth argument REPLACE is non-nil,
-it means replace the current buffer contents (in the accessible portion)
-with the file contents.  This is better than simply deleting and inserting
-the whole thing because (1) it preserves some marker positions
-and (2) it puts less data in the undo list.
-
-The coding system used for decoding the file is determined as follows:
-
-1. `coding-system-for-read', if non-nil.
-2. The result of `insert-file-contents-pre-hook', if non-nil.
-3. The matching value for this filename from
-   `file-coding-system-alist', if any.
-4. `buffer-file-coding-system-for-read', if non-nil.
-5. The coding system 'raw-text.
-
-If a local value for `buffer-file-coding-system' in the current buffer
-does not exist, it is set to the coding system which was actually used
-for reading.
-
-See also `insert-file-contents-access-hook',
-`insert-file-contents-pre-hook', `insert-file-contents-error-hook',
-and `insert-file-contents-post-hook'."
-
-  ;; REVISIT: This is /so/ not finished...
-
-  ;; Error-check the parameters...
-  (when (and visit (or start end))
-    (tramp2-error "If VISIT, START and END must be nil" start end visit))
-
-  ;; Make sure this isn't a read-only buffer...
-  (barf-if-buffer-read-only)
-
-  ;; Fill in some basics...
-  (let ((filename (tramp2-do-expand-file-name file))
-	(attr     (tramp2-do-file-attributes file)))
-    ;; Deal with the visit stuff...
-    (when visit
-      (setq buffer-file-name filename)
-      (set-visited-file-modtime (or (nth 5 attr) '(0 0)))
-      (set-buffer-modified-p nil))
-    
-    ;; If the file does not exist...
-    (unless (tramp2-do-file-exists-p file)
-      (error 'file-error (format "File `%s' not found on remote host" filename))
-      (list filename 0))
-
-    ;; Otherwise, we read the data and put it in it's place...
-    (let ((data (tramp2-read start end file)))
-      (unless (buffer-live-p data)
-	(tramp2-error
-		      (format "Failed to read from %s"
-			      (tramp2-path-remote-file file))))
-      
-      ;; Are we doing the magic replace thing?
-      (if replace
-	  (let ((temp (tramp2-temp-file-name)))
-	    (with-temp-file temp
-	      (insert-buffer data))
-	    ;; Don't let the C visit, we did that already.
-	    (insert-file-contents temp nil start end replace)
-	    (delete-file temp))
-	;; Just insert the data...
-	(insert-buffer data))
-
-      ;; Return the absolute file name and the length of data inserted.
-      (list filename (or (and start end (- end start))
-			 (nth 7 attr))))))
-  
-    
-	
-
-
-
-(provide 'tramp2-ops)
-
-;; TODO:
-;; * `insert-file-contents' needs to be polished and checked for errors.
-;;
-;; * `file-newer-than-file-p' needs to use test(1) (or whatever) when the
-;;   remote system does not support the Perl `file-attributes' implementation.
-;;
-;; * Support visiting of files (implement these ops):
-;;
-;; vc-registered create-file-buffer get-file-buffer abbreviate-file-name
-;; substitute-in-file-name
-
-
-;;; tramp2-ops.el ends here

File lisp/tramp2-util.el

-;;; tramp2-util.el --- TRAMP2 utility functions
-
-;; Copyright (C) 2001 by Daniel Pittman <daniel@localhost>
-
-;;; Commentary:
-
-;; This module contains routines that are likely to be valuable to
-;; user-defined tramp2 code or that are used in multiple modules and don't
-;; really fit into the main tramp2.el file.
-
-;;; Code:
-(eval-when-compile
-  (require 'tramp2))
-
-(require 'shell)
-
-;; Special characters for various shells:
-;; When enclosed in double quotes ("), only $, `, \ and " need to be quoted.
-;; This is uber-cool and true of any shell I have met thus far...
-(defun tramp2-shell-quote (text)
-  "Return a string that will be identical to TEXT after Bourne
-shell parsing."
-  (save-match-data
-    (let ((result text)
-	  (start 0))
-    (while (string-match "[$`\\\"]" result 0)
-      (setq result (replace-match "\\\0" nil nil result)
-	    start  (match-end 0)))
-    (if (> (length result) 0)
-	(concat "\"" result "\"")
-      result))))
-
-	
-
-(defun tramp2-util-shell-write (file coder append data)
-  "Write DATA to FILE on the remote machine, appending to it if
-APPEND is not nil. DATA is the encoded data to transmit to the
-remote machine and CODER is the executable to decode data on the
-remote machine.
-
-This routine returns t if the call succeeds and nil otherwise."
-  (let ((end-of-data (format "end of data %x %x"
-			     (mod (apply 'logxor (current-time)) (emacs-pid))
-			     (apply 'logxor (current-time)))))
-    ;; This is the critical operation. Breaking during a write can leave
-    ;; god knows what corrupt data in flight to the remote machine...
-    (debug)
-    (condition-case nil
-	(= 0 (tramp2-run-command file (format "%s <<'%s' %s %s\n%s\n%s\n"
-					      coder
-					      end-of-data
-					      (if append ">>" ">")
-					      (tramp2-shell-quote
-					       (tramp2-path-remote-file file))
-					      data
-					      end-of-data)))
-      (t
-       ;; Kill this connection buffer. It's easier than trying to recover
-       ;; any other way. We leak the temp file but, heck, it's hardly any
-       ;; sort of real loss. Better to leak than to corrupt data.
-       (unless tramp2-debug-preserve-evidence
-	 (when (buffer-live-p (current-buffer))
-	   (kill-buffer (current-buffer))))))))
-
-
-
-(defun tramp2-util-shell-read (file encoder decoder start end)
-  "Read the bytes from START to END from file on the remote machine.
-Use ENCODER to encode it on the remote machine and DECODER to
-decode it locally.
-
-ENCODER must be a string, a shell command to run.
-DECODER must be a function that accepts two arguments, the start
-and end point of the encoded data in the current buffer."
-  (when (and start end (> start end))
-    (tramp2-error
-		  (format "End of data %s less than start of data %s" end start)))
-  (unless (and (stringp encoder)
-	       (fboundp decoder))
-    (tramp2-error
-		  (format "Invalid coder specified" encoder decoder)))
-  ;; Right, do the actual hacking...
-  (tramp2-with-connection file
-    (let ((cut (when (and start end tramp2-dd)
-		 (format "{ 2>/dev/null %s bs=1 skip=%s count=%s } |"
-			 tramp2-dd start (- end start)))))
-      (when (= 0 (tramp2-run-command file (format "<%s %s %s"
-						  (tramp2-shell-quote
-						   (tramp2-path-remote-file file))
-						  (or cut "") encoder)))
-	;; Got the data, yay.
-	(funcall decoder (point-min) (point-max))
-	;; Did we clip with dd?
-	(when (and start end (not tramp2-dd))
-	  ;; Nope, clip ourselves. Sadness.
-	  (delete-region (point-min) start)
-	  (delete-region end (point-max)))
-	;; Return the buffer with the decoded data...
-	(current-buffer)))))
-				       
-
-(defun tramp2-temp-file-name ()
-  "Return a file-name suitable for a temporary file.
-FILE is used as a basis for making it unique and all."
-  (let* ((dir (tramp2-temp-dir))
-	 (prefix (or (and (boundp 'tramp2-temp-name-prefix) tramp2-temp-name-prefix)
-		     "tramp2."))
-	 ;; Generate the temporary name...
-	 (path (funcall (or (and (fboundp 'make-temp-name) #'make-temp-name)
-			    (and (fboundp 'make-temp-file) #'make-temp-file)
-			    #'tramp2-temp-file-name-internal)
-			(concat dir prefix))))
-    path))
-
-(defun tramp2-temp-file-name-internal (prefix)
-  "If no suitable temp-name generator exists on this system, fake it."
-  (apply 'format "%s.%s.%s%s%s" prefix (emacs-pid) (current-time)))
-	  
-
-(defun tramp2-getenv (path &optional name)
-  "Get the value of the environment variable NAME.
-If there is a local value, use that, otherwise try on the machine
-at the end of PATH."
-  (or (getenv name)
-      (and path
-	   (tramp2-with-connection path
-	     (unless (= 0 (tramp2-run-command path (format "echo ${%s}" name)))
-	       (tramp2-error "Unable to expand environment value" name))
-	     (buffer-substring (tramp2-point-at-bol) (tramp2-point-at-eol))))))
-
-
-(defun tramp2-case-insenitive-glob (name)
-  "Take NAME and return a shell glob that will match it
-in a case-insensitive fashion."
-  (mapconcat #'tramp2-case-insenitive-glob-internal name ""))
-
-(defun tramp2-case-insenitive-glob-internal (char)
-  "Take char and return a string that is a case-insensitive shell
-glob matching it."
-  (let ((upper (upcase char))
-	(lower (downcase char)))
-    (if (eq upper lower)
-	(tramp2-shell-quote (string char))
-      (format "[%c%c]" upper lower))))
-
-
-(provide 'tramp2-util)
-
-;;; tramp2-util.el ends here

File lisp/tramp2.el

-;;; tramp2.el --- Network file access via login shell
-
-;; Copyright (C) 2001 Free Software Foundation, Inc.
-
-;;; Commentary:
-
-;; Based on the TRAMP code by Kai Gro�johann, et al.
-
-;;; Code:
-
-(require 'cl)				
-(require 'timer)
-(require 'shell)
-
-(require 'tramp2-compat)
-
-;; Byte compiler pacifiers.
-(eval-when-compile
-  (defvar tramp2-state	nil)
-  (defvar tramp2-perl	nil)
-  (defvar tramp2-ls	nil)
-  (defvar tramp2-dd	nil)
-  (defvar tramp2-read	nil)
-  (defvar tramp2-write	nil)
-)
-
-
-(defconst tramp2-version "$Id$"
-  "The CVS version number of this tramp2 release.")
-
-
-;; Error thrown when a file is invalid.
-(define-error 'tramp2-file-error
-  "Error thrown when a tramp2 specific error occurs.
-Inheritance ensures that anything expecting generic file errors will be happy."
-  'file-error)
-
-
-(defvar tramp2-load-hooks nil
-  "*Hooks run when the tramp2 file interface is loaded.")
-
-(defvar tramp2-temp-dir nil
-  "If not nil, a directory in which to store tramp2 temporary files.
-By default, the value of TMPDIR or TMP is used, or \"/tmp\".")
-
-(defvar tramp2-temp-name-prefix nil
-  "If not nil, a unique prefix string to identify tramp2 files.")
-
-
-(defconst tramp2-path-tag "/!/"
-  "Regular expression matching a TRAMP2 path tag.
-If you redefine this, be aware that you *need* the second `/' in
-the value before any `:' is present.
-
-Since `:' is an integral part of the tramp2 connect syntax, this
-requires that the path tag contain a `/'.
-
-Other possible values here are: \"/tramp/\" or \"/!t/\".")
-
-
-;; Internal.
-(defconst tramp2-path-connect (concat ;; match a protocol statement
-			              ;; 1     2      2        3            3   1
-				      "\\(\\[\\([^]]+\\)\\]\\|\\([a-zA-Z]+\\)|\\)?"
-				      ;; match a user statement
-				      ;; 4  5                5   4
-				      "\\(\\([-_a-zA-Z0-9]+\\)@\\)?"
-				      ;; match a host
-				      ;; 6               6
-				      "\\([-a-zA-Z0-9]+\\)?"
-				      ":")
-  "Regular expression matching a single complete connect expression.
-This does not (and can't cleanly) represent all the rules for a /valid/
-connect expression, but it simplifies the first-stage approximation well.")
-
-(defvar tramp2-shell-prompt-pattern (list
-				     (cons 'default shell-prompt-pattern))
-  "A set of regular expressions to match the prompt of a remote host.
-Values in this are looked up with `tramp2-find-value'.")
-
-
-(defvar tramp2-remote-shell-alist (list
-				   '(default ("/bin/sh -i"
-					      "/bin/bash -i"
-					      "/bin/ksh -i"
-					      "/bin/zsh -i")))
-  "Define the remote shell to run on a particular host.
-Values in this are looked up with `tramp2-find-value' and the
-result is treated as an active expression (`tramp2-expression').
-
-The shell run by executing the command-line given should be an
-interactive Bourne shell capable of expanding a '~' into the
-home directory of a user.
-
-If the value is a list of strings, these strings are tested in
-order to detect which of them supports tilde expansion. The
-default set should work with the auto-detection support on
-most systems.")
-
-
-(defvar tramp2-directory-abbrev-alist nil
-  "An alist of directory abbreviation lists to use on remote systems.
-Values in this are looked up with `tramp2-find-value'.
-
-This is the equivalent of `directory-abbrev-alist' for tramp2 remote
-machines.")
-
-
-;; REVISIT: Internal...
-(defvar tramp2-handler-alist nil
-  "Associative list of tramp2 file operation handlers.
-To define a file operation handler, see the `def-tramp-handler' macro.
-
-This list is automatically generated. You shouldn't change this
-by hand.")
-
-
-;; REVISIT: What should this be in the release?
-(defvar tramp2-default-protocol 'ssh
-  "The default protocol to use.")
-
-;; REVISIT: Populate this with a larger number of connections.
-(defvar tramp2-protocol-alist '((ssh . ((command . tramp2-ssh-make-command))))
-  "An associative set of protocol tags, each mapping to an alist
-defining the characteristics of the connection.
-
-Each protocol has a symbol as a tag. The defined characteristics are:
-
-* `command', the command line to execute. A tramp2 active expression.
-  See `tramp2-expression' for more details.
-
-* `encoding', the encoding to use for the connection.
-  If this is unspecified, an inline transfer encoding is automatically
-  detected on the remote machine. See `tramp2-encoding-alist' for
-  more details.")
-
-   
-(defvar tramp2-ssh-executable (list
-			       '(default "ssh"))
-  "Arguments to provide to an ssh connection.
-Values in this are looked up with `tramp2-find-value' and the
-result treated with `tramp2-expression'.")
-
-
-(defvar tramp2-ssh-arguments (list
-			      '(default "-t -e none"))
-  "Arguments to provide to an ssh connection.
-Values in this are looked up with `tramp2-find-value' and the
-result treated with `tramp2-expression'.")
-
-
-
-(defvar tramp2-encoding-alist '((base64 . ((test  . tramp2-base64-test)
-					   (write . tramp2-base64-write)
-					   (read  . tramp2-base64-read)))
-				
-				(uuencode . ((test  . tramp2-uuencode-test)
-					     (write . tramp2-uuencode-write)
-					     (read  . tramp2-uuencode-read))))
-  "An associative list of encoding types and their properties.
-Each encoding has a name and a number of properties. Each property
-is a symbol representing a function to call to achieve a specified
-result.
-
-* `test', a function to test if the encoding is suitable for use
-  with a given connection.
-
-  It is called with two arguments, the final connection and the
-  path that triggered the connection. It should return `t' if the
-  encoding is suitable and `nil' otherwise.
-
-  If this property is not present, the encoding will be used if
-  specified in a protocol without verification, and will not be
-  detected automatically on a remote machine.
-
-* `write', a function to send data to the remote machine.
-  It is a function name that is called with five arguments,
-  SOURCE, START, END, FILE and APPEND.
-
-  SOURCE is the buffer that holds the data to be sent. This data
-  *must not* be changed by this routine.
-
-  START and END are positions in the SOURCE buffer. The data from
-  START to END should be written to the remote file.
-
-  FILE is the full tramp2 path of the file to write.
-
-  If APPEND is non-nil, the data should be appended to the file,
-  if it already exists. The file should be overwritten otherwise.
-
-  This routine *must not* change the current buffer.
-
-
-* `read', a function to read data from a file on the remote machine.
-  It will be called in the connection buffer for a connection, with
-  three arguments, START, END and FILE.
-
-  START and END are byte positions in the remote file to be read.
-  START and END may be nil, in which case the whole file should be read.
-
-  FILE is the remote file to read from.
-
-  This routine should return a buffer object that contains the decoded
-  data from the remote machine. This must contain *only* the bytes from
-  START to END in the remote file.")
-  
-
-
-(defvar tramp2-base64-coder
-  (list
-   `(default ((encoder ("mimencode"
-			"recode ../64"
-			,(concat "perl -e 'use MIME::Base64 qw(encode_base64);"
-				  "$/ = undef; print encode_base64(<STDIN>);'")))
-	      (decoder ("mimencode -u"
-			"recode /64.."
-			,(concat "perl -e 'use MIME::Base64 qw(decode_base64);"
-				  "$/ = undef; print decode_base64(<STDIN>);'"))))))
-  "An associative list of base64 coding programs for remote machines.
-Values in this are looked up with `tramp2-find-value'.
-
-The value is a list of properties with the following predefined:
-
-* `encoder', the remote command to encode to base64.
-* `decoder', the remote command to decode from base64.
-
-Each of these may be a string, in which case they are used as a
-command directly, or a list of strings in which case each command
-is tried in turn until one is found that succeeds.
-
-The encoder and decoder command need not be the same executable
-or even the same item in the list.")
-
-
-
-;; REVISIT: Semi-public, fill this in.
-(defvar tramp2-connect-actors
-  (list
-   '("pass\\(phrase\\|word\\)[^:]*:" 	. tramp2-send-password)
-   '(tramp2-shell-prompt 		. (throw 'ready t)))
-  "A list of actions to take while connecting to a remote machine.
-See `tramp2-run-actors' for details on the content of this list.
-
-This set of actions is run while establishing each hop in the connection
-sequence. Matching for password prompts and similar questions should
-go here.")
-
-
-(defvar tramp2-shell-startup-actors
-  (list
-   '(tramp2-shell-prompt                . (throw 'ready t)))
-  "A list of actions to take while executing a remote login shell.
-See `tramp2-run-actors' for details on the content of this list.
-
-This set of actions is run while executing a suitable login shell
-on the remote machine.")
-
-
-
-;; REVISIT: Semi-public.
-(defvar tramp2-setup-functions '(tramp2-setup-coding-system
-                                 tramp2-setup-interactive-shell
-				 tramp2-setup-remote-environment
-				 tramp2-setup-detect-tools
-				 tramp2-setup-file-transfer
-				 tramp2-setup-file-newer-than)
-  "The list of functions to run, in order, to setup the remote shell.
-This is run in the tramp2 connection buffer and should run commands
-to ensure that the remote shell is ready to accept commands.
-
-The function is run in the connection buffer. Setup functions must
-accept two arguments, the connect object for the final hop of the
-connection and the full path that triggered the request.
-
-See `tramp2-send-command' for details on sending a command to the
-remote system.
-
-Note that you almost certainly *DON'T* want to make any function
-other than `tramp2-setup-interactive-shell' the first function in
-this list.
-
-If you do, you should be aware that `tramp2-send-command' (amongst
-other things) will not work.")
-
-
-(defconst tramp2-shell-default-environment '(("HISTFILE"  nil)
-					     ("TRAMP"     "yes")
-					     ("PATH"      tramp2-shell-path)
-					     ("TERM"      "dumb")
-					     ("MAIL"      nil)
-					     ("MAILCHECK" nil)
-					     ("MAILPATH"  nil)
-					     ("CDPATH"    nil)
-					     ("LC_TIME"   "C")
-					     ("PS1"       "1> ")
-					     ("PS2"       "2> ")
-					     ("PS3"       "3> "))
-  "Default remote environment values set into the remote shell.
-The values here can be overridden by values in `tramp2-shell-environment'.
-
-You should not need to change the values in here directly. Values
-in this list are processed in the same way as values in the
-`tramp2-shell-environment' list.")
-
-
-(defvar tramp2-shell-environment nil
-  "Remote environment values to set for the remote shell.
-Values in this are looked up with `tramp2-find-value'.
-
-The value is a list of values to set into the remote environment.
-Each entry in the list is a string value, naming the environment
-value, and an active expression (`tramp2-expression') to set it to.
-
-If the value to set the variable to is `nil' the variable is unset
-instead. To set an empty value, use \"\" as the value.
-
-Values in this list override the TRAMP2 provided system default
-values in `tramp2-shell-default-environment'.")
-
-
-(defvar tramp2-remote-shell-path   '("/bin"
-				     "/usr/bin"
-				     "/usr/sbin"
-				     "/usr/local/bin"
-				     "/usr/ccs/bin"
-				     "/local/bin"
-				     "/local/freeware/bin"
-				     "/local/gnu/bin"
-				     "/usr/freeware/bin"
-				     "/usr/pkg/bin")
-  "*The directories to search for directories on the remote machine.")
-
-
-(defvar tramp2-remote-tools '((tramp2-perl ("perl5" "perl")      tramp2-remote-perl-v5)
-			      (tramp2-ls   "ls"			 tramp2-remote-ls-verify)
-			      (tramp2-ln   "ln")
-			      (tramp2-dd   "dd"))
-  "A list of tools to detect on the remote machine.
-Each entry is a list with two or three entries. These are:
-
-* symbol, the name of the variable to set.
-
-  This symbol is made a buffer local variable for the connection
-  and set to the full path of the tool, or `nil' if the tool was
-  not found.
-
-* tool, a string or a list of strings.
-
-  This is the name of the tool to look for. If it is a string, it
-  is searched for directly. If it is a list, each string in it is
-  searched for in order.
-
-* verify, an optional function to call to verify the tool.
-
-  If the third element is present, it is called as a function with
-  two arguments, the current path and the full path of the detected
-  tool.
-
-  If this routine returns nil, the tool is ignored and the search
-  continues.")
-
-
-  
-
-(defvar tramp2-remote-file-newer-than
-  (list
-   "test $1 -nt $2"
-   "test -n \"`find $1 -prune -newer $2 -print`\""
-   (concat "perl -e \"if ((stat(\\\"$1\\\"))[9] > "
-	   "(stat(\\\"$2\\\"))[9]) { exit 0 } else { exit 1 }\""))