comparison lisp/efs/efs.el @ 48:56c54cf7c5b6 r19-16b90

Import from CVS: tag r19-16b90
author cvs
date Mon, 13 Aug 2007 08:56:04 +0200
parents 8d2a9b52c682
children
comparison
equal deleted inserted replaced
47:11c6df210d7f 48:56c54cf7c5b6
4 ;; File: efs.el 4 ;; File: efs.el
5 ;; Release: $efs release: 1.15 $ 5 ;; Release: $efs release: 1.15 $
6 ;; Version: #Revision: 1.56 $ 6 ;; Version: #Revision: 1.56 $
7 ;; RCS: 7 ;; RCS:
8 ;; Description: Transparent FTP support for the original GNU Emacs 8 ;; Description: Transparent FTP support for the original GNU Emacs
9 ;; from FSF and Lucid Emacs 9 ;; from FSF and XEmacs
10 ;; Authors: Andy Norman <ange@hplb.hpl.hp.com>, 10 ;; Authors: Andy Norman <ange@hplb.hpl.hp.com>,
11 ;; Sandy Rutherford <sandy@ibm550.sissa.it> 11 ;; Sandy Rutherford <sandy@ibm550.sissa.it>
12 ;; Created: Thu Oct 12 14:00:05 1989 (as ange-ftp) 12 ;; Created: Thu Oct 12 14:00:05 1989 (as ange-ftp)
13 ;; 13 ;;
14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1386 Applies when nslookup is used to compute a fully qualified domain name 1386 Applies when nslookup is used to compute a fully qualified domain name
1387 for the local host, in the case when `system-name' does not return one. 1387 for the local host, in the case when `system-name' does not return one.
1388 If you set this to nil, efs will wait an arbitrary amount of time to get 1388 If you set this to nil, efs will wait an arbitrary amount of time to get
1389 output.") 1389 output.")
1390 1390
1391 (defvar efs-remote-shell-file-name
1392 (if (memq system-type '(hpux usg-unix-v)) ; hope that's right
1393 "remsh"
1394 "rsh")
1395 "Remote shell used by efs.")
1396
1397 (defvar efs-remote-shell-takes-user
1398 (null (null (memq system-type '(aix aix-v3 hpux silicon-graphics-unix
1399 berkeley-unix))))
1400 ;; Complete? Doubt it.
1401 "Set to non-nil if your remote shell command takes \"-l USER\".")
1402
1391 (defvar efs-make-backup-files efs-unix-host-types 1403 (defvar efs-make-backup-files efs-unix-host-types
1392 "*A list of operating systems for which efs will make Emacs backup files. 1404 "*A list of operating systems for which efs will make Emacs backup files.
1393 The backup files are made on the remote host. 1405 The backup files are made on the remote host.
1394 1406
1395 For example: 1407 For example:
1583 the option to type commands at the FTP connection. Normally, the connection 1595 the option to type commands at the FTP connection. Normally, the connection
1584 is killed first. Note that doing this may result in the FTP process filter 1596 is killed first. Note that doing this may result in the FTP process filter
1585 getting out of synch with the FTP client, so using this feature routinely 1597 getting out of synch with the FTP client, so using this feature routinely
1586 isn't recommended.") 1598 isn't recommended.")
1587 1599
1600 (defvar efs-use-passive-mode nil
1601 "*If non-nil, the ftp client will specify passive mode for all transfers.")
1602
1588 ;;; Hooks and crooks. 1603 ;;; Hooks and crooks.
1589 1604
1590 (defvar efs-ftp-startup-hook nil 1605 (defvar efs-ftp-startup-hook nil
1591 "Hook to run immediately after starting the FTP client. 1606 "Hook to run immediately after starting the FTP client.
1592 This hook is run before the FTP OPEN command is sent.") 1607 This hook is run before the FTP OPEN command is sent.")
1643 ;; file existence. 1658 ;; file existence.
1644 1659
1645 (defvar efs-cmd-ok-cmds 1660 (defvar efs-cmd-ok-cmds
1646 (concat 1661 (concat
1647 "^quote port \\|^type \\|^quote site \\|^chmod \\|^quote noop\\|" 1662 "^quote port \\|^type \\|^quote site \\|^chmod \\|^quote noop\\|"
1648 "^quote pasv")) 1663 "^quote pasv\\|^passive"))
1649 ;; Regexp to match commands for which efs-cmd-ok-msgs is a valid server 1664 ;; Regexp to match commands for which efs-cmd-ok-msgs is a valid server
1650 ;; response for success. 1665 ;; response for success.
1651 1666
1652 (defvar efs-passwd-cmds 1667 (defvar efs-passwd-cmds
1653 "^quote pass \\|^quote acct \\|^quote site gpass ") 1668 "^quote pass \\|^quote acct \\|^quote site gpass ")
1676 "^2[01345][0-7] \\|" ; 2yz = positive completion reply 1691 "^2[01345][0-7] \\|" ; 2yz = positive completion reply
1677 "^22[02-7] \\|" ; 221 = successful logout 1692 "^22[02-7] \\|" ; 221 = successful logout
1678 ; (Sometimes get this with a timeout, 1693 ; (Sometimes get this with a timeout,
1679 ; so treat as fatal.) 1694 ; so treat as fatal.)
1680 "^3[0-5][0-7] \\|" ; 3yz = positive intermediate reply 1695 "^3[0-5][0-7] \\|" ; 3yz = positive intermediate reply
1696 ;; passive
1697 "^[Pp]assive \\|"
1681 ;; client codes 1698 ;; client codes
1682 "^[Hh]ash mark ")) 1699 "^[Hh]ash mark "))
1683 ;; Response to indicate that the requested action was successfully completed. 1700 ;; Response to indicate that the requested action was successfully completed.
1684 1701
1685 (defvar efs-failed-msgs 1702 (defvar efs-failed-msgs
3642 3659
3643 (progn 3660 (progn
3644 ;; Tell client to send back hash-marks as progress. It isn't 3661 ;; Tell client to send back hash-marks as progress. It isn't
3645 ;; usually fatal if this command fails. 3662 ;; usually fatal if this command fails.
3646 (efs-guess-hash-mark-size proc) 3663 (efs-guess-hash-mark-size proc)
3664
3665 (if efs-use-passive-mode
3666 (efs-passive-mode host user))
3647 3667
3648 ;; Run any user startup functions 3668 ;; Run any user startup functions
3649 (let ((alist efs-ftp-startup-function-alist) 3669 (let ((alist efs-ftp-startup-function-alist)
3650 (case-fold-search t)) 3670 (case-fold-search t))
3651 (while alist 3671 (while alist
3682 (if (string-match "^[0-9]+$" size) 3702 (if (string-match "^[0-9]+$" size)
3683 (set (if gate-p 3703 (set (if gate-p
3684 'efs-gateway-hash-mark-size 3704 'efs-gateway-hash-mark-size
3685 'efs-hash-mark-size) 3705 'efs-hash-mark-size)
3686 (string-to-int size)))))))))) 3706 (string-to-int size))))))))))
3707
3708 (defun efs-passive-mode (host user)
3709 ;; put ftp into passive mode
3710 (efs-send-cmd host user '(passive)))
3687 3711
3688 ;;;; ------------------------------------------------------------ 3712 ;;;; ------------------------------------------------------------
3689 ;;;; Simple FTP process shell support. 3713 ;;;; Simple FTP process shell support.
3690 ;;;; ------------------------------------------------------------ 3714 ;;;; ------------------------------------------------------------
3691 3715
4064 (efs-fix-path host-type cmd1)) 4088 (efs-fix-path host-type cmd1))
4065 cmd2 (efs-quote-string host-type 4089 cmd2 (efs-quote-string host-type
4066 (efs-fix-path host-type cmd2)) 4090 (efs-fix-path host-type cmd2))
4067 cmd-string (concat "rename " cmd1 " " cmd2)))) 4091 cmd-string (concat "rename " cmd1 " " cmd2))))
4068 4092
4093 ;; passive command
4094 ((eq cmd0 'passive)
4095 (setq cmd-string "passive"))
4096
4069 (t 4097 (t
4070 (error "efs: Don't know how to send %s %s %s %s" 4098 (error "efs: Don't know how to send %s %s %s %s"
4071 cmd0 cmd1 cmd2 cmd3)))) 4099 cmd0 cmd1 cmd2 cmd3))))
4072 4100
4073 ;; Actually send the resulting command. 4101 ;; Actually send the resulting command.
4197 (let ((gate (efs-use-gateway-p host))) 4225 (let ((gate (efs-use-gateway-p host)))
4198 (if (eq gate 'kerberos) 4226 (if (eq gate 'kerberos)
4199 (progn 4227 (progn
4200 (setq proc (efs-kerberos-login host user proc)) 4228 (setq proc (efs-kerberos-login host user proc))
4201 (efs-login-send-user host user proc gate)) 4229 (efs-login-send-user host user proc gate))
4202 (let ((to (if (memq gate '(proxy local raptor)) 4230 (let ((to (if (memq gate '(proxy raptor))
4203 efs-gateway-host 4231 efs-gateway-host
4204 host)) 4232 host))
4205 port cmd result) 4233 port cmd result)
4206 (if (string-match "#" to) 4234 (if (string-match "#" to)
4207 (setq port (substring to (match-end 0)) 4235 (setq port (substring to (match-end 0))
4231 (defun efs-login-send-user (host user proc &optional gate retry) 4259 (defun efs-login-send-user (host user proc &optional gate retry)
4232 "Send user command to HOST and USER. PROC is the ftp client process. 4260 "Send user command to HOST and USER. PROC is the ftp client process.
4233 Optional argument GATE specifies which type of gateway is being used. 4261 Optional argument GATE specifies which type of gateway is being used.
4234 RETRY argument specifies to try twice if we get a 421 response." 4262 RETRY argument specifies to try twice if we get a 421 response."
4235 (let ((cmd (cond 4263 (let ((cmd (cond
4236 ((memq gate '(local proxy interlock)) 4264 ((memq gate '(proxy interlock))
4237 (format "quote USER \"%s\"@%s" user 4265 (format "quote USER \"%s\"@%s" user
4238 (if (and efs-nslookup-on-connect 4266 (if (and efs-nslookup-on-connect
4239 (string-match "[^0-9.]" host)) 4267 (string-match "[^0-9.]" host))
4240 (efs-nslookup-host host) 4268 (efs-nslookup-host host)
4241 host))) 4269 host)))
4259 (setq to (concat to "@" port)))) 4287 (setq to (concat to "@" port))))
4260 (format "quote user \"%s\"@%s" user to))) 4288 (format "quote user \"%s\"@%s" user to)))
4261 (t 4289 (t
4262 (format "quote user \"%s\"" user)))) 4290 (format "quote user \"%s\"" user))))
4263 (msg (format "Logging in as user %s%s..." user 4291 (msg (format "Logging in as user %s%s..." user
4264 (if (memq gate '(proxy local raptor kerberos)) 4292 (if (memq gate '(proxy raptor kerberos))
4265 (concat "@" host) ""))) 4293 (concat "@" host) "")))
4266 result code) 4294 result code)
4267 4295
4268 ;; Send the message by hand so that we can report on the size 4296 ;; Send the message by hand so that we can report on the size
4269 ;; of the MOTD. 4297 ;; of the MOTD.
8087 (sticky (memq int '(1 3 5 7)))) 8115 (sticky (memq int '(1 3 5 7))))
8088 (concat (efs-build-mode-string-element owner-int suid nil) 8116 (concat (efs-build-mode-string-element owner-int suid nil)
8089 (efs-build-mode-string-element group-int sgid nil) 8117 (efs-build-mode-string-element group-int sgid nil)
8090 (efs-build-mode-string-element other-int nil sticky)))) 8118 (efs-build-mode-string-element other-int nil sticky))))
8091 8119
8120 (defun efs-shell-call-process (command dir &optional in-background)
8121 ;; Runs shell process on remote hosts.
8122 (let* ((parsed (efs-ftp-path dir))
8123 (host (car parsed))
8124 (user (nth 1 parsed))
8125 (rdir (nth 2 parsed))
8126 (file-name-handler-alist nil))
8127 (or (string-equal (efs-internal-directory-file-name dir)
8128 (efs-expand-tilde "~" (efs-host-type host) host user))
8129 (string-match "^cd " command)
8130 (setq command (concat "cd " rdir "; " command)))
8131 (setq command
8132 (format "%s %s%s \"%s\"" ; remsh -l USER does not work well
8133 ; on a hp-ux machine I tried
8134 efs-remote-shell-file-name host
8135 (if efs-remote-shell-takes-user
8136 (concat " -l " user)
8137 "")
8138 command))
8139 (message "Doing shell command on %s..." host)
8140 ;; do it
8141 (let ((process-connection-type ; don't waste pty's
8142 (null (null in-background))))
8143 (setq default-directory (file-name-directory efs-tmp-name-template))
8144 (if in-background
8145 (progn
8146 (setq mode-line-process '(": %s"))
8147 (start-process "Shell" (current-buffer)
8148 shell-file-name "-c" command))
8149 (call-process shell-file-name nil t nil "-c" command)))))
8150
8092 (defun efs-set-file-modes (file mode) 8151 (defun efs-set-file-modes (file mode)
8093 ;; set-file-modes for remote files. 8152 ;; set-file-modes for remote files.
8094 ;; For remote files, if mode is nil, does nothing. 8153 ;; For remote files, if mode is nil, does nothing.
8095 ;; This is because efs-file-modes returns nil if the modes 8154 ;; This is because efs-file-modes returns nil if the modes
8096 ;; of a remote file couldn't be determined, even if the file exists. 8155 ;; of a remote file couldn't be determined, even if the file exists.
8109 host user 8168 host user
8110 (list 'quote 'site 'chmod omode r-file) 8169 (list 'quote 'site 'chmod omode r-file)
8111 nil nil 8170 nil nil
8112 (efs-cont (result line cont-lines) (host file r-file omode) 8171 (efs-cont (result line cont-lines) (host file r-file omode)
8113 (if result 8172 (if result
8114 (progn 8173 (let ((exit-code
8115 (efs-set-host-property host 'chmod-failed t) 8174 (efs-shell-call-process
8116 (message "CHMOD %s failed for %s on %s." omode r-file host) 8175 (concat "chmod " mode " " (file-name-nondirectory file))
8117 (if efs-ding-on-chmod-failure 8176 (file-name-directory file))))
8118 (progn (ding) (sit-for 1)))) 8177 (if (not (equal 0 exit-code))
8178 (progn
8179 (efs-set-host-property host 'chmod-failed t)
8180 (message "CHMOD %s failed for %s on %s." omode r-file host)
8181 (if efs-ding-on-chmod-failure
8182 (progn (ding) (sit-for 1))))))
8119 (let ((ent (efs-get-file-entry file))) 8183 (let ((ent (efs-get-file-entry file)))
8120 (if ent 8184 (if ent
8121 (let* ((type 8185 (let* ((type
8122 (cond 8186 (cond
8123 ((null (car ent)) "-") 8187 ((null (car ent)) "-")
8859 (downcase def-user)) 8923 (downcase def-user))
8860 (string-equal user def-user)) 8924 (string-equal user def-user))
8861 (format efs-path-format-without-user host path) 8925 (format efs-path-format-without-user host path)
8862 (format efs-path-format-string user host path)))) 8926 (format efs-path-format-string user host path))))
8863 8927
8864 (efs-define-fun efs-abbreviate-file-name (filename) 8928 (efs-define-fun efs-abbreviate-file-name (filename &optional ignored-for-now)
8865 ;; Version of abbreviate-file-name for remote files. 8929 ;; Version of abbreviate-file-name for remote files.
8866 (efs-save-match-data 8930 (efs-save-match-data
8867 (let ((tail directory-abbrev-alist)) 8931 (let ((tail directory-abbrev-alist))
8868 (while tail 8932 (while tail
8869 (if (string-match (car (car tail)) filename) 8933 (if (string-match (car (car tail)) filename)
10759 (apply operation args)))) 10823 (apply operation args))))
10760 10824
10761 ;; Yes, this is what it looks like. I'm defining the handler to run our 10825 ;; Yes, this is what it looks like. I'm defining the handler to run our
10762 ;; version whenever there is an environment variable. 10826 ;; version whenever there is an environment variable.
10763 10827
10764 (nconc file-name-handler-alist 10828 (defvar efs-path-sifn-regexp "\\(^\\|[^$]\\)\\(\\$\\$\\)*\\$[{a-zA-Z0-9]"
10765 (list 10829 "Regexp to match environment variables in file names.")
10766 (cons "\\(^\\|[^$]\\)\\(\\$\\$\\)*\\$[{a-zA-Z0-9]" 10830
10767 'efs-sifn-handler-function))) 10831 (or (assoc efs-path-sifn-regexp file-name-handler-alist)
10832 (nconc file-name-handler-alist
10833 (list
10834 (cons efs-path-sifn-regexp
10835 'efs-sifn-handler-function))))
10768 10836
10769 ;;;; ------------------------------------------------------------ 10837 ;;;; ------------------------------------------------------------
10770 ;;;; Necessary overloads. 10838 ;;;; Necessary overloads.
10771 ;;;; ------------------------------------------------------------ 10839 ;;;; ------------------------------------------------------------
10772 10840