/[tramp]/tramp/lisp/tramp-smb.el
ViewVC logotype

Diff of /tramp/lisp/tramp-smb.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2.2 by albinus, Sun Oct 27 21:35:08 2002 UTC revision 2.3 by albinus, Sun Nov 3 22:34:54 2002 UTC
# Line 49  Change it only if you know what you do." Line 49  Change it only if you know what you do."
49    :type 'string)    :type 'string)
50    
51  ;; ... and add it to the method list.  ;; ... and add it to the method list.
52  (add-to-list 'tramp-methods (cons tramp-smb-method nil))  (when tramp-use-smb
53      (add-to-list 'tramp-methods (cons tramp-smb-method nil)))
54    
55  ;; Add completion function for SMB method.  ;; Add completion function for SMB method.
56  (unless (memq system-type '(windows-nt))  (when tramp-use-smb
57    (tramp-set-completion-function    (tramp-set-completion-function
58     tramp-smb-method     tramp-smb-method
59     '((tramp-parse-netrc "~/.netrc"))))     '((tramp-parse-netrc "~/.netrc"))))
# Line 62  Change it only if you know what you do." Line 63  Change it only if you know what you do."
63    :group 'tramp    :group 'tramp
64    :type 'string)    :type 'string)
65    
66  (defconst tramp-smb-prompt "smb: \\> "  (defconst tramp-smb-prompt "^smb: \\S-+> "
67    "String used as prompt in smbclient.")    "Regexp used as prompt in smbclient.")
68    
69    (defconst tramp-smb-line
70      (mapconcat
71       'identity
72       '("^"
73         "\\(\\S-+\\)"                ; file name
74         "\\([ADHRS]*\\)"             ; permissions
75         "\\([0-9]+\\)"               ; size
76         "\\(\\w+\\)"                 ; weekday
77         "\\(\\w+\\)"                 ; month
78         "\\([0-9]+\\)"               ; day
79         "\\([0-9]+:[0-9]+\\):[0-9]+" ; time
80         "\\([0-9]+\\)$")             ; year
81       "\\s-+")
82      "Regexp describing line format of DIR listings in smbclient.")
83    
84    (defconst tramp-smb-errors
85      (mapconcat
86       'identity
87       '("ERRSRV" "ERRbadpw" "ERRDOS") ; Samba
88       "\\|")
89      "Regexp for possible error strings of SMB servers.
90    Used instead of analyzing error codes of commands.")
91    
92  ;; New handlers should be added here.  ;; New handlers should be added here.
93  (defconst tramp-smb-file-name-handler-alist  (defconst tramp-smb-file-name-handler-alist
94    '(    '(
95  ;    (load . tramp-handle-load)      ;; `access-file' performed by default handler
96  ;    (make-symbolic-link . tramp-handle-make-symbolic-link)      (add-name-to-file . tramp-smb-not-handled)
97  ;    (file-name-directory . tramp-handle-file-name-directory)      ;; `byte-compiler-base-file-name' performed by default handler
98  ;    (file-name-nondirectory . tramp-handle-file-name-nondirectory)      (copy-file . tramp-smb-not-handled)
99  ;    (file-truename . tramp-handle-file-truename)      (delete-directory . tramp-smb-not-handled)
100        (delete-file . tramp-smb-not-handled)
101        (diff-latest-backup-file . tramp-smb-not-handled)
102        ;; `directory-file-name' performed by default handler
103        (directory-files . tramp-smb-not-handled)
104        (directory-files-and-attributes . tramp-smb-not-handled)
105        (dired-call-process . tramp-smb-not-handled)
106        (dired-compress-file . tramp-smb-not-handled)
107        ;; `dired-uncache' performed by default handler
108        ;; `expand-file-name' not necessary because we cannot expand "~/"
109        (file-accessible-directory-p . tramp-smb-handle-file-directory-p)
110        (file-attributes . tramp-smb-not-handled)
111        (file-directory-p .  tramp-smb-handle-file-directory-p)
112        (file-executable-p . tramp-smb-handle-file-exists-p)
113      (file-exists-p . tramp-smb-handle-file-exists-p)      (file-exists-p . tramp-smb-handle-file-exists-p)
114  ;    (file-directory-p . tramp-handle-file-directory-p)      (file-local-copy . tramp-smb-handle-file-local-copy)
115  ;    (file-executable-p . tramp-handle-file-executable-p)      (file-modes . tramp-smb-not-handled)
116  ;    (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)      (file-name-all-completions . tramp-smb-not-handled)
117  ;    (file-readable-p . tramp-handle-file-readable-p)      ;; `file-name-as-directory' performed by default handler
118  ;    (file-regular-p . tramp-handle-file-regular-p)      (file-name-completion . tramp-smb-not-handled)
119  ;    (file-symlink-p . tramp-handle-file-symlink-p)      (file-name-directory . tramp-handle-file-name-directory)
120  ;    (file-writable-p . tramp-handle-file-writable-p)      (file-name-nondirectory . tramp-handle-file-name-nondirectory)
121  ;    (file-ownership-preserved-p . tramp-handle-file-ownership-preserved-p)      ;; `file-name-sans-versions' performed by default handler
122  ;    (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)      (file-newer-than-file-p . tramp-smb-not-handled)
123  ;    (file-attributes . tramp-handle-file-attributes)      (file-ownership-preserved-p . tramp-smb-not-handled)
124  ;    (file-modes . tramp-handle-file-modes)      (file-readable-p . tramp-smb-handle-file-exists-p)
125  ;    (file-directory-files . tramp-handle-file-directory-files)      (file-regular-p . tramp-smb-not-handled)
126  ;    (directory-files . tramp-handle-directory-files)      (file-symlink-p . tramp-smb-handle-file-symlink-p)
127  ;    (file-name-all-completions . tramp-handle-file-name-all-completions)      ;; `file-truename' performed by default handler
128  ;    (file-name-completion . tramp-handle-file-name-completion)      (file-writable-p . tramp-smb-handle-file-writable-p)
129  ;    (add-name-to-file . tramp-handle-add-name-to-file)      (find-backup-file-name . tramp-smb-not-handled)
130  ;    (copy-file . tramp-handle-copy-file)      (find-file-noselect . tramp-smb-not-handled)
131  ;    (rename-file . tramp-handle-rename-file)      ;; `get-file-buffer' performed by default handler
132  ;    (set-file-modes . tramp-handle-set-file-modes)      (insert-directory . tramp-smb-handle-insert-directory)
133  ;    (make-directory . tramp-handle-make-directory)      (insert-file-contents . tramp-handle-insert-file-contents)
134  ;    (delete-directory . tramp-handle-delete-directory)      (load . tramp-smb-not-handled)
135  ;    (delete-file . tramp-handle-delete-file)      (make-directory . tramp-smb-not-handled)
136  ;    (directory-file-name . tramp-handle-directory-file-name)      (make-directory-internal . tramp-smb-not-handled)
137  ;    (shell-command . tramp-handle-shell-command)      (make-symbolic-link . tramp-smb-not-handled)
138  ;    (insert-directory . tramp-handle-insert-directory)      (rename-file . tramp-smb-not-handled)
139  ;    (expand-file-name . tramp-handle-expand-file-name)      (set-file-modes . tramp-smb-not-handled)
140  ;    (file-local-copy . tramp-handle-file-local-copy)      (set-visited-file-modtime . tramp-smb-not-handled)
141  ;    (insert-file-contents . tramp-handle-insert-file-contents)      (shell-command . tramp-smb-not-handled)
142  ;    (write-region . tramp-handle-write-region)      ;; `substitute-in-file-name' performed by default handler
143  ;    (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)      (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
144  ;    (dired-call-process . tramp-handle-dired-call-process)      ;; `vc-registered' performed by default handler
145  ;    (dired-recursive-delete-directory      (verify-visited-file-modtime . tramp-smb-not-handled)
146  ;     . tramp-handle-dired-recursive-delete-directory)      (write-region . tramp-smb-not-handled)
147  ;    (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)  )
148  ;    (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime))    "Alist of handler functions for Tramp SMB method.
149  )        "Alist of handler functions.  Operations not mentioned here will be handled by the default Emacs primitives.")
 Operations not mentioned here will be handled by the normal Emacs functions.")  
150    
151  (defun tramp-smb-file-name-p (filename)  (defun tramp-smb-file-name-p (filename)
152    "Check if it's a filename for SMB servers."    "Check if it's a filename for SMB servers."
# Line 127  Operations not mentioned here will be ha Line 163  Operations not mentioned here will be ha
163    "Invoke the SMB related OPERATION.    "Invoke the SMB related OPERATION.
164  First arg specifies the OPERATION, second arg is a list of arguments to  First arg specifies the OPERATION, second arg is a list of arguments to
165  pass to the OPERATION."  pass to the OPERATION."
   ; temporarily disable SMB as long as under development  
   (unless tramp-use-smb (error "SMB method not supported yet"))  
166    (let ((fn (assoc operation tramp-smb-file-name-handler-alist)))    (let ((fn (assoc operation tramp-smb-file-name-handler-alist)))
167      (if fn      (if fn
168          (save-match-data (apply (cdr fn) args))          (if (equal (cdr fn) 'tramp-smb-not-handled)
169                (apply (cdr fn) operation args)
170              (save-match-data (apply (cdr fn) args)))
171        (tramp-run-real-handler operation args))))        (tramp-run-real-handler operation args))))
172    
173  (add-to-list 'tramp-foreign-file-name-handler-alist  (when tramp-use-smb
174               (cons 'tramp-smb-file-name-p 'tramp-smb-file-name-handler))    (add-to-list 'tramp-foreign-file-name-handler-alist
175                   (cons 'tramp-smb-file-name-p 'tramp-smb-file-name-handler)))
176    
177  ;; File name primitives  ;; File name primitives
178    
179    (defun tramp-smb-not-handled (operation &rest args)
180      "Default handler for all functions.
181    Used during development in order to get an impression what's left to do."
182      (tramp-message 1 "Not handled yet: %s %s" operation args)
183      (tramp-run-real-handler operation args))
184    
185    (defun tramp-handle-file-attributes (filename &optional nonnumeric)
186      "Like `file-attributes' for tramp files.
187    Optional argument NONNUMERIC means return user and group name
188    rather than as numbers."
189      (with-parsed-tramp-file-name filename nil
190        (save-excursion
191          (let* ((share (tramp-smb-get-share path))
192                 (file  (tramp-smb-get-path  path))
193                 (entry (tramp-smb-get-file-entry user host share file)))
194            ; check result
195            (and (nth 1 entry)
196                 (string-match "D" (nth 1 entry)))))))
197    
198    (defun tramp-smb-handle-file-directory-p (filename)
199      "Like `file-directory-p' for tramp files."
200      (with-parsed-tramp-file-name filename nil
201        (save-excursion
202          (let* ((share (tramp-smb-get-share path))
203                 (file  (tramp-smb-get-path  path))
204                 (entry (tramp-smb-get-file-entry user host share file)))
205            ; check result
206            (and (nth 1 entry)
207                 (string-match "D" (nth 1 entry)))))))
208    
209  (defun tramp-smb-handle-file-exists-p (filename)  (defun tramp-smb-handle-file-exists-p (filename)
210    "Like `file-exists-p' for tramp files."    "Like `file-exists-p' for tramp files."
211    (with-parsed-tramp-file-name filename nil    (with-parsed-tramp-file-name filename nil
# Line 147  pass to the OPERATION." Line 214  pass to the OPERATION."
214               (file  (tramp-smb-get-path  path))               (file  (tramp-smb-get-path  path))
215               (entry (tramp-smb-get-file-entry user host share file)))               (entry (tramp-smb-get-file-entry user host share file)))
216          ; check result          ; check result
217          (string-equal (car entry) (file-name-nondirectory file))))))          (and file (nth 0 entry)
218                 (string-equal (file-name-nondirectory file) (nth 0 entry)))))))
219    
220    (defun tramp-smb-handle-file-local-copy (filename)
221      "Like `file-local-copy' for tramp files."
222      (with-parsed-tramp-file-name filename nil
223        (let ((share (tramp-smb-get-share path))
224              (file  (tramp-smb-get-path  path))
225              (tmpfil (tramp-make-temp-file)))
226          (unless (file-exists-p filename)
227            (error "Cannot make local copy of non-existing file `%s'" filename))
228          (tramp-message-for-buffer
229           nil tramp-smb-method user host
230           5 "Fetching %s to tmp file %s..." filename tmpfil)
231          (tramp-smb-maybe-open-connection user host share)
232          (tramp-smb-send-command user host (format "get %s %s" file tmpfil))
233          (tramp-message-for-buffer
234           nil tramp-smb-method user host
235           5 "Fetching %s to tmp file %s...done" filename tmpfil)
236        tmpfil)))
237    
238    (defun tramp-smb-handle-file-symlink-p (filename)
239      "Like `file-symlink-p' for tramp files."
240      nil)
241    
242    (defun tramp-smb-handle-file-writable-p (filename)
243      "Like `file-writable-p' for tramp files."
244      (with-parsed-tramp-file-name filename nil
245        (save-excursion
246          (let* ((share (tramp-smb-get-share path))
247                 (file  (tramp-smb-get-path  path))
248                 (entry (tramp-smb-get-file-entry user host share file)))
249            ; check result
250            (and (nth 1 entry)
251                 (not (string-match "R" (nth 1 entry))))))))
252    
253    (defun tramp-smb-handle-insert-directory
254      (filename switches &optional wildcard full-directory-p)
255      "Like `insert-directory' for tramp files.
256    SWITCHES, WILDCARD and FULL-DIRECTORY-P are not handled."
257      (setq filename (expand-file-name filename))
258      (with-parsed-tramp-file-name filename nil
259        (save-excursion
260          (save-match-data
261            (let* ((share (tramp-smb-get-share path))
262                   (file  (tramp-smb-get-path  path))
263                   entry list)
264              (tramp-message-for-buffer
265               nil tramp-smb-method user host 10
266               "Inserting directory `dir %s'" path)
267              (tramp-smb-maybe-open-connection user host share)
268              (tramp-smb-send-command user host (format "dir %s*" file))
269              (insert-buffer-substring
270               (tramp-get-buffer nil tramp-smb-method user host))
271    
272              ;; read entries
273              (beginning-of-buffer)
274              (while (setq entry (tramp-smb-read-file-entry))
275                (add-to-list 'list entry)
276                (delete-region (point) (1+ (tramp-point-at-eol))))
277    
278              (delete-region (point) (re-search-forward "\\s-+"))
279              (forward-line 1)
280              (delete-region (point) (point-max))
281    
282              ; print entries
283              (mapcar
284               '(lambda (x)
285                  (let ((mode (concat
286                          (if (string-match "D" (nth 1 x)) "d" "-") "r"
287                          (if (string-match "R" (nth 1 x)) "-" "w") "x------")))
288                    (insert
289                     (format
290                      "%10s %3d %-8s %-8s %8s %3s %2s %5s %s\n"
291                      mode 1 "nouser" "nogroup"
292                      (nth 2 x) ; size
293                      (nth 3 x) ; month
294                      (nth 4 x) ; day
295                      (if (equal (format-time-string "%Y")
296                                 (nth 6 x))
297                          (nth 5 x) ; time
298                        (nth 6 x)) ; year
299                      (nth 0 x))) ; file name
300                    (forward-line)
301                    (beginning-of-line)))
302               (sort list '(lambda (x y) (string-lessp (nth 0 x) (nth 0 y))))))))))
303    
304  ;; Internal file name functions  ;; Internal file name functions
305    
306  (defun tramp-smb-get-share (path)  (defun tramp-smb-get-share (path)
307    "Returns the share name of PATH."    "Returns the share name of PATH."
308    (save-match-data    (save-match-data
309      (string-match "^/?\\([^/]+\\)" path)      (when (string-match "^/?\\([^/]+\\)" path)
310      (match-string 1 path)))        (match-string 1 path))))
311    
312  (defun tramp-smb-get-path (path)  (defun tramp-smb-get-path (path)
313    "Returns the file name of PATH."    "Returns the file name of PATH."
314    (save-match-data    (save-match-data
315      (string-match "^/?[^/]+/\\(.*\\)" path)      (when (string-match "^/?[^/]+/\\(.*\\)" path)
316      (match-string 1 path)))        (match-string 1 path))))
317    
318  (defun tramp-smb-get-file-entry (user host share path)  (defun tramp-smb-get-file-entry (user host share path)
319    "Read entry PATH with the `dir' command.    "Read entry PATH with the `dir' command.
320  Result is the list (PATH MODE SIZE DATE)."  Result is the list (PATH MODE SIZE MONTH DAY TIME YEAR)."
321    (tramp-smb-maybe-open-connection user host share)    (save-excursion
322    (tramp-smb-send-command user host (concat "dir " path))      (set-buffer (tramp-get-buffer nil tramp-smb-method user host))
323    (tramp-smb-wait-for-output 10)      (tramp-smb-maybe-open-connection user host share)
324    (goto-char (point-min))      (tramp-smb-send-command user host (concat "dir " path))
325    (unless (re-search-forward "ERRDOS" nil t)      (goto-char (point-min))
326      (let ((line (buffer-substring (point-min) (tramp-point-at-eol))))      (unless (re-search-forward tramp-smb-errors nil t)
327        (string-match        (tramp-smb-read-file-entry))))
328         (concat "^[ \t]+\\([^ \t]+\\)"  
329                  "[ \t]+\\([^ \t]+\\)"  (defun tramp-smb-read-file-entry ()
330                  "[ \t]+\\([^ \t]+\\)"    "Parse entry in SMB output buffer.
331                  "[ \t]+\\(.+\\)[ \t]*$")  Result is the list (PATH MODE SIZE MONTH DAY TIME YEAR)."
332         line)    (let ((line (buffer-substring (point) (tramp-point-at-eol))))
333        (list (match-string 1 line) (match-string 2 line)      (when (string-match tramp-smb-line line)
334              (match-string 3 line) (match-string 4 line)))))        (list
335           (match-string 1 line)     ; file name
336           (match-string 2 line)     ; permissions
337           (match-string 3 line)     ; size
338           (match-string 5 line)     ; month
339           (match-string 6 line)     ; day
340           (match-string 7 line)     ; time
341           (match-string 8 line))))) ; year
342    
343    
344  ;; Connection functions  ;; Connection functions
345    
346  (defun tramp-smb-send-command (user host command)  (defun tramp-smb-send-command (user host command)
347    "Send the COMMAND to USER at HOST (logged into an SMB session).    "Send the COMMAND to USER at HOST (logged into an SMB session).
348  Erases temporary buffer before sending the command."  Erases temporary buffer before sending the command.
349    (tramp-send-command nil "smb" user host command nil t))  Returns nil in case of unsuccessfull execution."
350      (save-excursion
351        (set-buffer (tramp-get-buffer nil tramp-smb-method user host))
352        (tramp-send-command nil tramp-smb-method user host command nil t)
353        (and
354         (tramp-smb-wait-for-output user host)
355         (save-match-data (not (re-search-forward tramp-smb-errors nil t))))))
356    
357  (defun tramp-smb-maybe-open-connection (user host share)  (defun tramp-smb-maybe-open-connection (user host share)
358    "Maybe open a connection to HOST, logging in as USER, using `tramp-smb-program'.    "Maybe open a connection to HOST, logging in as USER, using `tramp-smb-program'.
359  Does not do anything if a connection is already open, but re-opens the  Does not do anything if a connection is already open, but re-opens the
360  connection if a previous connection has died for some reason."  connection if a previous connection has died for some reason."
361    (let ((p (get-buffer-process (tramp-get-buffer nil "smb" user host)))    (let ((p (get-buffer-process
362                (tramp-get-buffer nil tramp-smb-method user host)))
363          last-cmd-time)          last-cmd-time)
     ;; If too much time has passed since last command was sent, look  
     ;; whether process is still alive.  If it isn't, kill it.  When  
     ;; using ssh, it can sometimes happen that the remote end has hung  
     ;; up but the local ssh client doesn't recognize this until it  
     ;; tries to send some data to the remote end.  So that's why we  
     ;; try to send a command from time to time, then look again  
     ;; whether the process is really alive.  
364      (save-excursion      (save-excursion
365        (set-buffer (tramp-get-buffer nil "smb" user host))        (set-buffer (tramp-get-buffer nil tramp-smb-method user host))
366          ;; Check whether it is still the same share
367          (unless (and p (processp p) (string-equal smb-share share))
368            (when (and p (processp p))
369              (delete-process p)
370              (setq p nil)))
371          ;; If too much time has passed since last command was sent, look
372          ;; whether process is still alive.  If it isn't, kill it.
373        (when (and tramp-last-cmd-time        (when (and tramp-last-cmd-time
374                   (> (tramp-time-diff (current-time) tramp-last-cmd-time) 60)                   (> (tramp-time-diff (current-time) tramp-last-cmd-time) 60)
375                   p (processp p) (memq (process-status p) '(run open)))                   p (processp p) (memq (process-status p) '(run open)))
376          (tramp-smb-send-command user host "help")          (unless (tramp-smb-send-command user host "help")
         (unless (tramp-smb-wait-for-output 10)  
377            (delete-process p)            (delete-process p)
378            (setq p nil))            (setq p nil))
379          (erase-buffer)))          (erase-buffer)))
# Line 226  then sends the password to the remote ho Line 391  then sends the password to the remote ho
391  If USER is nil, uses value returned by `(user-login-name)' instead."  If USER is nil, uses value returned by `(user-login-name)' instead."
392    
393    (save-match-data    (save-match-data
394      (tramp-pre-connection nil "smb" user host)      (let* ((user (or user (user-login-name)))
395      (tramp-message 7 "Opening connection for //%s@%s/%s..."             (buffer (tramp-get-buffer nil tramp-smb-method user host)))
396                     (or user (user-login-name)) host share)        (tramp-pre-connection nil tramp-smb-method user host)
397      (let ((process-environment (copy-sequence process-environment)))        (tramp-message 7 "Opening connection for //%s@%s/%s..." user host share)
       (setenv "TERM" tramp-terminal-type)  
398        (let* ((default-directory (tramp-temporary-file-directory))        (let* ((default-directory (tramp-temporary-file-directory))
399               ;; If we omit the conditional here, then we would use               ;; If we omit the conditional here, then we would use
400               ;; `undecided-dos' in some cases.  With the conditional,               ;; `undecided-dos' in some cases.  With the conditional,
401               ;; we use nil in these cases.  Which one is right?               ;; we use nil in these cases.  Which one is right?
402               (coding-system-for-read (unless (and (not (featurep 'xemacs))               (coding-system-for-read (unless (and (not (featurep 'xemacs))
403                                                    (> emacs-major-version 20))                                                    (> emacs-major-version 20))
404                                         tramp-dos-coding-system))                                         tramp-dos-coding-system))
405               (p (funcall 'start-process               (p (funcall 'start-process
406                           (tramp-buffer-name nil "smb" user host)                           (buffer-name buffer)
407                           (tramp-get-buffer nil "smb" user host)                           buffer
408                           tramp-smb-program                           tramp-smb-program
409                           (concat "//" host "/" share)                           (concat "//" host "/" share)
410                           "-U" user)))                           "-U" user)))
411          (process-kill-without-query p)          (process-kill-without-query p)
412          (set-buffer (tramp-get-buffer nil "smb" user host))          (set-buffer buffer)
413            (set (make-local-variable 'smb-share) share)
414    
415          ; send password          ; send password
416          (let ((pw-prompt "Password:"))          (let ((pw-prompt "Password:"))
417            (tramp-message 9 "Sending password")            (tramp-message 9 "Sending password")
418            (tramp-enter-password p pw-prompt))            (tramp-enter-password p pw-prompt))
419    
420          (tramp-smb-wait-for-output 10))))          (when (tramp-smb-wait-for-output user host)
421          (erase-buffer))            (erase-buffer))))))
422    
423  (defun tramp-smb-wait-for-output (&optional timeout)  (defun tramp-smb-wait-for-output (user host)
424    "Wait for output from remote smbclient command."    "Wait for output from smbclient command.
425    (let ((proc (get-buffer-process (current-buffer)))  Sets position to begin of buffer.  Returns nil if `tramp-smb-prompt'
426          (found nil)  is not found."
427          (start-time (current-time))    (save-excursion
428          (end-of-output (concat "^" (regexp-quote tramp-smb-prompt))))      (let ((proc (get-buffer-process (current-buffer)))
429              (found nil)
430              (start-time (current-time))
431              (timeout 10))
432      ;; Algorithm: get waiting output.  See if last line contains      ;; Algorithm: get waiting output.  See if last line contains
433      ;; end-of-output sentinel.  If not, wait a bit and again get      ;; tramp-smb-prompt sentinel.  If not, wait a bit and again get
434      ;; waiting output.  Repeat until timeout expires or end-of-output      ;; waiting output.  Repeat until timeout expires or tramp-smb-prompt
435      ;; sentinel is seen.  Will hang if timeout is nil and      ;; sentinel is seen.
436      ;; end-of-output sentinel never appears.        (save-match-data
437      (save-match-data          ;; Work around an XEmacs bug, where the timeout expires
438        (cond (timeout          ;; faster than it should.  This degenerates into polling
439               ;; Work around an XEmacs bug, where the timeout expires          ;; for buggy XEmacsen, but oh, well.
440               ;; faster than it should.  This degenerates into polling          (while (and (not found)
441               ;; for buggy XEmacsen, but oh, well.                      (< (tramp-time-diff (current-time) start-time)
442               (while (and (not found)                         timeout))
443                           (< (tramp-time-diff (current-time) start-time)            (with-timeout (timeout)
444                              timeout))              (while (not found)
445                 (with-timeout (timeout)                (accept-process-output proc 1)
446                   (while (not found)                (goto-char (point-max))
447                     (accept-process-output proc 1)                (beginning-of-line)
448                     (goto-char (point-max))                (setq found (looking-at tramp-smb-prompt))))))
449                     (beginning-of-line)        ;; Add output to debug buffer if appropriate.
450                     (setq found (looking-at end-of-output))))))        (when tramp-debug-buffer
451              (t          (append-to-buffer
452               (while (not found)           (tramp-get-debug-buffer nil tramp-smb-method user host)
453                 (accept-process-output proc 1)           (point-min) (point-max))
454                 (goto-char (point-max))          (when (not found)
455                 (forward-line -1)            (save-excursion
456                 (setq found (looking-at end-of-output))))))              (set-buffer
457      ;; Add output to debug buffer if appropriate.               (tramp-get-debug-buffer nil tramp-smb-method user host))
458      (when tramp-debug-buffer              (goto-char (point-max))
459        (append-to-buffer              (insert (format "[[Remote prompt `%s' not found in %d secs]]\n"
460         (tramp-get-debug-buffer tramp-current-multi-method tramp-current-method                              tramp-smb-prompt timeout)))))
461                               tramp-current-user tramp-current-host)        (goto-char (point-min))
462         (point-min) (point-max))        ;; Return value is whether tramp-smb-prompt sentinel was found.
463        (when (not found)        found)))
         (save-excursion  
           (set-buffer  
            (tramp-get-debug-buffer tramp-current-multi-method tramp-current-method  
                                  tramp-current-user tramp-current-host))  
           (goto-char (point-max))  
           (insert "[[Remote prompt `" end-of-output "' not found"  
                   (if timeout (format " in %d secs" timeout) "")  
                   "]]"))))  
     (goto-char (point-min))  
     ;; Return value is whether end-of-output sentinel was found.  
     found))  
464    
465  (provide 'tramp-smb)  (provide 'tramp-smb)
466    
467  ;;; TODO:  ;;; TODO:
468    
469  ;; * Provide a local smb.conf. The default one might not be readable  ;; * Provide a local smb.conf. The default one might not be readable.
470    ;; * Error handling in most of the functions. Brrrr.
471    ;; * Read password from "~/.netrc".
472    ;; * Update documentation.
473    ;; * Provide variables for debug.
474    
475  ;;; tramp-smb.el ends here  ;;; tramp-smb.el ends here

Legend:
Removed from v.2.2  
changed lines
  Added in v.2.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26