diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 14 | ||||
| -rw-r--r-- | lisp/net/tramp-smb.el | 216 |
2 files changed, 123 insertions, 107 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0475e238c89..4aaaee7a2b1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2009-10-21 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * net/tramp-smb.el (tramp-smb-get-stat-capability): New defun. | ||
| 4 | (tramp-smb-handle-file-attributes): Use it. | ||
| 5 | (tramp-smb-do-file-attributes-with-stat): Don't raise an error. | ||
| 6 | (tramp-smb-handle-insert-directory): Use `mapc' rather than | ||
| 7 | `mapcar'. Use `tramp-smb-get-stat-capability'. Add | ||
| 8 | `dired-filename' text properties. | ||
| 9 | (tramp-smb-get-cifs-capabilities): Apply `save-match-data'. | ||
| 10 | (tramp-smb-maybe-open-connection): Simplify check for smbclient | ||
| 11 | version. | ||
| 12 | |||
| 1 | 2009-10-20 Stefan Monnier <monnier@iro.umontreal.ca> | 13 | 2009-10-20 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 14 | ||
| 3 | * subr.el (read-key-delay): Reduce to 0.01. | 15 | * subr.el (read-key-delay): Reduce to 0.01. |
| @@ -532,7 +544,7 @@ | |||
| 532 | 544 | ||
| 533 | * net/tramp.el (tramp-file-name-real-user, tramp-file-name-domain) | 545 | * net/tramp.el (tramp-file-name-real-user, tramp-file-name-domain) |
| 534 | (tramp-file-name-real-host, tramp-file-name-port): | 546 | (tramp-file-name-real-host, tramp-file-name-port): |
| 535 | Apply `save-match-data. | 547 | Apply `save-match-data'. |
| 536 | 548 | ||
| 537 | * net/tramp-smb.el (tramp-smb-handle-copy-directory): Handle the | 549 | * net/tramp-smb.el (tramp-smb-handle-copy-directory): Handle the |
| 538 | case both directories are remote. | 550 | case both directories are remote. |
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index c7ab6b00095..036b98e8df1 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el | |||
| @@ -481,7 +481,7 @@ PRESERVE-UID-GID is completely ignored." | |||
| 481 | (unless id-format (setq id-format 'integer)) | 481 | (unless id-format (setq id-format 'integer)) |
| 482 | (with-parsed-tramp-file-name filename nil | 482 | (with-parsed-tramp-file-name filename nil |
| 483 | (with-file-property v localname (format "file-attributes-%s" id-format) | 483 | (with-file-property v localname (format "file-attributes-%s" id-format) |
| 484 | (if (and (tramp-smb-get-share v) (tramp-smb-get-cifs-capabilities v)) | 484 | (if (and (tramp-smb-get-share v) (tramp-smb-get-stat-capability v)) |
| 485 | (tramp-smb-do-file-attributes-with-stat v id-format) | 485 | (tramp-smb-do-file-attributes-with-stat v id-format) |
| 486 | ;; Reading just the filename entry via "dir localname" is not | 486 | ;; Reading just the filename entry via "dir localname" is not |
| 487 | ;; possible, because when filename is a directory, some | 487 | ;; possible, because when filename is a directory, some |
| @@ -519,71 +519,64 @@ PRESERVE-UID-GID is completely ignored." | |||
| 519 | vec 5 "file attributes with stat: %s" (tramp-file-name-localname vec)) | 519 | vec 5 "file attributes with stat: %s" (tramp-file-name-localname vec)) |
| 520 | (with-current-buffer (tramp-get-buffer vec) | 520 | (with-current-buffer (tramp-get-buffer vec) |
| 521 | (let* (size id link uid gid atime mtime ctime mode inode) | 521 | (let* (size id link uid gid atime mtime ctime mode inode) |
| 522 | (unless | 522 | (when (tramp-smb-send-command |
| 523 | (tramp-smb-send-command | 523 | vec (format "stat \"%s\"" (tramp-smb-get-localname vec))) |
| 524 | vec (format "stat \"%s\"" (tramp-smb-get-localname vec))) | ||
| 525 | ;; Error. | ||
| 526 | (with-current-buffer (tramp-get-connection-buffer vec) | ||
| 527 | (goto-char (point-min)) | ||
| 528 | (search-forward-regexp tramp-smb-errors nil t) | ||
| 529 | (tramp-error | ||
| 530 | vec 'file-error "%s" (match-string 0)))) | ||
| 531 | 524 | ||
| 532 | ;; Loop the listing. | 525 | ;; Loop the listing. |
| 533 | (goto-char (point-min)) | 526 | (goto-char (point-min)) |
| 534 | (unless (re-search-forward tramp-smb-errors nil t) | 527 | (unless (re-search-forward tramp-smb-errors nil t) |
| 535 | (while (not (eobp)) | 528 | (while (not (eobp)) |
| 536 | (cond | 529 | (cond |
| 537 | ((looking-at | 530 | ((looking-at |
| 538 | "Size:\\s-+\\([0-9]+\\)\\s-+Blocks:\\s-+[0-9]+\\s-+\\(\\w+\\)") | 531 | "Size:\\s-+\\([0-9]+\\)\\s-+Blocks:\\s-+[0-9]+\\s-+\\(\\w+\\)") |
| 539 | (setq size (string-to-number (match-string 1)) | 532 | (setq size (string-to-number (match-string 1)) |
| 540 | id (if (string-equal "directory" (match-string 2)) t | 533 | id (if (string-equal "directory" (match-string 2)) t |
| 541 | (if (string-equal "symbolic" (match-string 2)) "")))) | 534 | (if (string-equal "symbolic" (match-string 2)) "")))) |
| 542 | ((looking-at | 535 | ((looking-at |
| 543 | "Inode:\\s-+\\([0-9]+\\)\\s-+Links:\\s-+\\([0-9]+\\)") | 536 | "Inode:\\s-+\\([0-9]+\\)\\s-+Links:\\s-+\\([0-9]+\\)") |
| 544 | (setq inode (string-to-number (match-string 1)) | 537 | (setq inode (string-to-number (match-string 1)) |
| 545 | link (string-to-number (match-string 2)))) | 538 | link (string-to-number (match-string 2)))) |
| 546 | ((looking-at | 539 | ((looking-at |
| 547 | "Access:\\s-+([0-9]+/\\(\\S-+\\))\\s-+Uid:\\s-+\\([0-9]+\\)\\s-+Gid:\\s-+\\([0-9]+\\)") | 540 | "Access:\\s-+([0-9]+/\\(\\S-+\\))\\s-+Uid:\\s-+\\([0-9]+\\)\\s-+Gid:\\s-+\\([0-9]+\\)") |
| 548 | (setq mode (match-string 1) | 541 | (setq mode (match-string 1) |
| 549 | uid (if (equal id-format 'string) (match-string 2) | 542 | uid (if (equal id-format 'string) (match-string 2) |
| 550 | (string-to-number (match-string 2))) | 543 | (string-to-number (match-string 2))) |
| 551 | gid (if (equal id-format 'string) (match-string 3) | 544 | gid (if (equal id-format 'string) (match-string 3) |
| 552 | (string-to-number (match-string 3))))) | 545 | (string-to-number (match-string 3))))) |
| 553 | ((looking-at | 546 | ((looking-at |
| 554 | "Access:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") | 547 | "Access:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") |
| 555 | (setq atime | 548 | (setq atime |
| 556 | (encode-time | 549 | (encode-time |
| 557 | (string-to-number (match-string 6)) ;; sec | 550 | (string-to-number (match-string 6)) ;; sec |
| 558 | (string-to-number (match-string 5)) ;; min | 551 | (string-to-number (match-string 5)) ;; min |
| 559 | (string-to-number (match-string 4)) ;; hour | 552 | (string-to-number (match-string 4)) ;; hour |
| 560 | (string-to-number (match-string 3)) ;; day | 553 | (string-to-number (match-string 3)) ;; day |
| 561 | (string-to-number (match-string 2)) ;; month | 554 | (string-to-number (match-string 2)) ;; month |
| 562 | (string-to-number (match-string 1))))) ;; year | 555 | (string-to-number (match-string 1))))) ;; year |
| 563 | ((looking-at | 556 | ((looking-at |
| 564 | "Modify:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") | 557 | "Modify:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") |
| 565 | (setq mtime | 558 | (setq mtime |
| 566 | (encode-time | 559 | (encode-time |
| 567 | (string-to-number (match-string 6)) ;; sec | 560 | (string-to-number (match-string 6)) ;; sec |
| 568 | (string-to-number (match-string 5)) ;; min | 561 | (string-to-number (match-string 5)) ;; min |
| 569 | (string-to-number (match-string 4)) ;; hour | 562 | (string-to-number (match-string 4)) ;; hour |
| 570 | (string-to-number (match-string 3)) ;; day | 563 | (string-to-number (match-string 3)) ;; day |
| 571 | (string-to-number (match-string 2)) ;; month | 564 | (string-to-number (match-string 2)) ;; month |
| 572 | (string-to-number (match-string 1))))) ;; year | 565 | (string-to-number (match-string 1))))) ;; year |
| 573 | ((looking-at | 566 | ((looking-at |
| 574 | "Change:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") | 567 | "Change:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") |
| 575 | (setq ctime | 568 | (setq ctime |
| 576 | (encode-time | 569 | (encode-time |
| 577 | (string-to-number (match-string 6)) ;; sec | 570 | (string-to-number (match-string 6)) ;; sec |
| 578 | (string-to-number (match-string 5)) ;; min | 571 | (string-to-number (match-string 5)) ;; min |
| 579 | (string-to-number (match-string 4)) ;; hour | 572 | (string-to-number (match-string 4)) ;; hour |
| 580 | (string-to-number (match-string 3)) ;; day | 573 | (string-to-number (match-string 3)) ;; day |
| 581 | (string-to-number (match-string 2)) ;; month | 574 | (string-to-number (match-string 2)) ;; month |
| 582 | (string-to-number (match-string 1)))))) ;; year | 575 | (string-to-number (match-string 1)))))) ;; year |
| 583 | (forward-line)) | 576 | (forward-line)) |
| 584 | ;; Return the result. | 577 | ;; Return the result. |
| 585 | (list id link uid gid atime mtime ctime size mode nil inode | 578 | (list id link uid gid atime mtime ctime size mode nil inode |
| 586 | (tramp-get-device vec)))))) | 579 | (tramp-get-device vec))))))) |
| 587 | 580 | ||
| 588 | (defun tramp-smb-handle-file-directory-p (filename) | 581 | (defun tramp-smb-handle-file-directory-p (filename) |
| 589 | "Like `file-directory-p' for Tramp files." | 582 | "Like `file-directory-p' for Tramp files." |
| @@ -709,30 +702,33 @@ PRESERVE-UID-GID is completely ignored." | |||
| 709 | entries)) | 702 | entries)) |
| 710 | 703 | ||
| 711 | ;; Print entries. | 704 | ;; Print entries. |
| 712 | (mapcar | 705 | (mapc |
| 713 | (lambda (x) | 706 | (lambda (x) |
| 714 | (when (not (zerop (length (nth 0 x)))) | 707 | (when (not (zerop (length (nth 0 x)))) |
| 715 | (let ((attr | 708 | (let ((attr |
| 716 | (when (tramp-smb-get-cifs-capabilities v) | 709 | (when (tramp-smb-get-stat-capability v) |
| 717 | (ignore-errors | 710 | (ignore-errors |
| 718 | (file-attributes | 711 | (file-attributes |
| 719 | (expand-file-name (nth 0 x)) 'string))))) | 712 | (expand-file-name (nth 0 x)) 'string))))) |
| 720 | (insert | 713 | (insert |
| 721 | (format | 714 | (format |
| 722 | "%10s %3d %-8s %-8s %8s %s %s\n" | 715 | "%10s %3d %-8s %-8s %8s %s " |
| 723 | (or (nth 8 attr) (nth 1 x)) ; mode | 716 | (or (nth 8 attr) (nth 1 x)) ; mode |
| 724 | (or (nth 1 attr) 1) ; link | 717 | (or (nth 1 attr) 1) ; inode |
| 725 | (or (nth 2 attr) "nobody") ; uid | 718 | (or (nth 2 attr) "nobody") ; uid |
| 726 | (or (nth 3 attr) "nogroup") ; gid | 719 | (or (nth 3 attr) "nogroup") ; gid |
| 727 | (nth 2 x) ; size | 720 | (or (nth 7 attr) (nth 2 x)) ; size |
| 728 | (format-time-string | 721 | (format-time-string |
| 729 | (if (tramp-time-less-p | 722 | (if (tramp-time-less-p |
| 730 | (tramp-time-subtract (current-time) (nth 3 x)) | 723 | (tramp-time-subtract (current-time) (nth 3 x)) |
| 731 | tramp-half-a-year) | 724 | tramp-half-a-year) |
| 732 | "%b %e %R" | 725 | "%b %e %R" |
| 733 | "%b %e %Y") | 726 | "%b %e %Y") |
| 734 | (nth 3 x)) ; date | 727 | (nth 3 x)))) ; date |
| 735 | (nth 0 x))) ; file name | 728 | ;; We mark the filename. |
| 729 | (let ((start (point))) | ||
| 730 | (insert (format "%s\n" (nth 0 x))) ; file name | ||
| 731 | (put-text-property start (1- (point)) 'dired-filename t)) | ||
| 736 | (forward-line) | 732 | (forward-line) |
| 737 | (beginning-of-line)))) | 733 | (beginning-of-line)))) |
| 738 | entries))))) | 734 | entries))))) |
| @@ -1171,15 +1167,26 @@ Result is the list (LOCALNAME MODE SIZE MTIME)." | |||
| 1171 | (and p (processp p) (memq (process-status p) '(run open)))) | 1167 | (and p (processp p) (memq (process-status p) '(run open)))) |
| 1172 | (with-connection-property | 1168 | (with-connection-property |
| 1173 | (tramp-get-connection-process vec) "cifs-capabilities" | 1169 | (tramp-get-connection-process vec) "cifs-capabilities" |
| 1174 | (when (tramp-smb-send-command vec "posix") | 1170 | (save-match-data |
| 1175 | (with-current-buffer (tramp-get-buffer vec) | 1171 | (when (tramp-smb-send-command vec "posix") |
| 1176 | (goto-char (point-min)) | 1172 | (with-current-buffer (tramp-get-buffer vec) |
| 1177 | (when (re-search-forward "Server supports CIFS capabilities" nil t) | 1173 | (goto-char (point-min)) |
| 1178 | (member | 1174 | (when |
| 1179 | "pathnames" | 1175 | (re-search-forward "Server supports CIFS capabilities" nil t) |
| 1180 | (split-string | 1176 | (member |
| 1181 | (buffer-substring | 1177 | "pathnames" |
| 1182 | (point) (tramp-compat-line-end-position)) nil t)))))))) | 1178 | (split-string |
| 1179 | (buffer-substring | ||
| 1180 | (point) (tramp-compat-line-end-position)) nil t))))))))) | ||
| 1181 | |||
| 1182 | (defun tramp-smb-get-stat-capability (vec) | ||
| 1183 | "Check, whether the SMB server supports the STAT command." | ||
| 1184 | ;; When we are not logged in yet, we return nil. | ||
| 1185 | (if (let ((p (tramp-get-connection-process vec))) | ||
| 1186 | (and p (processp p) (memq (process-status p) '(run open)))) | ||
| 1187 | (with-connection-property | ||
| 1188 | (tramp-get-connection-process vec) "stat-capability" | ||
| 1189 | (tramp-smb-send-command vec "stat .")))) | ||
| 1183 | 1190 | ||
| 1184 | 1191 | ||
| 1185 | ;; Connection functions. | 1192 | ;; Connection functions. |
| @@ -1204,33 +1211,30 @@ connection if a previous connection has died for some reason." | |||
| 1204 | ;; Otherwise, we must delete the connection cache, because | 1211 | ;; Otherwise, we must delete the connection cache, because |
| 1205 | ;; capabilities migh have changed. | 1212 | ;; capabilities migh have changed. |
| 1206 | (unless (processp p) | 1213 | (unless (processp p) |
| 1207 | (unless (let ((default-directory | 1214 | (let ((default-directory (tramp-compat-temporary-file-directory)) |
| 1208 | (tramp-compat-temporary-file-directory))) | 1215 | (command (concat tramp-smb-program " -V"))) |
| 1209 | (executable-find tramp-smb-program)) | 1216 | |
| 1210 | (tramp-error | 1217 | (unless tramp-smb-version |
| 1211 | vec 'file-error | 1218 | (unless (executable-find tramp-smb-program) |
| 1212 | "Cannot find command %s in %s" tramp-smb-program exec-path)) | 1219 | (tramp-error |
| 1213 | 1220 | vec 'file-error | |
| 1214 | (let* ((default-directory (tramp-compat-temporary-file-directory)) | 1221 | "Cannot find command %s in %s" tramp-smb-program exec-path)) |
| 1215 | (smbclient-version tramp-smb-version)) | 1222 | (setq tramp-smb-version (shell-command-to-string command)) |
| 1216 | (unless smbclient-version | 1223 | (tramp-message vec 6 command) |
| 1217 | (setq smbclient-version | 1224 | (tramp-message vec 6 "\n%s" tramp-smb-version) |
| 1218 | (shell-command-to-string (concat tramp-smb-program " -V"))) | 1225 | (if (string-match "[ \t\n\r]+\\'" tramp-smb-version) |
| 1219 | (tramp-message vec 6 (concat tramp-smb-program " -V")) | 1226 | (setq tramp-smb-version |
| 1220 | (tramp-message vec 6 "\n%s" smbclient-version) | 1227 | (replace-match "" nil nil tramp-smb-version)))) |
| 1221 | (if (string-match "[ \t\n\r]+\\'" smbclient-version) | 1228 | |
| 1222 | (setq smbclient-version | 1229 | (unless (string-equal |
| 1223 | (replace-match "" nil nil smbclient-version)))) | 1230 | tramp-smb-version |
| 1224 | (unless | 1231 | (tramp-get-connection-property |
| 1225 | (string-equal | 1232 | vec "smbclient-version" tramp-smb-version)) |
| 1226 | smbclient-version | ||
| 1227 | (tramp-get-connection-property | ||
| 1228 | vec "smbclient-version" smbclient-version)) | ||
| 1229 | (tramp-flush-directory-property vec "") | 1233 | (tramp-flush-directory-property vec "") |
| 1230 | (tramp-flush-connection-property vec)) | 1234 | (tramp-flush-connection-property vec)) |
| 1231 | (setq tramp-smb-version | 1235 | |
| 1232 | (tramp-set-connection-property | 1236 | (tramp-set-connection-property |
| 1233 | vec "smbclient-version" smbclient-version)))) | 1237 | vec "smbclient-version" tramp-smb-version))) |
| 1234 | 1238 | ||
| 1235 | ;; If too much time has passed since last command was sent, look | 1239 | ;; If too much time has passed since last command was sent, look |
| 1236 | ;; whether there has been an error message; maybe due to | 1240 | ;; whether there has been an error message; maybe due to |