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