diff options
| author | Richard M. Stallman | 2002-01-20 22:10:54 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2002-01-20 22:10:54 +0000 |
| commit | 9c35d70676c537a9990bac17a501f7e7e9c1906e (patch) | |
| tree | 91f07c25b9f0e3812d77f3688b4f067cff059c04 | |
| parent | 3c17e0623770992013cf3c4f80e4b97b1bd02e39 (diff) | |
| download | emacs-9c35d70676c537a9990bac17a501f7e7e9c1906e.tar.gz emacs-9c35d70676c537a9990bac17a501f7e7e9c1906e.zip | |
Added support for BS2000, and for raw ftp
login commands (needed in some circumstances).
(ange-ftp-raw-login): New custom var.
(ange-ftp-normal-login): Perform login with raw ftp commands, if
ange-ftp-raw-login is set and account password is needed.
(ange-ftp-host-type, ange-ftp-guess-host-type): Handle BS2000 hosts.
(ange-ftp-bs2000-filename-pubset-regexp)
(ange-ftp-bs2000-filename-username-regexp)
(ange-ftp-bs2000-filename-prefix-regexp)
(ange-ftp-bs2000-name-template): New consts.
(ange-ftp-bs2000-short-filename-regexp)
(ange-ftp-bs2000-fix-name-regexp-reverse)
(ange-ftp-bs2000-fix-name-regexp): New consts.
(ange-ftp-bs2000-special-prefix): New custom var.
(ange-ftp-fix-name-for-bs2000)
(ange-ftp-fix-dir-name-for-bs2000): New funs.
(ange-ftp-bs2000-host-regexp, ange-ftp-bs2000-posix-host-regexp)
(ange-ftp-bs2000-posix-hook-installed): New vars.
(ange-ftp-parse-bs2000-filename, ange-ftp-parse-bs2000-listing)
(ange-ftp-bs2000-host, ange-ftp-bs2000-posix-host)
(ange-ftp-add-bs2000-host, ange-ftp-add-bs2000-posix-host): New funs.
(ange-ftp-bs2000-filename-regexp): New const.
(ange-ftp-bs2000-additional-pubsets): New custom var.
(ange-ftp-bs2000-cd-to-posix): New fun.
| -rw-r--r-- | lisp/net/ange-ftp.el | 385 |
1 files changed, 373 insertions, 12 deletions
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index ae86391ffbc..2af51044896 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el | |||
| @@ -385,6 +385,66 @@ | |||
| 385 | ;; 2. Ange-ftp cannot send "write passwords" for a minidisk. Hopefully, we | 385 | ;; 2. Ange-ftp cannot send "write passwords" for a minidisk. Hopefully, we |
| 386 | ;; can fix this. | 386 | ;; can fix this. |
| 387 | ;; | 387 | ;; |
| 388 | ;; BS2000 support: | ||
| 389 | ;; | ||
| 390 | ;; Ange-ftp has full support for BS2000 hosts. It should be able to | ||
| 391 | ;; automatically recognize any BS2000 machine. However, if it fails to | ||
| 392 | ;; do this, you can use the command ange-ftp-add-bs2000-host. As well, | ||
| 393 | ;; you can set the variable ange-ftp-bs2000-host-regexp in your .emacs | ||
| 394 | ;; file. We would be grateful if you would report any failures to auto- | ||
| 395 | ;; matically recognize a BS2000 host as a bug. | ||
| 396 | ;; | ||
| 397 | ;; If you want to access the POSIX subsystem on BS2000 you MUST use | ||
| 398 | ;; command ange-ftp-add-bs2000-posix-host for that particular | ||
| 399 | ;; hostname. ange-ftp can't decide if you want to access the native | ||
| 400 | ;; filesystem or the POSIX filesystem, so it accesses the native | ||
| 401 | ;; filesystem by default. And if you have an ASCII filesystem in | ||
| 402 | ;; your BS2000 POSIX subsystem you must use | ||
| 403 | ;; ange-ftp-binary-file-name-regexp to access its files. | ||
| 404 | ;; | ||
| 405 | ;; Filename Syntax: | ||
| 406 | ;; | ||
| 407 | ;; For ease of *implementation*, the user enters the BS2000 filename | ||
| 408 | ;; syntax in a UNIX-y way. For example: | ||
| 409 | ;; :PUB:$PUBLIC.ANONYMOUS.SDSCPUB.NEXT.README.TXT | ||
| 410 | ;; would be entered as: | ||
| 411 | ;; /:PUB:/$$PUBLIC/ANONYMOUS.SDSCPUB.NEXT.README.TXT | ||
| 412 | ;; You dont't have to type pubset and account, if they have default values, | ||
| 413 | ;; i.e. to log in as anonymous on bs2000.anywhere.com and grab the file | ||
| 414 | ;; IMPORTANT.TEXT.ON.BS2000 on the default pubset X on userid PUBLIC | ||
| 415 | ;; (there are only 8 characters in a valid username), you could type: | ||
| 416 | ;; C-x C-f /public@bs2000.anywhere.com:/IMPORTANT.TEXT.ON.BS2000 | ||
| 417 | ;; or | ||
| 418 | ;; C-x C-f /anonym@bs2000.anywhere.com:/:X:/$$PUBLIC/IMPORTANT.TEXT.ON.BS2000 | ||
| 419 | ;; | ||
| 420 | ;; If X is not your default pubset, you could add it as 'subdirectory' (BS2000 | ||
| 421 | ;; has a flat architecture) with the command | ||
| 422 | ;; (setq ange-ftp-bs2000-additional-pubsets '(":X:")) | ||
| 423 | ;; and then you could type: | ||
| 424 | ;; C-x C-f /anonym@bs2000.anywhere.com:/:X:/IMPORTANT.TEXT.ON.BS2000 | ||
| 425 | ;; | ||
| 426 | ;; Valid characters in an BS2000 filename are A-Z 0-9 $ # @ . - | ||
| 427 | ;; If the first character in a filename is # or @, this is replaced with | ||
| 428 | ;; ange-ftp-bs2000-special-prefix because names starting with # or @ | ||
| 429 | ;; are reserved for temporary files. | ||
| 430 | ;; This is especially important for auto-save files. | ||
| 431 | ;; Valid file generations are ending with ([+|-|*]0-9...) . | ||
| 432 | ;; File generations are not supported yet! | ||
| 433 | ;; A filename must at least contain one character (A-Z) and cannot be longer | ||
| 434 | ;; than 41 characters. | ||
| 435 | ;; | ||
| 436 | ;; Tips: | ||
| 437 | ;; 1. Although BS2000 is not case sensitive, EMACS running under UNIX is. | ||
| 438 | ;; Therefore, to access a BS2000 file, you must enter the filename with | ||
| 439 | ;; upper case letters. | ||
| 440 | ;; 2. EMACS has a feature in which it does environment variable substitution | ||
| 441 | ;; in filenames. Therefore, to enter a $ in a filename, you must quote it | ||
| 442 | ;; by typing $$. | ||
| 443 | ;; 3. BS2000 machines, with the exception of anonymous accounts, nearly | ||
| 444 | ;; always need an account password. To have ange-ftp send an account | ||
| 445 | ;; password, you can either include it in your .netrc file, or use | ||
| 446 | ;; ange-ftp-set-account. | ||
| 447 | ;; | ||
| 388 | ;; ------------------------------------------------------------------ | 448 | ;; ------------------------------------------------------------------ |
| 389 | ;; Bugs: | 449 | ;; Bugs: |
| 390 | ;; ------------------------------------------------------------------ | 450 | ;; ------------------------------------------------------------------ |
| @@ -1994,6 +2054,13 @@ on the gateway machine to do the ftp instead." | |||
| 1994 | (make-local-variable 'paragraph-start) | 2054 | (make-local-variable 'paragraph-start) |
| 1995 | (setq paragraph-start comint-prompt-regexp))) | 2055 | (setq paragraph-start comint-prompt-regexp))) |
| 1996 | 2056 | ||
| 2057 | (defcustom ange-ftp-raw-login nil | ||
| 2058 | "*Use raw ftp commands for login, if account password is not nil. | ||
| 2059 | Some ftp implementations need this, e.g. ftp in NT 4.0." | ||
| 2060 | :group 'ange-ftp | ||
| 2061 | :version "21.3" | ||
| 2062 | :type 'boolean) | ||
| 2063 | |||
| 1997 | (defun ange-ftp-smart-login (host user pass account proc) | 2064 | (defun ange-ftp-smart-login (host user pass account proc) |
| 1998 | "Connect to the FTP-server on HOST as USER using PASSWORD and ACCOUNT. | 2065 | "Connect to the FTP-server on HOST as USER using PASSWORD and ACCOUNT. |
| 1999 | PROC is the FTP-client's process. This routine uses the smart-gateway | 2066 | PROC is the FTP-client's process. This routine uses the smart-gateway |
| @@ -2044,13 +2111,42 @@ suffix of the form #PORT to specify a non-default port" | |||
| 2044 | (ange-ftp-error host user | 2111 | (ange-ftp-error host user |
| 2045 | (concat "OPEN request failed: " | 2112 | (concat "OPEN request failed: " |
| 2046 | (cdr result)))) | 2113 | (cdr result)))) |
| 2047 | (setq result (ange-ftp-raw-send-cmd | 2114 | (if (not (and ange-ftp-raw-login (string< "" account))) |
| 2048 | proc | 2115 | (setq result (ange-ftp-raw-send-cmd |
| 2049 | (if (and (ange-ftp-use-smart-gateway-p host) | 2116 | proc |
| 2050 | ange-ftp-gateway-host) | 2117 | (if (and (ange-ftp-use-smart-gateway-p host) |
| 2051 | (format "user \"%s\"@%s %s %s" user nshost pass account) | 2118 | ange-ftp-gateway-host) |
| 2052 | (format "user \"%s\" %s %s" user pass account)) | 2119 | (format "user \"%s\"@%s %s %s" |
| 2053 | (format "Logging in as user %s@%s" user host))) | 2120 | user nshost pass account) |
| 2121 | (format "user \"%s\" %s %s" user pass account)) | ||
| 2122 | (format "Logging in as user %s@%s" user host))) | ||
| 2123 | (let ((good ange-ftp-good-msgs) | ||
| 2124 | (skip ange-ftp-skip-msgs)) | ||
| 2125 | (setq ange-ftp-good-msgs (concat ange-ftp-good-msgs | ||
| 2126 | "\\|^331 \\|^332 ")) | ||
| 2127 | (if (string-match (regexp-quote "\\|^331 ") ange-ftp-skip-msgs) | ||
| 2128 | (setq ange-ftp-skip-msgs | ||
| 2129 | (replace-match "" t t ange-ftp-skip-msgs))) | ||
| 2130 | (if (string-match (regexp-quote "\\|^332 ") ange-ftp-skip-msgs) | ||
| 2131 | (setq ange-ftp-skip-msgs | ||
| 2132 | (replace-match "" t t ange-ftp-skip-msgs))) | ||
| 2133 | (setq result (ange-ftp-raw-send-cmd | ||
| 2134 | proc | ||
| 2135 | (format "quote \"USER %s\"" user) | ||
| 2136 | (format "Logging in as user %s@%s" user host))) | ||
| 2137 | (and (car result) | ||
| 2138 | (setq result (ange-ftp-raw-send-cmd | ||
| 2139 | proc | ||
| 2140 | (format "quote \"PASS %s\"" pass) | ||
| 2141 | (format "Logging in as user %s@%s" user host))) | ||
| 2142 | (and (car result) | ||
| 2143 | (setq result (ange-ftp-raw-send-cmd | ||
| 2144 | proc | ||
| 2145 | (format "quote \"ACCT %s\"" account) | ||
| 2146 | (format "Logging in as user %s@%s" user host))) | ||
| 2147 | )) | ||
| 2148 | (setq ange-ftp-good-msgs good | ||
| 2149 | ange-ftp-skip-msgs skip))) | ||
| 2054 | (or (car result) | 2150 | (or (car result) |
| 2055 | (progn | 2151 | (progn |
| 2056 | (ange-ftp-set-passwd host user nil) ;reset password. | 2152 | (ange-ftp-set-passwd host user nil) ;reset password. |
| @@ -2174,6 +2270,12 @@ host-type by logging in as USER." | |||
| 2174 | ((and (fboundp 'ange-ftp-cms-host) | 2270 | ((and (fboundp 'ange-ftp-cms-host) |
| 2175 | (ange-ftp-cms-host host)) | 2271 | (ange-ftp-cms-host host)) |
| 2176 | 'cms) | 2272 | 'cms) |
| 2273 | ((and (fboundp 'ange-ftp-bs2000-posix-host) | ||
| 2274 | (ange-ftp-bs2000-posix-host host)) | ||
| 2275 | 'text-unix) ; POSIX is a non-ASCII Unix | ||
| 2276 | ((and (fboundp 'ange-ftp-bs2000-host) | ||
| 2277 | (ange-ftp-bs2000-host host)) | ||
| 2278 | 'bs2000) | ||
| 2177 | (t | 2279 | (t |
| 2178 | 'unix)))))) | 2280 | 'unix)))))) |
| 2179 | 2281 | ||
| @@ -2324,6 +2426,20 @@ and NOWAIT." | |||
| 2324 | "^[-A-Z0-9_$]+:\\[[-A-Z0-9_$]+\\(\\.[-A-Z0-9_$]+\\)*\\]$") | 2426 | "^[-A-Z0-9_$]+:\\[[-A-Z0-9_$]+\\(\\.[-A-Z0-9_$]+\\)*\\]$") |
| 2325 | (defconst ange-ftp-mts-name-template | 2427 | (defconst ange-ftp-mts-name-template |
| 2326 | "^[A-Z0-9._][A-Z0-9._][A-Z0-9._][A-Z0-9._]:$") | 2428 | "^[A-Z0-9._][A-Z0-9._][A-Z0-9._][A-Z0-9._]:$") |
| 2429 | (defconst ange-ftp-bs2000-filename-pubset-regexp | ||
| 2430 | ":[A-Z0-9]+:" | ||
| 2431 | "Valid pubset for an BS2000 file name.") | ||
| 2432 | (defconst ange-ftp-bs2000-filename-username-regexp | ||
| 2433 | (concat | ||
| 2434 | "\\$[A-Z0-9]*\\.") | ||
| 2435 | "Valid username for an BS2000 file name.") | ||
| 2436 | (defconst ange-ftp-bs2000-filename-prefix-regexp | ||
| 2437 | (concat | ||
| 2438 | ange-ftp-bs2000-filename-pubset-regexp | ||
| 2439 | ange-ftp-bs2000-filename-username-regexp) | ||
| 2440 | "Valid prefix for an BS2000 file name (pubset and user).") | ||
| 2441 | (defconst ange-ftp-bs2000-name-template | ||
| 2442 | (concat "^" ange-ftp-bs2000-filename-prefix-regexp "$")) | ||
| 2327 | 2443 | ||
| 2328 | (defun ange-ftp-guess-host-type (host user) | 2444 | (defun ange-ftp-guess-host-type (host user) |
| 2329 | "Guess the host type of HOST. | 2445 | "Guess the host type of HOST. |
| @@ -2370,6 +2486,17 @@ Works by doing a pwd and examining the directory syntax." | |||
| 2370 | (setq ange-ftp-host-cache host | 2486 | (setq ange-ftp-host-cache host |
| 2371 | ange-ftp-host-type-cache 'cms)) | 2487 | ange-ftp-host-type-cache 'cms)) |
| 2372 | 2488 | ||
| 2489 | ;; try for BS2000-POSIX | ||
| 2490 | ((ange-ftp-bs2000-posix-host host) | ||
| 2491 | (ange-ftp-add-bs2000-host host) | ||
| 2492 | (setq ange-ftp-host-cache host | ||
| 2493 | ange-ftp-host-type-cache 'text-unix)) | ||
| 2494 | ;; try for BS2000 | ||
| 2495 | ((and (string-match ange-ftp-bs2000-name-template dir) | ||
| 2496 | (not (ange-ftp-bs2000-posix-host host))) | ||
| 2497 | (ange-ftp-add-bs2000-host host) | ||
| 2498 | (setq ange-ftp-host-cache host | ||
| 2499 | ange-ftp-host-type-cache 'bs2000)) | ||
| 2373 | ;; assume UN*X | 2500 | ;; assume UN*X |
| 2374 | (t | 2501 | (t |
| 2375 | (setq ange-ftp-host-cache host | 2502 | (setq ange-ftp-host-cache host |
| @@ -2825,14 +2952,17 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained." | |||
| 2825 | ;;; (or | 2952 | ;;; (or |
| 2826 | ;;; ;; Deal with dired | 2953 | ;;; ;; Deal with dired |
| 2827 | ;;; (and (boundp 'dired-local-variables-file) ; in the dired-x package | 2954 | ;;; (and (boundp 'dired-local-variables-file) ; in the dired-x package |
| 2828 | ;;; (stringp dired-local-variables-file) | 2955 | ;;; (stringp dired-local-variables-file) |
| 2829 | ;;; (string-equal dired-local-variables-file efile)) | 2956 | ;;; (string-equal dired-local-variables-file efile)) |
| 2830 | ;;; ;; No dots in dir names in vms. | 2957 | ;;; ;; No dots in dir names in vms. |
| 2831 | ;;; (and (eq host-type 'vms) | 2958 | ;;; (and (eq host-type 'vms) |
| 2832 | ;;; (string-match "\\." efile)) | 2959 | ;;; (string-match "\\." efile)) |
| 2833 | ;;; ;; No subdirs in mts of cms. | 2960 | ;;; ;; No subdirs in mts of cms. |
| 2834 | ;;; (and (memq host-type '(mts cms)) | 2961 | ;;; (and (memq host-type '(mts cms)) |
| 2835 | ;;; (not (string-equal "/" (nth 2 parsed))))))) | 2962 | ;;; (not (string-equal "/" (nth 2 parsed)))) |
| 2963 | ;;; ;; No dots in pseudo-dir names in bs2000. | ||
| 2964 | ;;; (and (eq host-type 'bs2000) | ||
| 2965 | ;;; (string-match "\\." efile))))))) | ||
| 2836 | 2966 | ||
| 2837 | (defun ange-ftp-file-entry-p (name) | 2967 | (defun ange-ftp-file-entry-p (name) |
| 2838 | "Given NAME, return whether there is a file entry for it." | 2968 | "Given NAME, return whether there is a file entry for it." |
| @@ -5808,6 +5938,237 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5808 | ;; ange-ftp-dired-get-filename-alist))) | 5938 | ;; ange-ftp-dired-get-filename-alist))) |
| 5809 | 5939 | ||
| 5810 | ;;;; ------------------------------------------------------------ | 5940 | ;;;; ------------------------------------------------------------ |
| 5941 | ;;;; BS2000 support | ||
| 5942 | ;;;; ------------------------------------------------------------ | ||
| 5943 | |||
| 5944 | ;; There seems to be an error with regexps. '-' has to be the first | ||
| 5945 | ;; character inside of the square brackets. | ||
| 5946 | (defconst ange-ftp-bs2000-short-filename-regexp | ||
| 5947 | "[-A-Z0-9$#@.]*[A-Z][-A-Z0-9$#@.]*" | ||
| 5948 | "Regular expression to match for a valid short BS2000 file name.") | ||
| 5949 | |||
| 5950 | (defconst ange-ftp-bs2000-fix-name-regexp-reverse | ||
| 5951 | (concat | ||
| 5952 | "^\\(" ange-ftp-bs2000-filename-pubset-regexp "\\)?" | ||
| 5953 | "\\(" ange-ftp-bs2000-filename-username-regexp "\\)?" | ||
| 5954 | "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") | ||
| 5955 | "Regular expression used in ange-ftp-fix-name-for-bs2000.") | ||
| 5956 | |||
| 5957 | (defconst ange-ftp-bs2000-fix-name-regexp | ||
| 5958 | (concat | ||
| 5959 | "/?\\(" ange-ftp-bs2000-filename-pubset-regexp "/\\)?" | ||
| 5960 | "\\(\\$[A-Z0-9]*/\\)?" | ||
| 5961 | "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") | ||
| 5962 | "Regular expression used in ange-ftp-fix-name-for-bs2000.") | ||
| 5963 | |||
| 5964 | (defcustom ange-ftp-bs2000-special-prefix | ||
| 5965 | "X" | ||
| 5966 | "*Prefix used for filenames starting with '#' or '@'." | ||
| 5967 | :group 'ange-ftp | ||
| 5968 | :type 'string) | ||
| 5969 | |||
| 5970 | ;; Convert NAME from UNIX-ish to BS2000. If REVERSE given then convert from | ||
| 5971 | ;; BS2000 to UNIX-ish. | ||
| 5972 | (defun ange-ftp-fix-name-for-bs2000 (name &optional reverse) | ||
| 5973 | (save-match-data | ||
| 5974 | (if reverse | ||
| 5975 | (if (string-match | ||
| 5976 | ange-ftp-bs2000-fix-name-regexp-reverse | ||
| 5977 | name) | ||
| 5978 | (let ((pubset (if (match-beginning 1) | ||
| 5979 | (substring name 0 (match-end 1)))) | ||
| 5980 | (userid (if (match-beginning 2) | ||
| 5981 | (substring name | ||
| 5982 | (match-beginning 2) | ||
| 5983 | (1- (match-end 2))))) | ||
| 5984 | (filename (if (match-beginning 3) | ||
| 5985 | (substring name (match-beginning 3))))) | ||
| 5986 | (concat | ||
| 5987 | "/" | ||
| 5988 | ;; we have to insert "_/" here to prevent expand-file-name to | ||
| 5989 | ;; interpret BS2000 pubsets as the special escape prefix: | ||
| 5990 | (and pubset (concat "_/" pubset "/")) | ||
| 5991 | (and userid (concat userid "/")) | ||
| 5992 | filename)) | ||
| 5993 | (error "name %s didn't match" name)) | ||
| 5994 | ;; and here we (maybe) have to remove the inserted "_/" 'cause | ||
| 5995 | ;; of our prevention of the special escape prefix above: | ||
| 5996 | (if (string-match (concat "^/_/") name) | ||
| 5997 | (setq name (substring name 2))) | ||
| 5998 | (if (string-match | ||
| 5999 | ange-ftp-bs2000-fix-name-regexp | ||
| 6000 | name) | ||
| 6001 | (let ((pubset (if (match-beginning 1) | ||
| 6002 | (substring name | ||
| 6003 | (match-beginning 1) | ||
| 6004 | (1- (match-end 1))))) | ||
| 6005 | (userid (if (match-beginning 2) | ||
| 6006 | (substring name | ||
| 6007 | (match-beginning 2) | ||
| 6008 | (1- (match-end 2))))) | ||
| 6009 | (filename (if (match-beginning 3) | ||
| 6010 | (substring name (match-beginning 3))))) | ||
| 6011 | (if (and (boundp 'filename) | ||
| 6012 | (stringp filename) | ||
| 6013 | (string-match "[#@].+" filename)) | ||
| 6014 | (setq filename (concat ange-ftp-bs2000-special-prefix | ||
| 6015 | (substring filename 1)))) | ||
| 6016 | (upcase | ||
| 6017 | (concat | ||
| 6018 | pubset | ||
| 6019 | (and userid (concat userid ".")) | ||
| 6020 | ;; change every '/' in filename to a '.', normally not neccessary | ||
| 6021 | (and filename | ||
| 6022 | (apply (function concat) | ||
| 6023 | (mapcar (function (lambda (char) | ||
| 6024 | (if (= char ?/) | ||
| 6025 | (vector ?.) | ||
| 6026 | (vector char)))) | ||
| 6027 | filename)))))) | ||
| 6028 | ;; Let's hope that BS2000 recognize this anyway: | ||
| 6029 | name)))) | ||
| 6030 | |||
| 6031 | (or (assq 'bs2000 ange-ftp-fix-name-func-alist) | ||
| 6032 | (setq ange-ftp-fix-name-func-alist | ||
| 6033 | (cons '(bs2000 . ange-ftp-fix-name-for-bs2000) | ||
| 6034 | ange-ftp-fix-name-func-alist))) | ||
| 6035 | |||
| 6036 | ;; Convert name from UNIX-ish to BS2000 ready for a DIRectory listing. | ||
| 6037 | ;; Remember that there are no directories in BS2000. | ||
| 6038 | (defun ange-ftp-fix-dir-name-for-bs2000 (dir-name) | ||
| 6039 | (if (string-equal dir-name "/") | ||
| 6040 | "*" ;; Don't use an empty string here! | ||
| 6041 | (ange-ftp-fix-name-for-bs2000 dir-name))) | ||
| 6042 | |||
| 6043 | (or (assq 'bs2000 ange-ftp-fix-dir-name-func-alist) | ||
| 6044 | (setq ange-ftp-fix-dir-name-func-alist | ||
| 6045 | (cons '(bs2000 . ange-ftp-fix-dir-name-for-bs2000) | ||
| 6046 | ange-ftp-fix-dir-name-func-alist))) | ||
| 6047 | |||
| 6048 | (or (memq 'bs2000 ange-ftp-dumb-host-types) | ||
| 6049 | (setq ange-ftp-dumb-host-types | ||
| 6050 | (cons 'bs2000 ange-ftp-dumb-host-types))) | ||
| 6051 | |||
| 6052 | (defvar ange-ftp-bs2000-host-regexp nil) | ||
| 6053 | (defvar ange-ftp-bs2000-posix-host-regexp nil) | ||
| 6054 | |||
| 6055 | ;; Return non-nil if HOST is running BS2000. | ||
| 6056 | (defun ange-ftp-bs2000-host (host) | ||
| 6057 | (and ange-ftp-bs2000-host-regexp | ||
| 6058 | (save-match-data | ||
| 6059 | (string-match ange-ftp-bs2000-host-regexp host)))) | ||
| 6060 | ;; Return non-nil if HOST is running BS2000 with POSIX subsystem. | ||
| 6061 | (defun ange-ftp-bs2000-posix-host (host) | ||
| 6062 | (and ange-ftp-bs2000-posix-host-regexp | ||
| 6063 | (save-match-data | ||
| 6064 | (string-match ange-ftp-bs2000-posix-host-regexp host)))) | ||
| 6065 | |||
| 6066 | (defun ange-ftp-add-bs2000-host (host) | ||
| 6067 | "Mark HOST as the name of a machine running BS2000." | ||
| 6068 | (interactive | ||
| 6069 | (list (read-string "Host: " | ||
| 6070 | (let ((name (or (buffer-file-name) default-directory))) | ||
| 6071 | (and name (car (ange-ftp-ftp-name name))))))) | ||
| 6072 | (if (not (ange-ftp-bs2000-host host)) | ||
| 6073 | (setq ange-ftp-bs2000-host-regexp | ||
| 6074 | (concat "^" (regexp-quote host) "$" | ||
| 6075 | (and ange-ftp-bs2000-host-regexp "\\|") | ||
| 6076 | ange-ftp-bs2000-host-regexp) | ||
| 6077 | ange-ftp-host-cache nil))) | ||
| 6078 | |||
| 6079 | (defun ange-ftp-add-bs2000-posix-host (host) | ||
| 6080 | "Mark HOST as the name of a machine running BS2000 with POSIX subsystem." | ||
| 6081 | (interactive | ||
| 6082 | (list (read-string "Host: " | ||
| 6083 | (let ((name (or (buffer-file-name) default-directory))) | ||
| 6084 | (and name (car (ange-ftp-ftp-name name))))))) | ||
| 6085 | (if (not (ange-ftp-bs2000-posix-host host)) | ||
| 6086 | (setq ange-ftp-bs2000-posix-host-regexp | ||
| 6087 | (concat "^" (regexp-quote host) "$" | ||
| 6088 | (and ange-ftp-bs2000-posix-host-regexp "\\|") | ||
| 6089 | ange-ftp-bs2000-posix-host-regexp) | ||
| 6090 | ange-ftp-host-cache nil)) | ||
| 6091 | ;; Install CD hook to cd to posix on connecting: | ||
| 6092 | (and (not ange-ftp-bs2000-posix-hook-installed) | ||
| 6093 | (add-hook 'ange-ftp-process-startup-hook 'ange-ftp-bs2000-cd-to-posix) | ||
| 6094 | (setq ange-ftp-bs2000-posix-hook-installed t)) | ||
| 6095 | host) | ||
| 6096 | |||
| 6097 | (defconst ange-ftp-bs2000-filename-regexp | ||
| 6098 | (concat | ||
| 6099 | "\\(" ange-ftp-bs2000-filename-prefix-regexp "\\)?" | ||
| 6100 | "\\(" ange-ftp-bs2000-short-filename-regexp "\\)") | ||
| 6101 | "Regular expression to match for a valid BS2000 file name.") | ||
| 6102 | |||
| 6103 | (defcustom ange-ftp-bs2000-additional-pubsets | ||
| 6104 | nil | ||
| 6105 | "*List of additional pubsets available to all users." | ||
| 6106 | :group 'ange-ftp | ||
| 6107 | :type 'string) | ||
| 6108 | |||
| 6109 | ;; These parsing functions are as general as possible because the syntax | ||
| 6110 | ;; of ftp listings from BS2000 hosts is a bit erratic. What saves us is that | ||
| 6111 | ;; the BS2000 filename syntax is so rigid. | ||
| 6112 | |||
| 6113 | ;; Extract the next filename from a BS2000 dired-like listing. | ||
| 6114 | (defun ange-ftp-parse-bs2000-filename () | ||
| 6115 | (if (re-search-forward ange-ftp-bs2000-filename-regexp nil t) | ||
| 6116 | (buffer-substring (match-beginning 2) (match-end 2)))) | ||
| 6117 | |||
| 6118 | ;; Parse the current buffer which is assumed to be in (some) BS2000 FTP dir | ||
| 6119 | ;; format, and return a hashtable as the result. | ||
| 6120 | (defun ange-ftp-parse-bs2000-listing () | ||
| 6121 | (let ((tbl (ange-ftp-make-hashtable)) | ||
| 6122 | pubset | ||
| 6123 | file) | ||
| 6124 | ;; get current pubset | ||
| 6125 | (goto-char (point-min)) | ||
| 6126 | (if (re-search-forward ange-ftp-bs2000-filename-pubset-regexp nil t) | ||
| 6127 | (setq pubset (buffer-substring (match-beginning 0) (match-end 0)))) | ||
| 6128 | ;; add files to hashtable | ||
| 6129 | (goto-char (point-min)) | ||
| 6130 | (save-match-data | ||
| 6131 | (while (setq file (ange-ftp-parse-bs2000-filename)) | ||
| 6132 | (ange-ftp-put-hash-entry file nil tbl))) | ||
| 6133 | ;; add . and .. | ||
| 6134 | (ange-ftp-put-hash-entry "." t tbl) | ||
| 6135 | (ange-ftp-put-hash-entry ".." t tbl) | ||
| 6136 | ;; add all additional pubsets, if not listing one of them | ||
| 6137 | (if (not (member pubset ange-ftp-bs2000-additional-pubsets)) | ||
| 6138 | (mapcar (function (lambda (pubset) | ||
| 6139 | (ange-ftp-put-hash-entry pubset t tbl))) | ||
| 6140 | ange-ftp-bs2000-additional-pubsets)) | ||
| 6141 | tbl)) | ||
| 6142 | |||
| 6143 | (or (assq 'bs2000 ange-ftp-parse-list-func-alist) | ||
| 6144 | (setq ange-ftp-parse-list-func-alist | ||
| 6145 | (cons '(bs2000 . ange-ftp-parse-bs2000-listing) | ||
| 6146 | ange-ftp-parse-list-func-alist))) | ||
| 6147 | |||
| 6148 | (defvar ange-ftp-bs2000-posix-hook-installed nil) | ||
| 6149 | (defun ange-ftp-bs2000-cd-to-posix () | ||
| 6150 | "cd to POSIX subsystem if the current host matches | ||
| 6151 | ange-ftp-bs2000-posix-host-regexp. All BS2000 hosts with POSIX subsystem | ||
| 6152 | MUST BE EXPLICITLY SET with ange-ftp-add-bs2000-posix-host for they cannot | ||
| 6153 | be recognized automatically (they are all valid BS2000 hosts too)." | ||
| 6154 | (if (and host (ange-ftp-bs2000-posix-host host)) | ||
| 6155 | (progn | ||
| 6156 | ;; change to POSIX: | ||
| 6157 | ; (ange-ftp-raw-send-cmd proc "cd %POSIX") | ||
| 6158 | (ange-ftp-cd host user "%POSIX") | ||
| 6159 | ;; put new home directory in the expand-dir hashtable. | ||
| 6160 | (ange-ftp-put-hash-entry (concat host "/" user "/~") | ||
| 6161 | (car (ange-ftp-get-pwd host user)) | ||
| 6162 | ange-ftp-expand-dir-hashtable)))) | ||
| 6163 | |||
| 6164 | ;; Not available yet: | ||
| 6165 | ;; ange-ftp-bs2000-delete-file-entry | ||
| 6166 | ;; ange-ftp-bs2000-add-file-entry | ||
| 6167 | ;; ange-ftp-bs2000-file-name-as-directory | ||
| 6168 | ;; ange-ftp-bs2000-make-compressed-filename | ||
| 6169 | ;; ange-ftp-bs2000-file-name-sans-versions | ||
| 6170 | |||
| 6171 | ;;;; ------------------------------------------------------------ | ||
| 5811 | ;;;; Finally provide package. | 6172 | ;;;; Finally provide package. |
| 5812 | ;;;; ------------------------------------------------------------ | 6173 | ;;;; ------------------------------------------------------------ |
| 5813 | 6174 | ||