Mercurial > emacs
changeset 105690:8d8fc5285759
* net/tramp-smb.el (tramp-smb-get-stat-capability): New defun.
(tramp-smb-handle-file-attributes): Use it.
(tramp-smb-do-file-attributes-with-stat): Don't raise an error.
(tramp-smb-handle-insert-directory): Use `mapc' rather than
`mapcar'. Use `tramp-smb-get-stat-capability'. Add
`dired-filename' text properties.
(tramp-smb-get-cifs-capabilities): Apply `save-match-data'.
(tramp-smb-maybe-open-connection): Simplify check for smbclient
version.
author | Michael Albinus <michael.albinus@gmx.de> |
---|---|
date | Wed, 21 Oct 2009 11:27:26 +0000 |
parents | d81a8bc83c5e |
children | ed970ee2fe76 |
files | lisp/net/tramp-smb.el |
diffstat | 1 files changed, 109 insertions(+), 105 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/net/tramp-smb.el Tue Oct 20 14:03:48 2009 +0000 +++ b/lisp/net/tramp-smb.el Wed Oct 21 11:27:26 2009 +0000 @@ -481,7 +481,7 @@ (unless id-format (setq id-format 'integer)) (with-parsed-tramp-file-name filename nil (with-file-property v localname (format "file-attributes-%s" id-format) - (if (and (tramp-smb-get-share v) (tramp-smb-get-cifs-capabilities v)) + (if (and (tramp-smb-get-share v) (tramp-smb-get-stat-capability v)) (tramp-smb-do-file-attributes-with-stat v id-format) ;; Reading just the filename entry via "dir localname" is not ;; possible, because when filename is a directory, some @@ -519,71 +519,64 @@ vec 5 "file attributes with stat: %s" (tramp-file-name-localname vec)) (with-current-buffer (tramp-get-buffer vec) (let* (size id link uid gid atime mtime ctime mode inode) - (unless - (tramp-smb-send-command - vec (format "stat \"%s\"" (tramp-smb-get-localname vec))) - ;; Error. - (with-current-buffer (tramp-get-connection-buffer vec) - (goto-char (point-min)) - (search-forward-regexp tramp-smb-errors nil t) - (tramp-error - vec 'file-error "%s" (match-string 0)))) + (when (tramp-smb-send-command + vec (format "stat \"%s\"" (tramp-smb-get-localname vec))) - ;; Loop the listing. - (goto-char (point-min)) - (unless (re-search-forward tramp-smb-errors nil t) - (while (not (eobp)) - (cond - ((looking-at - "Size:\\s-+\\([0-9]+\\)\\s-+Blocks:\\s-+[0-9]+\\s-+\\(\\w+\\)") - (setq size (string-to-number (match-string 1)) - id (if (string-equal "directory" (match-string 2)) t - (if (string-equal "symbolic" (match-string 2)) "")))) - ((looking-at - "Inode:\\s-+\\([0-9]+\\)\\s-+Links:\\s-+\\([0-9]+\\)") - (setq inode (string-to-number (match-string 1)) - link (string-to-number (match-string 2)))) - ((looking-at - "Access:\\s-+([0-9]+/\\(\\S-+\\))\\s-+Uid:\\s-+\\([0-9]+\\)\\s-+Gid:\\s-+\\([0-9]+\\)") - (setq mode (match-string 1) - uid (if (equal id-format 'string) (match-string 2) - (string-to-number (match-string 2))) - gid (if (equal id-format 'string) (match-string 3) - (string-to-number (match-string 3))))) - ((looking-at - "Access:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") - (setq atime - (encode-time - (string-to-number (match-string 6)) ;; sec - (string-to-number (match-string 5)) ;; min - (string-to-number (match-string 4)) ;; hour - (string-to-number (match-string 3)) ;; day - (string-to-number (match-string 2)) ;; month - (string-to-number (match-string 1))))) ;; year - ((looking-at - "Modify:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") - (setq mtime - (encode-time - (string-to-number (match-string 6)) ;; sec - (string-to-number (match-string 5)) ;; min - (string-to-number (match-string 4)) ;; hour - (string-to-number (match-string 3)) ;; day - (string-to-number (match-string 2)) ;; month - (string-to-number (match-string 1))))) ;; year - ((looking-at - "Change:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") - (setq ctime - (encode-time - (string-to-number (match-string 6)) ;; sec - (string-to-number (match-string 5)) ;; min - (string-to-number (match-string 4)) ;; hour - (string-to-number (match-string 3)) ;; day - (string-to-number (match-string 2)) ;; month - (string-to-number (match-string 1)))))) ;; year - (forward-line)) - ;; Return the result. - (list id link uid gid atime mtime ctime size mode nil inode - (tramp-get-device vec)))))) + ;; Loop the listing. + (goto-char (point-min)) + (unless (re-search-forward tramp-smb-errors nil t) + (while (not (eobp)) + (cond + ((looking-at + "Size:\\s-+\\([0-9]+\\)\\s-+Blocks:\\s-+[0-9]+\\s-+\\(\\w+\\)") + (setq size (string-to-number (match-string 1)) + id (if (string-equal "directory" (match-string 2)) t + (if (string-equal "symbolic" (match-string 2)) "")))) + ((looking-at + "Inode:\\s-+\\([0-9]+\\)\\s-+Links:\\s-+\\([0-9]+\\)") + (setq inode (string-to-number (match-string 1)) + link (string-to-number (match-string 2)))) + ((looking-at + "Access:\\s-+([0-9]+/\\(\\S-+\\))\\s-+Uid:\\s-+\\([0-9]+\\)\\s-+Gid:\\s-+\\([0-9]+\\)") + (setq mode (match-string 1) + uid (if (equal id-format 'string) (match-string 2) + (string-to-number (match-string 2))) + gid (if (equal id-format 'string) (match-string 3) + (string-to-number (match-string 3))))) + ((looking-at + "Access:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") + (setq atime + (encode-time + (string-to-number (match-string 6)) ;; sec + (string-to-number (match-string 5)) ;; min + (string-to-number (match-string 4)) ;; hour + (string-to-number (match-string 3)) ;; day + (string-to-number (match-string 2)) ;; month + (string-to-number (match-string 1))))) ;; year + ((looking-at + "Modify:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") + (setq mtime + (encode-time + (string-to-number (match-string 6)) ;; sec + (string-to-number (match-string 5)) ;; min + (string-to-number (match-string 4)) ;; hour + (string-to-number (match-string 3)) ;; day + (string-to-number (match-string 2)) ;; month + (string-to-number (match-string 1))))) ;; year + ((looking-at + "Change:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") + (setq ctime + (encode-time + (string-to-number (match-string 6)) ;; sec + (string-to-number (match-string 5)) ;; min + (string-to-number (match-string 4)) ;; hour + (string-to-number (match-string 3)) ;; day + (string-to-number (match-string 2)) ;; month + (string-to-number (match-string 1)))))) ;; year + (forward-line)) + ;; Return the result. + (list id link uid gid atime mtime ctime size mode nil inode + (tramp-get-device vec))))))) (defun tramp-smb-handle-file-directory-p (filename) "Like `file-directory-p' for Tramp files." @@ -709,30 +702,33 @@ entries)) ;; Print entries. - (mapcar + (mapc (lambda (x) (when (not (zerop (length (nth 0 x)))) (let ((attr - (when (tramp-smb-get-cifs-capabilities v) + (when (tramp-smb-get-stat-capability v) (ignore-errors (file-attributes (expand-file-name (nth 0 x)) 'string))))) (insert (format - "%10s %3d %-8s %-8s %8s %s %s\n" + "%10s %3d %-8s %-8s %8s %s " (or (nth 8 attr) (nth 1 x)) ; mode - (or (nth 1 attr) 1) ; link + (or (nth 1 attr) 1) ; inode (or (nth 2 attr) "nobody") ; uid (or (nth 3 attr) "nogroup") ; gid - (nth 2 x) ; size + (or (nth 7 attr) (nth 2 x)) ; size (format-time-string (if (tramp-time-less-p (tramp-time-subtract (current-time) (nth 3 x)) tramp-half-a-year) "%b %e %R" "%b %e %Y") - (nth 3 x)) ; date - (nth 0 x))) ; file name + (nth 3 x)))) ; date + ;; We mark the filename. + (let ((start (point))) + (insert (format "%s\n" (nth 0 x))) ; file name + (put-text-property start (1- (point)) 'dired-filename t)) (forward-line) (beginning-of-line)))) entries))))) @@ -1171,15 +1167,26 @@ (and p (processp p) (memq (process-status p) '(run open)))) (with-connection-property (tramp-get-connection-process vec) "cifs-capabilities" - (when (tramp-smb-send-command vec "posix") - (with-current-buffer (tramp-get-buffer vec) - (goto-char (point-min)) - (when (re-search-forward "Server supports CIFS capabilities" nil t) - (member - "pathnames" - (split-string - (buffer-substring - (point) (tramp-compat-line-end-position)) nil t)))))))) + (save-match-data + (when (tramp-smb-send-command vec "posix") + (with-current-buffer (tramp-get-buffer vec) + (goto-char (point-min)) + (when + (re-search-forward "Server supports CIFS capabilities" nil t) + (member + "pathnames" + (split-string + (buffer-substring + (point) (tramp-compat-line-end-position)) nil t))))))))) + +(defun tramp-smb-get-stat-capability (vec) + "Check, whether the SMB server supports the STAT command." + ;; When we are not logged in yet, we return nil. + (if (let ((p (tramp-get-connection-process vec))) + (and p (processp p) (memq (process-status p) '(run open)))) + (with-connection-property + (tramp-get-connection-process vec) "stat-capability" + (tramp-smb-send-command vec "stat .")))) ;; Connection functions. @@ -1204,33 +1211,30 @@ ;; Otherwise, we must delete the connection cache, because ;; capabilities migh have changed. (unless (processp p) - (unless (let ((default-directory - (tramp-compat-temporary-file-directory))) - (executable-find tramp-smb-program)) - (tramp-error - vec 'file-error - "Cannot find command %s in %s" tramp-smb-program exec-path)) + (let ((default-directory (tramp-compat-temporary-file-directory)) + (command (concat tramp-smb-program " -V"))) - (let* ((default-directory (tramp-compat-temporary-file-directory)) - (smbclient-version tramp-smb-version)) - (unless smbclient-version - (setq smbclient-version - (shell-command-to-string (concat tramp-smb-program " -V"))) - (tramp-message vec 6 (concat tramp-smb-program " -V")) - (tramp-message vec 6 "\n%s" smbclient-version) - (if (string-match "[ \t\n\r]+\\'" smbclient-version) - (setq smbclient-version - (replace-match "" nil nil smbclient-version)))) - (unless - (string-equal - smbclient-version - (tramp-get-connection-property - vec "smbclient-version" smbclient-version)) + (unless tramp-smb-version + (unless (executable-find tramp-smb-program) + (tramp-error + vec 'file-error + "Cannot find command %s in %s" tramp-smb-program exec-path)) + (setq tramp-smb-version (shell-command-to-string command)) + (tramp-message vec 6 command) + (tramp-message vec 6 "\n%s" tramp-smb-version) + (if (string-match "[ \t\n\r]+\\'" tramp-smb-version) + (setq tramp-smb-version + (replace-match "" nil nil tramp-smb-version)))) + + (unless (string-equal + tramp-smb-version + (tramp-get-connection-property + vec "smbclient-version" tramp-smb-version)) (tramp-flush-directory-property vec "") (tramp-flush-connection-property vec)) - (setq tramp-smb-version - (tramp-set-connection-property - vec "smbclient-version" smbclient-version)))) + + (tramp-set-connection-property + vec "smbclient-version" tramp-smb-version))) ;; If too much time has passed since last command was sent, look ;; whether there has been an error message; maybe due to