Mercurial > emacs
comparison lisp/ange-ftp.el @ 10244:3d95ea97eb9e
(ange-ftp-save-match-data): Macro deleted.
Most callers use save-match-data.
(ange-ftp-process-filter, ange-ftp-process-sentinel)
(ange-ftp-gwp-filter): Don't save the match data explicitly.
(ange-ftp-process-filter, ange-ftp-gwp-filter):
After comint output processing, update STR.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 25 Dec 1994 14:35:19 +0000 |
parents | 7e22057e9516 |
children | 8b26137996f9 |
comparison
equal
deleted
inserted
replaced
10243:ea9dda158056 | 10244:3d95ea97eb9e |
---|---|
917 ;; New error symbols. | 917 ;; New error symbols. |
918 (put 'ftp-error 'error-conditions '(ftp-error file-error error)) | 918 (put 'ftp-error 'error-conditions '(ftp-error file-error error)) |
919 ;; (put 'ftp-error 'error-message "FTP error") | 919 ;; (put 'ftp-error 'error-message "FTP error") |
920 | 920 |
921 ;;; ------------------------------------------------------------ | 921 ;;; ------------------------------------------------------------ |
922 ;;; Match-data support (stolen from Kyle I think) | |
923 ;;; ------------------------------------------------------------ | |
924 | |
925 (defmacro ange-ftp-save-match-data (&rest body) | |
926 "Execute the BODY forms, restoring the global value of the match data. | |
927 Also makes matching case-sensitive within BODY." | |
928 (let ((original (make-symbol "match-data")) | |
929 case-fold-search) | |
930 (list | |
931 'let (list (list original '(match-data))) | |
932 (list 'unwind-protect | |
933 (cons 'progn body) | |
934 (list 'store-match-data original))))) | |
935 | |
936 (put 'ange-ftp-save-match-data 'lisp-indent-hook 0) | |
937 (put 'ange-ftp-save-match-data 'edebug-form-hook '(&rest form)) | |
938 | |
939 ;;; ------------------------------------------------------------ | |
940 ;;; Enhanced message support. | 922 ;;; Enhanced message support. |
941 ;;; ------------------------------------------------------------ | 923 ;;; ------------------------------------------------------------ |
942 | 924 |
943 (defun ange-ftp-message (fmt &rest args) | 925 (defun ange-ftp-message (fmt &rest args) |
944 "Display message in echo area, but indicate if truncated. | 926 "Display message in echo area, but indicate if truncated. |
951 | 933 |
952 (defun ange-ftp-abbreviate-filename (file &optional new) | 934 (defun ange-ftp-abbreviate-filename (file &optional new) |
953 "Abbreviate the file name FILE relative to the default-directory. | 935 "Abbreviate the file name FILE relative to the default-directory. |
954 If the optional parameter NEW is given and the non-directory parts match, | 936 If the optional parameter NEW is given and the non-directory parts match, |
955 only return the directory part of FILE." | 937 only return the directory part of FILE." |
956 (ange-ftp-save-match-data | 938 (save-match-data |
957 (if (and default-directory | 939 (if (and default-directory |
958 (string-match (concat "^" | 940 (string-match (concat "^" |
959 (regexp-quote default-directory) | 941 (regexp-quote default-directory) |
960 ".") file)) | 942 ".") file)) |
961 (setq file (substring file (1- (match-end 0))))) | 943 (setq file (substring file (1- (match-end 0))))) |
1044 (ange-ftp-map-hashtable | 1026 (ange-ftp-map-hashtable |
1045 (function (lambda (host val) | 1027 (function (lambda (host val) |
1046 (if (ange-ftp-lookup-passwd host user) | 1028 (if (ange-ftp-lookup-passwd host user) |
1047 (throw 'found-one host)))) | 1029 (throw 'found-one host)))) |
1048 ange-ftp-user-hashtable) | 1030 ange-ftp-user-hashtable) |
1049 (ange-ftp-save-match-data | 1031 (save-match-data |
1050 (ange-ftp-map-hashtable | 1032 (ange-ftp-map-hashtable |
1051 (function | 1033 (function |
1052 (lambda (key value) | 1034 (lambda (key value) |
1053 (if (string-match "^[^/]*\\(/\\).*$" key) | 1035 (if (string-match "^[^/]*\\(/\\).*$" key) |
1054 (let ((host (substring key 0 (match-beginning 1)))) | 1036 (let ((host (substring key 0 (match-beginning 1)))) |
1217 (let* ((file (ange-ftp-chase-symlinks | 1199 (let* ((file (ange-ftp-chase-symlinks |
1218 (ange-ftp-real-expand-file-name ange-ftp-netrc-filename))) | 1200 (ange-ftp-real-expand-file-name ange-ftp-netrc-filename))) |
1219 (attr (ange-ftp-real-file-attributes file))) | 1201 (attr (ange-ftp-real-file-attributes file))) |
1220 (if (and attr ; file exists. | 1202 (if (and attr ; file exists. |
1221 (not (equal (nth 5 attr) ange-ftp-netrc-modtime))) ; file changed | 1203 (not (equal (nth 5 attr) ange-ftp-netrc-modtime))) ; file changed |
1222 (ange-ftp-save-match-data | 1204 (save-match-data |
1223 (if (or ange-ftp-disable-netrc-security-check | 1205 (if (or ange-ftp-disable-netrc-security-check |
1224 (and (eq (nth 2 attr) (user-uid)) ; Same uids. | 1206 (and (eq (nth 2 attr) (user-uid)) ; Same uids. |
1225 (string-match ".r..------" (nth 8 attr)))) | 1207 (string-match ".r..------" (nth 8 attr)))) |
1226 (save-excursion | 1208 (save-excursion |
1227 ;; we are cheating a bit here. I'm trying to do the equivalent | 1209 ;; we are cheating a bit here. I'm trying to do the equivalent |
1248 ;; Return a list of prefixes of the form 'user@host:' to be used when | 1230 ;; Return a list of prefixes of the form 'user@host:' to be used when |
1249 ;; completion is done in the root directory. | 1231 ;; completion is done in the root directory. |
1250 | 1232 |
1251 (defun ange-ftp-generate-root-prefixes () | 1233 (defun ange-ftp-generate-root-prefixes () |
1252 (ange-ftp-parse-netrc) | 1234 (ange-ftp-parse-netrc) |
1253 (ange-ftp-save-match-data | 1235 (save-match-data |
1254 (let (res) | 1236 (let (res) |
1255 (ange-ftp-map-hashtable | 1237 (ange-ftp-map-hashtable |
1256 (function | 1238 (function |
1257 (lambda (key value) | 1239 (lambda (key value) |
1258 (if (string-match "^[^/]*\\(/\\).*$" key) | 1240 (if (string-match "^[^/]*\\(/\\).*$" key) |
1286 (defun ange-ftp-ftp-name (name) | 1268 (defun ange-ftp-ftp-name (name) |
1287 (if (string-equal name ange-ftp-ftp-name-arg) | 1269 (if (string-equal name ange-ftp-ftp-name-arg) |
1288 ange-ftp-ftp-name-res | 1270 ange-ftp-ftp-name-res |
1289 (setq ange-ftp-ftp-name-arg name | 1271 (setq ange-ftp-ftp-name-arg name |
1290 ange-ftp-ftp-name-res | 1272 ange-ftp-ftp-name-res |
1291 (ange-ftp-save-match-data | 1273 (save-match-data |
1292 (if (string-match (car ange-ftp-name-format) name) | 1274 (if (string-match (car ange-ftp-name-format) name) |
1293 (let* ((ns (cdr ange-ftp-name-format)) | 1275 (let* ((ns (cdr ange-ftp-name-format)) |
1294 (host (ange-ftp-ftp-name-component 0 ns name)) | 1276 (host (ange-ftp-ftp-name-component 0 ns name)) |
1295 (user (ange-ftp-ftp-name-component 1 ns name)) | 1277 (user (ange-ftp-ftp-name-component 1 ns name)) |
1296 (name (ange-ftp-ftp-name-component 2 ns name))) | 1278 (name (ange-ftp-ftp-name-component 2 ns name))) |
1300 nil))))) | 1282 nil))))) |
1301 | 1283 |
1302 ;; Take a FULLNAME that matches according to ange-ftp-name-format and | 1284 ;; Take a FULLNAME that matches according to ange-ftp-name-format and |
1303 ;; replace the name component with NAME. | 1285 ;; replace the name component with NAME. |
1304 (defun ange-ftp-replace-name-component (fullname name) | 1286 (defun ange-ftp-replace-name-component (fullname name) |
1305 (ange-ftp-save-match-data | 1287 (save-match-data |
1306 (if (string-match (car ange-ftp-name-format) fullname) | 1288 (if (string-match (car ange-ftp-name-format) fullname) |
1307 (let* ((ns (cdr ange-ftp-name-format)) | 1289 (let* ((ns (cdr ange-ftp-name-format)) |
1308 (elt (nth 2 ns))) | 1290 (elt (nth 2 ns))) |
1309 (concat (substring fullname 0 (match-beginning elt)) | 1291 (concat (substring fullname 0 (match-beginning elt)) |
1310 name | 1292 name |
1476 (old-buffer (current-buffer))) | 1458 (old-buffer (current-buffer))) |
1477 | 1459 |
1478 ;; see if the buffer is still around... it could have been deleted. | 1460 ;; see if the buffer is still around... it could have been deleted. |
1479 (if (buffer-name buffer) | 1461 (if (buffer-name buffer) |
1480 (unwind-protect | 1462 (unwind-protect |
1481 (ange-ftp-save-match-data | 1463 (progn |
1482 (set-buffer (process-buffer proc)) | 1464 (set-buffer (process-buffer proc)) |
1483 | 1465 |
1484 ;; handle hash mark printing | 1466 ;; handle hash mark printing |
1485 (and ange-ftp-hash-mark-unit | 1467 (and ange-ftp-hash-mark-unit |
1486 ange-ftp-process-busy | 1468 ange-ftp-process-busy |
1487 (string-match "^#+$" str) | 1469 (string-match "^#+$" str) |
1488 (setq str (ange-ftp-process-handle-hash str))) | 1470 (setq str (ange-ftp-process-handle-hash str))) |
1489 (comint-output-filter proc str) | 1471 (comint-output-filter proc str) |
1472 ;; Replace STR by the result of the comint processing. | |
1473 (setq str (buffer-substring comint-last-output-start | |
1474 (process-mark proc))) | |
1490 (if ange-ftp-process-busy | 1475 (if ange-ftp-process-busy |
1491 (progn | 1476 (progn |
1492 (setq ange-ftp-process-string (concat ange-ftp-process-string | 1477 (setq ange-ftp-process-string (concat ange-ftp-process-string |
1493 str)) | 1478 str)) |
1494 | 1479 |
1533 ange-ftp-process-result-line)))))) | 1518 ange-ftp-process-result-line)))))) |
1534 (set-buffer old-buffer))))) | 1519 (set-buffer old-buffer))))) |
1535 | 1520 |
1536 (defun ange-ftp-process-sentinel (proc str) | 1521 (defun ange-ftp-process-sentinel (proc str) |
1537 "When ftp process changes state, nuke all file-entries in cache." | 1522 "When ftp process changes state, nuke all file-entries in cache." |
1538 (ange-ftp-save-match-data | 1523 (let ((name (process-name proc))) |
1539 (let ((name (process-name proc))) | 1524 (if (string-match "\\*ftp \\([^@]+\\)@\\([^*]+\\)*" name) |
1540 (if (string-match "\\*ftp \\([^@]+\\)@\\([^*]+\\)*" name) | 1525 (let ((user (substring name (match-beginning 1) (match-end 1))) |
1541 (let ((user (substring name (match-beginning 1) (match-end 1))) | 1526 (host (substring name (match-beginning 2) (match-end 2)))) |
1542 (host (substring name (match-beginning 2) (match-end 2)))) | 1527 (ange-ftp-wipe-file-entries host user)))) |
1543 (ange-ftp-wipe-file-entries host user)))) | 1528 (setq ange-ftp-ls-cache-file nil)) |
1544 (setq ange-ftp-ls-cache-file nil))) | |
1545 | 1529 |
1546 ;;;; ------------------------------------------------------------ | 1530 ;;;; ------------------------------------------------------------ |
1547 ;;;; Gateway support. | 1531 ;;;; Gateway support. |
1548 ;;;; ------------------------------------------------------------ | 1532 ;;;; ------------------------------------------------------------ |
1549 | 1533 |
1550 (defun ange-ftp-use-gateway-p (host) | 1534 (defun ange-ftp-use-gateway-p (host) |
1551 "Returns whether to access this host via a normal (non-smart) gateway." | 1535 "Returns whether to access this host via a normal (non-smart) gateway." |
1552 ;; yes, I know that I could simplify the following expression, but it is | 1536 ;; yes, I know that I could simplify the following expression, but it is |
1553 ;; clearer (to me at least) this way. | 1537 ;; clearer (to me at least) this way. |
1554 (and (not ange-ftp-smart-gateway) | 1538 (and (not ange-ftp-smart-gateway) |
1555 (ange-ftp-save-match-data | 1539 (save-match-data |
1556 (not (string-match ange-ftp-local-host-regexp host))))) | 1540 (not (string-match ange-ftp-local-host-regexp host))))) |
1557 | 1541 |
1558 (defun ange-ftp-use-smart-gateway-p (host) | 1542 (defun ange-ftp-use-smart-gateway-p (host) |
1559 "Returns whether to access this host via a smart gateway." | 1543 "Returns whether to access this host via a smart gateway." |
1560 (and ange-ftp-smart-gateway | 1544 (and ange-ftp-smart-gateway |
1561 (ange-ftp-save-match-data | 1545 (save-match-data |
1562 (not (string-match ange-ftp-local-host-regexp host))))) | 1546 (not (string-match ange-ftp-local-host-regexp host))))) |
1563 | 1547 |
1564 | 1548 |
1565 ;;; ------------------------------------------------------------ | 1549 ;;; ------------------------------------------------------------ |
1566 ;;; Temporary file location and deletion... | 1550 ;;; Temporary file location and deletion... |
1613 | 1597 |
1614 (defun ange-ftp-gwp-sentinel (proc str) | 1598 (defun ange-ftp-gwp-sentinel (proc str) |
1615 (setq ange-ftp-gwp-running nil)) | 1599 (setq ange-ftp-gwp-running nil)) |
1616 | 1600 |
1617 (defun ange-ftp-gwp-filter (proc str) | 1601 (defun ange-ftp-gwp-filter (proc str) |
1618 (ange-ftp-save-match-data | 1602 (comint-output-filter proc str) |
1619 (comint-output-filter proc str) | 1603 ;; Replace STR by the result of the comint processing. |
1620 (cond ((string-match "login: *$" str) | 1604 (setq str (buffer-substring comint-last-output-start (process-mark proc))) |
1621 (send-string proc | 1605 (cond ((string-match "login: *$" str) |
1622 (concat | 1606 (send-string proc |
1623 (let ((ange-ftp-default-user t)) | 1607 (concat |
1624 (ange-ftp-get-user ange-ftp-gateway-host)) | 1608 (let ((ange-ftp-default-user t)) |
1625 "\n"))) | 1609 (ange-ftp-get-user ange-ftp-gateway-host)) |
1626 ((string-match "Password: *$" str) | 1610 "\n"))) |
1627 (send-string proc | 1611 ((string-match "Password: *$" str) |
1628 (concat | 1612 (send-string proc |
1629 (ange-ftp-get-passwd ange-ftp-gateway-host | 1613 (concat |
1630 (ange-ftp-get-user | 1614 (ange-ftp-get-passwd ange-ftp-gateway-host |
1631 ange-ftp-gateway-host)) | 1615 (ange-ftp-get-user |
1632 "\n"))) | 1616 ange-ftp-gateway-host)) |
1633 ((string-match ange-ftp-gateway-fatal-msgs str) | 1617 "\n"))) |
1634 (delete-process proc) | 1618 ((string-match ange-ftp-gateway-fatal-msgs str) |
1635 (setq ange-ftp-gwp-running nil)) | 1619 (delete-process proc) |
1636 ((string-match ange-ftp-gateway-prompt-pattern str) | 1620 (setq ange-ftp-gwp-running nil)) |
1637 (setq ange-ftp-gwp-running nil | 1621 ((string-match ange-ftp-gateway-prompt-pattern str) |
1638 ange-ftp-gwp-status t))))) | 1622 (setq ange-ftp-gwp-running nil |
1623 ange-ftp-gwp-status t)))) | |
1639 | 1624 |
1640 (defun ange-ftp-gwp-start (host user name args) | 1625 (defun ange-ftp-gwp-start (host user name args) |
1641 "Login to the gateway machine and fire up an ftp process." | 1626 "Login to the gateway machine and fire up an ftp process." |
1642 (let* ((gw-user (ange-ftp-get-user ange-ftp-gateway-host)) | 1627 (let* ((gw-user (ange-ftp-get-user ange-ftp-gateway-host)) |
1643 ;; It would be nice to make process-connection-type nil, | 1628 ;; It would be nice to make process-connection-type nil, |
1714 cmd (concat cmd "\n")) | 1699 cmd (concat cmd "\n")) |
1715 (and msg ange-ftp-process-verbose (ange-ftp-message "%s..." msg)) | 1700 (and msg ange-ftp-process-verbose (ange-ftp-message "%s..." msg)) |
1716 (goto-char (point-max)) | 1701 (goto-char (point-max)) |
1717 (move-marker comint-last-input-start (point)) | 1702 (move-marker comint-last-input-start (point)) |
1718 ;; don't insert the password into the buffer on the USER command. | 1703 ;; don't insert the password into the buffer on the USER command. |
1719 (ange-ftp-save-match-data | 1704 (save-match-data |
1720 (if (string-match "^user \"[^\"]*\"" cmd) | 1705 (if (string-match "^user \"[^\"]*\"" cmd) |
1721 (insert (substring cmd 0 (match-end 0)) " Turtle Power!\n") | 1706 (insert (substring cmd 0 (match-end 0)) " Turtle Power!\n") |
1722 (insert cmd))) | 1707 (insert cmd))) |
1723 (move-marker comint-last-input-end (point)) | 1708 (move-marker comint-last-input-end (point)) |
1724 (send-string proc cmd) | 1709 (send-string proc cmd) |
1905 (save-excursion | 1890 (save-excursion |
1906 (set-buffer (process-buffer proc)) | 1891 (set-buffer (process-buffer proc)) |
1907 (let* ((status (ange-ftp-raw-send-cmd proc "hash")) | 1892 (let* ((status (ange-ftp-raw-send-cmd proc "hash")) |
1908 (result (car status)) | 1893 (result (car status)) |
1909 (line (cdr status))) | 1894 (line (cdr status))) |
1910 (ange-ftp-save-match-data | 1895 (save-match-data |
1911 (if (string-match ange-ftp-hash-mark-msgs line) | 1896 (if (string-match ange-ftp-hash-mark-msgs line) |
1912 (let ((size (string-to-int | 1897 (let ((size (string-to-int |
1913 (substring line | 1898 (substring line |
1914 (match-beginning 1) | 1899 (match-beginning 1) |
1915 (match-end 1))))) | 1900 (match-end 1))))) |
2136 Works by doing a pwd and examining the directory syntax." | 2121 Works by doing a pwd and examining the directory syntax." |
2137 (let ((host-type (ange-ftp-host-type host)) | 2122 (let ((host-type (ange-ftp-host-type host)) |
2138 (key (concat host "/" user "/~"))) | 2123 (key (concat host "/" user "/~"))) |
2139 (if (eq host-type 'unix) | 2124 (if (eq host-type 'unix) |
2140 ;; Note that ange-ftp-host-type returns unix as the default value. | 2125 ;; Note that ange-ftp-host-type returns unix as the default value. |
2141 (ange-ftp-save-match-data | 2126 (save-match-data |
2142 (let* ((result (ange-ftp-get-pwd host user)) | 2127 (let* ((result (ange-ftp-get-pwd host user)) |
2143 (dir (car result)) | 2128 (dir (car result)) |
2144 fix-name-func) | 2129 fix-name-func) |
2145 (cond ((null dir) | 2130 (cond ((null dir) |
2146 (message "Warning! Unable to get home directory") | 2131 (message "Warning! Unable to get home directory") |
2212 | 2197 |
2213 ;; Returns whether HOST's FTP server doesn't like \'ls\' or \'dir\' commands | 2198 ;; Returns whether HOST's FTP server doesn't like \'ls\' or \'dir\' commands |
2214 ;; to take switch arguments. | 2199 ;; to take switch arguments. |
2215 (defun ange-ftp-dumb-unix-host (host) | 2200 (defun ange-ftp-dumb-unix-host (host) |
2216 (and ange-ftp-dumb-unix-host-regexp | 2201 (and ange-ftp-dumb-unix-host-regexp |
2217 (ange-ftp-save-match-data | 2202 (save-match-data |
2218 (string-match ange-ftp-dumb-unix-host-regexp host)))) | 2203 (string-match ange-ftp-dumb-unix-host-regexp host)))) |
2219 | 2204 |
2220 (defun ange-ftp-add-dumb-unix-host (host) | 2205 (defun ange-ftp-add-dumb-unix-host (host) |
2221 "Interactively adds a given HOST to ange-ftp-dumb-unix-host-regexp." | 2206 "Interactively adds a given HOST to ange-ftp-dumb-unix-host-regexp." |
2222 (interactive | 2207 (interactive |
2484 ;; Parse the current buffer which is assumed to be in a dired-like listing | 2469 ;; Parse the current buffer which is assumed to be in a dired-like listing |
2485 ;; format, and return a hashtable as the result. If the listing is not really | 2470 ;; format, and return a hashtable as the result. If the listing is not really |
2486 ;; a listing, then return nil. | 2471 ;; a listing, then return nil. |
2487 | 2472 |
2488 (defun ange-ftp-parse-dired-listing (&optional switches) | 2473 (defun ange-ftp-parse-dired-listing (&optional switches) |
2489 (ange-ftp-save-match-data | 2474 (save-match-data |
2490 (cond | 2475 (cond |
2491 ((looking-at "^total [0-9]+$") | 2476 ((looking-at "^total [0-9]+$") |
2492 (forward-line 1) | 2477 (forward-line 1) |
2493 ;; Some systems put in a blank line here. | 2478 ;; Some systems put in a blank line here. |
2494 (if (eolp) (forward-line 1)) | 2479 (if (eolp) (forward-line 1)) |
2524 "Given a given DIRECTORY, return a hashtable of file entries. | 2509 "Given a given DIRECTORY, return a hashtable of file entries. |
2525 This will give an error or return nil, depending on the value of | 2510 This will give an error or return nil, depending on the value of |
2526 NO-ERROR, if a listing for DIRECTORY cannot be obtained." | 2511 NO-ERROR, if a listing for DIRECTORY cannot be obtained." |
2527 (setq directory (file-name-as-directory directory)) ;normalize | 2512 (setq directory (file-name-as-directory directory)) ;normalize |
2528 (or (ange-ftp-get-hash-entry directory ange-ftp-files-hashtable) | 2513 (or (ange-ftp-get-hash-entry directory ange-ftp-files-hashtable) |
2529 (ange-ftp-save-match-data | 2514 (save-match-data |
2530 (and (ange-ftp-ls directory | 2515 (and (ange-ftp-ls directory |
2531 ;; This is an efficiency hack. We try to | 2516 ;; This is an efficiency hack. We try to |
2532 ;; anticipate what sort of listing dired | 2517 ;; anticipate what sort of listing dired |
2533 ;; might want, and cache just such a listing. | 2518 ;; might want, and cache just such a listing. |
2534 (if (and (boundp 'dired-actual-switches) | 2519 (if (and (boundp 'dired-actual-switches) |
2716 and LINE is the relevant success or fail line from the FTP-client." | 2701 and LINE is the relevant success or fail line from the FTP-client." |
2717 (let* ((result (ange-ftp-send-cmd host user '(pwd) "Getting PWD")) | 2702 (let* ((result (ange-ftp-send-cmd host user '(pwd) "Getting PWD")) |
2718 (line (cdr result)) | 2703 (line (cdr result)) |
2719 dir) | 2704 dir) |
2720 (if (car result) | 2705 (if (car result) |
2721 (ange-ftp-save-match-data | 2706 (save-match-data |
2722 (and (or (string-match "\"\\([^\"]*\\)\"" line) | 2707 (and (or (string-match "\"\\([^\"]*\\)\"" line) |
2723 (string-match " \\([^ ]+\\) " line)) ; stone-age VMS servers! | 2708 (string-match " \\([^ ]+\\) " line)) ; stone-age VMS servers! |
2724 (setq dir (substring line | 2709 (setq dir (substring line |
2725 (match-beginning 1) | 2710 (match-beginning 1) |
2726 (match-end 1)))))) | 2711 (match-end 1)))))) |
2832 (ange-ftp-real-file-name-nondirectory n) | 2817 (ange-ftp-real-file-name-nondirectory n) |
2833 (ange-ftp-real-file-name-directory n)))))) | 2818 (ange-ftp-real-file-name-directory n)))))) |
2834 | 2819 |
2835 (defun ange-ftp-expand-file-name (name &optional default) | 2820 (defun ange-ftp-expand-file-name (name &optional default) |
2836 "Documented as original." | 2821 "Documented as original." |
2837 (ange-ftp-save-match-data | 2822 (save-match-data |
2838 (if (eq (string-to-char name) ?/) | 2823 (if (eq (string-to-char name) ?/) |
2839 (while (cond ((string-match "[^:]+//" name) ;don't upset Apollo users | 2824 (while (cond ((string-match "[^:]+//" name) ;don't upset Apollo users |
2840 (setq name (substring name (1- (match-end 0))))) | 2825 (setq name (substring name (1- (match-end 0))))) |
2841 ((string-match "/~" name) | 2826 ((string-match "/~" name) |
2842 (setq name (substring name (1- (match-end 0)))))))) | 2827 (setq name (substring name (1- (match-end 0)))))))) |
2873 (defun ange-ftp-file-name-directory (name) | 2858 (defun ange-ftp-file-name-directory (name) |
2874 "Documented as original." | 2859 "Documented as original." |
2875 (let ((parsed (ange-ftp-ftp-name name))) | 2860 (let ((parsed (ange-ftp-ftp-name name))) |
2876 (if parsed | 2861 (if parsed |
2877 (let ((filename (nth 2 parsed))) | 2862 (let ((filename (nth 2 parsed))) |
2878 (if (ange-ftp-save-match-data | 2863 (if (save-match-data |
2879 (string-match "^~[^/]*$" filename)) | 2864 (string-match "^~[^/]*$" filename)) |
2880 name | 2865 name |
2881 (ange-ftp-replace-name-component | 2866 (ange-ftp-replace-name-component |
2882 name | 2867 name |
2883 (ange-ftp-real-file-name-directory filename)))) | 2868 (ange-ftp-real-file-name-directory filename)))) |
2886 (defun ange-ftp-file-name-nondirectory (name) | 2871 (defun ange-ftp-file-name-nondirectory (name) |
2887 "Documented as original." | 2872 "Documented as original." |
2888 (let ((parsed (ange-ftp-ftp-name name))) | 2873 (let ((parsed (ange-ftp-ftp-name name))) |
2889 (if parsed | 2874 (if parsed |
2890 (let ((filename (nth 2 parsed))) | 2875 (let ((filename (nth 2 parsed))) |
2891 (if (ange-ftp-save-match-data | 2876 (if (save-match-data |
2892 (string-match "^~[^/]*$" filename)) | 2877 (string-match "^~[^/]*$" filename)) |
2893 "" | 2878 "" |
2894 (ange-ftp-real-file-name-nondirectory name))) | 2879 (ange-ftp-real-file-name-nondirectory name))) |
2895 (ange-ftp-real-file-name-nondirectory name)))) | 2880 (ange-ftp-real-file-name-nondirectory name)))) |
2896 | 2881 |
2906 | 2891 |
2907 ;;; Hooks that handle Emacs primitives. | 2892 ;;; Hooks that handle Emacs primitives. |
2908 | 2893 |
2909 ;; Returns non-nil if should transfer FILE in binary mode. | 2894 ;; Returns non-nil if should transfer FILE in binary mode. |
2910 (defun ange-ftp-binary-file (file) | 2895 (defun ange-ftp-binary-file (file) |
2911 (ange-ftp-save-match-data | 2896 (save-match-data |
2912 (string-match ange-ftp-binary-file-name-regexp file))) | 2897 (string-match ange-ftp-binary-file-name-regexp file))) |
2913 | 2898 |
2914 (defun ange-ftp-write-region (start end filename &optional append visit) | 2899 (defun ange-ftp-write-region (start end filename &optional append visit) |
2915 (setq filename (expand-file-name filename)) | 2900 (setq filename (expand-file-name filename)) |
2916 (let ((parsed (ange-ftp-ftp-name filename))) | 2901 (let ((parsed (ange-ftp-ftp-name filename))) |
3084 (ange-ftp-barf-if-not-directory directory) | 3069 (ange-ftp-barf-if-not-directory directory) |
3085 (let ((tail (ange-ftp-hash-table-keys | 3070 (let ((tail (ange-ftp-hash-table-keys |
3086 (ange-ftp-get-files directory))) | 3071 (ange-ftp-get-files directory))) |
3087 files f) | 3072 files f) |
3088 (setq directory (file-name-as-directory directory)) | 3073 (setq directory (file-name-as-directory directory)) |
3089 (ange-ftp-save-match-data | 3074 (save-match-data |
3090 (while tail | 3075 (while tail |
3091 (setq f (car tail) | 3076 (setq f (car tail) |
3092 tail (cdr tail)) | 3077 tail (cdr tail)) |
3093 (if (or (not match) (string-match match f)) | 3078 (if (or (not match) (string-match match f)) |
3094 (setq files | 3079 (setq files |
3566 (lambda (s) (if (stringp s) | 3551 (lambda (s) (if (stringp s) |
3567 (concat (regexp-quote s) "$") | 3552 (concat (regexp-quote s) "$") |
3568 "/"))) ; / never in filename | 3553 "/"))) ; / never in filename |
3569 completion-ignored-extensions | 3554 completion-ignored-extensions |
3570 "\\|"))) | 3555 "\\|"))) |
3571 (ange-ftp-save-match-data | 3556 (save-match-data |
3572 (or (ange-ftp-file-name-completion-1 | 3557 (or (ange-ftp-file-name-completion-1 |
3573 file tbl ange-ftp-this-dir | 3558 file tbl ange-ftp-this-dir |
3574 (function ange-ftp-file-entry-not-ignored-p)) | 3559 (function ange-ftp-file-entry-not-ignored-p)) |
3575 (ange-ftp-file-name-completion-1 | 3560 (ange-ftp-file-name-completion-1 |
3576 file tbl ange-ftp-this-dir | 3561 file tbl ange-ftp-this-dir |
3739 (if (and parsed | 3724 (if (and parsed |
3740 (setq conversion-func | 3725 (setq conversion-func |
3741 (cdr (assq (ange-ftp-host-type (car parsed)) | 3726 (cdr (assq (ange-ftp-host-type (car parsed)) |
3742 ange-ftp-make-compressed-filename-alist)))) | 3727 ange-ftp-make-compressed-filename-alist)))) |
3743 (let* ((decision | 3728 (let* ((decision |
3744 (ange-ftp-save-match-data (funcall conversion-func name))) | 3729 (save-match-data (funcall conversion-func name))) |
3745 (compressing (car decision)) | 3730 (compressing (car decision)) |
3746 (newfile (nth 1 decision))) | 3731 (newfile (nth 1 decision))) |
3747 (if compressing | 3732 (if compressing |
3748 (ange-ftp-compress name newfile) | 3733 (ange-ftp-compress name newfile) |
3749 (ange-ftp-uncompress name newfile))) | 3734 (ange-ftp-uncompress name newfile))) |
4391 ;(defvar ange-ftp-vos-host-regexp nil | 4376 ;(defvar ange-ftp-vos-host-regexp nil |
4392 ; "If a host matches this regexp then it is assumed to be running VOS.") | 4377 ; "If a host matches this regexp then it is assumed to be running VOS.") |
4393 ; | 4378 ; |
4394 ;(defun ange-ftp-vos-host (host) | 4379 ;(defun ange-ftp-vos-host (host) |
4395 ; (and ange-ftp-vos-host-regexp | 4380 ; (and ange-ftp-vos-host-regexp |
4396 ; (ange-ftp-save-match-data | 4381 ; (save-match-data |
4397 ; (string-match ange-ftp-vos-host-regexp host)))) | 4382 ; (string-match ange-ftp-vos-host-regexp host)))) |
4398 ; | 4383 ; |
4399 ;(defun ange-ftp-parse-vos-listing () | 4384 ;(defun ange-ftp-parse-vos-listing () |
4400 ; "Parse the current buffer which is assumed to be in VOS list -all | 4385 ; "Parse the current buffer which is assumed to be in VOS list -all |
4401 ;format, and return a hashtable as the result." | 4386 ;format, and return a hashtable as the result." |
4403 ; (type-list | 4388 ; (type-list |
4404 ; '(("^Files: [0-9]+ +Blocks: [0-9]+\n+" nil 40) | 4389 ; '(("^Files: [0-9]+ +Blocks: [0-9]+\n+" nil 40) |
4405 ; ("^Dirs: [0-9]+\n+" t 30))) | 4390 ; ("^Dirs: [0-9]+\n+" t 30))) |
4406 ; type-regexp type-is-dir type-col file) | 4391 ; type-regexp type-is-dir type-col file) |
4407 ; (goto-char (point-min)) | 4392 ; (goto-char (point-min)) |
4408 ; (ange-ftp-save-match-data | 4393 ; (save-match-data |
4409 ; (while type-list | 4394 ; (while type-list |
4410 ; (setq type-regexp (car (car type-list)) | 4395 ; (setq type-regexp (car (car type-list)) |
4411 ; type-is-dir (nth 1 (car type-list)) | 4396 ; type-is-dir (nth 1 (car type-list)) |
4412 ; type-col (nth 2 (car type-list)) | 4397 ; type-col (nth 2 (car type-list)) |
4413 ; type-list (cdr type-list)) | 4398 ; type-list (cdr type-list)) |
4434 ;;;; ------------------------------------------------------------ | 4419 ;;;; ------------------------------------------------------------ |
4435 | 4420 |
4436 ;; Convert NAME from UNIX-ish to VMS. If REVERSE given then convert from VMS | 4421 ;; Convert NAME from UNIX-ish to VMS. If REVERSE given then convert from VMS |
4437 ;; to UNIX-ish. | 4422 ;; to UNIX-ish. |
4438 (defun ange-ftp-fix-name-for-vms (name &optional reverse) | 4423 (defun ange-ftp-fix-name-for-vms (name &optional reverse) |
4439 (ange-ftp-save-match-data | 4424 (save-match-data |
4440 (if reverse | 4425 (if reverse |
4441 (if (string-match "^\\([^:]+:\\)?\\(\\[.*\\]\\)?\\([^][]*\\)$" name) | 4426 (if (string-match "^\\([^:]+:\\)?\\(\\[.*\\]\\)?\\([^][]*\\)$" name) |
4442 (let (drive dir file) | 4427 (let (drive dir file) |
4443 (if (match-beginning 1) | 4428 (if (match-beginning 1) |
4444 (setq drive (substring name | 4429 (setq drive (substring name |
4520 (defvar ange-ftp-vms-host-regexp nil) | 4505 (defvar ange-ftp-vms-host-regexp nil) |
4521 | 4506 |
4522 ;; Return non-nil if HOST is running VMS. | 4507 ;; Return non-nil if HOST is running VMS. |
4523 (defun ange-ftp-vms-host (host) | 4508 (defun ange-ftp-vms-host (host) |
4524 (and ange-ftp-vms-host-regexp | 4509 (and ange-ftp-vms-host-regexp |
4525 (ange-ftp-save-match-data | 4510 (save-match-data |
4526 (string-match ange-ftp-vms-host-regexp host)))) | 4511 (string-match ange-ftp-vms-host-regexp host)))) |
4527 | 4512 |
4528 ;; Because some VMS ftp servers convert filenames to lower case | 4513 ;; Because some VMS ftp servers convert filenames to lower case |
4529 ;; we allow a-z in the filename regexp. I'm not too happy about this. | 4514 ;; we allow a-z in the filename regexp. I'm not too happy about this. |
4530 | 4515 |
4554 ;; format, and return a hashtable as the result. | 4539 ;; format, and return a hashtable as the result. |
4555 (defun ange-ftp-parse-vms-listing () | 4540 (defun ange-ftp-parse-vms-listing () |
4556 (let ((tbl (ange-ftp-make-hashtable)) | 4541 (let ((tbl (ange-ftp-make-hashtable)) |
4557 file) | 4542 file) |
4558 (goto-char (point-min)) | 4543 (goto-char (point-min)) |
4559 (ange-ftp-save-match-data | 4544 (save-match-data |
4560 (while (setq file (ange-ftp-parse-vms-filename)) | 4545 (while (setq file (ange-ftp-parse-vms-filename)) |
4561 (if (string-match "\\.\\(DIR\\|dir\\);[0-9]+" file) | 4546 (if (string-match "\\.\\(DIR\\|dir\\);[0-9]+" file) |
4562 ;; deal with directories | 4547 ;; deal with directories |
4563 (ange-ftp-put-hash-entry | 4548 (ange-ftp-put-hash-entry |
4564 (substring file 0 (match-beginning 0)) t tbl) | 4549 (substring file 0 (match-beginning 0)) t tbl) |
4588 ;; completion functions? | 4573 ;; completion functions? |
4589 | 4574 |
4590 (defun ange-ftp-vms-delete-file-entry (name &optional dir-p) | 4575 (defun ange-ftp-vms-delete-file-entry (name &optional dir-p) |
4591 (if dir-p | 4576 (if dir-p |
4592 (ange-ftp-internal-delete-file-entry name t) | 4577 (ange-ftp-internal-delete-file-entry name t) |
4593 (ange-ftp-save-match-data | 4578 (save-match-data |
4594 (let ((file (ange-ftp-get-file-part name))) | 4579 (let ((file (ange-ftp-get-file-part name))) |
4595 (if (string-match ";[0-9]+$" file) | 4580 (if (string-match ";[0-9]+$" file) |
4596 ;; In VMS you can't delete a file without an explicit | 4581 ;; In VMS you can't delete a file without an explicit |
4597 ;; version number, or wild-card (e.g. FOO;*) | 4582 ;; version number, or wild-card (e.g. FOO;*) |
4598 ;; For now, we give up on wildcards. | 4583 ;; For now, we give up on wildcards. |
4629 (let ((files (ange-ftp-get-hash-entry | 4614 (let ((files (ange-ftp-get-hash-entry |
4630 (file-name-directory name) | 4615 (file-name-directory name) |
4631 ange-ftp-files-hashtable))) | 4616 ange-ftp-files-hashtable))) |
4632 (if files | 4617 (if files |
4633 (let ((file (ange-ftp-get-file-part name))) | 4618 (let ((file (ange-ftp-get-file-part name))) |
4634 (ange-ftp-save-match-data | 4619 (save-match-data |
4635 (if (string-match ";[0-9]+$" file) | 4620 (if (string-match ";[0-9]+$" file) |
4636 (ange-ftp-put-hash-entry | 4621 (ange-ftp-put-hash-entry |
4637 (substring file 0 (match-beginning 0)) | 4622 (substring file 0 (match-beginning 0)) |
4638 nil files) | 4623 nil files) |
4639 ;; Need to figure out what version of the file | 4624 ;; Need to figure out what version of the file |
4678 ange-ftp-vms-host-regexp) | 4663 ange-ftp-vms-host-regexp) |
4679 ange-ftp-host-cache nil))) | 4664 ange-ftp-host-cache nil))) |
4680 | 4665 |
4681 | 4666 |
4682 (defun ange-ftp-vms-file-name-as-directory (name) | 4667 (defun ange-ftp-vms-file-name-as-directory (name) |
4683 (ange-ftp-save-match-data | 4668 (save-match-data |
4684 (if (string-match "\\.\\(DIR\\|dir\\)\\(;[0-9]+\\)?$" name) | 4669 (if (string-match "\\.\\(DIR\\|dir\\)\\(;[0-9]+\\)?$" name) |
4685 (setq name (substring name 0 (match-beginning 0)))) | 4670 (setq name (substring name 0 (match-beginning 0)))) |
4686 (ange-ftp-real-file-name-as-directory name))) | 4671 (ange-ftp-real-file-name-as-directory name))) |
4687 | 4672 |
4688 (or (assq 'vms ange-ftp-file-name-as-directory-alist) | 4673 (or (assq 'vms ange-ftp-file-name-as-directory-alist) |
4840 ;; (setq ange-ftp-dired-ls-trim-alist | 4825 ;; (setq ange-ftp-dired-ls-trim-alist |
4841 ;; (cons '(vms . ange-ftp-dired-vms-ls-trim) | 4826 ;; (cons '(vms . ange-ftp-dired-vms-ls-trim) |
4842 ;; ange-ftp-dired-ls-trim-alist))) | 4827 ;; ange-ftp-dired-ls-trim-alist))) |
4843 | 4828 |
4844 (defun ange-ftp-vms-sans-version (name) | 4829 (defun ange-ftp-vms-sans-version (name) |
4845 (ange-ftp-save-match-data | 4830 (save-match-data |
4846 (if (string-match ";[0-9]+$" name) | 4831 (if (string-match ";[0-9]+$" name) |
4847 (substring name 0 (match-beginning 0)) | 4832 (substring name 0 (match-beginning 0)) |
4848 name))) | 4833 name))) |
4849 | 4834 |
4850 (or (assq 'vms ange-ftp-sans-version-alist) | 4835 (or (assq 'vms ange-ftp-sans-version-alist) |
4997 | 4982 |
4998 | 4983 |
4999 ;; Convert NAME from UNIX-ish to MTS. If REVERSE given then convert from | 4984 ;; Convert NAME from UNIX-ish to MTS. If REVERSE given then convert from |
5000 ;; MTS to UNIX-ish. | 4985 ;; MTS to UNIX-ish. |
5001 (defun ange-ftp-fix-name-for-mts (name &optional reverse) | 4986 (defun ange-ftp-fix-name-for-mts (name &optional reverse) |
5002 (ange-ftp-save-match-data | 4987 (save-match-data |
5003 (if reverse | 4988 (if reverse |
5004 (if (string-match "^\\([^:]+:\\)?\\(.*\\)$" name) | 4989 (if (string-match "^\\([^:]+:\\)?\\(.*\\)$" name) |
5005 (let (acct file) | 4990 (let (acct file) |
5006 (if (match-beginning 1) | 4991 (if (match-beginning 1) |
5007 (setq acct (substring name 0 (match-end 1)))) | 4992 (setq acct (substring name 0 (match-end 1)))) |
5047 (defvar ange-ftp-mts-host-regexp nil) | 5032 (defvar ange-ftp-mts-host-regexp nil) |
5048 | 5033 |
5049 ;; Return non-nil if HOST is running MTS. | 5034 ;; Return non-nil if HOST is running MTS. |
5050 (defun ange-ftp-mts-host (host) | 5035 (defun ange-ftp-mts-host (host) |
5051 (and ange-ftp-mts-host-regexp | 5036 (and ange-ftp-mts-host-regexp |
5052 (ange-ftp-save-match-data | 5037 (save-match-data |
5053 (string-match ange-ftp-mts-host-regexp host)))) | 5038 (string-match ange-ftp-mts-host-regexp host)))) |
5054 | 5039 |
5055 ;; Parse the current buffer which is assumed to be in mts ftp dir format. | 5040 ;; Parse the current buffer which is assumed to be in mts ftp dir format. |
5056 (defun ange-ftp-parse-mts-listing () | 5041 (defun ange-ftp-parse-mts-listing () |
5057 (let ((tbl (ange-ftp-make-hashtable))) | 5042 (let ((tbl (ange-ftp-make-hashtable))) |
5058 (goto-char (point-min)) | 5043 (goto-char (point-min)) |
5059 (ange-ftp-save-match-data | 5044 (save-match-data |
5060 (while (re-search-forward ange-ftp-date-regexp nil t) | 5045 (while (re-search-forward ange-ftp-date-regexp nil t) |
5061 (end-of-line) | 5046 (end-of-line) |
5062 (skip-chars-backward " ") | 5047 (skip-chars-backward " ") |
5063 (let ((end (point))) | 5048 (let ((end (point))) |
5064 (skip-chars-backward "-A-Z0-9_.!") | 5049 (skip-chars-backward "-A-Z0-9_.!") |
5160 ;; usually close the connection after 5 minutes of inactivity. | 5145 ;; usually close the connection after 5 minutes of inactivity. |
5161 | 5146 |
5162 ;; Have I got the filename character set right? | 5147 ;; Have I got the filename character set right? |
5163 | 5148 |
5164 (defun ange-ftp-fix-name-for-cms (name &optional reverse) | 5149 (defun ange-ftp-fix-name-for-cms (name &optional reverse) |
5165 (ange-ftp-save-match-data | 5150 (save-match-data |
5166 (if reverse | 5151 (if reverse |
5167 ;; Since we only convert output from a pwd in this direction, | 5152 ;; Since we only convert output from a pwd in this direction, |
5168 ;; we'll assume that it's a minidisk, and make it into a | 5153 ;; we'll assume that it's a minidisk, and make it into a |
5169 ;; directory file name. Note that the expand-dir-hashtable | 5154 ;; directory file name. Note that the expand-dir-hashtable |
5170 ;; stores directories without the trailing /. Is this | 5155 ;; stores directories without the trailing /. Is this |
5250 "Regular expression to match hosts running the CMS operating system.") | 5235 "Regular expression to match hosts running the CMS operating system.") |
5251 | 5236 |
5252 ;; Return non-nil if HOST is running CMS. | 5237 ;; Return non-nil if HOST is running CMS. |
5253 (defun ange-ftp-cms-host (host) | 5238 (defun ange-ftp-cms-host (host) |
5254 (and ange-ftp-cms-host-regexp | 5239 (and ange-ftp-cms-host-regexp |
5255 (ange-ftp-save-match-data | 5240 (save-match-data |
5256 (string-match ange-ftp-cms-host-regexp host)))) | 5241 (string-match ange-ftp-cms-host-regexp host)))) |
5257 | 5242 |
5258 (defun ange-ftp-add-cms-host (host) | 5243 (defun ange-ftp-add-cms-host (host) |
5259 "Mark HOST as the name of a CMS host." | 5244 "Mark HOST as the name of a CMS host." |
5260 (interactive | 5245 (interactive |
5287 ; (ange-ftp-put-hash-entry "." t root-tbl) | 5272 ; (ange-ftp-put-hash-entry "." t root-tbl) |
5288 ; (ange-ftp-set-files root root-tbl))) | 5273 ; (ange-ftp-set-files root root-tbl))) |
5289 ;; Now do the usual parsing | 5274 ;; Now do the usual parsing |
5290 (let ((tbl (ange-ftp-make-hashtable))) | 5275 (let ((tbl (ange-ftp-make-hashtable))) |
5291 (goto-char (point-min)) | 5276 (goto-char (point-min)) |
5292 (ange-ftp-save-match-data | 5277 (save-match-data |
5293 (while | 5278 (while |
5294 (re-search-forward | 5279 (re-search-forward |
5295 "^\\([-A-Z0-9$_]+\\) +\\([-A-Z0-9$_]+\\) +[VF] +[0-9]+ " nil t) | 5280 "^\\([-A-Z0-9$_]+\\) +\\([-A-Z0-9$_]+\\) +[VF] +[0-9]+ " nil t) |
5296 (ange-ftp-put-hash-entry | 5281 (ange-ftp-put-hash-entry |
5297 (concat (buffer-substring (match-beginning 1) | 5282 (concat (buffer-substring (match-beginning 1) |