Mercurial > emacs
comparison lisp/net/ange-ftp.el @ 90237:aa89c814f853
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-88
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 569-579)
- Update from CVS
- Merge from gnus--rel--5.10
* gnus--rel--5.10 (patch 129-132)
- Update from CVS
- Merge from emacs--cvs-trunk--0
author | Miles Bader <miles@gnu.org> |
---|---|
date | Fri, 07 Oct 2005 07:15:40 +0000 |
parents | fa0da9b57058 967a91879fee |
children | 0ca0d9181b5e |
comparison
equal
deleted
inserted
replaced
90236:7871ecd1281b | 90237:aa89c814f853 |
---|---|
1296 (let (temp) | 1296 (let (temp) |
1297 (while (setq temp (ange-ftp-real-file-symlink-p file)) | 1297 (while (setq temp (ange-ftp-real-file-symlink-p file)) |
1298 (setq file | 1298 (setq file |
1299 (if (file-name-absolute-p temp) | 1299 (if (file-name-absolute-p temp) |
1300 temp | 1300 temp |
1301 ;; Wouldn't `expand-file-name' be better than `concat' ? | |
1302 ;; It would fail when `a/b/..' != `a', tho. --Stef | |
1301 (concat (file-name-directory file) temp))))) | 1303 (concat (file-name-directory file) temp))))) |
1302 file) | 1304 file) |
1303 | 1305 |
1304 ;; Move along current line looking for the value of the TOKEN. | 1306 ;; Move along current line looking for the value of the TOKEN. |
1305 ;; Valid separators between TOKEN and its value are commas and | 1307 ;; Valid separators between TOKEN and its value are commas and |
1383 (not (equal (nth 5 attr) ange-ftp-netrc-modtime))) ; file changed | 1385 (not (equal (nth 5 attr) ange-ftp-netrc-modtime))) ; file changed |
1384 (save-match-data | 1386 (save-match-data |
1385 (if (or ange-ftp-disable-netrc-security-check | 1387 (if (or ange-ftp-disable-netrc-security-check |
1386 (and (eq (nth 2 attr) (user-uid)) ; Same uids. | 1388 (and (eq (nth 2 attr) (user-uid)) ; Same uids. |
1387 (string-match ".r..------" (nth 8 attr)))) | 1389 (string-match ".r..------" (nth 8 attr)))) |
1388 (save-excursion | 1390 (with-current-buffer |
1389 ;; we are cheating a bit here. I'm trying to do the equivalent | 1391 ;; we are cheating a bit here. I'm trying to do the equivalent |
1390 ;; of find-file on the .netrc file, but then nuke it afterwards. | 1392 ;; of find-file on the .netrc file, but then nuke it afterwards. |
1391 ;; with the bit of logic below we should be able to have | 1393 ;; with the bit of logic below we should be able to have |
1392 ;; encrypted .netrc files. | 1394 ;; encrypted .netrc files. |
1393 (set-buffer (generate-new-buffer "*ftp-.netrc*")) | 1395 (generate-new-buffer "*ftp-.netrc*") |
1394 (ange-ftp-real-insert-file-contents file) | 1396 (ange-ftp-real-insert-file-contents file) |
1395 (setq buffer-file-name file) | 1397 (setq buffer-file-name file) |
1396 (setq default-directory (file-name-directory file)) | 1398 (setq default-directory (file-name-directory file)) |
1397 (normal-mode t) | 1399 (normal-mode t) |
1398 (run-hooks 'find-file-hook) | 1400 (run-hooks 'find-file-hook) |
1509 (interactive "bKill FTP process associated with buffer: ") | 1511 (interactive "bKill FTP process associated with buffer: ") |
1510 (if (null buffer) | 1512 (if (null buffer) |
1511 (setq buffer (current-buffer)) | 1513 (setq buffer (current-buffer)) |
1512 (setq buffer (get-buffer buffer))) | 1514 (setq buffer (get-buffer buffer))) |
1513 (let ((file (or (buffer-file-name buffer) | 1515 (let ((file (or (buffer-file-name buffer) |
1514 (save-excursion (set-buffer buffer) default-directory)))) | 1516 (with-current-buffer buffer default-directory)))) |
1515 (if file | 1517 (if file |
1516 (let ((parsed (ange-ftp-ftp-name (expand-file-name file)))) | 1518 (let ((parsed (ange-ftp-ftp-name (expand-file-name file)))) |
1517 (if parsed | 1519 (if parsed |
1518 (let ((host (nth 0 parsed)) | 1520 (let ((host (nth 0 parsed)) |
1519 (user (nth 1 parsed))) | 1521 (user (nth 1 parsed))) |
1590 "Set the size of the next FTP transfer in bytes." | 1592 "Set the size of the next FTP transfer in bytes." |
1591 (let ((proc (ange-ftp-get-process host user))) | 1593 (let ((proc (ange-ftp-get-process host user))) |
1592 (if proc | 1594 (if proc |
1593 (let ((buf (process-buffer proc))) | 1595 (let ((buf (process-buffer proc))) |
1594 (if buf | 1596 (if buf |
1595 (save-excursion | 1597 (with-current-buffer buf |
1596 (set-buffer buf) | |
1597 (setq ange-ftp-xfer-size | 1598 (setq ange-ftp-xfer-size |
1598 ;; For very large files, BYTES can be a float. | 1599 ;; For very large files, BYTES can be a float. |
1599 (if (integerp bytes) | 1600 (if (integerp bytes) |
1600 (ash bytes -10) | 1601 (ash bytes -10) |
1601 (/ bytes 1024))))))))) | 1602 (/ bytes 1024))))))))) |
1761 (defun ange-ftp-gwp-sentinel (proc str) | 1762 (defun ange-ftp-gwp-sentinel (proc str) |
1762 (setq ange-ftp-gwp-running nil)) | 1763 (setq ange-ftp-gwp-running nil)) |
1763 | 1764 |
1764 (defun ange-ftp-gwp-filter (proc str) | 1765 (defun ange-ftp-gwp-filter (proc str) |
1765 (comint-output-filter proc str) | 1766 (comint-output-filter proc str) |
1766 (save-excursion | 1767 (with-current-buffer (process-buffer proc) |
1767 (set-buffer (process-buffer proc)) | |
1768 ;; Replace STR by the result of the comint processing. | 1768 ;; Replace STR by the result of the comint processing. |
1769 (setq str (buffer-substring comint-last-output-start (process-mark proc)))) | 1769 (setq str (buffer-substring comint-last-output-start (process-mark proc)))) |
1770 (cond ((string-match "login: *$" str) | 1770 (cond ((string-match "login: *$" str) |
1771 (process-send-string proc | 1771 (process-send-string proc |
1772 (concat | 1772 (concat |
1798 ange-ftp-gateway-host))) | 1798 ange-ftp-gateway-host))) |
1799 (ftp (mapconcat 'identity args " "))) | 1799 (ftp (mapconcat 'identity args " "))) |
1800 (set-process-query-on-exit-flag proc nil) | 1800 (set-process-query-on-exit-flag proc nil) |
1801 (set-process-sentinel proc 'ange-ftp-gwp-sentinel) | 1801 (set-process-sentinel proc 'ange-ftp-gwp-sentinel) |
1802 (set-process-filter proc 'ange-ftp-gwp-filter) | 1802 (set-process-filter proc 'ange-ftp-gwp-filter) |
1803 (save-excursion | 1803 (with-current-buffer (process-buffer proc) |
1804 (set-buffer (process-buffer proc)) | |
1805 (goto-char (point-max)) | 1804 (goto-char (point-max)) |
1806 (set-marker (process-mark proc) (point))) | 1805 (set-marker (process-mark proc) (point))) |
1807 (setq ange-ftp-gwp-running t | 1806 (setq ange-ftp-gwp-running t |
1808 ange-ftp-gwp-status nil) | 1807 ange-ftp-gwp-status nil) |
1809 (ange-ftp-message "Connecting to gateway %s..." ange-ftp-gateway-host) | 1808 (ange-ftp-message "Connecting to gateway %s..." ange-ftp-gateway-host) |
1905 (proc (let ((process-connection-type t)) | 1904 (proc (let ((process-connection-type t)) |
1906 (start-process " *nslookup*" " *nslookup*" | 1905 (start-process " *nslookup*" " *nslookup*" |
1907 ange-ftp-nslookup-program host))) | 1906 ange-ftp-nslookup-program host))) |
1908 (res host)) | 1907 (res host)) |
1909 (set-process-query-on-exit-flag proc nil) | 1908 (set-process-query-on-exit-flag proc nil) |
1910 (save-excursion | 1909 (with-current-buffer (process-buffer proc) |
1911 (set-buffer (process-buffer proc)) | |
1912 (while (memq (process-status proc) '(run open)) | 1910 (while (memq (process-status proc) '(run open)) |
1913 (accept-process-output proc)) | 1911 (accept-process-output proc)) |
1914 (goto-char (point-min)) | 1912 (goto-char (point-min)) |
1915 (if (re-search-forward "Name:.*\nAddress: *\\(.*\\)$" nil t) | 1913 (if (re-search-forward "Name:.*\nAddress: *\\(.*\\)$" nil t) |
1916 (setq res (match-string 1))) | 1914 (setq res (match-string 1))) |
1945 ;; Can anyone find a fix for that? | 1943 ;; Can anyone find a fix for that? |
1946 (let ((process-connection-type t) | 1944 (let ((process-connection-type t) |
1947 ;; Copy this so we don't alter it permanently. | 1945 ;; Copy this so we don't alter it permanently. |
1948 (process-environment (copy-tree process-environment)) | 1946 (process-environment (copy-tree process-environment)) |
1949 (buffer (get-buffer-create name))) | 1947 (buffer (get-buffer-create name))) |
1950 (save-excursion | 1948 (with-current-buffer buffer |
1951 (set-buffer buffer) | |
1952 (internal-ange-ftp-mode)) | 1949 (internal-ange-ftp-mode)) |
1953 ;; This tells GNU ftp not to output any fancy escape sequences. | 1950 ;; This tells GNU ftp not to output any fancy escape sequences. |
1954 (setenv "TERM" "dumb") | 1951 (setenv "TERM" "dumb") |
1955 (if use-gateway | 1952 (if use-gateway |
1956 (if ange-ftp-gateway-program-interactive | 1953 (if ange-ftp-gateway-program-interactive |
1958 (setq proc (apply 'start-process name name | 1955 (setq proc (apply 'start-process name name |
1959 (append (list ange-ftp-gateway-program | 1956 (append (list ange-ftp-gateway-program |
1960 ange-ftp-gateway-host) | 1957 ange-ftp-gateway-host) |
1961 args)))) | 1958 args)))) |
1962 (setq proc (apply 'start-process name name args)))) | 1959 (setq proc (apply 'start-process name name args)))) |
1963 (save-excursion | 1960 (with-current-buffer (process-buffer proc) |
1964 (set-buffer (process-buffer proc)) | |
1965 (goto-char (point-max)) | 1961 (goto-char (point-max)) |
1966 (set-marker (process-mark proc) (point))) | 1962 (set-marker (process-mark proc) (point))) |
1967 (set-process-query-on-exit-flag proc nil) | 1963 (set-process-query-on-exit-flag proc nil) |
1968 (set-process-sentinel proc 'ange-ftp-process-sentinel) | 1964 (set-process-sentinel proc 'ange-ftp-process-sentinel) |
1969 (set-process-filter proc 'ange-ftp-process-filter) | 1965 (set-process-filter proc 'ange-ftp-process-filter) |
2125 "[hH]ash mark [^0-9]*\\([0-9]+\\)" | 2121 "[hH]ash mark [^0-9]*\\([0-9]+\\)" |
2126 "*Regexp matching the FTP client's output upon doing a HASH command.") | 2122 "*Regexp matching the FTP client's output upon doing a HASH command.") |
2127 | 2123 |
2128 (defun ange-ftp-guess-hash-mark-size (proc) | 2124 (defun ange-ftp-guess-hash-mark-size (proc) |
2129 (if ange-ftp-send-hash | 2125 (if ange-ftp-send-hash |
2130 (save-excursion | 2126 (with-current-buffer (process-buffer proc) |
2131 (set-buffer (process-buffer proc)) | |
2132 (let* ((status (ange-ftp-raw-send-cmd proc "hash")) | 2127 (let* ((status (ange-ftp-raw-send-cmd proc "hash")) |
2133 (line (cdr status))) | 2128 (line (cdr status))) |
2134 (save-match-data | 2129 (save-match-data |
2135 (if (string-match ange-ftp-hash-mark-msgs line) | 2130 (if (string-match ange-ftp-hash-mark-msgs line) |
2136 (let ((size (string-to-number (match-string 1 line)))) | 2131 (let ((size (string-to-number (match-string 1 line)))) |
2306 (and (eq host-type 'unix) | 2301 (and (eq host-type 'unix) |
2307 (string-match "/\\'" cmd1) | 2302 (string-match "/\\'" cmd1) |
2308 (not (string-match "R" cmd3)) | 2303 (not (string-match "R" cmd3)) |
2309 (setq cmd1 (concat cmd1 "."))) | 2304 (setq cmd1 (concat cmd1 "."))) |
2310 | 2305 |
2306 ;; Using "ls -flags foo" has several problems: | |
2307 ;; - if foo is a symlink, we may get a single line showing the symlink | |
2308 ;; rather than the listing of the directory it points to. | |
2309 ;; - if "foo" has spaces, the parsing of the command may be done wrong. | |
2310 ;; - some version of netbsd's ftpd only accept a single argument after | |
2311 ;; `ls', which can either be the directory or the flags. | |
2312 ;; So to work around those problems, we use "cd foo; ls -flags". | |
2313 | |
2311 ;; If the dir name contains a space, some ftp servers will | 2314 ;; If the dir name contains a space, some ftp servers will |
2312 ;; refuse to list it. We instead change directory to the | 2315 ;; refuse to list it. We instead change directory to the |
2313 ;; directory in question and ls ".". | 2316 ;; directory in question and ls ".". |
2314 (when (string-match " " cmd1) | 2317 (when (string-match " " cmd1) |
2315 ;; Keep the result. In case of failure, we will (see below) | 2318 ;; Keep the result. In case of failure, we will (see below) |
2322 (setq cmd0 'ls) | 2325 (setq cmd0 'ls) |
2323 ;; We cd and then use `ls' with no directory argument. | 2326 ;; We cd and then use `ls' with no directory argument. |
2324 ;; This works around a misfeature of some versions of netbsd ftpd | 2327 ;; This works around a misfeature of some versions of netbsd ftpd |
2325 ;; where `ls' can only take one argument: either one set of flags | 2328 ;; where `ls' can only take one argument: either one set of flags |
2326 ;; or a file/directory name. | 2329 ;; or a file/directory name. |
2327 ;; FIXME: if we're trying to `ls' a single file, this fails since we | 2330 ;; If we're trying to `ls' a single file, this fails since we |
2328 ;; can't cd to a file. We can't fix this problem here, tho, because | 2331 ;; can't cd to a file. We can't fix this problem here, tho, because |
2329 ;; at this point we don't know whether the argument is a file or | 2332 ;; at this point we don't know whether the argument is a file or |
2330 ;; a directory. Such an `ls' is only every used (apparently) from | 2333 ;; a directory. Such an `ls' is only ever used (apparently) from |
2331 ;; `insert-directory' when the `full-directory-p' argument is nil | 2334 ;; `insert-directory' when the `full-directory-p' argument is nil |
2332 ;; (which seems to only be used by dired when updating its display | 2335 ;; (which seems to only be used by dired when updating its display |
2333 ;; after operating on a set of files). We should change | 2336 ;; after operating on a set of files). So we've changed |
2334 ;; ange-ftp-insert-directory so that this case is handled by getting | 2337 ;; `ange-ftp-insert-directory' such that in this case it gets |
2335 ;; a full listing of the directory and extracting the line | 2338 ;; a full listing of the directory and extracting the line |
2336 ;; corresponding to the requested file. | 2339 ;; corresponding to the requested file. |
2337 (unless (equal cmd1 ".") | 2340 (unless (equal cmd1 ".") |
2338 (setq result (ange-ftp-cd host user (nth 1 cmd) 'noerror))) | 2341 (setq result (ange-ftp-cd host user (nth 1 cmd) 'noerror))) |
2339 (setq cmd1 cmd3))) | 2342 (setq cmd1 cmd3))) |
2604 user | 2607 user |
2605 lscmd | 2608 lscmd |
2606 (format "Listing %s" | 2609 (format "Listing %s" |
2607 (ange-ftp-abbreviate-filename | 2610 (ange-ftp-abbreviate-filename |
2608 ange-ftp-this-file))))) | 2611 ange-ftp-this-file))))) |
2609 (save-excursion | 2612 (with-current-buffer (get-buffer-create |
2610 (set-buffer (get-buffer-create | 2613 ange-ftp-data-buffer-name) |
2611 ange-ftp-data-buffer-name)) | |
2612 (erase-buffer) | 2614 (erase-buffer) |
2613 (if (ange-ftp-real-file-readable-p temp) | 2615 (if (ange-ftp-real-file-readable-p temp) |
2614 (ange-ftp-real-insert-file-contents temp) | 2616 (ange-ftp-real-insert-file-contents temp) |
2615 (sleep-for ange-ftp-retry-time) | 2617 (sleep-for ange-ftp-retry-time) |
2616 ;wait for file to possibly appear | 2618 ;wait for file to possibly appear |
3020 (defun ange-ftp-set-binary-mode (host user) | 3022 (defun ange-ftp-set-binary-mode (host user) |
3021 "Tell the ftp process for the given HOST & USER to switch to binary mode." | 3023 "Tell the ftp process for the given HOST & USER to switch to binary mode." |
3022 (let ((result (ange-ftp-send-cmd host user '(type "binary")))) | 3024 (let ((result (ange-ftp-send-cmd host user '(type "binary")))) |
3023 (if (not (car result)) | 3025 (if (not (car result)) |
3024 (ange-ftp-error host user (concat "BINARY failed: " (cdr result))) | 3026 (ange-ftp-error host user (concat "BINARY failed: " (cdr result))) |
3025 (save-excursion | 3027 (with-current-buffer (process-buffer (ange-ftp-get-process host user)) |
3026 (set-buffer (process-buffer (ange-ftp-get-process host user))) | |
3027 (and ange-ftp-binary-hash-mark-size | 3028 (and ange-ftp-binary-hash-mark-size |
3028 (setq ange-ftp-hash-mark-unit | 3029 (setq ange-ftp-hash-mark-unit |
3029 (ash ange-ftp-binary-hash-mark-size -4))))))) | 3030 (ash ange-ftp-binary-hash-mark-size -4))))))) |
3030 | 3031 |
3031 (defun ange-ftp-set-ascii-mode (host user) | 3032 (defun ange-ftp-set-ascii-mode (host user) |
3032 "Tell the ftp process for the given HOST & USER to switch to ascii mode." | 3033 "Tell the ftp process for the given HOST & USER to switch to ascii mode." |
3033 (let ((result (ange-ftp-send-cmd host user '(type "ascii")))) | 3034 (let ((result (ange-ftp-send-cmd host user '(type "ascii")))) |
3034 (if (not (car result)) | 3035 (if (not (car result)) |
3035 (ange-ftp-error host user (concat "ASCII failed: " (cdr result))) | 3036 (ange-ftp-error host user (concat "ASCII failed: " (cdr result))) |
3036 (save-excursion | 3037 (with-current-buffer (process-buffer (ange-ftp-get-process host user)) |
3037 (set-buffer (process-buffer (ange-ftp-get-process host user))) | |
3038 (and ange-ftp-ascii-hash-mark-size | 3038 (and ange-ftp-ascii-hash-mark-size |
3039 (setq ange-ftp-hash-mark-unit | 3039 (setq ange-ftp-hash-mark-unit |
3040 (ash ange-ftp-ascii-hash-mark-size -4))))))) | 3040 (ash ange-ftp-ascii-hash-mark-size -4))))))) |
3041 | 3041 |
3042 (defun ange-ftp-cd (host user dir &optional noerror) | 3042 (defun ange-ftp-cd (host user dir &optional noerror) |
3172 (ange-ftp-real-expand-file-name | 3172 (ange-ftp-real-expand-file-name |
3173 (ange-ftp-real-file-name-nondirectory n) | 3173 (ange-ftp-real-file-name-nondirectory n) |
3174 (ange-ftp-real-file-name-directory n)))))) | 3174 (ange-ftp-real-file-name-directory n)))))) |
3175 | 3175 |
3176 (defun ange-ftp-expand-file-name (name &optional default) | 3176 (defun ange-ftp-expand-file-name (name &optional default) |
3177 "Documented as original." | 3177 "Documented as `expand-file-name'." |
3178 (save-match-data | 3178 (save-match-data |
3179 (setq default (or default default-directory)) | 3179 (setq default (or default default-directory)) |
3180 (cond ((eq (string-to-char name) ?~) | 3180 (cond ((eq (string-to-char name) ?~) |
3181 (ange-ftp-real-expand-file-name name)) | 3181 (ange-ftp-real-expand-file-name name)) |
3182 ((eq (string-to-char name) ?/) | 3182 ((eq (string-to-char name) ?/) |
3287 (or visit 'quiet)) | 3287 (or visit 'quiet)) |
3288 (setq coding-system-used last-coding-system-used)) | 3288 (setq coding-system-used last-coding-system-used)) |
3289 ;; cleanup forms | 3289 ;; cleanup forms |
3290 (setq coding-system-used last-coding-system-used) | 3290 (setq coding-system-used last-coding-system-used) |
3291 (setq buffer-file-name filename) | 3291 (setq buffer-file-name filename) |
3292 (set-buffer-modified-p mod-p))) | 3292 (restore-buffer-modified-p mod-p))) |
3293 (if binary | 3293 (if binary |
3294 (ange-ftp-set-binary-mode host user)) | 3294 (ange-ftp-set-binary-mode host user)) |
3295 | 3295 |
3296 ;; tell the process filter what size the transfer will be. | 3296 ;; tell the process filter what size the transfer will be. |
3297 (let ((attr (file-attributes temp))) | 3297 (let ((attr (file-attributes temp))) |
3446 ;; machines (VMS) use a .DIR to indicate the filename associated | 3446 ;; machines (VMS) use a .DIR to indicate the filename associated |
3447 ;; with a directory. This needs to be canonicalized. | 3447 ;; with a directory. This needs to be canonicalized. |
3448 (let ((file-ent (ange-ftp-get-file-entry | 3448 (let ((file-ent (ange-ftp-get-file-entry |
3449 (ange-ftp-file-name-as-directory name)))) | 3449 (ange-ftp-file-name-as-directory name)))) |
3450 (if (stringp file-ent) | 3450 (if (stringp file-ent) |
3451 (file-directory-p | 3451 ;; Calling file-directory-p doesn't work because ange-ftp |
3452 ;; is temporarily disabled for this operation. | |
3453 (ange-ftp-file-directory-p | |
3452 (ange-ftp-expand-symlink file-ent | 3454 (ange-ftp-expand-symlink file-ent |
3453 (file-name-directory | 3455 (file-name-directory |
3454 (directory-file-name name)))) | 3456 (directory-file-name name)))) |
3455 file-ent)) | 3457 file-ent)) |
3456 (ange-ftp-real-file-directory-p name))) | 3458 (ange-ftp-real-file-directory-p name))) |
3638 ;; (process-kill-without-query proc) | 3640 ;; (process-kill-without-query proc) |
3639 ;; (with-current-buffer (process-buffer proc) | 3641 ;; (with-current-buffer (process-buffer proc) |
3640 ;; (set (make-local-variable 'copy-cont) cont)))) | 3642 ;; (set (make-local-variable 'copy-cont) cont)))) |
3641 ;; | 3643 ;; |
3642 ;; (defun ange-ftp-copy-file-locally-sentinel (proc status) | 3644 ;; (defun ange-ftp-copy-file-locally-sentinel (proc status) |
3643 ;; (save-excursion | 3645 ;; (with-current-buffer (process-buffer proc) |
3644 ;; (set-buffer (process-buffer proc)) | |
3645 ;; (let ((cont copy-cont) | 3646 ;; (let ((cont copy-cont) |
3646 ;; (result (buffer-string))) | 3647 ;; (result (buffer-string))) |
3647 ;; (unwind-protect | 3648 ;; (unwind-protect |
3648 ;; (if (and (string-equal status "finished\n") | 3649 ;; (if (and (string-equal status "finished\n") |
3649 ;; (zerop (length result))) | 3650 ;; (zerop (length result))) |
4474 | 4475 |
4475 ;; When called from dired, SWITCHES may start with "--dired". | 4476 ;; When called from dired, SWITCHES may start with "--dired". |
4476 ;; `ange-ftp-ls' handles this. | 4477 ;; `ange-ftp-ls' handles this. |
4477 | 4478 |
4478 (defun ange-ftp-insert-directory (file switches &optional wildcard full) | 4479 (defun ange-ftp-insert-directory (file switches &optional wildcard full) |
4479 (let ((parsed (ange-ftp-ftp-name (expand-file-name file))) | 4480 (if (not (ange-ftp-ftp-name (expand-file-name file))) |
4480 tem) | 4481 (ange-ftp-real-insert-directory file switches wildcard full) |
4481 (if parsed | 4482 ;; We used to follow symlinks on `file' here. Apparently it was done |
4482 (if (and (not wildcard) | 4483 ;; because some FTP servers react to "ls foo" by listing the symlink foo |
4483 (setq tem (file-symlink-p (directory-file-name file)))) | 4484 ;; rather than the directory it points to. Now that ange-ftp-ls uses |
4484 (ange-ftp-insert-directory | 4485 ;; "cd foo; ls" instead, this is not necesssary any more. |
4485 (ange-ftp-expand-symlink | 4486 (insert |
4486 tem (file-name-directory (directory-file-name file))) | 4487 (cond |
4487 switches wildcard full) | 4488 (wildcard |
4488 (insert | 4489 (let ((default-directory (file-name-directory file))) |
4489 (if wildcard | 4490 (ange-ftp-ls (file-name-nondirectory file) switches nil nil t))) |
4490 (let ((default-directory (file-name-directory file))) | 4491 (full |
4491 (ange-ftp-ls (file-name-nondirectory file) switches nil nil t)) | 4492 (ange-ftp-ls file switches 'parse)) |
4492 (ange-ftp-ls file switches full)))) | 4493 (t |
4493 (ange-ftp-real-insert-directory file switches wildcard full)))) | 4494 ;; If `full' is nil we're going to do `ls' for a single file. |
4495 ;; Problem is that for various reasons, ange-ftp-ls needs to cd and | |
4496 ;; then do an ls of current dir, which obviously won't work if we | |
4497 ;; want to ls a file. So instead, we get a full listing of the | |
4498 ;; parent directory and extract the line corresponding to `file'. | |
4499 (when (string-match "d\\'" switches) | |
4500 ;; Remove "d" which dired added to `switches'. | |
4501 (setq switches (substring switches 0 (match-beginning 0)))) | |
4502 (let* ((dirlist (ange-ftp-ls (or (file-name-directory file) ".") | |
4503 switches nil)) | |
4504 (filename (file-name-nondirectory (directory-file-name file))) | |
4505 (case-fold-search nil)) | |
4506 ;; FIXME: This presumes a particular output format, which is | |
4507 ;; basically Unix. | |
4508 (if (string-match (concat "^.+[^ ] " (regexp-quote filename) | |
4509 "\\( -> .*\\)?[@/*=]?\n") dirlist) | |
4510 (match-string 0 dirlist) | |
4511 ""))))))) | |
4494 | 4512 |
4495 (defun ange-ftp-dired-uncache (dir) | 4513 (defun ange-ftp-dired-uncache (dir) |
4496 (if (ange-ftp-ftp-name (expand-file-name dir)) | 4514 (if (ange-ftp-ftp-name (expand-file-name dir)) |
4497 (setq ange-ftp-ls-cache-file nil))) | 4515 (setq ange-ftp-ls-cache-file nil))) |
4498 | 4516 |
4500 "Alist of mapping host type into function to remove file version numbers.") | 4518 "Alist of mapping host type into function to remove file version numbers.") |
4501 | 4519 |
4502 (defun ange-ftp-file-name-sans-versions (file keep-backup-version) | 4520 (defun ange-ftp-file-name-sans-versions (file keep-backup-version) |
4503 (let* ((short (ange-ftp-abbreviate-filename file)) | 4521 (let* ((short (ange-ftp-abbreviate-filename file)) |
4504 (parsed (ange-ftp-ftp-name short)) | 4522 (parsed (ange-ftp-ftp-name short)) |
4505 func) | 4523 (func (if parsed (cdr (assq (ange-ftp-host-type (car parsed)) |
4506 (if parsed | 4524 ange-ftp-sans-version-alist))))) |
4507 (setq func (cdr (assq (ange-ftp-host-type (car parsed)) | |
4508 ange-ftp-sans-version-alist)))) | |
4509 (if func (funcall func file keep-backup-version) | 4525 (if func (funcall func file keep-backup-version) |
4510 (ange-ftp-real-file-name-sans-versions file keep-backup-version)))) | 4526 (ange-ftp-real-file-name-sans-versions file keep-backup-version)))) |
4511 | 4527 |
4512 ;; This is the handler for shell-command. | 4528 ;; This is the handler for shell-command. |
4513 (defun ange-ftp-shell-command (command &optional output-buffer error-buffer) | 4529 (defun ange-ftp-shell-command (command &optional output-buffer error-buffer) |
4647 | 4663 |
4648 ;;(defun ange-ftp-dcf-1 (file-creator operation fn-list name-constructor | 4664 ;;(defun ange-ftp-dcf-1 (file-creator operation fn-list name-constructor |
4649 ;; target marker-char buffer overwrite-query | 4665 ;; target marker-char buffer overwrite-query |
4650 ;; overwrite-backup-query failures skipped | 4666 ;; overwrite-backup-query failures skipped |
4651 ;; success-count total) | 4667 ;; success-count total) |
4652 ;; (let ((old-buf (current-buffer))) | 4668 ;; (with-current-buffer buffer |
4653 ;; (unwind-protect | |
4654 ;; (progn | |
4655 ;; (set-buffer buffer) | |
4656 ;; (if (null fn-list) | 4669 ;; (if (null fn-list) |
4657 ;; (ange-ftp-dcf-3 failures operation total skipped | 4670 ;; (ange-ftp-dcf-3 failures operation total skipped |
4658 ;; success-count buffer) | 4671 ;; success-count buffer) |
4659 | 4672 |
4660 ;; (let* ((from (car fn-list)) | 4673 ;; (let* ((from (car fn-list)) |
4722 ;; overwrite | 4735 ;; overwrite |
4723 ;; overwrite-confirmed | 4736 ;; overwrite-confirmed |
4724 ;; overwrite-query | 4737 ;; overwrite-query |
4725 ;; overwrite-backup-query | 4738 ;; overwrite-backup-query |
4726 ;; failures skipped success-count | 4739 ;; failures skipped success-count |
4727 ;; total)))))))) | 4740 ;; total))))))))) |
4728 ;; (set-buffer old-buf)))) | |
4729 | 4741 |
4730 ;;(defun ange-ftp-dcf-2 (result line err | 4742 ;;(defun ange-ftp-dcf-2 (result line err |
4731 ;; file-creator operation fn-list | 4743 ;; file-creator operation fn-list |
4732 ;; name-constructor | 4744 ;; name-constructor |
4733 ;; target | 4745 ;; target |
4737 ;; overwrite-confirmed | 4749 ;; overwrite-confirmed |
4738 ;; overwrite-query | 4750 ;; overwrite-query |
4739 ;; overwrite-backup-query | 4751 ;; overwrite-backup-query |
4740 ;; failures skipped success-count | 4752 ;; failures skipped success-count |
4741 ;; total) | 4753 ;; total) |
4742 ;; (let ((old-buf (current-buffer))) | 4754 ;; (with-current-buffer buffer |
4743 ;; (unwind-protect | |
4744 ;; (progn | |
4745 ;; (set-buffer buffer) | |
4746 ;; (if (or err (not result)) | 4755 ;; (if (or err (not result)) |
4747 ;; (progn | 4756 ;; (progn |
4748 ;; (setq failures (cons (dired-make-relative from) failures)) | 4757 ;; (setq failures (cons (dired-make-relative from) failures)) |
4749 ;; (dired-log "%s `%s' to `%s' failed:\n%s\n" | 4758 ;; (dired-log "%s `%s' to `%s' failed:\n%s\n" |
4750 ;; operation from to (or err line))) | 4759 ;; operation from to (or err line))) |
4763 ;; marker-char | 4772 ;; marker-char |
4764 ;; buffer | 4773 ;; buffer |
4765 ;; overwrite-query | 4774 ;; overwrite-query |
4766 ;; overwrite-backup-query | 4775 ;; overwrite-backup-query |
4767 ;; failures skipped success-count | 4776 ;; failures skipped success-count |
4768 ;; total)) | 4777 ;; total))) |
4769 ;; (set-buffer old-buf)))) | |
4770 | 4778 |
4771 ;;(defun ange-ftp-dcf-3 (failures operation total skipped success-count | 4779 ;;(defun ange-ftp-dcf-3 (failures operation total skipped success-count |
4772 ;; buffer) | 4780 ;; buffer) |
4773 ;; (let ((old-buf (current-buffer))) | 4781 ;; (with-current-buffer buffer |
4774 ;; (unwind-protect | |
4775 ;; (progn | |
4776 ;; (set-buffer buffer) | |
4777 ;; (cond | 4782 ;; (cond |
4778 ;; (failures | 4783 ;; (failures |
4779 ;; (dired-log-summary | 4784 ;; (dired-log-summary |
4780 ;; (message "%s failed for %d of %d file%s %s" | 4785 ;; (message "%s failed for %d of %d file%s %s" |
4781 ;; operation (length failures) total | 4786 ;; operation (length failures) total |
4786 ;; operation (length skipped) total | 4791 ;; operation (length skipped) total |
4787 ;; (dired-plural-s total) skipped))) | 4792 ;; (dired-plural-s total) skipped))) |
4788 ;; (t | 4793 ;; (t |
4789 ;; (message "%s: %s file%s." | 4794 ;; (message "%s: %s file%s." |
4790 ;; operation success-count (dired-plural-s success-count)))) | 4795 ;; operation success-count (dired-plural-s success-count)))) |
4791 ;; (dired-move-to-filename)) | 4796 ;; (dired-move-to-filename))) |
4792 ;; (set-buffer old-buf)))) | |
4793 | 4797 |
4794 ;;;; ----------------------------------------------- | 4798 ;;;; ----------------------------------------------- |
4795 ;;;; Unix Descriptive Listing (dl) Support | 4799 ;;;; Unix Descriptive Listing (dl) Support |
4796 ;;;; ----------------------------------------------- | 4800 ;;;; ----------------------------------------------- |
4797 | 4801 |