Function: tramp-gvfs-maybe-open-connection

tramp-gvfs-maybe-open-connection is a byte-compiled function defined in tramp-gvfs.el.gz.

Signature

(tramp-gvfs-maybe-open-connection VEC)

Documentation

Maybe open a connection VEC.

Does not do anything if a connection is already open, but re-opens the connection if a previous connection has died for some reason.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp-gvfs.el.gz
(defun tramp-gvfs-maybe-open-connection (vec)
  "Maybe open a connection VEC.
Does not do anything if a connection is already open, but re-opens the
connection if a previous connection has died for some reason."
  ;; 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"
    ;; Sanity check.
    (let ((method (tramp-file-name-method vec)))
      (unless (member
	       (or (assoc-default
		    method '(("smb" . "smb-share")
			     ("davs" . "dav")
			     ("nextcloud" . "dav")
			     ("afp" . "afp-volume")
			     ("gdrive" . "google-drive")))
		   method)
	       tramp-gvfs-mounttypes)
	(tramp-error
	 vec 'file-error "Method `%s' not supported by GVFS" method)))

    ;; For password handling, we need a process bound to the
    ;; connection buffer.  Therefore, we create a dummy process.
    ;; Maybe there is a better solution?
    (unless (get-buffer-process (tramp-get-connection-buffer vec))
      (let ((p (make-network-process
		:name (tramp-get-connection-name vec)
		:buffer (tramp-get-connection-buffer vec)
		:server t :host 'local :service t :noquery t)))
	(tramp-post-process-creation p vec)

	;; Set connection-local variables.
	(tramp-set-connection-local-variables vec)))

    (unless (tramp-gvfs-connection-mounted-p vec)
      (let ((method (tramp-file-name-method vec))
	    (user-domain (tramp-file-name-user-domain vec))
	    (host-port (tramp-file-name-host-port vec))
	    (localname (tramp-file-name-unquote-localname vec))
	    (object-path
	     (tramp-gvfs-object-path (tramp-make-tramp-file-name vec 'noloc))))

	(when (and (string-equal method "afp")
		   (string-equal localname "/"))
	  (tramp-user-error vec "Filename must contain an AFP volume"))

	(when (and (string-match-p (rx "dav" (? "s")) method)
		   (string-equal localname "/"))
	  (tramp-user-error vec "Filename must contain a WebDAV share"))

	(when (and (string-equal method "smb")
		   (string-equal localname "/"))
	  (tramp-user-error vec "Filename must contain a Windows share"))

	(when (member method tramp-goa-methods)
	  ;; Ensure that GNOME Online Accounts are cached.
	  (tramp-get-goa-accounts vec)
	  (when (tramp-get-connection-property
		 (tramp-get-goa-account vec) "FilesDisabled" t)
	    (tramp-user-error
	     vec "There is no Online Account `%s'"
	     (tramp-make-tramp-file-name vec 'noloc))))

	(with-tramp-progress-reporter
	    vec 3 (format "Opening connection for %s%s using %s"
			  (if (tramp-string-empty-or-nil-p user-domain)
			      "" (concat user-domain "@"))
			  host-port method)

	  ;; Enable `auth-source'.
	  (tramp-set-connection-property
	   vec "first-password-request" tramp-cache-read-persistent-data)

	  ;; There will be a callback of "askPassword" when a password is needed.
	  (dbus-register-method
	   :session dbus-service-emacs object-path
	   tramp-gvfs-interface-mountoperation "askPassword"
	   #'tramp-gvfs-handler-askpassword)
	  (dbus-register-method
	   :session dbus-service-emacs object-path
	   tramp-gvfs-interface-mountoperation "AskPassword"
	   #'tramp-gvfs-handler-askpassword)

	  ;; There could be a callback of "askQuestion" when adding
	  ;; fingerprints or checking certificates.
	  (dbus-register-method
	   :session dbus-service-emacs object-path
	   tramp-gvfs-interface-mountoperation "askQuestion"
	   #'tramp-gvfs-handler-askquestion)
	  (dbus-register-method
	   :session dbus-service-emacs object-path
	   tramp-gvfs-interface-mountoperation "AskQuestion"
	   #'tramp-gvfs-handler-askquestion)

	  ;; The call must be asynchronously, because of the
	  ;; "askPassword" or "askQuestion" callbacks.
	  (if (string-match-p (rx "(so)" eol) tramp-gvfs-mountlocation-signature)
	      (with-tramp-dbus-call-method vec nil
		:session tramp-gvfs-service-daemon tramp-gvfs-path-mounttracker
		tramp-gvfs-interface-mounttracker tramp-gvfs-mountlocation
		(tramp-gvfs-mount-spec vec)
		`(:struct :string ,(dbus-get-unique-name :session)
			  :object-path ,object-path))
	    (with-tramp-dbus-call-method vec nil
	      :session tramp-gvfs-service-daemon tramp-gvfs-path-mounttracker
	      tramp-gvfs-interface-mounttracker tramp-gvfs-mountlocation
	      (tramp-gvfs-mount-spec vec)
	      :string (dbus-get-unique-name :session) :object-path object-path))

	  ;; We must wait, until the mount is applied.  This will be
	  ;; indicated by the "mounted" signal, i.e. the
	  ;; "fuse-mountpoint" file property.
	  (with-timeout
	      ((tramp-get-method-parameter
		vec 'tramp-connection-timeout tramp-connection-timeout)
	       (if (tramp-string-empty-or-nil-p user-domain)
		   (tramp-error
		    vec 'file-error
		    "Timeout reached mounting %s using %s" host-port method)
		 (tramp-error
		  vec 'file-error
		  "Timeout reached mounting %s@%s using %s"
		  user-domain host-port method)))
	    (while (not (tramp-get-file-property vec "/" "fuse-mountpoint"))
	      (read-event nil nil 0.1)))

	  ;; If `tramp-gvfs-handler-askquestion' has returned "No", it
	  ;; is marked with the fuse-mountpoint "/".  We shall react.
	  (when (string-equal
		 (tramp-get-file-property vec "/" "fuse-mountpoint" "") "/")
	    (tramp-error vec 'file-error "FUSE mount denied"))

	  ;; Save the password.
	  (ignore-errors
	    (and (functionp tramp-password-save-function)
		 (funcall tramp-password-save-function)))

	  ;; Mark it as connected.
	  (tramp-set-connection-property
	   (tramp-get-connection-process vec) "connected" t))))))