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))
(with-tramp-debug-message vec "Opening connection"
(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 (rx (+ (any " \t\r\n")) eos) 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)
(search-forward-regexp 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 (tramp-string-empty-or-nil-p user)
(setq args (append args (list "-N")))
(setq args (append args (list "-U" user))))
(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 (tramp-string-empty-or-nil-p user)
"" (concat user "@"))
host (or share ""))
(let* (coding-system-for-read
(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-post-process-creation p vec)
;; 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))
;; 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))))))))))))))