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 (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)
		 (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 (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-message vec 6 "%s" (string-join (process-command p) " "))
	      (process-put p 'tramp-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))

		    ;; 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)))))))))))))