Mercurial > hg > xemacs-beta
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 |