Function: tramp-smb-maybe-open-connection
tramp-smb-maybe-open-connection is a byte-compiled function defined in
tramp-smb.el.gz.
Signature
(tramp-smb-maybe-open-connection VEC &optional ARGUMENT)
Documentation
Maybe open a connection to HOST, log in as USER, using tramp-smb-program.
Does not do anything if a connection is already open, but re-opens the
connection if a previous connection has died for some reason.
If ARGUMENT is non-nil, use it as argument for
tramp-smb-winexe-program, and suppress any checks.
Source Code
;; Defined in /usr/src/emacs/lisp/net/tramp-smb.el.gz
(defun tramp-smb-maybe-open-connection (vec &optional argument)
"Maybe open a connection to HOST, log in as USER, using `tramp-smb-program'.
Does not do anything if a connection is already open, but re-opens the
connection if a previous connection has died for some reason.
If ARGUMENT is non-nil, use it as argument for
`tramp-smb-winexe-program', and suppress any checks."
;; During completion, don't reopen a new connection.
(unless (tramp-connectable-p vec)
(throw 'non-essential 'non-essential))
(let* ((share (tramp-smb-get-share vec))
(buf (tramp-get-connection-buffer vec))
(p (get-buffer-process buf)))
;; Check whether we still have the same smbclient version.
;; Otherwise, we must delete the connection cache, because
;; capabilities might have changed.
(unless (or argument (processp p))
(let ((default-directory tramp-compat-temporary-file-directory)
(command (concat tramp-smb-program " -V")))
(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-properties vec "")
(tramp-flush-connection-properties vec))
(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
;; connection timeout.
(with-current-buffer buf
(goto-char (point-min))
(when (and (time-less-p
60 (time-since
(tramp-get-connection-property p "last-cmd-time" 0)))
(process-live-p p)
(re-search-forward tramp-smb-errors nil t))
(delete-process p)
(setq p nil)))
;; Check whether it is still the same share.
(unless (and (process-live-p p)
(or argument
(string-equal
share
(tramp-get-connection-property p "smb-share" ""))))
(save-match-data
;; There might be unread output from checking for share names.
(when buf (with-current-buffer buf (erase-buffer)))
(when (and p (processp p)) (delete-process p))
(let* ((user (tramp-file-name-user vec))
(host (tramp-file-name-host vec))
(domain (tramp-file-name-domain vec))
(port (tramp-file-name-port vec))
(options tramp-smb-options)
args)
(cond
(argument
(setq args (list (concat "//" host))))
(share
(setq args (list (concat "//" host "/" share))))
(t
(setq args (list "-g" "-L" host ))))
(if (not (zerop (length user)))
(setq args (append args (list "-U" user)))
(setq args (append args (list "-N"))))
(when domain (setq args (append args (list "-W" domain))))
(when port (setq args (append args (list "-p" port))))
(when tramp-smb-conf
(setq args (append args (list "-s" tramp-smb-conf))))
(dolist (option options)
(setq args (append args (list "--option" option))))
(when argument
(setq args (append args (list argument))))
;; OK, let's go.
(with-tramp-progress-reporter
vec 3
(format "Opening connection for //%s%s/%s"
(if (not (zerop (length user))) (concat user "@") "")
host (or share ""))
(let* ((coding-system-for-read nil)
(process-connection-type tramp-process-connection-type)
(p (let ((default-directory
tramp-compat-temporary-file-directory)
(process-environment
(cons (concat "TERM=" tramp-terminal-type)
process-environment)))
(apply #'start-process
(tramp-get-connection-name vec)
(tramp-get-connection-buffer vec)
(if argument
tramp-smb-winexe-program tramp-smb-program)
args))))
(tramp-message vec 6 "%s" (string-join (process-command p) " "))
(process-put p 'vector vec)
(process-put p 'adjust-window-size-function #'ignore)
(set-process-query-on-exit-flag p nil)
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)
(condition-case err
(let ((inhibit-message t))
;; Play login scenario.
(tramp-process-actions
p vec nil
(if (or argument share)
tramp-smb-actions-with-share
tramp-smb-actions-without-share))
;; Check server version.
;; FIXME: With recent smbclient versions, this
;; information isn't printed anymore.
;; (unless argument
;; (with-current-buffer (tramp-get-connection-buffer vec)
;; (goto-char (point-min))
;; (search-forward-regexp tramp-smb-server-version nil t)
;; (let ((smbserver-version (match-string 0)))
;; (unless
;; (string-equal
;; smbserver-version
;; (tramp-get-connection-property
;; vec "smbserver-version" smbserver-version))
;; (tramp-flush-directory-properties vec "")
;; (tramp-flush-connection-properties vec))
;; (tramp-set-connection-property
;; vec "smbserver-version" smbserver-version))))
;; Set chunksize to 1. smbclient reads its input
;; character by character; if we send the string
;; at once, it is read painfully slow.
(tramp-set-connection-property p "smb-share" share)
(tramp-set-connection-property p "chunksize" 1)
;; Mark it as connected.
(tramp-set-connection-property p "connected" t))
;; Check for the error reason. If it was due to wrong
;; password, reestablish the connection. We cannot
;; handle this in `tramp-process-actions', because
;; smbclient does not ask for the password, again.
(error
(with-current-buffer (tramp-get-connection-buffer vec)
(goto-char (point-min))
(if (and (bound-and-true-p auth-sources)
(search-forward-regexp
tramp-smb-wrong-passwd-regexp nil t))
;; Disable `auth-source' and `password-cache'.
(let (auth-sources)
(tramp-message
vec 3 "Retry connection with new password")
(tramp-cleanup-connection vec t)
(tramp-smb-maybe-open-connection vec argument))
;; Propagate the error.
(signal (car err) (cdr err)))))))))))))