aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2009-10-07 11:31:21 +0000
committerMichael Albinus2009-10-07 11:31:21 +0000
commitc2dc9732f76a0f90613519fd34f88df9dcba6c48 (patch)
treede683fd768feedc1ba62a3ba79714bf44414fa2a
parente946faaf51d3b5a1f6f9bc061546dd195c132a93 (diff)
downloademacs-c2dc9732f76a0f90613519fd34f88df9dcba6c48.tar.gz
emacs-c2dc9732f76a0f90613519fd34f88df9dcba6c48.zip
* net/tramp-smb.el (tramp-smb-errors): Add error messages.
(tramp-smb-file-name-handler-alist): Add handler for `copy-directory', `expand-file-name', `set-file-modes'. (tramp-smb-handle-copy-directory) (tramp-smb-handle-expand-file-name) (tramp-smb-handle-set-file-modes): New defuns. (tramp-smb-handle-copy-file): Handle KEPP-DATE. (tramp-smb-handle-file-attributes): Simplify check for retrieving entry. (tramp-smb-handle-insert-directory): Don't flush the cache. (tramp-smb-maybe-open-connection): Check for samba client and server versions.
-rw-r--r--lisp/ChangeLog18
-rw-r--r--lisp/net/tramp-smb.el244
2 files changed, 201 insertions, 61 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 445aa4ad7d7..60181af667d 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,21 @@
12009-10-07 Michael Albinus <michael.albinus@gmx.de>
2
3 * net/tramp-cache.el (tramp-flush-connection-property): Add trace
4 message.
5
6 * net/tramp-smb.el (tramp-smb-errors): Add error messages.
7 (tramp-smb-file-name-handler-alist): Add handler for
8 `copy-directory', `expand-file-name', `set-file-modes'.
9 (tramp-smb-handle-copy-directory)
10 (tramp-smb-handle-expand-file-name)
11 (tramp-smb-handle-set-file-modes): New defuns.
12 (tramp-smb-handle-copy-file): Handle KEEP-DATE.
13 (tramp-smb-handle-file-attributes): Simplify check for retrieving
14 entry.
15 (tramp-smb-handle-insert-directory): Don't flush the cache.
16 (tramp-smb-maybe-open-connection): Check for samba client and
17 server versions.
18
12009-10-07 Eli Zaretskii <eliz@gnu.org> 192009-10-07 Eli Zaretskii <eliz@gnu.org>
2 20
3 * emacs-lisp/autoload.el (batch-update-autoloads): Fix last change 21 * emacs-lisp/autoload.el (batch-update-autoloads): Fix last change
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 48d015013c0..ff2a5d13cb7 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -68,11 +68,13 @@
68 ;; `regexp-opt' not possible because of first string. 68 ;; `regexp-opt' not possible because of first string.
69 (mapconcat 69 (mapconcat
70 'identity 70 'identity
71 '(;; Connection error / timeout 71 '(;; Connection error / timeout / unknown command.
72 "Connection to \\S-+ failed" 72 "Connection to \\S-+ failed"
73 "Read from server failed, maybe it closed the connection" 73 "Read from server failed, maybe it closed the connection"
74 "Call timed out: server did not respond" 74 "Call timed out: server did not respond"
75 ;; Samba 75 "\\S-+: command not found"
76 "Server doesn't support UNIX CIFS calls"
77 ;; Samba.
76 "ERRDOS" 78 "ERRDOS"
77 "ERRSRV" 79 "ERRSRV"
78 "ERRbadfile" 80 "ERRbadfile"
@@ -82,7 +84,7 @@
82 "ERRnomem" 84 "ERRnomem"
83 "ERRnosuchshare" 85 "ERRnosuchshare"
84 ;; Windows 4.0 (Windows NT), Windows 5.0 (Windows 2000), 86 ;; Windows 4.0 (Windows NT), Windows 5.0 (Windows 2000),
85 ;; Windows 5.1 (Windows XP), Windows 5.2 (Windows Server 2003) 87 ;; Windows 5.1 (Windows XP), Windows 5.2 (Windows Server 2003).
86 "NT_STATUS_ACCESS_DENIED" 88 "NT_STATUS_ACCESS_DENIED"
87 "NT_STATUS_ACCOUNT_LOCKED_OUT" 89 "NT_STATUS_ACCOUNT_LOCKED_OUT"
88 "NT_STATUS_BAD_NETWORK_NAME" 90 "NT_STATUS_BAD_NETWORK_NAME"
@@ -128,20 +130,22 @@ See `tramp-actions-before-shell' for more info.")
128;; New handlers should be added here. 130;; New handlers should be added here.
129(defconst tramp-smb-file-name-handler-alist 131(defconst tramp-smb-file-name-handler-alist
130 '( 132 '(
131 ;; `access-file' performed by default handler 133 ;; `access-file' performed by default handler.
132 (add-name-to-file . tramp-smb-handle-copy-file) ;; we're on Windows, honey. 134 (add-name-to-file . tramp-smb-handle-copy-file) ;; we're on Windows, honey.
133 ;; `byte-compiler-base-file-name' performed by default handler 135 ;; `byte-compiler-base-file-name' performed by default handler.
136 (copy-directory . tramp-smb-handle-copy-directory)
134 (copy-file . tramp-smb-handle-copy-file) 137 (copy-file . tramp-smb-handle-copy-file)
135 (delete-directory . tramp-smb-handle-delete-directory) 138 (delete-directory . tramp-smb-handle-delete-directory)
136 (delete-file . tramp-smb-handle-delete-file) 139 (delete-file . tramp-smb-handle-delete-file)
137 ;; `diff-latest-backup-file' performed by default handler 140 ;; `diff-latest-backup-file' performed by default handler.
138 (directory-file-name . tramp-handle-directory-file-name) 141 (directory-file-name . tramp-handle-directory-file-name)
139 (directory-files . tramp-smb-handle-directory-files) 142 (directory-files . tramp-smb-handle-directory-files)
140 (directory-files-and-attributes . tramp-smb-handle-directory-files-and-attributes) 143 (directory-files-and-attributes
144 . tramp-smb-handle-directory-files-and-attributes)
141 (dired-call-process . ignore) 145 (dired-call-process . ignore)
142 (dired-compress-file . ignore) 146 (dired-compress-file . ignore)
143 (dired-uncache . tramp-handle-dired-uncache) 147 (dired-uncache . tramp-handle-dired-uncache)
144 ;; `expand-file-name' not necessary because we cannot expand "~/" 148 (expand-file-name . tramp-smb-handle-expand-file-name)
145 (file-accessible-directory-p . tramp-smb-handle-file-directory-p) 149 (file-accessible-directory-p . tramp-smb-handle-file-directory-p)
146 (file-attributes . tramp-smb-handle-file-attributes) 150 (file-attributes . tramp-smb-handle-file-attributes)
147 (file-directory-p . tramp-smb-handle-file-directory-p) 151 (file-directory-p . tramp-smb-handle-file-directory-p)
@@ -155,17 +159,17 @@ See `tramp-actions-before-shell' for more info.")
155 (file-name-completion . tramp-handle-file-name-completion) 159 (file-name-completion . tramp-handle-file-name-completion)
156 (file-name-directory . tramp-handle-file-name-directory) 160 (file-name-directory . tramp-handle-file-name-directory)
157 (file-name-nondirectory . tramp-handle-file-name-nondirectory) 161 (file-name-nondirectory . tramp-handle-file-name-nondirectory)
158 ;; `file-name-sans-versions' performed by default handler 162 ;; `file-name-sans-versions' performed by default handler.
159 (file-newer-than-file-p . tramp-smb-handle-file-newer-than-file-p) 163 (file-newer-than-file-p . tramp-smb-handle-file-newer-than-file-p)
160 (file-ownership-preserved-p . ignore) 164 (file-ownership-preserved-p . ignore)
161 (file-readable-p . tramp-smb-handle-file-exists-p) 165 (file-readable-p . tramp-smb-handle-file-exists-p)
162 (file-regular-p . tramp-handle-file-regular-p) 166 (file-regular-p . tramp-handle-file-regular-p)
163 (file-symlink-p . tramp-handle-file-symlink-p) 167 (file-symlink-p . tramp-handle-file-symlink-p)
164 ;; `file-truename' performed by default handler 168 ;; `file-truename' performed by default handler.
165 (file-writable-p . tramp-smb-handle-file-writable-p) 169 (file-writable-p . tramp-smb-handle-file-writable-p)
166 (find-backup-file-name . tramp-handle-find-backup-file-name) 170 (find-backup-file-name . tramp-handle-find-backup-file-name)
167 ;; `find-file-noselect' performed by default handler 171 ;; `find-file-noselect' performed by default handler.
168 ;; `get-file-buffer' performed by default handler 172 ;; `get-file-buffer' performed by default handler.
169 (insert-directory . tramp-smb-handle-insert-directory) 173 (insert-directory . tramp-smb-handle-insert-directory)
170 (insert-file-contents . tramp-handle-insert-file-contents) 174 (insert-file-contents . tramp-handle-insert-file-contents)
171 (load . tramp-handle-load) 175 (load . tramp-handle-load)
@@ -173,7 +177,8 @@ See `tramp-actions-before-shell' for more info.")
173 (make-directory-internal . tramp-smb-handle-make-directory-internal) 177 (make-directory-internal . tramp-smb-handle-make-directory-internal)
174 (make-symbolic-link . ignore) 178 (make-symbolic-link . ignore)
175 (rename-file . tramp-smb-handle-rename-file) 179 (rename-file . tramp-smb-handle-rename-file)
176 (set-file-modes . ignore) 180 (set-file-modes . tramp-smb-handle-set-file-modes)
181 (set-file-times . ignore)
177 (set-visited-file-modtime . ignore) 182 (set-visited-file-modtime . ignore)
178 (shell-command . ignore) 183 (shell-command . ignore)
179 (substitute-in-file-name . tramp-smb-handle-substitute-in-file-name) 184 (substitute-in-file-name . tramp-smb-handle-substitute-in-file-name)
@@ -203,7 +208,50 @@ pass to the OPERATION."
203 (cons 'tramp-smb-file-name-p 'tramp-smb-file-name-handler)) 208 (cons 'tramp-smb-file-name-p 'tramp-smb-file-name-handler))
204 209
205 210
206;; File name primitives 211;; File name primitives.
212
213(defun tramp-smb-handle-copy-directory
214 (dirname newname &optional keep-date parents)
215 "Like `copy-directory' for Tramp files."
216 (setq dirname (expand-file-name dirname)
217 newname (expand-file-name newname))
218 (let ((t1 (tramp-tramp-file-p dirname))
219 (t2 (tramp-tramp-file-p newname)))
220 (with-parsed-tramp-file-name (if t1 dirname newname) nil
221 (if (or (null t1) (null t2))
222 ;; We can copy recursively.
223 (let ((prompt (tramp-smb-send-command v "prompt"))
224 (recurse (tramp-smb-send-command v "recurse")))
225 (unless (file-directory-p newname)
226 (make-directory newname parents))
227 (unwind-protect
228 (unless
229 (and
230 prompt recurse
231 (tramp-smb-send-command
232 v (format "cd \"%s\""
233 (tramp-smb-get-localname localname t)))
234 (tramp-smb-send-command
235 v (format "lcd \"%s\"" (if t1 newname dirname)))
236 (if t1
237 (tramp-smb-send-command v "mget *")
238 (tramp-smb-send-command v "mput *")))
239 ;; Error.
240 (with-current-buffer (tramp-get-connection-buffer v)
241 (goto-char (point-min))
242 (search-forward-regexp tramp-smb-errors nil t)
243 (tramp-error
244 v 'file-error
245 "%s `%s'" (match-string 0) (if t1 dirname newname))))
246 ;; Always go home.
247 (tramp-smb-send-command v (format "cd \\"))
248 ;; Toggle prompt and recurse OFF.
249 (if prompt (tramp-smb-send-command v "prompt"))
250 (if recurse (tramp-smb-send-command v "recurse"))))
251
252 ;; We must do it file-wise.
253 (tramp-run-real-handler
254 'copy-directory (list dirname newname keep-date parents))))))
207 255
208(defun tramp-smb-handle-copy-file 256(defun tramp-smb-handle-copy-file
209 (filename newname &optional ok-if-already-exists keep-date preserve-uid-gid) 257 (filename newname &optional ok-if-already-exists keep-date preserve-uid-gid)
@@ -247,7 +295,10 @@ PRESERVE-UID-GID is completely ignored."
247 v (format "put %s \"%s\"" filename file)) 295 v (format "put %s \"%s\"" filename file))
248 (tramp-message 296 (tramp-message
249 v 0 "Copying file %s to file %s...done" filename newname) 297 v 0 "Copying file %s to file %s...done" filename newname)
250 (tramp-error v 'file-error "Cannot copy `%s'" filename))))))) 298 (tramp-error v 'file-error "Cannot copy `%s'" filename))))))
299
300 ;; KEEP-DATE handling.
301 (when keep-date (set-file-times newname (nth 5 (file-attributes filename)))))
251 302
252(defun tramp-smb-handle-delete-directory (directory &optional recursive) 303(defun tramp-smb-handle-delete-directory (directory &optional recursive)
253 "Like `delete-directory' for Tramp files." 304 "Like `delete-directory' for Tramp files."
@@ -273,13 +324,13 @@ PRESERVE-UID-GID is completely ignored."
273 (unless (and 324 (unless (and
274 (tramp-smb-send-command v (format "cd \"%s\"" dir)) 325 (tramp-smb-send-command v (format "cd \"%s\"" dir))
275 (tramp-smb-send-command v (format "rmdir \"%s\"" file))) 326 (tramp-smb-send-command v (format "rmdir \"%s\"" file)))
276 ;; Error 327 ;; Error.
277 (with-current-buffer (tramp-get-connection-buffer v) 328 (with-current-buffer (tramp-get-connection-buffer v)
278 (goto-char (point-min)) 329 (goto-char (point-min))
279 (search-forward-regexp tramp-smb-errors nil t) 330 (search-forward-regexp tramp-smb-errors nil t)
280 (tramp-error 331 (tramp-error
281 v 'file-error "%s `%s'" (match-string 0) directory))) 332 v 'file-error "%s `%s'" (match-string 0) directory)))
282 ;; Always go home 333 ;; Always go home.
283 (tramp-smb-send-command v (format "cd \\"))))))) 334 (tramp-smb-send-command v (format "cd \\")))))))
284 335
285(defun tramp-smb-handle-delete-file (filename) 336(defun tramp-smb-handle-delete-file (filename)
@@ -297,13 +348,13 @@ PRESERVE-UID-GID is completely ignored."
297 (unless (and 348 (unless (and
298 (tramp-smb-send-command v (format "cd \"%s\"" dir)) 349 (tramp-smb-send-command v (format "cd \"%s\"" dir))
299 (tramp-smb-send-command v (format "rm \"%s\"" file))) 350 (tramp-smb-send-command v (format "rm \"%s\"" file)))
300 ;; Error 351 ;; Error.
301 (with-current-buffer (tramp-get-connection-buffer v) 352 (with-current-buffer (tramp-get-connection-buffer v)
302 (goto-char (point-min)) 353 (goto-char (point-min))
303 (search-forward-regexp tramp-smb-errors nil t) 354 (search-forward-regexp tramp-smb-errors nil t)
304 (tramp-error 355 (tramp-error
305 v 'file-error "%s `%s'" (match-string 0) filename))) 356 v 'file-error "%s `%s'" (match-string 0) filename)))
306 ;; Always go home 357 ;; Always go home.
307 (tramp-smb-send-command v (format "cd \\"))))))) 358 (tramp-smb-send-command v (format "cd \\")))))))
308 359
309(defun tramp-smb-handle-directory-files 360(defun tramp-smb-handle-directory-files
@@ -311,21 +362,21 @@ PRESERVE-UID-GID is completely ignored."
311 "Like `directory-files' for Tramp files." 362 "Like `directory-files' for Tramp files."
312 (let ((result (mapcar 'directory-file-name 363 (let ((result (mapcar 'directory-file-name
313 (file-name-all-completions "" directory)))) 364 (file-name-all-completions "" directory))))
314 ;; Discriminate with regexp 365 ;; Discriminate with regexp.
315 (when match 366 (when match
316 (setq result 367 (setq result
317 (delete nil 368 (delete nil
318 (mapcar (lambda (x) (when (string-match match x) x)) 369 (mapcar (lambda (x) (when (string-match match x) x))
319 result)))) 370 result))))
320 ;; Append directory 371 ;; Append directory.
321 (when full 372 (when full
322 (setq result 373 (setq result
323 (mapcar 374 (mapcar
324 (lambda (x) (expand-file-name x directory)) 375 (lambda (x) (expand-file-name x directory))
325 result))) 376 result)))
326 ;; Sort them if necessary 377 ;; Sort them if necessary.
327 (unless nosort (setq result (sort result 'string-lessp))) 378 (unless nosort (setq result (sort result 'string-lessp)))
328 ;; That's it 379 ;; That's it.
329 result)) 380 result))
330 381
331(defun tramp-smb-handle-directory-files-and-attributes 382(defun tramp-smb-handle-directory-files-and-attributes
@@ -337,6 +388,35 @@ PRESERVE-UID-GID is completely ignored."
337 (if full x (expand-file-name x directory)) id-format))) 388 (if full x (expand-file-name x directory)) id-format)))
338 (directory-files directory full match nosort))) 389 (directory-files directory full match nosort)))
339 390
391(defun tramp-smb-handle-expand-file-name (name &optional dir)
392 "Like `expand-file-name' for Tramp files."
393 ;; If DIR is not given, use DEFAULT-DIRECTORY or "/".
394 (setq dir (or dir default-directory "/"))
395 ;; Unless NAME is absolute, concat DIR and NAME.
396 (unless (file-name-absolute-p name)
397 (setq name (concat (file-name-as-directory dir) name)))
398 ;; If NAME is not a Tramp file, run the real handler.
399 (if (not (tramp-tramp-file-p name))
400 (tramp-run-real-handler 'expand-file-name (list name nil))
401 ;; Dissect NAME.
402 (with-parsed-tramp-file-name name nil
403 (unless (tramp-run-real-handler 'file-name-absolute-p (list localname))
404 (setq localname (concat "/" localname)))
405 ;; Tilde expansion if necessary. We use the user name as share,
406 ;; which is offen the case in work groups.
407 (when (string-match "\\`~[^/]*" localname)
408 (setq localname
409 (replace-match
410 (if (zerop (length (match-string 0 localname)))
411 (tramp-file-name-real-user v)
412 (match-string 0 localname))
413 nil nil localname)))
414 ;; No tilde characters in file name, do normal
415 ;; `expand-file-name' (this does "/./" and "/../").
416 (tramp-make-tramp-file-name
417 method user host
418 (tramp-run-real-handler 'expand-file-name (list localname))))))
419
340(defun tramp-smb-handle-file-attributes (filename &optional id-format) 420(defun tramp-smb-handle-file-attributes (filename &optional id-format)
341 "Like `file-attributes' for Tramp files." 421 "Like `file-attributes' for Tramp files."
342 ;; Reading just the filename entry via "dir localname" is not 422 ;; Reading just the filename entry via "dir localname" is not
@@ -348,8 +428,7 @@ PRESERVE-UID-GID is completely ignored."
348 (with-file-property v localname (format "file-attributes-%s" id-format) 428 (with-file-property v localname (format "file-attributes-%s" id-format)
349 (let* ((entries (tramp-smb-get-file-entries 429 (let* ((entries (tramp-smb-get-file-entries
350 (file-name-directory filename))) 430 (file-name-directory filename)))
351 (entry (and entries 431 (entry (assoc (file-name-nondirectory filename) entries))
352 (assoc (file-name-nondirectory filename) entries)))
353 (uid (if (and id-format (equal id-format 'string)) "nobody" -1)) 432 (uid (if (and id-format (equal id-format 'string)) "nobody" -1))
354 (gid (if (and id-format (equal id-format 'string)) "nogroup" -1)) 433 (gid (if (and id-format (equal id-format 'string)) "nogroup" -1))
355 (inode (tramp-get-inode v)) 434 (inode (tramp-get-inode v))
@@ -442,7 +521,6 @@ PRESERVE-UID-GID is completely ignored."
442 ;; Called from `dired-add-entry'. 521 ;; Called from `dired-add-entry'.
443 (setq filename (file-name-as-directory filename))) 522 (setq filename (file-name-as-directory filename)))
444 (with-parsed-tramp-file-name filename nil 523 (with-parsed-tramp-file-name filename nil
445 (tramp-flush-file-property v (file-name-directory localname))
446 (save-match-data 524 (save-match-data
447 (let ((base (file-name-nondirectory filename)) 525 (let ((base (file-name-nondirectory filename))
448 ;; We should not destroy the cache entry. 526 ;; We should not destroy the cache entry.
@@ -527,10 +605,10 @@ PRESERVE-UID-GID is completely ignored."
527 (save-match-data 605 (save-match-data
528 (let* ((share (tramp-smb-get-share localname)) 606 (let* ((share (tramp-smb-get-share localname))
529 (ldir (file-name-directory dir))) 607 (ldir (file-name-directory dir)))
530 ;; Make missing directory parts 608 ;; Make missing directory parts.
531 (when (and parents share (not (file-directory-p ldir))) 609 (when (and parents share (not (file-directory-p ldir)))
532 (make-directory ldir parents)) 610 (make-directory ldir parents))
533 ;; Just do it 611 ;; Just do it.
534 (when (file-directory-p ldir) 612 (when (file-directory-p ldir)
535 (make-directory-internal dir)) 613 (make-directory-internal dir))
536 (unless (file-directory-p dir) 614 (unless (file-directory-p dir)
@@ -592,6 +670,17 @@ PRESERVE-UID-GID is completely ignored."
592 670
593 (delete-file filename)) 671 (delete-file filename))
594 672
673(defun tramp-smb-handle-set-file-modes (filename mode)
674 "Like `set-file-modes' for Tramp files."
675 (with-parsed-tramp-file-name filename nil
676 (tramp-flush-file-property v localname)
677 (unless (tramp-smb-send-command
678 v (format "chmod \"%s\" %s"
679 (tramp-smb-get-localname localname t)
680 (tramp-decimal-to-octal mode)))
681 (tramp-error
682 v 'file-error "Error while changing file's mode %s" filename))))
683
595(defun tramp-smb-handle-substitute-in-file-name (filename) 684(defun tramp-smb-handle-substitute-in-file-name (filename)
596 "Like `handle-substitute-in-file-name' for Tramp files. 685 "Like `handle-substitute-in-file-name' for Tramp files.
597\"//\" substitutes only in the local filename part. Catches 686\"//\" substitutes only in the local filename part. Catches
@@ -652,7 +741,7 @@ errors for shares like \"C$/\", which are common in Microsoft Windows."
652 (set-visited-file-modtime))))) 741 (set-visited-file-modtime)))))
653 742
654 743
655;; Internal file name functions 744;; Internal file name functions.
656 745
657(defun tramp-smb-get-share (localname) 746(defun tramp-smb-get-share (localname)
658 "Returns the share name of LOCALNAME." 747 "Returns the share name of LOCALNAME."
@@ -677,7 +766,7 @@ If CONVERT is non-nil exchange \"/\" by \"\\\\\"."
677 (match-string 1 res) 766 (match-string 1 res)
678 ""))) 767 "")))
679 768
680 ;; Sometimes we have discarded `substitute-in-file-name' 769 ;; Sometimes we have discarded `substitute-in-file-name'.
681 (when (string-match "\\(\\$\\$\\)\\(/\\|$\\)" res) 770 (when (string-match "\\(\\$\\$\\)\\(/\\|$\\)" res)
682 (setq res (replace-match "$" nil nil res 1))) 771 (setq res (replace-match "$" nil nil res 1)))
683 772
@@ -699,19 +788,19 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
699 res entry) 788 res entry)
700 789
701 (if (and (not share) cache) 790 (if (and (not share) cache)
702 ;; Return cached shares 791 ;; Return cached shares.
703 (setq res cache) 792 (setq res cache)
704 793
705 ;; Read entries 794 ;; Read entries.
706 (setq file (file-name-as-directory file)) 795 (setq file (file-name-as-directory file))
707 (when (string-match "^\\./" file) 796 (when (string-match "^\\./" file)
708 (setq file (substring file 1))) 797 (setq file (substring file 1)))
709 (if share 798 (if share
710 (tramp-smb-send-command v (format "dir \"%s*\"" file)) 799 (tramp-smb-send-command v (format "dir \"%s*\"" file))
711 ;; `tramp-smb-maybe-open-connection' lists also the share names 800 ;; `tramp-smb-maybe-open-connection' lists also the share names.
712 (tramp-smb-maybe-open-connection v)) 801 (tramp-smb-maybe-open-connection v))
713 802
714 ;; Loop the listing 803 ;; Loop the listing.
715 (goto-char (point-min)) 804 (goto-char (point-min))
716 (unless (re-search-forward tramp-smb-errors nil t) 805 (unless (re-search-forward tramp-smb-errors nil t)
717 (while (not (eobp)) 806 (while (not (eobp))
@@ -719,23 +808,23 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
719 (forward-line) 808 (forward-line)
720 (when entry (add-to-list 'res entry)))) 809 (when entry (add-to-list 'res entry))))
721 810
722 ;; Cache share entries 811 ;; Cache share entries.
723 (unless share 812 (unless share
724 (tramp-set-connection-property v "share-cache" res))) 813 (tramp-set-connection-property v "share-cache" res)))
725 814
726 ;; Add directory itself 815 ;; Add directory itself.
727 (add-to-list 'res '("" "drwxrwxrwx" 0 (0 0))) 816 (add-to-list 'res '("" "drwxrwxrwx" 0 (0 0)))
728 817
729 ;; There's a very strange error (debugged with XEmacs 21.4.14) 818 ;; There's a very strange error (debugged with XEmacs 21.4.14)
730 ;; If there's no short delay, it returns nil. No idea about. 819 ;; If there's no short delay, it returns nil. No idea about.
731 (when (featurep 'xemacs) (sleep-for 0.01)) 820 (when (featurep 'xemacs) (sleep-for 0.01))
732 821
733 ;; Return entries 822 ;; Return entries.
734 (delq nil res)))))) 823 (delq nil res))))))
735 824
736;; Return either a share name (if SHARE is nil), or a file name 825;; Return either a share name (if SHARE is nil), or a file name.
737;; 826;;
738;; If shares are listed, the following format is expected 827;; If shares are listed, the following format is expected:
739;; 828;;
740;; \s-\{8,8} - leading spaces 829;; \s-\{8,8} - leading spaces
741;; \S-\(.*\S-\)\s-* - share name, 14 char 830;; \S-\(.*\S-\)\s-* - share name, 14 char
@@ -807,13 +896,13 @@ Result is the list (LOCALNAME MODE SIZE MTIME)."
807 ;; Real listing. 896 ;; Real listing.
808 (block nil 897 (block nil
809 898
810 ;; year 899 ;; year.
811 (if (string-match "\\([0-9]+\\)$" line) 900 (if (string-match "\\([0-9]+\\)$" line)
812 (setq year (string-to-number (match-string 1 line)) 901 (setq year (string-to-number (match-string 1 line))
813 line (substring line 0 -5)) 902 line (substring line 0 -5))
814 (return)) 903 (return))
815 904
816 ;; time 905 ;; time.
817 (if (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)$" line) 906 (if (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)$" line)
818 (setq hour (string-to-number (match-string 1 line)) 907 (setq hour (string-to-number (match-string 1 line))
819 min (string-to-number (match-string 2 line)) 908 min (string-to-number (match-string 2 line))
@@ -821,24 +910,24 @@ Result is the list (LOCALNAME MODE SIZE MTIME)."
821 line (substring line 0 -9)) 910 line (substring line 0 -9))
822 (return)) 911 (return))
823 912
824 ;; day 913 ;; day.
825 (if (string-match "\\([0-9]+\\)$" line) 914 (if (string-match "\\([0-9]+\\)$" line)
826 (setq day (string-to-number (match-string 1 line)) 915 (setq day (string-to-number (match-string 1 line))
827 line (substring line 0 -3)) 916 line (substring line 0 -3))
828 (return)) 917 (return))
829 918
830 ;; month 919 ;; month.
831 (if (string-match "\\(\\w+\\)$" line) 920 (if (string-match "\\(\\w+\\)$" line)
832 (setq month (match-string 1 line) 921 (setq month (match-string 1 line)
833 line (substring line 0 -4)) 922 line (substring line 0 -4))
834 (return)) 923 (return))
835 924
836 ;; weekday 925 ;; weekday.
837 (if (string-match "\\(\\w+\\)$" line) 926 (if (string-match "\\(\\w+\\)$" line)
838 (setq line (substring line 0 -5)) 927 (setq line (substring line 0 -5))
839 (return)) 928 (return))
840 929
841 ;; size 930 ;; size.
842 (if (string-match "\\([0-9]+\\)$" line) 931 (if (string-match "\\([0-9]+\\)$" line)
843 (let ((length (- (max 10 (1+ (length (match-string 1 line))))))) 932 (let ((length (- (max 10 (1+ (length (match-string 1 line)))))))
844 (setq size (string-to-number (match-string 1 line))) 933 (setq size (string-to-number (match-string 1 line)))
@@ -847,7 +936,7 @@ Result is the list (LOCALNAME MODE SIZE MTIME)."
847 (setq line (substring line 0 length))) 936 (setq line (substring line 0 length)))
848 (return)) 937 (return))
849 938
850 ;; mode: ARCH, DIR, HIDDEN, RONLY, SYSTEM, VOLID 939 ;; mode: ARCH, DIR, HIDDEN, RONLY, SYSTEM, VOLID.
851 (if (string-match "\\([ADHRSV]+\\)?$" line) 940 (if (string-match "\\([ADHRSV]+\\)?$" line)
852 (setq 941 (setq
853 mode (or (match-string 1 line) "") 942 mode (or (match-string 1 line) "")
@@ -860,7 +949,7 @@ Result is the list (LOCALNAME MODE SIZE MTIME)."
860 line (substring line 0 -7)) 949 line (substring line 0 -7))
861 (return)) 950 (return))
862 951
863 ;; localname 952 ;; localname.
864 (if (string-match "^\\s-+\\(\\S-\\(.*\\S-\\)?\\)\\s-*$" line) 953 (if (string-match "^\\s-+\\(\\S-\\(.*\\S-\\)?\\)\\s-*$" line)
865 (setq localname (match-string 1 line)) 954 (setq localname (match-string 1 line))
866 (return)))) 955 (return))))
@@ -876,7 +965,7 @@ Result is the list (LOCALNAME MODE SIZE MTIME)."
876 (list localname mode size mtime)))) 965 (list localname mode size mtime))))
877 966
878 967
879;; Connection functions 968;; Connection functions.
880 969
881(defun tramp-smb-send-command (vec command) 970(defun tramp-smb-send-command (vec command)
882 "Send the COMMAND to connection VEC. 971 "Send the COMMAND to connection VEC.
@@ -894,8 +983,32 @@ connection if a previous connection has died for some reason."
894 (buf (tramp-get-buffer vec)) 983 (buf (tramp-get-buffer vec))
895 (p (get-buffer-process buf))) 984 (p (get-buffer-process buf)))
896 985
986 ;; Check whether we still have the same smbclient version.
987 ;; Otherwise, we must delete the connection cache, because
988 ;; capabilities migh have changed.
989 (unless (processp p)
990 (unless (let ((default-directory
991 (tramp-compat-temporary-file-directory)))
992 (executable-find tramp-smb-program))
993 (tramp-error
994 vec 'file-error
995 "Cannot find command %s in %s" tramp-smb-program exec-path))
996
997 (let* ((default-directory (tramp-compat-temporary-file-directory))
998 (smbclient-version
999 (shell-command-to-string (concat tramp-smb-program " -V"))))
1000 (unless (string-equal
1001 smbclient-version
1002 (tramp-get-connection-property vec "smbclient-version" ""))
1003 (tramp-flush-directory-property vec "")
1004 (tramp-flush-connection-property vec)
1005 (tramp-set-connection-property
1006 vec "smbclient-version" smbclient-version)
1007 (setq buf (tramp-get-buffer vec)))))
1008
897 ;; If too much time has passed since last command was sent, look 1009 ;; If too much time has passed since last command was sent, look
898 ;; whether has been an error message; maybe due to connection timeout. 1010 ;; whether there has been an error message; maybe due to
1011 ;; connection timeout.
899 (with-current-buffer buf 1012 (with-current-buffer buf
900 (goto-char (point-min)) 1013 (goto-char (point-min))
901 (when (and (> (tramp-time-diff 1014 (when (and (> (tramp-time-diff
@@ -920,11 +1033,6 @@ connection if a previous connection has died for some reason."
920 (when buf (with-current-buffer buf (erase-buffer))) 1033 (when buf (with-current-buffer buf (erase-buffer)))
921 (when (and p (processp p)) (delete-process p)) 1034 (when (and p (processp p)) (delete-process p))
922 1035
923 (unless (let ((default-directory
924 (tramp-compat-temporary-file-directory)))
925 (executable-find tramp-smb-program))
926 (error "Cannot find command %s in %s" tramp-smb-program exec-path))
927
928 (let* ((user (tramp-file-name-user vec)) 1036 (let* ((user (tramp-file-name-user vec))
929 (host (tramp-file-name-host vec)) 1037 (host (tramp-file-name-host vec))
930 (real-user (tramp-file-name-real-user vec)) 1038 (real-user (tramp-file-name-real-user vec))
@@ -962,17 +1070,12 @@ connection if a previous connection has died for some reason."
962 (tramp-message 1070 (tramp-message
963 vec 6 "%s" (mapconcat 'identity (process-command p) " ")) 1071 vec 6 "%s" (mapconcat 'identity (process-command p) " "))
964 (tramp-set-process-query-on-exit-flag p nil) 1072 (tramp-set-process-query-on-exit-flag p nil)
965 (tramp-set-connection-property p "smb-share" share)
966 1073
967 ;; Set variables for computing the prompt for reading password. 1074 ;; Set variables for computing the prompt for reading password.
968 (setq tramp-current-method tramp-smb-method 1075 (setq tramp-current-method tramp-smb-method
969 tramp-current-user user 1076 tramp-current-user user
970 tramp-current-host host) 1077 tramp-current-host host)
971 1078
972 ;; Set chunksize. Otherwise, `tramp-send-string' might
973 ;; try it itself.
974 (tramp-set-connection-property p "chunksize" tramp-chunksize)
975
976 ;; Play login scenario. 1079 ;; Play login scenario.
977 (tramp-process-actions 1080 (tramp-process-actions
978 p vec 1081 p vec
@@ -980,6 +1083,26 @@ connection if a previous connection has died for some reason."
980 tramp-smb-actions-with-share 1083 tramp-smb-actions-with-share
981 tramp-smb-actions-without-share)) 1084 tramp-smb-actions-without-share))
982 1085
1086 ;; Check server version.
1087 (with-current-buffer (tramp-get-connection-buffer vec)
1088 (goto-char (point-min))
1089 (search-forward-regexp
1090 "Domain=\\[[^]]*\\] OS=\\[[^]]*\\] Server=\\[[^]]*\\]" nil t)
1091 (let ((smbserver-version (match-string 0)))
1092 (when (not (string-equal
1093 smbserver-version
1094 (tramp-get-connection-property
1095 vec "smbserver-version" "")))
1096 (tramp-flush-directory-property vec "")
1097 (tramp-flush-connection-property vec)
1098 (tramp-set-connection-property
1099 vec "smbserver-version" smbserver-version))))
1100
1101 ;; Set chunksize. Otherwise, `tramp-send-string' might
1102 ;; try it itself.
1103 (tramp-set-connection-property p "smb-share" share)
1104 (tramp-set-connection-property p "chunksize" tramp-chunksize)
1105
983 (tramp-message 1106 (tramp-message
984 vec 3 "Opening connection for //%s%s/%s...done" 1107 vec 3 "Opening connection for //%s%s/%s...done"
985 (if (not (zerop (length user))) (concat user "@") "") 1108 (if (not (zerop (length user))) (concat user "@") "")
@@ -1033,8 +1156,7 @@ Returns nil if an error message has appeared."
1033 1156
1034;; * Error handling in case password is wrong. 1157;; * Error handling in case password is wrong.
1035;; * Read password from "~/.netrc". 1158;; * Read password from "~/.netrc".
1036;; * Return more comprehensive file permission string. Think whether it is 1159;; * Return more comprehensive file permission string.
1037;; possible to implement `set-file-modes'.
1038;; * Handle links (FILENAME.LNK). 1160;; * Handle links (FILENAME.LNK).
1039;; * Try to remove the inclusion of dummy "" directory. Seems to be at 1161;; * Try to remove the inclusion of dummy "" directory. Seems to be at
1040;; several places, especially in `tramp-smb-handle-insert-directory'. 1162;; several places, especially in `tramp-smb-handle-insert-directory'.