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