diff options
| author | Stefan Monnier | 2002-07-13 22:10:02 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-07-13 22:10:02 +0000 |
| commit | 6e85ef5fd113cd98b6b58a8eb7e614dc18c50ac4 (patch) | |
| tree | be0116e63f829917cfd85348c2287f908f281dcf | |
| parent | 6946ae5b110a82d238c6546f29fec986f32d071b (diff) | |
| download | emacs-6e85ef5fd113cd98b6b58a8eb7e614dc18c50ac4.tar.gz emacs-6e85ef5fd113cd98b6b58a8eb7e614dc18c50ac4.zip | |
Use hash-tables.
(ange-ftp-make-hashtable, ange-ftp-map-hashtable)
(ange-ftp-make-hash-key, ange-ftp-get-hash-entry)
(ange-ftp-put-hash-entry, ange-ftp-del-hash-entry): Remove.
Replace with make-hash-table, maphash, gethash, puthash and remhash.
(ange-ftp-hash-entry-exists-p): Rewrite.
(ange-ftp-vms-delete-file-entry, ange-ftp-vms-add-file-entry):
Change mapatom -> maphash.
(ange-ftp-file-entry-active-p, ange-ftp-file-entry-not-ignored-p):
Update to new calling mode.
| -rw-r--r-- | lisp/net/ange-ftp.el | 391 |
1 files changed, 159 insertions, 232 deletions
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index ca0a17b3dd7..f38864d743e 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el | |||
| @@ -1020,60 +1020,16 @@ or nil meaning don't change it." | |||
| 1020 | 1020 | ||
| 1021 | (require 'backquote) | 1021 | (require 'backquote) |
| 1022 | 1022 | ||
| 1023 | (defun ange-ftp-make-hashtable (&optional size) | ||
| 1024 | "Make an obarray suitable for use as a hashtable. | ||
| 1025 | SIZE, if supplied, should be a prime number." | ||
| 1026 | (make-vector (or size 31) 0)) | ||
| 1027 | |||
| 1028 | (defun ange-ftp-map-hashtable (fun tbl) | ||
| 1029 | "Call FUNCTION on each key and value in HASHTABLE." | ||
| 1030 | (mapatoms | ||
| 1031 | (function | ||
| 1032 | (lambda (sym) | ||
| 1033 | (funcall fun (get sym 'key) (get sym 'val)))) | ||
| 1034 | tbl)) | ||
| 1035 | |||
| 1036 | (defmacro ange-ftp-make-hash-key (key) | ||
| 1037 | "Convert KEY into a suitable key for a hashtable." | ||
| 1038 | `(if (stringp ,key) | ||
| 1039 | ,key | ||
| 1040 | (prin1-to-string ,key))) | ||
| 1041 | |||
| 1042 | (defun ange-ftp-get-hash-entry (key tbl) | ||
| 1043 | "Return the value associated with KEY in HASHTABLE." | ||
| 1044 | (let ((sym (intern-soft (ange-ftp-make-hash-key key) tbl))) | ||
| 1045 | (and sym (get sym 'val)))) | ||
| 1046 | |||
| 1047 | (defun ange-ftp-put-hash-entry (key val tbl) | ||
| 1048 | "Record an association between KEY and VALUE in HASHTABLE." | ||
| 1049 | (let ((sym (intern (ange-ftp-make-hash-key key) tbl))) | ||
| 1050 | (put sym 'val val) | ||
| 1051 | (put sym 'key key))) | ||
| 1052 | |||
| 1053 | (defun ange-ftp-del-hash-entry (key tbl) | ||
| 1054 | "Copy all symbols except KEY in HASHTABLE and return modified hashtable." | ||
| 1055 | (let* ((len (length tbl)) | ||
| 1056 | (new-tbl (ange-ftp-make-hashtable len)) | ||
| 1057 | (i (1- len))) | ||
| 1058 | (ange-ftp-map-hashtable | ||
| 1059 | (function | ||
| 1060 | (lambda (k v) | ||
| 1061 | (or (equal k key) | ||
| 1062 | (ange-ftp-put-hash-entry k v new-tbl)))) | ||
| 1063 | tbl) | ||
| 1064 | (while (>= i 0) | ||
| 1065 | (aset tbl i (aref new-tbl i)) | ||
| 1066 | (setq i (1- i))) | ||
| 1067 | tbl)) | ||
| 1068 | |||
| 1069 | (defun ange-ftp-hash-entry-exists-p (key tbl) | 1023 | (defun ange-ftp-hash-entry-exists-p (key tbl) |
| 1070 | "Return whether there is an association for KEY in TABLE." | 1024 | "Return whether there is an association for KEY in TABLE." |
| 1071 | (intern-soft (ange-ftp-make-hash-key key) tbl)) | 1025 | (not (eq (gethash key tbl 'unknown) 'unknown))) |
| 1072 | 1026 | ||
| 1073 | (defun ange-ftp-hash-table-keys (tbl) | 1027 | (defun ange-ftp-hash-table-keys (tbl) |
| 1074 | "Return a sorted list of all the active keys in TABLE, as strings." | 1028 | "Return a sorted list of all the active keys in TABLE, as strings." |
| 1075 | (sort (all-completions "" tbl) | 1029 | ;; (let ((keys nil)) |
| 1076 | (function string-lessp))) | 1030 | ;; (maphash (lambda (k v) (push k keys)) tbl) |
| 1031 | ;; (sort keys 'string-lessp)) | ||
| 1032 | (sort (all-completions "" tbl) 'string-lessp)) | ||
| 1077 | 1033 | ||
| 1078 | ;;;; ------------------------------------------------------------ | 1034 | ;;;; ------------------------------------------------------------ |
| 1079 | ;;;; Internal variables. | 1035 | ;;;; Internal variables. |
| @@ -1085,20 +1041,20 @@ SIZE, if supplied, should be a prime number." | |||
| 1085 | (defvar ange-ftp-netrc-modtime nil | 1041 | (defvar ange-ftp-netrc-modtime nil |
| 1086 | "Last modified time of the netrc file from file-attributes.") | 1042 | "Last modified time of the netrc file from file-attributes.") |
| 1087 | 1043 | ||
| 1088 | (defvar ange-ftp-user-hashtable (ange-ftp-make-hashtable) | 1044 | (defvar ange-ftp-user-hashtable (make-hash-table :test 'equal) |
| 1089 | "Hash table holding associations between HOST, USER pairs.") | 1045 | "Hash table holding associations between HOST, USER pairs.") |
| 1090 | 1046 | ||
| 1091 | (defvar ange-ftp-passwd-hashtable (ange-ftp-make-hashtable) | 1047 | (defvar ange-ftp-passwd-hashtable (make-hash-table :test 'equal) |
| 1092 | "Mapping between a HOST, USER pair and a PASSWORD for them. | 1048 | "Mapping between a HOST, USER pair and a PASSWORD for them. |
| 1093 | All HOST values should be in lower case.") | 1049 | All HOST values should be in lower case.") |
| 1094 | 1050 | ||
| 1095 | (defvar ange-ftp-account-hashtable (ange-ftp-make-hashtable) | 1051 | (defvar ange-ftp-account-hashtable (make-hash-table :test 'equal) |
| 1096 | "Mapping between a HOST, USER pair and a ACCOUNT password for them.") | 1052 | "Mapping between a HOST, USER pair and a ACCOUNT password for them.") |
| 1097 | 1053 | ||
| 1098 | (defvar ange-ftp-files-hashtable (ange-ftp-make-hashtable 97) | 1054 | (defvar ange-ftp-files-hashtable (make-hash-table :test 'equal :size 97) |
| 1099 | "Hash table for storing directories and their respective files.") | 1055 | "Hash table for storing directories and their respective files.") |
| 1100 | 1056 | ||
| 1101 | (defvar ange-ftp-inodes-hashtable (ange-ftp-make-hashtable 97) | 1057 | (defvar ange-ftp-inodes-hashtable (make-hash-table :test 'equal :size 97) |
| 1102 | "Hash table for storing file names and their \"inode numbers\".") | 1058 | "Hash table for storing file names and their \"inode numbers\".") |
| 1103 | 1059 | ||
| 1104 | (defvar ange-ftp-next-inode-number 1 | 1060 | (defvar ange-ftp-next-inode-number 1 |
| @@ -1113,7 +1069,7 @@ All HOST values should be in lower case.") | |||
| 1113 | (defvar ange-ftp-ls-cache-res nil | 1069 | (defvar ange-ftp-ls-cache-res nil |
| 1114 | "Last result returned from ange-ftp-ls.") | 1070 | "Last result returned from ange-ftp-ls.") |
| 1115 | 1071 | ||
| 1116 | (defconst ange-ftp-expand-dir-hashtable (ange-ftp-make-hashtable)) | 1072 | (defconst ange-ftp-expand-dir-hashtable (make-hash-table :test 'equal)) |
| 1117 | 1073 | ||
| 1118 | (defconst ange-ftp-expand-dir-regexp "^5.0 \\([^: ]+\\):") | 1074 | (defconst ange-ftp-expand-dir-regexp "^5.0 \\([^: ]+\\):") |
| 1119 | 1075 | ||
| @@ -1151,7 +1107,7 @@ All HOST values should be in lower case.") | |||
| 1151 | (defun ange-ftp-message (fmt &rest args) | 1107 | (defun ange-ftp-message (fmt &rest args) |
| 1152 | "Display message in echo area, but indicate if truncated. | 1108 | "Display message in echo area, but indicate if truncated. |
| 1153 | Args are as in `message': a format string, plus arguments to be formatted." | 1109 | Args are as in `message': a format string, plus arguments to be formatted." |
| 1154 | (let ((msg (apply (function format) fmt args)) | 1110 | (let ((msg (apply 'format fmt args)) |
| 1155 | (max (window-width (minibuffer-window)))) | 1111 | (max (window-width (minibuffer-window)))) |
| 1156 | (if noninteractive | 1112 | (if noninteractive |
| 1157 | msg | 1113 | msg |
| @@ -1183,12 +1139,12 @@ only return the directory part of FILE." | |||
| 1183 | (defun ange-ftp-set-user (host user) | 1139 | (defun ange-ftp-set-user (host user) |
| 1184 | "For a given HOST, set or change the default USER." | 1140 | "For a given HOST, set or change the default USER." |
| 1185 | (interactive "sHost: \nsUser: ") | 1141 | (interactive "sHost: \nsUser: ") |
| 1186 | (ange-ftp-put-hash-entry host user ange-ftp-user-hashtable)) | 1142 | (puthash host user ange-ftp-user-hashtable)) |
| 1187 | 1143 | ||
| 1188 | (defun ange-ftp-get-user (host) | 1144 | (defun ange-ftp-get-user (host) |
| 1189 | "Given a HOST, return the default USER." | 1145 | "Given a HOST, return the default USER." |
| 1190 | (ange-ftp-parse-netrc) | 1146 | (ange-ftp-parse-netrc) |
| 1191 | (let ((user (ange-ftp-get-hash-entry host ange-ftp-user-hashtable))) | 1147 | (let ((user (gethash host ange-ftp-user-hashtable))) |
| 1192 | (or user | 1148 | (or user |
| 1193 | (prog1 | 1149 | (prog1 |
| 1194 | (setq user | 1150 | (setq user |
| @@ -1214,36 +1170,33 @@ only return the directory part of FILE." | |||
| 1214 | `(concat (downcase ,host) "/" ,user)) | 1170 | `(concat (downcase ,host) "/" ,user)) |
| 1215 | 1171 | ||
| 1216 | (defmacro ange-ftp-lookup-passwd (host user) | 1172 | (defmacro ange-ftp-lookup-passwd (host user) |
| 1217 | `(ange-ftp-get-hash-entry (ange-ftp-generate-passwd-key ,host ,user) | 1173 | `(gethash (ange-ftp-generate-passwd-key ,host ,user) |
| 1218 | ange-ftp-passwd-hashtable)) | 1174 | ange-ftp-passwd-hashtable)) |
| 1219 | 1175 | ||
| 1220 | (defun ange-ftp-set-passwd (host user passwd) | 1176 | (defun ange-ftp-set-passwd (host user passwd) |
| 1221 | "For a given HOST and USER, set or change the associated PASSWORD." | 1177 | "For a given HOST and USER, set or change the associated PASSWORD." |
| 1222 | (interactive (list (read-string "Host: ") | 1178 | (interactive (list (read-string "Host: ") |
| 1223 | (read-string "User: ") | 1179 | (read-string "User: ") |
| 1224 | (read-passwd "Password: "))) | 1180 | (read-passwd "Password: "))) |
| 1225 | (ange-ftp-put-hash-entry (ange-ftp-generate-passwd-key host user) | 1181 | (puthash (ange-ftp-generate-passwd-key host user) |
| 1226 | passwd | 1182 | passwd ange-ftp-passwd-hashtable)) |
| 1227 | ange-ftp-passwd-hashtable)) | ||
| 1228 | 1183 | ||
| 1229 | (defun ange-ftp-get-host-with-passwd (user) | 1184 | (defun ange-ftp-get-host-with-passwd (user) |
| 1230 | "Given a USER, return a host we know the password for." | 1185 | "Given a USER, return a host we know the password for." |
| 1231 | (ange-ftp-parse-netrc) | 1186 | (ange-ftp-parse-netrc) |
| 1232 | (catch 'found-one | 1187 | (catch 'found-one |
| 1233 | (ange-ftp-map-hashtable | 1188 | (maphash |
| 1234 | (function (lambda (host val) | 1189 | (lambda (host val) |
| 1235 | (if (ange-ftp-lookup-passwd host user) | 1190 | (if (ange-ftp-lookup-passwd host user) (throw 'found-one host))) |
| 1236 | (throw 'found-one host)))) | ||
| 1237 | ange-ftp-user-hashtable) | 1191 | ange-ftp-user-hashtable) |
| 1238 | (save-match-data | 1192 | (save-match-data |
| 1239 | (ange-ftp-map-hashtable | 1193 | (maphash |
| 1240 | (function | 1194 | (lambda (key value) |
| 1241 | (lambda (key value) | 1195 | (if (string-match "^[^/]*\\(/\\).*$" key) |
| 1242 | (if (string-match "^[^/]*\\(/\\).*$" key) | 1196 | (let ((host (substring key 0 (match-beginning 1)))) |
| 1243 | (let ((host (substring key 0 (match-beginning 1)))) | 1197 | (if (and (string-equal user (substring key (match-end 1))) |
| 1244 | (if (and (string-equal user (substring key (match-end 1))) | 1198 | value) |
| 1245 | value) | 1199 | (throw 'found-one host))))) |
| 1246 | (throw 'found-one host)))))) | ||
| 1247 | ange-ftp-passwd-hashtable)) | 1200 | ange-ftp-passwd-hashtable)) |
| 1248 | nil)) | 1201 | nil)) |
| 1249 | 1202 | ||
| @@ -1310,15 +1263,14 @@ only return the directory part of FILE." | |||
| 1310 | (interactive (list (read-string "Host: ") | 1263 | (interactive (list (read-string "Host: ") |
| 1311 | (read-string "User: ") | 1264 | (read-string "User: ") |
| 1312 | (read-passwd "Account password: "))) | 1265 | (read-passwd "Account password: "))) |
| 1313 | (ange-ftp-put-hash-entry (ange-ftp-generate-passwd-key host user) | 1266 | (puthash (ange-ftp-generate-passwd-key host user) |
| 1314 | account | 1267 | account ange-ftp-account-hashtable)) |
| 1315 | ange-ftp-account-hashtable)) | ||
| 1316 | 1268 | ||
| 1317 | (defun ange-ftp-get-account (host user) | 1269 | (defun ange-ftp-get-account (host user) |
| 1318 | "Given a HOST and USER, return the FTP account." | 1270 | "Given a HOST and USER, return the FTP account." |
| 1319 | (ange-ftp-parse-netrc) | 1271 | (ange-ftp-parse-netrc) |
| 1320 | (or (ange-ftp-get-hash-entry (ange-ftp-generate-passwd-key host user) | 1272 | (or (gethash (ange-ftp-generate-passwd-key host user) |
| 1321 | ange-ftp-account-hashtable) | 1273 | ange-ftp-account-hashtable) |
| 1322 | (and (stringp ange-ftp-default-user) | 1274 | (and (stringp ange-ftp-default-user) |
| 1323 | (string-equal user ange-ftp-default-user) | 1275 | (string-equal user ange-ftp-default-user) |
| 1324 | ange-ftp-default-account) | 1276 | ange-ftp-default-account) |
| @@ -1453,17 +1405,15 @@ only return the directory part of FILE." | |||
| 1453 | (ange-ftp-parse-netrc) | 1405 | (ange-ftp-parse-netrc) |
| 1454 | (save-match-data | 1406 | (save-match-data |
| 1455 | (let (res) | 1407 | (let (res) |
| 1456 | (ange-ftp-map-hashtable | 1408 | (maphash |
| 1457 | (function | 1409 | (lambda (key value) |
| 1458 | (lambda (key value) | 1410 | (if (string-match "^[^/]*\\(/\\).*$" key) |
| 1459 | (if (string-match "^[^/]*\\(/\\).*$" key) | 1411 | (let ((host (substring key 0 (match-beginning 1))) |
| 1460 | (let ((host (substring key 0 (match-beginning 1))) | 1412 | (user (substring key (match-end 1)))) |
| 1461 | (user (substring key (match-end 1)))) | 1413 | (push (concat user "@" host ":") res)))) |
| 1462 | (push (concat user "@" host ":") res))))) | ||
| 1463 | ange-ftp-passwd-hashtable) | 1414 | ange-ftp-passwd-hashtable) |
| 1464 | (ange-ftp-map-hashtable | 1415 | (maphash |
| 1465 | (function (lambda (host user) | 1416 | (lambda (host user) (push (concat host ":") res)) |
| 1466 | (push (concat host ":") res))) | ||
| 1467 | ange-ftp-user-hashtable) | 1417 | ange-ftp-user-hashtable) |
| 1468 | (or res (list nil))))) | 1418 | (or res (list nil))))) |
| 1469 | 1419 | ||
| @@ -1653,14 +1603,13 @@ good, skip, fatal, or unknown." | |||
| 1653 | (let ((kbytes (ash (* ange-ftp-hash-mark-unit | 1603 | (let ((kbytes (ash (* ange-ftp-hash-mark-unit |
| 1654 | ange-ftp-hash-mark-count) | 1604 | ange-ftp-hash-mark-count) |
| 1655 | -6))) | 1605 | -6))) |
| 1656 | (if (zerop ange-ftp-xfer-size) | 1606 | (if (zerop ange-ftp-xfer-size) |
| 1657 | (ange-ftp-message "%s...%dk" ange-ftp-process-msg kbytes) | 1607 | (ange-ftp-message "%s...%dk" ange-ftp-process-msg kbytes) |
| 1658 | (let ((percent (/ (* 100 kbytes) ange-ftp-xfer-size))) | 1608 | (let ((percent (/ (* 100 kbytes) ange-ftp-xfer-size))) |
| 1659 | ;; cut out the redisplay of identical %-age messages. | 1609 | ;; cut out the redisplay of identical %-age messages. |
| 1660 | (if (not (eq percent ange-ftp-last-percent)) | 1610 | (unless (eq percent ange-ftp-last-percent) |
| 1661 | (progn | 1611 | (setq ange-ftp-last-percent percent) |
| 1662 | (setq ange-ftp-last-percent percent) | 1612 | (ange-ftp-message "%s...%d%%" ange-ftp-process-msg percent)))))) |
| 1663 | (ange-ftp-message "%s...%d%%" ange-ftp-process-msg percent))))))) | ||
| 1664 | str) | 1613 | str) |
| 1665 | 1614 | ||
| 1666 | ;; Call the function specified by CONT. CONT can be either a function | 1615 | ;; Call the function specified by CONT. CONT can be either a function |
| @@ -1781,8 +1730,8 @@ good, skip, fatal, or unknown." | |||
| 1781 | (defun ange-ftp-make-tmp-name (host) | 1730 | (defun ange-ftp-make-tmp-name (host) |
| 1782 | "This routine will return the name of a new file." | 1731 | "This routine will return the name of a new file." |
| 1783 | (make-temp-file (if (ange-ftp-use-gateway-p host) | 1732 | (make-temp-file (if (ange-ftp-use-gateway-p host) |
| 1784 | ange-ftp-gateway-tmp-name-template | 1733 | ange-ftp-gateway-tmp-name-template |
| 1785 | ange-ftp-tmp-name-template))) | 1734 | ange-ftp-tmp-name-template))) |
| 1786 | 1735 | ||
| 1787 | (defalias 'ange-ftp-del-tmp-name 'delete-file) | 1736 | (defalias 'ange-ftp-del-tmp-name 'delete-file) |
| 1788 | 1737 | ||
| @@ -2516,8 +2465,7 @@ Works by doing a pwd and examining the directory syntax." | |||
| 2516 | ange-ftp-fix-name-func-alist))) | 2465 | ange-ftp-fix-name-func-alist))) |
| 2517 | (if fix-name-func | 2466 | (if fix-name-func |
| 2518 | (setq dir (funcall fix-name-func dir 'reverse)))) | 2467 | (setq dir (funcall fix-name-func dir 'reverse)))) |
| 2519 | (ange-ftp-put-hash-entry key dir | 2468 | (puthash key dir ange-ftp-expand-dir-hashtable)))) |
| 2520 | ange-ftp-expand-dir-hashtable)))) | ||
| 2521 | 2469 | ||
| 2522 | ;; In the special case of CMS make sure that know the | 2470 | ;; In the special case of CMS make sure that know the |
| 2523 | ;; expansion of the home minidisk now, because we will | 2471 | ;; expansion of the home minidisk now, because we will |
| @@ -2527,8 +2475,7 @@ Works by doing a pwd and examining the directory syntax." | |||
| 2527 | key ange-ftp-expand-dir-hashtable))) | 2475 | key ange-ftp-expand-dir-hashtable))) |
| 2528 | (let ((dir (car (ange-ftp-get-pwd host user)))) | 2476 | (let ((dir (car (ange-ftp-get-pwd host user)))) |
| 2529 | (if dir | 2477 | (if dir |
| 2530 | (ange-ftp-put-hash-entry key (concat "/" dir) | 2478 | (puthash key (concat "/" dir) ange-ftp-expand-dir-hashtable) |
| 2531 | ange-ftp-expand-dir-hashtable) | ||
| 2532 | (message "Warning! Unable to get home directory") | 2479 | (message "Warning! Unable to get home directory") |
| 2533 | (sit-for 1)))))) | 2480 | (sit-for 1)))))) |
| 2534 | 2481 | ||
| @@ -2611,7 +2558,7 @@ away in the internal cache." | |||
| 2611 | (if (string-equal name "") | 2558 | (if (string-equal name "") |
| 2612 | (setq name | 2559 | (setq name |
| 2613 | (ange-ftp-real-file-name-as-directory | 2560 | (ange-ftp-real-file-name-as-directory |
| 2614 | (ange-ftp-expand-dir host user "~")))) | 2561 | (ange-ftp-expand-dir host user "~")))) |
| 2615 | (if (and ange-ftp-ls-cache-file | 2562 | (if (and ange-ftp-ls-cache-file |
| 2616 | (string-equal key ange-ftp-ls-cache-file) | 2563 | (string-equal key ange-ftp-ls-cache-file) |
| 2617 | ;; Don't care about lsargs for dumb hosts. | 2564 | ;; Don't care about lsargs for dumb hosts. |
| @@ -2763,7 +2710,7 @@ The main reason for this alist is to deal with file versions in VMS.") | |||
| 2763 | (defun ange-ftp-ls-parser () | 2710 | (defun ange-ftp-ls-parser () |
| 2764 | ;; Note that switches is dynamically bound. | 2711 | ;; Note that switches is dynamically bound. |
| 2765 | ;; Meant to be called by ange-ftp-parse-dired-listing | 2712 | ;; Meant to be called by ange-ftp-parse-dired-listing |
| 2766 | (let ((tbl (ange-ftp-make-hashtable)) | 2713 | (let ((tbl (make-hash-table :test 'equal)) |
| 2767 | (used-F (and (stringp switches) | 2714 | (used-F (and (stringp switches) |
| 2768 | (string-match "F" switches))) | 2715 | (string-match "F" switches))) |
| 2769 | file-type symlink directory file) | 2716 | file-type symlink directory file) |
| @@ -2806,10 +2753,10 @@ The main reason for this alist is to deal with file versions in VMS.") | |||
| 2806 | (and executable (string-match "*$" file)) | 2753 | (and executable (string-match "*$" file)) |
| 2807 | (and socket (string-match "=$" file))) | 2754 | (and socket (string-match "=$" file))) |
| 2808 | (setq file (substring file 0 -1))))) | 2755 | (setq file (substring file 0 -1))))) |
| 2809 | (ange-ftp-put-hash-entry file (or symlink directory) tbl) | 2756 | (puthash file (or symlink directory) tbl) |
| 2810 | (forward-line 1)) | 2757 | (forward-line 1)) |
| 2811 | (ange-ftp-put-hash-entry "." t tbl) | 2758 | (puthash "." t tbl) |
| 2812 | (ange-ftp-put-hash-entry ".." t tbl) | 2759 | (puthash ".." t tbl) |
| 2813 | tbl)) | 2760 | tbl)) |
| 2814 | 2761 | ||
| 2815 | ;;; The dl stuff for descriptive listings | 2762 | ;;; The dl stuff for descriptive listings |
| @@ -2836,9 +2783,9 @@ match subdirectories as well.") | |||
| 2836 | (defmacro ange-ftp-dl-parser () | 2783 | (defmacro ange-ftp-dl-parser () |
| 2837 | ;; Parse the current buffer, which is assumed to be a descriptive | 2784 | ;; Parse the current buffer, which is assumed to be a descriptive |
| 2838 | ;; listing, and return a hashtable. | 2785 | ;; listing, and return a hashtable. |
| 2839 | `(let ((tbl (ange-ftp-make-hashtable))) | 2786 | `(let ((tbl (make-hash-table :test 'equal))) |
| 2840 | (while (not (eobp)) | 2787 | (while (not (eobp)) |
| 2841 | (ange-ftp-put-hash-entry | 2788 | (puthash |
| 2842 | (buffer-substring (point) | 2789 | (buffer-substring (point) |
| 2843 | (progn | 2790 | (progn |
| 2844 | (skip-chars-forward "^ /\n") | 2791 | (skip-chars-forward "^ /\n") |
| @@ -2846,9 +2793,9 @@ match subdirectories as well.") | |||
| 2846 | (eq (following-char) ?/) | 2793 | (eq (following-char) ?/) |
| 2847 | tbl) | 2794 | tbl) |
| 2848 | (forward-line 1)) | 2795 | (forward-line 1)) |
| 2849 | (ange-ftp-put-hash-entry "." t tbl) | 2796 | (puthash "." t tbl) |
| 2850 | (ange-ftp-put-hash-entry ".." t tbl) | 2797 | (puthash ".." t tbl) |
| 2851 | tbl)) | 2798 | tbl)) |
| 2852 | 2799 | ||
| 2853 | ;; Parse the current buffer which is assumed to be in a dired-like listing | 2800 | ;; Parse the current buffer which is assumed to be in a dired-like listing |
| 2854 | ;; format, and return a hashtable as the result. If the listing is not really | 2801 | ;; format, and return a hashtable as the result. If the listing is not really |
| @@ -2886,15 +2833,15 @@ match subdirectories as well.") | |||
| 2886 | 2833 | ||
| 2887 | (defun ange-ftp-set-files (directory files) | 2834 | (defun ange-ftp-set-files (directory files) |
| 2888 | "For a given DIRECTORY, set or change the associated FILES hashtable." | 2835 | "For a given DIRECTORY, set or change the associated FILES hashtable." |
| 2889 | (and files (ange-ftp-put-hash-entry (file-name-as-directory directory) | 2836 | (and files (puthash (file-name-as-directory directory) |
| 2890 | files ange-ftp-files-hashtable))) | 2837 | files ange-ftp-files-hashtable))) |
| 2891 | 2838 | ||
| 2892 | (defun ange-ftp-get-files (directory &optional no-error) | 2839 | (defun ange-ftp-get-files (directory &optional no-error) |
| 2893 | "Given a given DIRECTORY, return a hashtable of file entries. | 2840 | "Given a given DIRECTORY, return a hashtable of file entries. |
| 2894 | This will give an error or return nil, depending on the value of | 2841 | This will give an error or return nil, depending on the value of |
| 2895 | NO-ERROR, if a listing for DIRECTORY cannot be obtained." | 2842 | NO-ERROR, if a listing for DIRECTORY cannot be obtained." |
| 2896 | (setq directory (file-name-as-directory directory)) ;normalize | 2843 | (setq directory (file-name-as-directory directory)) ;normalize |
| 2897 | (or (ange-ftp-get-hash-entry directory ange-ftp-files-hashtable) | 2844 | (or (gethash directory ange-ftp-files-hashtable) |
| 2898 | (save-match-data | 2845 | (save-match-data |
| 2899 | (and (ange-ftp-ls directory | 2846 | (and (ange-ftp-ls directory |
| 2900 | ;; This is an efficiency hack. We try to | 2847 | ;; This is an efficiency hack. We try to |
| @@ -2925,8 +2872,7 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained." | |||
| 2925 | dired-listing-switches | 2872 | dired-listing-switches |
| 2926 | "-al")) | 2873 | "-al")) |
| 2927 | t no-error) | 2874 | t no-error) |
| 2928 | (ange-ftp-get-hash-entry | 2875 | (gethash directory ange-ftp-files-hashtable))))) |
| 2929 | directory ange-ftp-files-hashtable))))) | ||
| 2930 | 2876 | ||
| 2931 | ;; Given NAME, return the file part that can be used for looking up the | 2877 | ;; Given NAME, return the file part that can be used for looking up the |
| 2932 | ;; file's entry in a hashtable. | 2878 | ;; file's entry in a hashtable. |
| @@ -2970,7 +2916,7 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained." | |||
| 2970 | "Given NAME, return whether there is a file entry for it." | 2916 | "Given NAME, return whether there is a file entry for it." |
| 2971 | (let* ((name (directory-file-name name)) | 2917 | (let* ((name (directory-file-name name)) |
| 2972 | (dir (file-name-directory name)) | 2918 | (dir (file-name-directory name)) |
| 2973 | (ent (ange-ftp-get-hash-entry dir ange-ftp-files-hashtable)) | 2919 | (ent (gethash dir ange-ftp-files-hashtable)) |
| 2974 | (file (ange-ftp-get-file-part name))) | 2920 | (file (ange-ftp-get-file-part name))) |
| 2975 | (if ent | 2921 | (if ent |
| 2976 | (ange-ftp-hash-entry-exists-p file ent) | 2922 | (ange-ftp-hash-entry-exists-p file ent) |
| @@ -2984,7 +2930,7 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained." | |||
| 2984 | ;; then dumb hosts will give an ftp error. Smart unix hosts | 2930 | ;; then dumb hosts will give an ftp error. Smart unix hosts |
| 2985 | ;; will simply send back the ls | 2931 | ;; will simply send back the ls |
| 2986 | ;; error message. | 2932 | ;; error message. |
| 2987 | (ange-ftp-get-hash-entry "." ent)) | 2933 | (gethash "." ent)) |
| 2988 | ;; Child lookup failed, so try the parent. | 2934 | ;; Child lookup failed, so try the parent. |
| 2989 | (let ((table (ange-ftp-get-files dir 'no-error))) | 2935 | (let ((table (ange-ftp-get-files dir 'no-error))) |
| 2990 | ;; If the dir doesn't exist, don't use it as a hash table. | 2936 | ;; If the dir doesn't exist, don't use it as a hash table. |
| @@ -2999,53 +2945,47 @@ or a string for a symlink. If the file isn't in the hashtable, | |||
| 2999 | this also returns nil." | 2945 | this also returns nil." |
| 3000 | (let* ((name (directory-file-name name)) | 2946 | (let* ((name (directory-file-name name)) |
| 3001 | (dir (file-name-directory name)) | 2947 | (dir (file-name-directory name)) |
| 3002 | (ent (ange-ftp-get-hash-entry dir ange-ftp-files-hashtable)) | 2948 | (ent (gethash dir ange-ftp-files-hashtable)) |
| 3003 | (file (ange-ftp-get-file-part name))) | 2949 | (file (ange-ftp-get-file-part name))) |
| 3004 | (if ent | 2950 | (if ent |
| 3005 | (ange-ftp-get-hash-entry file ent) | 2951 | (gethash file ent) |
| 3006 | (or (and (ange-ftp-allow-child-lookup dir file) | 2952 | (or (and (ange-ftp-allow-child-lookup dir file) |
| 3007 | (setq ent (ange-ftp-get-files name t)) | 2953 | (setq ent (ange-ftp-get-files name t)) |
| 3008 | (ange-ftp-get-hash-entry "." ent)) | 2954 | (gethash "." ent)) |
| 3009 | ;; i.e. it's a directory by child lookup | 2955 | ;; i.e. it's a directory by child lookup |
| 3010 | (ange-ftp-get-hash-entry file | 2956 | (gethash file (ange-ftp-get-files dir)))))) |
| 3011 | (ange-ftp-get-files dir)))))) | ||
| 3012 | 2957 | ||
| 3013 | (defun ange-ftp-internal-delete-file-entry (name &optional dir-p) | 2958 | (defun ange-ftp-internal-delete-file-entry (name &optional dir-p) |
| 3014 | (if dir-p | 2959 | (when dir-p |
| 3015 | (progn | 2960 | (setq name (file-name-as-directory name)) |
| 3016 | (setq name (file-name-as-directory name)) | 2961 | (remhash name ange-ftp-files-hashtable) |
| 3017 | (ange-ftp-del-hash-entry name ange-ftp-files-hashtable) | 2962 | (setq name (directory-file-name name))) |
| 3018 | (setq name (directory-file-name name)))) | ||
| 3019 | ;; Note that file-name-as-directory followed by directory-file-name | 2963 | ;; Note that file-name-as-directory followed by directory-file-name |
| 3020 | ;; serves to canonicalize directory file names to their unix form. | 2964 | ;; serves to canonicalize directory file names to their unix form. |
| 3021 | ;; i.e. in VMS, FOO.DIR -> FOO/ -> FOO | 2965 | ;; i.e. in VMS, FOO.DIR -> FOO/ -> FOO |
| 3022 | (let ((files (ange-ftp-get-hash-entry (file-name-directory name) | 2966 | (let ((files (gethash (file-name-directory name) ange-ftp-files-hashtable))) |
| 3023 | ange-ftp-files-hashtable))) | ||
| 3024 | (if files | 2967 | (if files |
| 3025 | (ange-ftp-del-hash-entry (ange-ftp-get-file-part name) | 2968 | (remhash (ange-ftp-get-file-part name) files)))) |
| 3026 | files)))) | ||
| 3027 | 2969 | ||
| 3028 | (defun ange-ftp-internal-add-file-entry (name &optional dir-p) | 2970 | (defun ange-ftp-internal-add-file-entry (name &optional dir-p) |
| 3029 | (and dir-p | 2971 | (and dir-p |
| 3030 | (setq name (directory-file-name name))) | 2972 | (setq name (directory-file-name name))) |
| 3031 | (let ((files (ange-ftp-get-hash-entry (file-name-directory name) | 2973 | (let ((files (gethash (file-name-directory name) ange-ftp-files-hashtable))) |
| 3032 | ange-ftp-files-hashtable))) | ||
| 3033 | (if files | 2974 | (if files |
| 3034 | (ange-ftp-put-hash-entry (ange-ftp-get-file-part name) | 2975 | (puthash (ange-ftp-get-file-part name) dir-p files)))) |
| 3035 | dir-p | ||
| 3036 | files)))) | ||
| 3037 | 2976 | ||
| 3038 | (defun ange-ftp-wipe-file-entries (host user) | 2977 | (defun ange-ftp-wipe-file-entries (host user) |
| 3039 | "Get rid of entry for HOST, USER pair from file entry information hashtable." | 2978 | "Get rid of entry for HOST, USER pair from file entry information hashtable." |
| 3040 | (let ((new-tbl (ange-ftp-make-hashtable (length ange-ftp-files-hashtable)))) | 2979 | (let ((new-tbl (make-hash-table :test 'equal |
| 3041 | (ange-ftp-map-hashtable | 2980 | :size (length ange-ftp-files-hashtable)))) |
| 2981 | (maphash | ||
| 3042 | (lambda (key val) | 2982 | (lambda (key val) |
| 3043 | (let ((parsed (ange-ftp-ftp-name key))) | 2983 | (let ((parsed (ange-ftp-ftp-name key))) |
| 3044 | (if parsed | 2984 | (if parsed |
| 3045 | (let ((h (nth 0 parsed)) | 2985 | (let ((h (nth 0 parsed)) |
| 3046 | (u (nth 1 parsed))) | 2986 | (u (nth 1 parsed))) |
| 3047 | (or (and (equal host h) (equal user u)) | 2987 | (or (and (equal host h) (equal user u)) |
| 3048 | (ange-ftp-put-hash-entry key val new-tbl)))))) | 2988 | (puthash key val new-tbl)))))) |
| 3049 | ange-ftp-files-hashtable) | 2989 | ange-ftp-files-hashtable) |
| 3050 | (setq ange-ftp-files-hashtable new-tbl))) | 2990 | (setq ange-ftp-files-hashtable new-tbl))) |
| 3051 | 2991 | ||
| @@ -3112,7 +3052,7 @@ logged in as user USER and cd'd to directory DIR." | |||
| 3112 | (fix-name-func | 3052 | (fix-name-func |
| 3113 | (cdr (assq host-type ange-ftp-fix-name-func-alist))) | 3053 | (cdr (assq host-type ange-ftp-fix-name-func-alist))) |
| 3114 | (key (concat host "/" user "/" dir)) | 3054 | (key (concat host "/" user "/" dir)) |
| 3115 | (res (ange-ftp-get-hash-entry key ange-ftp-expand-dir-hashtable))) | 3055 | (res (gethash key ange-ftp-expand-dir-hashtable))) |
| 3116 | (or res | 3056 | (or res |
| 3117 | (progn | 3057 | (progn |
| 3118 | (or | 3058 | (or |
| @@ -3144,8 +3084,7 @@ logged in as user USER and cd'd to directory DIR." | |||
| 3144 | (ange-ftp-this-host host)) | 3084 | (ange-ftp-this-host host)) |
| 3145 | (if fix-name-func | 3085 | (if fix-name-func |
| 3146 | (setq res (funcall fix-name-func res 'reverse))) | 3086 | (setq res (funcall fix-name-func res 'reverse))) |
| 3147 | (ange-ftp-put-hash-entry | 3087 | (puthash key res ange-ftp-expand-dir-hashtable))) |
| 3148 | key res ange-ftp-expand-dir-hashtable))) | ||
| 3149 | res)))) | 3088 | res)))) |
| 3150 | 3089 | ||
| 3151 | (defun ange-ftp-canonize-filename (n) | 3090 | (defun ange-ftp-canonize-filename (n) |
| @@ -3372,8 +3311,8 @@ system TYPE.") | |||
| 3372 | (if (or (file-exists-p filename) | 3311 | (if (or (file-exists-p filename) |
| 3373 | (progn | 3312 | (progn |
| 3374 | (setq ange-ftp-ls-cache-file nil) | 3313 | (setq ange-ftp-ls-cache-file nil) |
| 3375 | (ange-ftp-del-hash-entry (file-name-directory filename) | 3314 | (remhash (file-name-directory filename) |
| 3376 | ange-ftp-files-hashtable) | 3315 | ange-ftp-files-hashtable) |
| 3377 | (file-exists-p filename))) | 3316 | (file-exists-p filename))) |
| 3378 | (let* ((host (nth 0 parsed)) | 3317 | (let* ((host (nth 0 parsed)) |
| 3379 | (user (nth 1 parsed)) | 3318 | (user (nth 1 parsed)) |
| @@ -3447,13 +3386,13 @@ system TYPE.") | |||
| 3447 | (setq file (ange-ftp-expand-file-name file)) | 3386 | (setq file (ange-ftp-expand-file-name file)) |
| 3448 | (if (ange-ftp-ftp-name file) | 3387 | (if (ange-ftp-ftp-name file) |
| 3449 | (let ((file-ent | 3388 | (let ((file-ent |
| 3450 | (ange-ftp-get-hash-entry | 3389 | (gethash |
| 3451 | (ange-ftp-get-file-part file) | 3390 | (ange-ftp-get-file-part file) |
| 3452 | (ange-ftp-get-files (file-name-directory file))))) | 3391 | (ange-ftp-get-files (file-name-directory file))))) |
| 3453 | (if (stringp file-ent) | 3392 | (if (stringp file-ent) |
| 3454 | (if (file-name-absolute-p file-ent) | 3393 | (if (file-name-absolute-p file-ent) |
| 3455 | (ange-ftp-replace-name-component | 3394 | (ange-ftp-replace-name-component |
| 3456 | (file-name-directory file) file-ent) | 3395 | (file-name-directory file) file-ent) |
| 3457 | file-ent))) | 3396 | file-ent))) |
| 3458 | (ange-ftp-real-file-symlink-p file))) | 3397 | (ange-ftp-real-file-symlink-p file))) |
| 3459 | 3398 | ||
| @@ -3516,13 +3455,12 @@ system TYPE.") | |||
| 3516 | (let ((host (nth 0 parsed)) | 3455 | (let ((host (nth 0 parsed)) |
| 3517 | (user (nth 1 parsed)) | 3456 | (user (nth 1 parsed)) |
| 3518 | (name (nth 2 parsed)) | 3457 | (name (nth 2 parsed)) |
| 3519 | (dirp (ange-ftp-get-hash-entry part files)) | 3458 | (dirp (gethash part files)) |
| 3520 | (inode (ange-ftp-get-hash-entry | 3459 | (inode (gethash file ange-ftp-inodes-hashtable))) |
| 3521 | file ange-ftp-inodes-hashtable))) | ||
| 3522 | (unless inode | 3460 | (unless inode |
| 3523 | (setq inode ange-ftp-next-inode-number | 3461 | (setq inode ange-ftp-next-inode-number |
| 3524 | ange-ftp-next-inode-number (1+ inode)) | 3462 | ange-ftp-next-inode-number (1+ inode)) |
| 3525 | (ange-ftp-put-hash-entry file inode ange-ftp-inodes-hashtable)) | 3463 | (puthash file inode ange-ftp-inodes-hashtable)) |
| 3526 | (list (if (and (stringp dirp) (file-name-absolute-p dirp)) | 3464 | (list (if (and (stringp dirp) (file-name-absolute-p dirp)) |
| 3527 | (ange-ftp-expand-symlink dirp | 3465 | (ange-ftp-expand-symlink dirp |
| 3528 | (file-name-directory file)) | 3466 | (file-name-directory file)) |
| @@ -3905,7 +3843,7 @@ E.g., | |||
| 3905 | (and verbose-p (format "%s --> %s" from-file to-file)) | 3843 | (and verbose-p (format "%s --> %s" from-file to-file)) |
| 3906 | (list 'ange-ftp-copy-files-async verbose-p (cdr files)) | 3844 | (list 'ange-ftp-copy-files-async verbose-p (cdr files)) |
| 3907 | t)) | 3845 | t)) |
| 3908 | (message "%s: done" 'ange-ftp-copy-files-async))) | 3846 | (message "%s: done" 'ange-ftp-copy-files-async))) |
| 3909 | 3847 | ||
| 3910 | 3848 | ||
| 3911 | ;;;; ------------------------------------------------------------ | 3849 | ;;;; ------------------------------------------------------------ |
| @@ -3987,27 +3925,24 @@ E.g., | |||
| 3987 | 3925 | ||
| 3988 | ;; If the file entry SYM is a symlink, returns whether its file exists. | 3926 | ;; If the file entry SYM is a symlink, returns whether its file exists. |
| 3989 | ;; Note that `ange-ftp-this-dir' is used as a free variable. | 3927 | ;; Note that `ange-ftp-this-dir' is used as a free variable. |
| 3990 | (defun ange-ftp-file-entry-active-p (sym) | 3928 | (defun ange-ftp-file-entry-active-p (key val) |
| 3991 | (let ((val (get sym 'val))) | 3929 | (or (not (stringp val)) |
| 3992 | (or (not (stringp val)) | 3930 | (file-exists-p (ange-ftp-expand-symlink val ange-ftp-this-dir)))) |
| 3993 | (file-exists-p (ange-ftp-expand-symlink val ange-ftp-this-dir))))) | ||
| 3994 | 3931 | ||
| 3995 | ;; If the file entry is not a directory (nor a symlink pointing to a directory) | 3932 | ;; If the file entry is not a directory (nor a symlink pointing to a directory) |
| 3996 | ;; returns whether the file (or file pointed to by the symlink) is ignored | 3933 | ;; returns whether the file (or file pointed to by the symlink) is ignored |
| 3997 | ;; by completion-ignored-extensions. | 3934 | ;; by completion-ignored-extensions. |
| 3998 | ;; Note that `ange-ftp-this-dir' and `ange-ftp-completion-ignored-pattern' | 3935 | ;; Note that `ange-ftp-this-dir' and `ange-ftp-completion-ignored-pattern' |
| 3999 | ;; are used as free variables. | 3936 | ;; are used as free variables. |
| 4000 | (defun ange-ftp-file-entry-not-ignored-p (sym) | 3937 | (defun ange-ftp-file-entry-not-ignored-p (symname val) |
| 4001 | (let ((val (get sym 'val)) | 3938 | (if (stringp val) |
| 4002 | (symname (symbol-name sym))) | 3939 | (let ((file (ange-ftp-expand-symlink val ange-ftp-this-dir))) |
| 4003 | (if (stringp val) | 3940 | (or (file-directory-p file) |
| 4004 | (let ((file (ange-ftp-expand-symlink val ange-ftp-this-dir))) | 3941 | (and (file-exists-p file) |
| 4005 | (or (file-directory-p file) | 3942 | (not (string-match ange-ftp-completion-ignored-pattern |
| 4006 | (and (file-exists-p file) | 3943 | symname))))) |
| 4007 | (not (string-match ange-ftp-completion-ignored-pattern | 3944 | (or val ; is a directory name |
| 4008 | symname))))) | 3945 | (not (string-match ange-ftp-completion-ignored-pattern symname))))) |
| 4009 | (or val ; is a directory name | ||
| 4010 | (not (string-match ange-ftp-completion-ignored-pattern symname)))))) | ||
| 4011 | 3946 | ||
| 4012 | (defun ange-ftp-root-dir-p (dir) | 3947 | (defun ange-ftp-root-dir-p (dir) |
| 4013 | ;; Maybe we should use something more like | 3948 | ;; Maybe we should use something more like |
| @@ -4031,14 +3966,14 @@ E.g., | |||
| 4031 | ;; see whether each matching file is a directory or not... | 3966 | ;; see whether each matching file is a directory or not... |
| 4032 | (mapcar | 3967 | (mapcar |
| 4033 | (lambda (file) | 3968 | (lambda (file) |
| 4034 | (let ((ent (ange-ftp-get-hash-entry file tbl))) | 3969 | (let ((ent (gethash file tbl))) |
| 4035 | (if (and ent | 3970 | (if (and ent |
| 4036 | (or (not (stringp ent)) | 3971 | (or (not (stringp ent)) |
| 4037 | (file-directory-p | 3972 | (file-directory-p |
| 4038 | (ange-ftp-expand-symlink ent | 3973 | (ange-ftp-expand-symlink ent |
| 4039 | ange-ftp-this-dir)))) | 3974 | ange-ftp-this-dir)))) |
| 4040 | (concat file "/") | 3975 | (concat file "/") |
| 4041 | file))) | 3976 | file))) |
| 4042 | completions))) | 3977 | completions))) |
| 4043 | 3978 | ||
| 4044 | (if (ange-ftp-root-dir-p ange-ftp-this-dir) | 3979 | (if (ange-ftp-root-dir-p ange-ftp-this-dir) |
| @@ -4116,7 +4051,7 @@ directory, so that Emacs will know its current contents." | |||
| 4116 | (if (ange-ftp-ftp-name dir) | 4051 | (if (ange-ftp-ftp-name dir) |
| 4117 | (progn | 4052 | (progn |
| 4118 | (setq ange-ftp-ls-cache-file nil) | 4053 | (setq ange-ftp-ls-cache-file nil) |
| 4119 | (ange-ftp-del-hash-entry dir ange-ftp-files-hashtable) | 4054 | (remhash dir ange-ftp-files-hashtable) |
| 4120 | (ange-ftp-get-files dir t)))) | 4055 | (ange-ftp-get-files dir t)))) |
| 4121 | 4056 | ||
| 4122 | (defun ange-ftp-make-directory (dir &optional parents) | 4057 | (defun ange-ftp-make-directory (dir &optional parents) |
| @@ -4963,10 +4898,10 @@ NEWNAME should be the name to give the new compressed or uncompressed file.") | |||
| 4963 | ; (progn | 4898 | ; (progn |
| 4964 | ; (end-of-line 1) | 4899 | ; (end-of-line 1) |
| 4965 | ; (point)))) | 4900 | ; (point)))) |
| 4966 | ; (ange-ftp-put-hash-entry file type-is-dir tbl) | 4901 | ; (puthash file type-is-dir tbl) |
| 4967 | ; (forward-line 1)))) | 4902 | ; (forward-line 1)))) |
| 4968 | ; (ange-ftp-put-hash-entry "." 'vosdir tbl) | 4903 | ; (puthash "." 'vosdir tbl) |
| 4969 | ; (ange-ftp-put-hash-entry ".." 'vosdir tbl)) | 4904 | ; (puthash ".." 'vosdir tbl)) |
| 4970 | ; tbl)) | 4905 | ; tbl)) |
| 4971 | ; | 4906 | ; |
| 4972 | ;(or (assq 'vos ange-ftp-parse-list-func-alist) | 4907 | ;(or (assq 'vos ange-ftp-parse-list-func-alist) |
| @@ -5087,27 +5022,25 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5087 | ;; Parse the current buffer which is assumed to be in MultiNet FTP dir | 5022 | ;; Parse the current buffer which is assumed to be in MultiNet FTP dir |
| 5088 | ;; format, and return a hashtable as the result. | 5023 | ;; format, and return a hashtable as the result. |
| 5089 | (defun ange-ftp-parse-vms-listing () | 5024 | (defun ange-ftp-parse-vms-listing () |
| 5090 | (let ((tbl (ange-ftp-make-hashtable)) | 5025 | (let ((tbl (make-hash-table :test 'equal)) |
| 5091 | file) | 5026 | file) |
| 5092 | (goto-char (point-min)) | 5027 | (goto-char (point-min)) |
| 5093 | (save-match-data | 5028 | (save-match-data |
| 5094 | (while (setq file (ange-ftp-parse-vms-filename)) | 5029 | (while (setq file (ange-ftp-parse-vms-filename)) |
| 5095 | (if (string-match "\\.\\(DIR\\|dir\\);[0-9]+" file) | 5030 | (if (string-match "\\.\\(DIR\\|dir\\);[0-9]+" file) |
| 5096 | ;; deal with directories | 5031 | ;; deal with directories |
| 5097 | (ange-ftp-put-hash-entry | 5032 | (puthash (substring file 0 (match-beginning 0)) t tbl) |
| 5098 | (substring file 0 (match-beginning 0)) t tbl) | 5033 | (puthash file nil tbl) |
| 5099 | (ange-ftp-put-hash-entry file nil tbl) | ||
| 5100 | (if (string-match ";[0-9]+$" file) ; deal with extension | 5034 | (if (string-match ";[0-9]+$" file) ; deal with extension |
| 5101 | ;; sans extension | 5035 | ;; sans extension |
| 5102 | (ange-ftp-put-hash-entry | 5036 | (puthash (substring file 0 (match-beginning 0)) nil tbl))) |
| 5103 | (substring file 0 (match-beginning 0)) nil tbl))) | ||
| 5104 | (forward-line 1)) | 5037 | (forward-line 1)) |
| 5105 | ;; Would like to look for a "Total" line, or a "Directory" line to | 5038 | ;; Would like to look for a "Total" line, or a "Directory" line to |
| 5106 | ;; make sure that the listing isn't complete garbage before putting | 5039 | ;; make sure that the listing isn't complete garbage before putting |
| 5107 | ;; in "." and "..", but we can't even count on all VAX's giving us | 5040 | ;; in "." and "..", but we can't even count on all VAX's giving us |
| 5108 | ;; either of these. | 5041 | ;; either of these. |
| 5109 | (ange-ftp-put-hash-entry "." t tbl) | 5042 | (puthash "." t tbl) |
| 5110 | (ange-ftp-put-hash-entry ".." t tbl)) | 5043 | (puthash ".." t tbl)) |
| 5111 | tbl)) | 5044 | tbl)) |
| 5112 | 5045 | ||
| 5113 | (or (assq 'vms ange-ftp-parse-list-func-alist) | 5046 | (or (assq 'vms ange-ftp-parse-list-func-alist) |
| @@ -5130,9 +5063,8 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5130 | ;; In VMS you can't delete a file without an explicit | 5063 | ;; In VMS you can't delete a file without an explicit |
| 5131 | ;; version number, or wild-card (e.g. FOO;*) | 5064 | ;; version number, or wild-card (e.g. FOO;*) |
| 5132 | ;; For now, we give up on wildcards. | 5065 | ;; For now, we give up on wildcards. |
| 5133 | (let ((files (ange-ftp-get-hash-entry | 5066 | (let ((files (gethash (file-name-directory name) |
| 5134 | (file-name-directory name) | 5067 | ange-ftp-files-hashtable))) |
| 5135 | ange-ftp-files-hashtable))) | ||
| 5136 | (if files | 5068 | (if files |
| 5137 | (let* ((root (substring file 0 | 5069 | (let* ((root (substring file 0 |
| 5138 | (match-beginning 0))) | 5070 | (match-beginning 0))) |
| @@ -5140,17 +5072,17 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5140 | (regexp-quote root) | 5072 | (regexp-quote root) |
| 5141 | ";[0-9]+$")) | 5073 | ";[0-9]+$")) |
| 5142 | versions) | 5074 | versions) |
| 5143 | (ange-ftp-del-hash-entry file files) | 5075 | (remhash file files) |
| 5144 | ;; Now we need to check if there are any | 5076 | ;; Now we need to check if there are any |
| 5145 | ;; versions left. If not, then delete the | 5077 | ;; versions left. If not, then delete the |
| 5146 | ;; root entry. | 5078 | ;; root entry. |
| 5147 | (mapatoms | 5079 | (maphash |
| 5148 | (lambda (sym) | 5080 | (lambda (key val) |
| 5149 | (and (string-match regexp (get sym 'key)) | 5081 | (and (string-match regexp key) |
| 5150 | (setq versions t))) | 5082 | (setq versions t))) |
| 5151 | files) | 5083 | files) |
| 5152 | (or versions | 5084 | (or versions |
| 5153 | (ange-ftp-del-hash-entry root files)))))))))) | 5085 | (remhash root files)))))))))) |
| 5154 | 5086 | ||
| 5155 | (or (assq 'vms ange-ftp-delete-file-entry-alist) | 5087 | (or (assq 'vms ange-ftp-delete-file-entry-alist) |
| 5156 | (setq ange-ftp-delete-file-entry-alist | 5088 | (setq ange-ftp-delete-file-entry-alist |
| @@ -5160,38 +5092,34 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5160 | (defun ange-ftp-vms-add-file-entry (name &optional dir-p) | 5092 | (defun ange-ftp-vms-add-file-entry (name &optional dir-p) |
| 5161 | (if dir-p | 5093 | (if dir-p |
| 5162 | (ange-ftp-internal-add-file-entry name t) | 5094 | (ange-ftp-internal-add-file-entry name t) |
| 5163 | (let ((files (ange-ftp-get-hash-entry | 5095 | (let ((files (gethash (file-name-directory name) |
| 5164 | (file-name-directory name) | 5096 | ange-ftp-files-hashtable))) |
| 5165 | ange-ftp-files-hashtable))) | ||
| 5166 | (if files | 5097 | (if files |
| 5167 | (let ((file (ange-ftp-get-file-part name))) | 5098 | (let ((file (ange-ftp-get-file-part name))) |
| 5168 | (save-match-data | 5099 | (save-match-data |
| 5169 | (if (string-match ";[0-9]+$" file) | 5100 | (if (string-match ";[0-9]+$" file) |
| 5170 | (ange-ftp-put-hash-entry | 5101 | (puthash (substring file 0 (match-beginning 0)) nil files) |
| 5171 | (substring file 0 (match-beginning 0)) | ||
| 5172 | nil files) | ||
| 5173 | ;; Need to figure out what version of the file | 5102 | ;; Need to figure out what version of the file |
| 5174 | ;; is being added. | 5103 | ;; is being added. |
| 5175 | (let ((regexp (concat "^" | 5104 | (let ((regexp (concat "^" |
| 5176 | (regexp-quote file) | 5105 | (regexp-quote file) |
| 5177 | ";\\([0-9]+\\)$")) | 5106 | ";\\([0-9]+\\)$")) |
| 5178 | (version 0)) | 5107 | (version 0)) |
| 5179 | (mapatoms | 5108 | (maphash |
| 5180 | (lambda (sym) | 5109 | (lambda (name val) |
| 5181 | (let ((name (get sym 'key))) | 5110 | (and (string-match regexp name) |
| 5182 | (and (string-match regexp name) | 5111 | (setq version |
| 5183 | (setq version | 5112 | (max version |
| 5184 | (max version | 5113 | (string-to-int |
| 5185 | (string-to-int | 5114 | (substring name |
| 5186 | (substring name | 5115 | (match-beginning 1) |
| 5187 | (match-beginning 1) | 5116 | (match-end 1))))))) |
| 5188 | (match-end 1)))))))) | ||
| 5189 | files) | 5117 | files) |
| 5190 | (setq version (1+ version)) | 5118 | (setq version (1+ version)) |
| 5191 | (ange-ftp-put-hash-entry | 5119 | (puthash |
| 5192 | (concat file ";" (int-to-string version)) | 5120 | (concat file ";" (int-to-string version)) |
| 5193 | nil files)))) | 5121 | nil files)))) |
| 5194 | (ange-ftp-put-hash-entry file nil files)))))) | 5122 | (puthash file nil files)))))) |
| 5195 | 5123 | ||
| 5196 | (or (assq 'vms ange-ftp-add-file-entry-alist) | 5124 | (or (assq 'vms ange-ftp-add-file-entry-alist) |
| 5197 | (setq ange-ftp-add-file-entry-alist | 5125 | (setq ange-ftp-add-file-entry-alist |
| @@ -5588,7 +5516,7 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5588 | 5516 | ||
| 5589 | ;; Parse the current buffer which is assumed to be in mts ftp dir format. | 5517 | ;; Parse the current buffer which is assumed to be in mts ftp dir format. |
| 5590 | (defun ange-ftp-parse-mts-listing () | 5518 | (defun ange-ftp-parse-mts-listing () |
| 5591 | (let ((tbl (ange-ftp-make-hashtable))) | 5519 | (let ((tbl (make-hash-table :test 'equal))) |
| 5592 | (goto-char (point-min)) | 5520 | (goto-char (point-min)) |
| 5593 | (save-match-data | 5521 | (save-match-data |
| 5594 | (while (re-search-forward ange-ftp-date-regexp nil t) | 5522 | (while (re-search-forward ange-ftp-date-regexp nil t) |
| @@ -5596,10 +5524,10 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5596 | (skip-chars-backward " ") | 5524 | (skip-chars-backward " ") |
| 5597 | (let ((end (point))) | 5525 | (let ((end (point))) |
| 5598 | (skip-chars-backward "-A-Z0-9_.!") | 5526 | (skip-chars-backward "-A-Z0-9_.!") |
| 5599 | (ange-ftp-put-hash-entry (buffer-substring (point) end) nil tbl)) | 5527 | (puthash (buffer-substring (point) end) nil tbl)) |
| 5600 | (forward-line 1))) | 5528 | (forward-line 1))) |
| 5601 | ;; Don't need to bother with .. | 5529 | ;; Don't need to bother with .. |
| 5602 | (ange-ftp-put-hash-entry "." t tbl) | 5530 | (puthash "." t tbl) |
| 5603 | tbl)) | 5531 | tbl)) |
| 5604 | 5532 | ||
| 5605 | (or (assq 'mts ange-ftp-parse-list-func-alist) | 5533 | (or (assq 'mts ange-ftp-parse-list-func-alist) |
| @@ -5815,19 +5743,19 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5815 | ; (minidisk (ange-ftp-get-file-part dir-file)) | 5743 | ; (minidisk (ange-ftp-get-file-part dir-file)) |
| 5816 | ; (root-tbl (ange-ftp-get-hash-entry root ange-ftp-files-hashtable))) | 5744 | ; (root-tbl (ange-ftp-get-hash-entry root ange-ftp-files-hashtable))) |
| 5817 | ; (if root-tbl | 5745 | ; (if root-tbl |
| 5818 | ; (ange-ftp-put-hash-entry minidisk t root-tbl) | 5746 | ; (puthash minidisk t root-tbl) |
| 5819 | ; (setq root-tbl (ange-ftp-make-hashtable)) | 5747 | ; (setq root-tbl (ange-ftp-make-hashtable)) |
| 5820 | ; (ange-ftp-put-hash-entry minidisk t root-tbl) | 5748 | ; (puthash minidisk t root-tbl) |
| 5821 | ; (ange-ftp-put-hash-entry "." t root-tbl) | 5749 | ; (puthash "." t root-tbl) |
| 5822 | ; (ange-ftp-set-files root root-tbl))) | 5750 | ; (ange-ftp-set-files root root-tbl))) |
| 5823 | ;; Now do the usual parsing | 5751 | ;; Now do the usual parsing |
| 5824 | (let ((tbl (ange-ftp-make-hashtable))) | 5752 | (let ((tbl (make-hash-table :test 'equal))) |
| 5825 | (goto-char (point-min)) | 5753 | (goto-char (point-min)) |
| 5826 | (save-match-data | 5754 | (save-match-data |
| 5827 | (while | 5755 | (while |
| 5828 | (re-search-forward | 5756 | (re-search-forward |
| 5829 | "^\\([-A-Z0-9$_]+\\) +\\([-A-Z0-9$_]+\\) +[VF] +[0-9]+ " nil t) | 5757 | "^\\([-A-Z0-9$_]+\\) +\\([-A-Z0-9$_]+\\) +[VF] +[0-9]+ " nil t) |
| 5830 | (ange-ftp-put-hash-entry | 5758 | (puthash |
| 5831 | (concat (buffer-substring (match-beginning 1) | 5759 | (concat (buffer-substring (match-beginning 1) |
| 5832 | (match-end 1)) | 5760 | (match-end 1)) |
| 5833 | "." | 5761 | "." |
| @@ -5835,7 +5763,7 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5835 | (match-end 2))) | 5763 | (match-end 2))) |
| 5836 | nil tbl) | 5764 | nil tbl) |
| 5837 | (forward-line 1)) | 5765 | (forward-line 1)) |
| 5838 | (ange-ftp-put-hash-entry "." t tbl)) | 5766 | (puthash "." t tbl)) |
| 5839 | tbl)) | 5767 | tbl)) |
| 5840 | 5768 | ||
| 5841 | (or (assq 'cms ange-ftp-parse-list-func-alist) | 5769 | (or (assq 'cms ange-ftp-parse-list-func-alist) |
| @@ -5955,14 +5883,14 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 5955 | "^\\(" ange-ftp-bs2000-filename-pubset-regexp "\\)?" | 5883 | "^\\(" ange-ftp-bs2000-filename-pubset-regexp "\\)?" |
| 5956 | "\\(" ange-ftp-bs2000-filename-username-regexp "\\)?" | 5884 | "\\(" ange-ftp-bs2000-filename-username-regexp "\\)?" |
| 5957 | "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") | 5885 | "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") |
| 5958 | "Regular expression used in ange-ftp-fix-name-for-bs2000.") | 5886 | "Regular expression used in ange-ftp-fix-name-for-bs2000.") |
| 5959 | 5887 | ||
| 5960 | (defconst ange-ftp-bs2000-fix-name-regexp | 5888 | (defconst ange-ftp-bs2000-fix-name-regexp |
| 5961 | (concat | 5889 | (concat |
| 5962 | "/?\\(" ange-ftp-bs2000-filename-pubset-regexp "/\\)?" | 5890 | "/?\\(" ange-ftp-bs2000-filename-pubset-regexp "/\\)?" |
| 5963 | "\\(\\$[A-Z0-9]*/\\)?" | 5891 | "\\(\\$[A-Z0-9]*/\\)?" |
| 5964 | "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") | 5892 | "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") |
| 5965 | "Regular expression used in ange-ftp-fix-name-for-bs2000.") | 5893 | "Regular expression used in ange-ftp-fix-name-for-bs2000.") |
| 5966 | 5894 | ||
| 5967 | (defcustom ange-ftp-bs2000-special-prefix | 5895 | (defcustom ange-ftp-bs2000-special-prefix |
| 5968 | "X" | 5896 | "X" |
| @@ -6123,7 +6051,7 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 6123 | ;; Parse the current buffer which is assumed to be in (some) BS2000 FTP dir | 6051 | ;; Parse the current buffer which is assumed to be in (some) BS2000 FTP dir |
| 6124 | ;; format, and return a hashtable as the result. | 6052 | ;; format, and return a hashtable as the result. |
| 6125 | (defun ange-ftp-parse-bs2000-listing () | 6053 | (defun ange-ftp-parse-bs2000-listing () |
| 6126 | (let ((tbl (ange-ftp-make-hashtable)) | 6054 | (let ((tbl (make-hash-table :test 'equal)) |
| 6127 | pubset | 6055 | pubset |
| 6128 | file) | 6056 | file) |
| 6129 | ;; get current pubset | 6057 | ;; get current pubset |
| @@ -6134,14 +6062,13 @@ Other orders of $ and _ seem to all work just fine.") | |||
| 6134 | (goto-char (point-min)) | 6062 | (goto-char (point-min)) |
| 6135 | (save-match-data | 6063 | (save-match-data |
| 6136 | (while (setq file (ange-ftp-parse-bs2000-filename)) | 6064 | (while (setq file (ange-ftp-parse-bs2000-filename)) |
| 6137 | (ange-ftp-put-hash-entry file nil tbl))) | 6065 | (puthash file nil tbl))) |
| 6138 | ;; add . and .. | 6066 | ;; add . and .. |
| 6139 | (ange-ftp-put-hash-entry "." t tbl) | 6067 | (puthash "." t tbl) |
| 6140 | (ange-ftp-put-hash-entry ".." t tbl) | 6068 | (puthash ".." t tbl) |
| 6141 | ;; add all additional pubsets, if not listing one of them | 6069 | ;; add all additional pubsets, if not listing one of them |
| 6142 | (if (not (member pubset ange-ftp-bs2000-additional-pubsets)) | 6070 | (if (not (member pubset ange-ftp-bs2000-additional-pubsets)) |
| 6143 | (mapcar (function (lambda (pubset) | 6071 | (mapcar (lambda (pubset) (puthash pubset t tbl)) |
| 6144 | (ange-ftp-put-hash-entry pubset t tbl))) | ||
| 6145 | ange-ftp-bs2000-additional-pubsets)) | 6072 | ange-ftp-bs2000-additional-pubsets)) |
| 6146 | tbl)) | 6073 | tbl)) |
| 6147 | 6074 | ||
| @@ -6162,9 +6089,9 @@ be recognized automatically (they are all valid BS2000 hosts too)." | |||
| 6162 | (ange-ftp-cd host user "%POSIX") | 6089 | (ange-ftp-cd host user "%POSIX") |
| 6163 | ;; put new home directory in the expand-dir hashtable. | 6090 | ;; put new home directory in the expand-dir hashtable. |
| 6164 | ;; `host' and `user' are bound in ange-ftp-get-process. | 6091 | ;; `host' and `user' are bound in ange-ftp-get-process. |
| 6165 | (ange-ftp-put-hash-entry (concat host "/" user "/~") | 6092 | (puthash (concat host "/" user "/~") |
| 6166 | (car (ange-ftp-get-pwd host user)) | 6093 | (car (ange-ftp-get-pwd host user)) |
| 6167 | ange-ftp-expand-dir-hashtable)))) | 6094 | ange-ftp-expand-dir-hashtable)))) |
| 6168 | 6095 | ||
| 6169 | ;; Not available yet: | 6096 | ;; Not available yet: |
| 6170 | ;; ange-ftp-bs2000-delete-file-entry | 6097 | ;; ange-ftp-bs2000-delete-file-entry |