diff options
| author | Michael Albinus | 2020-01-22 16:54:55 +0100 |
|---|---|---|
| committer | Michael Albinus | 2020-01-22 16:54:55 +0100 |
| commit | 2d9d62bb24c662890c943f16750f4a852aa6dc8b (patch) | |
| tree | 46b0b60bed2bf49444f24ad5b04da55b133cf165 /lisp | |
| parent | 1a2a5a17a75d77961b94d88989353bd07cfd3ef5 (diff) | |
| download | emacs-2d9d62bb24c662890c943f16750f4a852aa6dc8b.tar.gz emacs-2d9d62bb24c662890c943f16750f4a852aa6dc8b.zip | |
Add new Tramp method "media"
* doc/misc/tramp.texi (Quick Start Guide, GVFS-based methods):
Add media devices.
* etc/NEWS: Mention new Tramp method "media".
* lisp/net/tramp-gvfs.el (tramp-gvfs-methods): Add "media" method.
(tramp-goa-methods): Add tramp-autoload cookie.
(tramp-media-methods): New defvar.
(tramp-gvfs-service-volumemonitor): New defsubst.
(top): Remove media methods if not supported. Add defaults for
`tramp-default-host-alist'.
(tramp-goa-account): Rename from `tramp-goa-name'. Adapt all callees.
(tramp-gvfs-service-afc-volumemonitor)
(tramp-gvfs-service-goa-volumemonitor)
(tramp-gvfs-service-gphoto2-volumemonitor)
(tramp-gvfs-service-mtp-volumemonitor)
(tramp-gvfs-path-remotevolumemonitor)
(tramp-gvfs-interface-remotevolumemonitor): New defconsts.
(tramp-media-device): New defstruct.
(tramp-gvfs-activation-uri): New defun.
(tramp-gvfs-url-file-name): Use it.
(tramp-gvfs-handler-mounted-unmounted)
(tramp-gvfs-connection-mounted-p, tramp-gvfs-mount-spec):
Handle "media" method.
(tramp-get-goa-account): Rename from `tramp-make-goa-name'. Adapt
all callees.
(tramp-get-goa-accounts): Adapt docstring. Cache with nil key.
(tramp-parse-goa-accounts, tramp-get-media-device)
(tramp-get-media-devices)
(tramp-parse-media-names): New defuns.
(top): Rework completion function registration.
* lisp/net/tramp.el (tramp-dns-sd-service-regexp): New defconst.
(tramp-set-completion-function): Use it.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/net/tramp-gvfs.el | 529 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 7 |
2 files changed, 446 insertions, 90 deletions
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 67135e30d64..3811c6767ac 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el | |||
| @@ -49,11 +49,15 @@ | |||
| 49 | 49 | ||
| 50 | ;; The user option `tramp-gvfs-methods' contains the list of supported | 50 | ;; The user option `tramp-gvfs-methods' contains the list of supported |
| 51 | ;; connection methods. Per default, these are "afp", "dav", "davs", | 51 | ;; connection methods. Per default, these are "afp", "dav", "davs", |
| 52 | ;; "gdrive", "nextcloud" and "sftp". | 52 | ;; "gdrive", "media", "nextcloud" and "sftp". |
| 53 | 53 | ||
| 54 | ;; "gdrive" and "nextcloud" connection methods require a respective | 54 | ;; "gdrive" and "nextcloud" connection methods require a respective |
| 55 | ;; account in GNOME Online Accounts, with enabled "Files" service. | 55 | ;; account in GNOME Online Accounts, with enabled "Files" service. |
| 56 | 56 | ||
| 57 | ;; The "media" connection method is responsible for media devices, | ||
| 58 | ;; like cell phones, tablets, cameras etc. The device must already be | ||
| 59 | ;; connected via USB, before accessing it. | ||
| 60 | |||
| 57 | ;; Other possible connection methods are "ftp", "http", "https" and | 61 | ;; Other possible connection methods are "ftp", "http", "https" and |
| 58 | ;; "smb". When one of these methods is added to the list, the remote | 62 | ;; "smb". When one of these methods is added to the list, the remote |
| 59 | ;; access for that method is performed via GVFS instead of the native | 63 | ;; access for that method is performed via GVFS instead of the native |
| @@ -127,10 +131,10 @@ | |||
| 127 | 131 | ||
| 128 | ;;;###tramp-autoload | 132 | ;;;###tramp-autoload |
| 129 | (defcustom tramp-gvfs-methods | 133 | (defcustom tramp-gvfs-methods |
| 130 | '("afp" "dav" "davs" "gdrive" "nextcloud" "sftp") | 134 | '("afp" "dav" "davs" "gdrive" "media" "nextcloud" "sftp") |
| 131 | "List of methods for remote files, accessed with GVFS." | 135 | "List of methods for remote files, accessed with GVFS." |
| 132 | :group 'tramp | 136 | :group 'tramp |
| 133 | :version "27.1" | 137 | :version "28.1" |
| 134 | :type '(repeat (choice (const "afp") | 138 | :type '(repeat (choice (const "afp") |
| 135 | (const "dav") | 139 | (const "dav") |
| 136 | (const "davs") | 140 | (const "davs") |
| @@ -138,10 +142,12 @@ | |||
| 138 | (const "gdrive") | 142 | (const "gdrive") |
| 139 | (const "http") | 143 | (const "http") |
| 140 | (const "https") | 144 | (const "https") |
| 145 | (const "media") | ||
| 141 | (const "nextcloud") | 146 | (const "nextcloud") |
| 142 | (const "sftp") | 147 | (const "sftp") |
| 143 | (const "smb")))) | 148 | (const "smb")))) |
| 144 | 149 | ||
| 150 | ;;;###tramp-autoload | ||
| 145 | (defconst tramp-goa-methods '("gdrive" "nextcloud") | 151 | (defconst tramp-goa-methods '("gdrive" "nextcloud") |
| 146 | "List of methods which require registration at GNOME Online Accounts.") | 152 | "List of methods which require registration at GNOME Online Accounts.") |
| 147 | 153 | ||
| @@ -151,15 +157,23 @@ | |||
| 151 | (dolist (method tramp-goa-methods) | 157 | (dolist (method tramp-goa-methods) |
| 152 | (setq tramp-gvfs-methods (delete method tramp-gvfs-methods)))) | 158 | (setq tramp-gvfs-methods (delete method tramp-gvfs-methods)))) |
| 153 | 159 | ||
| 154 | ;; Add defaults for `tramp-default-user-alist' and `tramp-default-host-alist'. | ||
| 155 | ;;;###tramp-autoload | 160 | ;;;###tramp-autoload |
| 156 | (tramp--with-startup | 161 | (defvar tramp-media-methods '("afc" "gphoto2" "mtp") |
| 157 | (when (string-match "\\(.+\\)@\\(\\(?:gmail\\|googlemail\\)\\.com\\)" | 162 | "List of GVFS methods which are covered by the \"media\" method. |
| 158 | user-mail-address) | 163 | They are checked during start up via |
| 159 | (add-to-list 'tramp-default-user-alist | 164 | `tramp-gvfs-interface-remotevolumemonitor'.") |
| 160 | `("\\`gdrive\\'" nil ,(match-string 1 user-mail-address))) | 165 | |
| 161 | (add-to-list 'tramp-default-host-alist | 166 | (defsubst tramp-gvfs-service-volumemonitor (method) |
| 162 | '("\\`gdrive\\'" nil ,(match-string 2 user-mail-address))))) | 167 | "Return the well known name of the volume monitor responsible for METHOD." |
| 168 | (symbol-value | ||
| 169 | (intern-soft (format "tramp-gvfs-service-%s-volumemonitor" method)))) | ||
| 170 | |||
| 171 | ;; Remove media methods if not supported. | ||
| 172 | (when tramp-gvfs-enabled | ||
| 173 | (dolist (method tramp-media-methods) | ||
| 174 | (unless (member (tramp-gvfs-service-volumemonitor method) | ||
| 175 | (dbus-list-known-names :session)) | ||
| 176 | (setq tramp-media-methods (delete method tramp-media-methods))))) | ||
| 163 | 177 | ||
| 164 | ;;;###tramp-autoload | 178 | ;;;###tramp-autoload |
| 165 | (defcustom tramp-gvfs-zeroconf-domain "local" | 179 | (defcustom tramp-gvfs-zeroconf-domain "local" |
| @@ -169,13 +183,15 @@ | |||
| 169 | :type 'string) | 183 | :type 'string) |
| 170 | 184 | ||
| 171 | ;; Add the methods to `tramp-methods', in order to allow minibuffer | 185 | ;; Add the methods to `tramp-methods', in order to allow minibuffer |
| 172 | ;; completion. | 186 | ;; completion. Add defaults for `tramp-default-host-alist'. |
| 173 | ;;;###tramp-autoload | 187 | ;;;###tramp-autoload |
| 174 | (when (featurep 'dbusbind) | 188 | (when (featurep 'dbusbind) |
| 175 | (tramp--with-startup | 189 | (tramp--with-startup |
| 176 | (dolist (elt tramp-gvfs-methods) | 190 | (dolist (method tramp-gvfs-methods) |
| 177 | (unless (assoc elt tramp-methods) | 191 | (unless (assoc method tramp-methods) |
| 178 | (add-to-list 'tramp-methods (cons elt nil)))))) | 192 | (add-to-list 'tramp-methods `(,method))) |
| 193 | (when (member method (cons "media" tramp-goa-methods)) | ||
| 194 | (add-to-list 'tramp-default-host-alist `(,method nil "")))))) | ||
| 179 | 195 | ||
| 180 | (defconst tramp-gvfs-path-tramp (concat dbus-path-emacs "/Tramp") | 196 | (defconst tramp-gvfs-path-tramp (concat dbus-path-emacs "/Tramp") |
| 181 | "The preceding object path for own objects.") | 197 | "The preceding object path for own objects.") |
| @@ -458,7 +474,208 @@ It has been changed in GVFS 1.14.") | |||
| 458 | 474 | ||
| 459 | ;; The basic structure for GNOME Online Accounts. We use a list :type, | 475 | ;; The basic structure for GNOME Online Accounts. We use a list :type, |
| 460 | ;; in order to be compatible with Emacs 25. | 476 | ;; in order to be compatible with Emacs 25. |
| 461 | (cl-defstruct (tramp-goa-name (:type list) :named) method user host port) | 477 | (cl-defstruct (tramp-goa-account (:type list) :named) method user host port) |
| 478 | |||
| 479 | ;;;###tramp-autoload | ||
| 480 | (defconst tramp-gvfs-service-afc-volumemonitor "org.gtk.vfs.AfcVolumeMonitor" | ||
| 481 | "The well known name of the AFC volume monitor.") | ||
| 482 | |||
| 483 | ;; This one is not needed yet. | ||
| 484 | (defconst tramp-gvfs-service-goa-volumemonitor "org.gtk.vfs.GoaVolumeMonitor" | ||
| 485 | "The well known name of the GOA volume monitor.") | ||
| 486 | |||
| 487 | ;;;###tramp-autoload | ||
| 488 | (defconst tramp-gvfs-service-gphoto2-volumemonitor | ||
| 489 | "org.gtk.vfs.GPhoto2VolumeMonitor" | ||
| 490 | "The well known name of the GPhoto2 volume monitor.") | ||
| 491 | |||
| 492 | ;;;###tramp-autoload | ||
| 493 | (defconst tramp-gvfs-service-mtp-volumemonitor "org.gtk.vfs.MTPVolumeMonitor" | ||
| 494 | "The well known name of the MTP volume monitor.") | ||
| 495 | |||
| 496 | (defconst tramp-gvfs-path-remotevolumemonitor | ||
| 497 | "/org/gtk/Private/RemoteVolumeMonitor" | ||
| 498 | "The object path of the remote volume monitor.") | ||
| 499 | |||
| 500 | (defconst tramp-gvfs-interface-remotevolumemonitor | ||
| 501 | "org.gtk.Private.RemoteVolumeMonitor" | ||
| 502 | "The volume monitor interface.") | ||
| 503 | |||
| 504 | ;; <interface name='org.gtk.Private.RemoteVolumeMonitor'> | ||
| 505 | ;; <method name="IsSupported"> | ||
| 506 | ;; <arg type='b' name='is_supported' direction='out'/> | ||
| 507 | ;; </method> | ||
| 508 | ;; <method name="List"> | ||
| 509 | ;; <arg type='a(ssssbbbbbbbbuasa{ss}sa{sv})' name='drives' direction='out'/> | ||
| 510 | ;; <arg type='a(ssssssbbssa{ss}sa{sv})' name='volumes' direction='out'/> | ||
| 511 | ;; <arg type='a(ssssssbsassa{sv})' name='mounts' direction='out'/> | ||
| 512 | ;; </method> | ||
| 513 | ;; <method name="CancelOperation"> | ||
| 514 | ;; <arg type='s' name='cancellation_id' direction='in'/> | ||
| 515 | ;; <arg type='b' name='was_cancelled' direction='out'/> | ||
| 516 | ;; </method> | ||
| 517 | ;; <method name="MountUnmount"> | ||
| 518 | ;; <arg type='s' name='id' direction='in'/> | ||
| 519 | ;; <arg type='s' name='cancellation_id' direction='in'/> | ||
| 520 | ;; <arg type='u' name='unmount_flags' direction='in'/> | ||
| 521 | ;; <arg type='s' name='mount_op_id' direction='in'/> | ||
| 522 | ;; </method> | ||
| 523 | ;; <method name="VolumeMount"> | ||
| 524 | ;; <arg type='s' name='id' direction='in'/> | ||
| 525 | ;; <arg type='s' name='cancellation_id' direction='in'/> | ||
| 526 | ;; <arg type='u' name='mount_flags' direction='in'/> | ||
| 527 | ;; <arg type='s' name='mount_op_id' direction='in'/> | ||
| 528 | ;; </method> | ||
| 529 | ;; <method name="DriveEject"> | ||
| 530 | ;; <arg type='s' name='id' direction='in'/> | ||
| 531 | ;; <arg type='s' name='cancellation_id' direction='in'/> | ||
| 532 | ;; <arg type='u' name='unmount_flags' direction='in'/> | ||
| 533 | ;; <arg type='s' name='mount_op_id' direction='in'/> | ||
| 534 | ;; </method> | ||
| 535 | ;; <method name="DrivePollForMedia"> | ||
| 536 | ;; <arg type='s' name='id' direction='in'/> | ||
| 537 | ;; <arg type='s' name='cancellation_id' direction='in'/> | ||
| 538 | ;; </method> | ||
| 539 | ;; <method name="DriveStart"> | ||
| 540 | ;; <arg type='s' name='id' direction='in'/> | ||
| 541 | ;; <arg type='s' name='cancellation_id' direction='in'/> | ||
| 542 | ;; <arg type='u' name='flags' direction='in'/> | ||
| 543 | ;; <arg type='s' name='mount_op_id' direction='in'/> | ||
| 544 | ;; </method> | ||
| 545 | ;; <method name="DriveStop"> | ||
| 546 | ;; <arg type='s' name='id' direction='in'/> | ||
| 547 | ;; <arg type='s' name='cancellation_id' direction='in'/> | ||
| 548 | ;; <arg type='u' name='unmount_flags' direction='in'/> | ||
| 549 | ;; <arg type='s' name='mount_op_id' direction='in'/> | ||
| 550 | ;; </method> | ||
| 551 | ;; <method name="MountOpReply"> | ||
| 552 | ;; <arg type='s' name='mount_op_id' direction='in'/> | ||
| 553 | ;; <arg type='i' name='result' direction='in'/> | ||
| 554 | ;; <arg type='s' name='user_name' direction='in'/> | ||
| 555 | ;; <arg type='s' name='domain' direction='in'/> | ||
| 556 | ;; <arg type='s' name='encoded_password' direction='in'/> | ||
| 557 | ;; <arg type='i' name='password_save' direction='in'/> | ||
| 558 | ;; <arg type='i' name='choice' direction='in'/> | ||
| 559 | ;; <arg type='b' name='anonymous' direction='in'/> | ||
| 560 | ;; </method> | ||
| 561 | ;; <signal name="DriveChanged"> | ||
| 562 | ;; <arg type='s' name='dbus_name'/> | ||
| 563 | ;; <arg type='s' name='id'/> | ||
| 564 | ;; <arg type='(ssssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> | ||
| 565 | ;; </signal> | ||
| 566 | ;; <signal name="DriveConnected"> | ||
| 567 | ;; <arg type='s' name='dbus_name'/> | ||
| 568 | ;; <arg type='s' name='id'/> | ||
| 569 | ;; <arg type='(ssssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> | ||
| 570 | ;; </signal> | ||
| 571 | ;; <signal name="DriveDisconnected"> | ||
| 572 | ;; <arg type='s' name='dbus_name'/> | ||
| 573 | ;; <arg type='s' name='id'/> | ||
| 574 | ;; <arg type='(ssssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> | ||
| 575 | ;; </signal> | ||
| 576 | ;; <signal name="DriveEjectButton"> | ||
| 577 | ;; <arg type='s' name='dbus_name'/> | ||
| 578 | ;; <arg type='s' name='id'/> | ||
| 579 | ;; <arg type='(ssssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> | ||
| 580 | ;; </signal> | ||
| 581 | ;; <signal name="DriveStopButton"> | ||
| 582 | ;; <arg type='s' name='dbus_name'/> | ||
| 583 | ;; <arg type='s' name='id'/> | ||
| 584 | ;; <arg type='(ssssbbbbbbbbuasa{ss}sa{sv})' name='drive'/> | ||
| 585 | ;; </signal> | ||
| 586 | ;; <signal name="VolumeChanged"> | ||
| 587 | ;; <arg type='s' name='dbus_name'/> | ||
| 588 | ;; <arg type='s' name='id'/> | ||
| 589 | ;; <arg type='(ssssssbbssa{ss}sa{sv})' name='volume'/> | ||
| 590 | ;; </signal> | ||
| 591 | ;; <signal name="VolumeAdded"> | ||
| 592 | ;; <arg type='s' name='dbus_name'/> | ||
| 593 | ;; <arg type='s' name='id'/> | ||
| 594 | ;; <arg type='(ssssssbbssa{ss}sa{sv})' name='volume'/> | ||
| 595 | ;; </signal> | ||
| 596 | ;; <signal name="VolumeRemoved"> | ||
| 597 | ;; <arg type='s' name='dbus_name'/> | ||
| 598 | ;; <arg type='s' name='id'/> | ||
| 599 | ;; <arg type='(ssssssbbssa{ss}sa{sv})' name='volume'/> | ||
| 600 | ;; </signal> | ||
| 601 | ;; <signal name="MountChanged"> | ||
| 602 | ;; <arg type='s' name='dbus_name'/> | ||
| 603 | ;; <arg type='s' name='id'/> | ||
| 604 | ;; <arg type='(ssssssbsassa{sv})' name='mount'/> | ||
| 605 | ;; </signal> | ||
| 606 | ;; <signal name="MountAdded"> | ||
| 607 | ;; <arg type='s' name='dbus_name'/> | ||
| 608 | ;; <arg type='s' name='id'/> | ||
| 609 | ;; <arg type='(ssssssbsassa{sv})' name='mount'/> | ||
| 610 | ;; </signal> | ||
| 611 | ;; <signal name="MountPreUnmount"> | ||
| 612 | ;; <arg type='s' name='dbus_name'/> | ||
| 613 | ;; <arg type='s' name='id'/> | ||
| 614 | ;; <arg type='(ssssssbsassa{sv})' name='mount'/> | ||
| 615 | ;; </signal> | ||
| 616 | ;; <signal name="MountRemoved"> | ||
| 617 | ;; <arg type='s' name='dbus_name'/> | ||
| 618 | ;; <arg type='s' name='id'/> | ||
| 619 | ;; <arg type='(ssssssbsassa{sv})' name='mount'/> | ||
| 620 | ;; </signal> | ||
| 621 | ;; <signal name="MountOpAskPassword"> | ||
| 622 | ;; <arg type='s' name='dbus_name'/> | ||
| 623 | ;; <arg type='s' name='id'/> | ||
| 624 | ;; <arg type='s' name='message_to_show'/> | ||
| 625 | ;; <arg type='s' name='default_user'/> | ||
| 626 | ;; <arg type='s' name='default_domain'/> | ||
| 627 | ;; <arg type='u' name='flags'/> | ||
| 628 | ;; </signal> | ||
| 629 | ;; <signal name="MountOpAskQuestion"> | ||
| 630 | ;; <arg type='s' name='dbus_name'/> | ||
| 631 | ;; <arg type='s' name='id'/> | ||
| 632 | ;; <arg type='s' name='message_to_show'/> | ||
| 633 | ;; <arg type='as' name='choices'/> | ||
| 634 | ;; </signal> | ||
| 635 | ;; <signal name="MountOpShowProcesses"> | ||
| 636 | ;; <arg type='s' name='dbus_name'/> | ||
| 637 | ;; <arg type='s' name='id'/> | ||
| 638 | ;; <arg type='s' name='message_to_show'/> | ||
| 639 | ;; <arg type='ai' name='pid'/> | ||
| 640 | ;; <arg type='as' name='choices'/> | ||
| 641 | ;; </signal> | ||
| 642 | ;; <signal name="MountOpShowUnmountProgress"> | ||
| 643 | ;; <arg type='s' name='dbus_name'/> | ||
| 644 | ;; <arg type='s' name='id'/> | ||
| 645 | ;; <arg type='s' name='message_to_show'/> | ||
| 646 | ;; <arg type='x' name='time_left'/> | ||
| 647 | ;; <arg type='x' name='bytes_left'/> | ||
| 648 | ;; </signal> | ||
| 649 | ;; <signal name="MountOpAborted"> | ||
| 650 | ;; <arg type='s' name='dbus_name'/> | ||
| 651 | ;; <arg type='s' name='id'/> | ||
| 652 | ;; </signal> | ||
| 653 | ;; </interface> | ||
| 654 | |||
| 655 | ;; STRUCT volume | ||
| 656 | ;; STRING id | ||
| 657 | ;; STRING name | ||
| 658 | ;; STRING gicon_data | ||
| 659 | ;; STRING symbolic_gicon_data | ||
| 660 | ;; STRING uuid | ||
| 661 | ;; STRING activation_uri | ||
| 662 | ;; BOOLEAN can-mount | ||
| 663 | ;; BOOLEAN should-automount | ||
| 664 | ;; STRING drive-id | ||
| 665 | ;; STRING mount-id | ||
| 666 | ;; ARRAY identifiers | ||
| 667 | ;; DICT | ||
| 668 | ;; STRING key (unix-device, class, uuid, ...) | ||
| 669 | ;; STRING value | ||
| 670 | ;; STRING sort_key | ||
| 671 | ;; ARRAY expansion | ||
| 672 | ;; DICT | ||
| 673 | ;; STRING key (always-call-mount, is-removable, ...) | ||
| 674 | ;; VARIANT value (boolean?) | ||
| 675 | |||
| 676 | ;; The basic structure for media devices. We use a list :type, in | ||
| 677 | ;; order to be compatible with Emacs 25. | ||
| 678 | (cl-defstruct (tramp-media-device (:type list) :named) method host port) | ||
| 462 | 679 | ||
| 463 | ;; "gvfs-<command>" utilities have been deprecated in GVFS 1.31.1. We | 680 | ;; "gvfs-<command>" utilities have been deprecated in GVFS 1.31.1. We |
| 464 | ;; must use "gio <command>" tool instead. | 681 | ;; must use "gio <command>" tool instead. |
| @@ -1381,36 +1598,45 @@ If FILE-SYSTEM is non-nil, return file system attributes." | |||
| 1381 | 1598 | ||
| 1382 | ;; File name conversions. | 1599 | ;; File name conversions. |
| 1383 | 1600 | ||
| 1601 | (defun tramp-gvfs-activation-uri (filename) | ||
| 1602 | "Return activation URI to be used in gio commands." | ||
| 1603 | (if (tramp-tramp-file-p filename) | ||
| 1604 | (with-parsed-tramp-file-name filename nil | ||
| 1605 | ;; Ensure that media devices are cached. | ||
| 1606 | (when (string-equal method "media") | ||
| 1607 | (tramp-get-media-device v)) | ||
| 1608 | (with-tramp-connection-property v "activation-uri" | ||
| 1609 | (setq localname "/") | ||
| 1610 | (when (string-equal "gdrive" method) | ||
| 1611 | (setq method "google-drive")) | ||
| 1612 | (when (string-equal "nextcloud" method) | ||
| 1613 | (setq method "davs" | ||
| 1614 | localname | ||
| 1615 | (concat (tramp-gvfs-get-remote-prefix v) localname))) | ||
| 1616 | (when (and user domain) | ||
| 1617 | (setq user (concat domain ";" user))) | ||
| 1618 | (url-recreate-url | ||
| 1619 | (url-parse-make-urlobj | ||
| 1620 | method (and user (url-hexify-string user)) | ||
| 1621 | nil (and host (url-hexify-string host)) | ||
| 1622 | (if (stringp port) (string-to-number port) port) | ||
| 1623 | localname nil nil t)))) | ||
| 1624 | ;; Local URI. | ||
| 1625 | (url-recreate-url | ||
| 1626 | (url-parse-make-urlobj "file" nil nil nil nil nil nil nil t)))) | ||
| 1627 | |||
| 1384 | (defun tramp-gvfs-url-file-name (filename) | 1628 | (defun tramp-gvfs-url-file-name (filename) |
| 1385 | "Return FILENAME in URL syntax." | 1629 | "Return FILENAME in URL syntax." |
| 1386 | ;; "/" must NOT be hexified. | ||
| 1387 | (setq filename (tramp-compat-file-name-unquote filename)) | 1630 | (setq filename (tramp-compat-file-name-unquote filename)) |
| 1388 | (let ((url-unreserved-chars (cons ?/ url-unreserved-chars)) | 1631 | (let* (;; "/" must NOT be hexified. |
| 1389 | result) | 1632 | (url-unreserved-chars (cons ?/ url-unreserved-chars)) |
| 1390 | (setq | 1633 | (result |
| 1391 | result | 1634 | (concat (substring (tramp-gvfs-activation-uri filename) 0 -1) |
| 1392 | (url-recreate-url | 1635 | (url-hexify-string (tramp-file-local-name filename))))) |
| 1393 | (if (tramp-tramp-file-p filename) | ||
| 1394 | (with-parsed-tramp-file-name filename nil | ||
| 1395 | (when (string-equal "gdrive" method) | ||
| 1396 | (setq method "google-drive")) | ||
| 1397 | (when (string-equal "nextcloud" method) | ||
| 1398 | (setq method "davs" | ||
| 1399 | localname | ||
| 1400 | (concat (tramp-gvfs-get-remote-prefix v) localname))) | ||
| 1401 | (when (and user domain) | ||
| 1402 | (setq user (concat domain ";" user))) | ||
| 1403 | (url-parse-make-urlobj | ||
| 1404 | method (and user (url-hexify-string user)) | ||
| 1405 | nil (and host (url-hexify-string host)) | ||
| 1406 | (if (stringp port) (string-to-number port) port) | ||
| 1407 | (and localname (url-hexify-string localname)) nil nil t)) | ||
| 1408 | (url-parse-make-urlobj | ||
| 1409 | "file" nil nil nil nil | ||
| 1410 | (url-hexify-string (file-truename filename)) nil nil t)))) | ||
| 1411 | (when (tramp-tramp-file-p filename) | 1636 | (when (tramp-tramp-file-p filename) |
| 1412 | (with-parsed-tramp-file-name filename nil | 1637 | (tramp-message |
| 1413 | (tramp-message v 10 "remote file `%s' is URL `%s'" filename result))) | 1638 | (tramp-dissect-file-name filename) 10 |
| 1639 | "remote file `%s' is URL `%s'" filename result)) | ||
| 1414 | result)) | 1640 | result)) |
| 1415 | 1641 | ||
| 1416 | (defun tramp-gvfs-object-path (filename) | 1642 | (defun tramp-gvfs-object-path (filename) |
| @@ -1567,6 +1793,17 @@ If FILE-SYSTEM is non-nil, return file system attributes." | |||
| 1567 | user (url-user uri) | 1793 | user (url-user uri) |
| 1568 | host (url-host uri) | 1794 | host (url-host uri) |
| 1569 | port (url-portspec uri))) | 1795 | port (url-portspec uri))) |
| 1796 | (when (member method tramp-media-methods) | ||
| 1797 | ;; Ensure that media devices are cached. | ||
| 1798 | (tramp-get-media-devices nil) | ||
| 1799 | (let ((v (tramp-get-connection-property | ||
| 1800 | (make-tramp-media-device | ||
| 1801 | :method method :host (downcase host) :port port) | ||
| 1802 | "vector" nil))) | ||
| 1803 | (when v | ||
| 1804 | (setq method (tramp-file-name-method v) | ||
| 1805 | host (tramp-file-name-host v) | ||
| 1806 | port (tramp-file-name-port v))))) | ||
| 1570 | (when (member method tramp-gvfs-methods) | 1807 | (when (member method tramp-gvfs-methods) |
| 1571 | (with-parsed-tramp-file-name | 1808 | (with-parsed-tramp-file-name |
| 1572 | (tramp-make-tramp-file-name method user domain host port "") nil | 1809 | (tramp-make-tramp-file-name method user domain host port "") nil |
| @@ -1657,6 +1894,17 @@ If FILE-SYSTEM is non-nil, return file system attributes." | |||
| 1657 | user (url-user uri) | 1894 | user (url-user uri) |
| 1658 | host (url-host uri) | 1895 | host (url-host uri) |
| 1659 | port (url-portspec uri))) | 1896 | port (url-portspec uri))) |
| 1897 | (when (member method tramp-media-methods) | ||
| 1898 | ;; Ensure that media devices are cached. | ||
| 1899 | (tramp-get-media-devices vec) | ||
| 1900 | (let ((v (tramp-get-connection-property | ||
| 1901 | (make-tramp-media-device | ||
| 1902 | :method method :host (downcase host) :port port) | ||
| 1903 | "vector" nil))) | ||
| 1904 | (when v | ||
| 1905 | (setq method (tramp-file-name-method v) | ||
| 1906 | host (tramp-file-name-host v) | ||
| 1907 | port (tramp-file-name-port v))))) | ||
| 1660 | (when (and | 1908 | (when (and |
| 1661 | (string-equal method (tramp-file-name-method vec)) | 1909 | (string-equal method (tramp-file-name-method vec)) |
| 1662 | (string-equal user (tramp-file-name-user vec)) | 1910 | (string-equal user (tramp-file-name-user vec)) |
| @@ -1694,11 +1942,16 @@ It was \"a(say)\", but has changed to \"a{sv})\"." | |||
| 1694 | 1942 | ||
| 1695 | (defun tramp-gvfs-mount-spec (vec) | 1943 | (defun tramp-gvfs-mount-spec (vec) |
| 1696 | "Return a mount-spec for \"org.gtk.vfs.MountTracker.mountLocation\"." | 1944 | "Return a mount-spec for \"org.gtk.vfs.MountTracker.mountLocation\"." |
| 1697 | (let* ((method (tramp-file-name-method vec)) | 1945 | (let* ((media (tramp-get-media-device vec)) |
| 1946 | (method (if media | ||
| 1947 | (tramp-media-device-method media) | ||
| 1948 | (tramp-file-name-method vec))) | ||
| 1698 | (user (tramp-file-name-user vec)) | 1949 | (user (tramp-file-name-user vec)) |
| 1699 | (domain (tramp-file-name-domain vec)) | 1950 | (domain (tramp-file-name-domain vec)) |
| 1700 | (host (tramp-file-name-host vec)) | 1951 | (host (if media |
| 1701 | (port (tramp-file-name-port vec)) | 1952 | (tramp-media-device-host media) (tramp-file-name-host vec))) |
| 1953 | (port (if media | ||
| 1954 | (tramp-media-device-port media) (tramp-file-name-port vec))) | ||
| 1702 | (localname (tramp-file-name-unquote-localname vec)) | 1955 | (localname (tramp-file-name-unquote-localname vec)) |
| 1703 | (share (when (string-match "^/?\\([^/]+\\)" localname) | 1956 | (share (when (string-match "^/?\\([^/]+\\)" localname) |
| 1704 | (match-string 1 localname))) | 1957 | (match-string 1 localname))) |
| @@ -1792,7 +2045,7 @@ This is relevant for GNOME Online Accounts." | |||
| 1792 | ;; Ensure that GNOME Online Accounts are cached. | 2045 | ;; Ensure that GNOME Online Accounts are cached. |
| 1793 | (when (member (tramp-file-name-method vec) tramp-goa-methods) | 2046 | (when (member (tramp-file-name-method vec) tramp-goa-methods) |
| 1794 | (tramp-get-goa-accounts vec)) | 2047 | (tramp-get-goa-accounts vec)) |
| 1795 | (tramp-get-connection-property (tramp-make-goa-name vec) "prefix" "/"))) | 2048 | (tramp-get-connection-property (tramp-get-goa-account vec) "prefix" "/"))) |
| 1796 | 2049 | ||
| 1797 | (defun tramp-gvfs-maybe-open-connection (vec) | 2050 | (defun tramp-gvfs-maybe-open-connection (vec) |
| 1798 | "Maybe open a connection VEC. | 2051 | "Maybe open a connection VEC. |
| @@ -1841,7 +2094,7 @@ connection if a previous connection has died for some reason." | |||
| 1841 | ;; Ensure that GNOME Online Accounts are cached. | 2094 | ;; Ensure that GNOME Online Accounts are cached. |
| 1842 | (tramp-get-goa-accounts vec) | 2095 | (tramp-get-goa-accounts vec) |
| 1843 | (when (tramp-get-connection-property | 2096 | (when (tramp-get-connection-property |
| 1844 | (tramp-make-goa-name vec) "FilesDisabled" t) | 2097 | (tramp-get-goa-account vec) "FilesDisabled" t) |
| 1845 | (tramp-user-error | 2098 | (tramp-user-error |
| 1846 | vec "There is no Online Account `%s'" | 2099 | vec "There is no Online Account `%s'" |
| 1847 | (tramp-make-tramp-file-name vec 'noloc)))) | 2100 | (tramp-make-tramp-file-name vec 'noloc)))) |
| @@ -1966,12 +2219,12 @@ is applied, and it returns t if the return code is zero." | |||
| 1966 | (and (tramp-flush-file-properties vec "/") nil))))) | 2219 | (and (tramp-flush-file-properties vec "/") nil))))) |
| 1967 | 2220 | ||
| 1968 | 2221 | ||
| 1969 | ;; D-Bus GNOME Online Accounts functions. | 2222 | ;; GNOME Online Accounts functions. |
| 1970 | 2223 | ||
| 1971 | (defun tramp-make-goa-name (vec) | 2224 | (defun tramp-get-goa-account (vec) |
| 1972 | "Transform VEC into a `tramp-goa-name' structure." | 2225 | "Transform VEC into a `tramp-goa-account' structure." |
| 1973 | (when (tramp-file-name-p vec) | 2226 | (when (tramp-file-name-p vec) |
| 1974 | (make-tramp-goa-name | 2227 | (make-tramp-goa-account |
| 1975 | :method (tramp-file-name-method vec) | 2228 | :method (tramp-file-name-method vec) |
| 1976 | :user (tramp-file-name-user vec) | 2229 | :user (tramp-file-name-user vec) |
| 1977 | :host (tramp-file-name-host vec) | 2230 | :host (tramp-file-name-host vec) |
| @@ -1979,12 +2232,12 @@ is applied, and it returns t if the return code is zero." | |||
| 1979 | 2232 | ||
| 1980 | (defun tramp-get-goa-accounts (vec) | 2233 | (defun tramp-get-goa-accounts (vec) |
| 1981 | "Retrieve GNOME Online Accounts, and cache them. | 2234 | "Retrieve GNOME Online Accounts, and cache them. |
| 1982 | The hash key is a `tramp-goa-name' structure. The value is an | 2235 | The hash key is a `tramp-goa-account' structure. The value is an |
| 1983 | alist of the properties of `tramp-goa-interface-account' and | 2236 | alist of the properties of `tramp-goa-interface-account' and |
| 1984 | `tramp-goa-interface-files' of the corresponding GNOME online | 2237 | `tramp-goa-interface-files' of the corresponding GNOME Online |
| 1985 | account. Additionally, a property \"prefix\" is added. | 2238 | Account. Additionally, a property \"prefix\" is added. |
| 1986 | VEC is used only for traces." | 2239 | VEC is used only for traces." |
| 1987 | (with-tramp-connection-property (tramp-make-goa-name vec) "goa-accounts" | 2240 | (with-tramp-connection-property nil "goa-accounts" |
| 1988 | (dolist | 2241 | (dolist |
| 1989 | (object-path | 2242 | (object-path |
| 1990 | (mapcar | 2243 | (mapcar |
| @@ -2010,15 +2263,15 @@ VEC is used only for traces." | |||
| 2010 | (cdr (assoc "ProviderType" account-properties)) | 2263 | (cdr (assoc "ProviderType" account-properties)) |
| 2011 | '("google" "owncloud")) | 2264 | '("google" "owncloud")) |
| 2012 | (string-match tramp-goa-identity-regexp identity)) | 2265 | (string-match tramp-goa-identity-regexp identity)) |
| 2013 | (setq key (make-tramp-goa-name | 2266 | (setq key (make-tramp-goa-account |
| 2014 | :method (cdr (assoc "ProviderType" account-properties)) | 2267 | :method (cdr (assoc "ProviderType" account-properties)) |
| 2015 | :user (match-string 1 identity) | 2268 | :user (match-string 1 identity) |
| 2016 | :host (match-string 2 identity) | 2269 | :host (match-string 2 identity) |
| 2017 | :port (match-string 3 identity))) | 2270 | :port (match-string 3 identity))) |
| 2018 | (when (string-equal (tramp-goa-name-method key) "google") | 2271 | (when (string-equal (tramp-goa-account-method key) "google") |
| 2019 | (setf (tramp-goa-name-method key) "gdrive")) | 2272 | (setf (tramp-goa-account-method key) "gdrive")) |
| 2020 | (when (string-equal (tramp-goa-name-method key) "owncloud") | 2273 | (when (string-equal (tramp-goa-account-method key) "owncloud") |
| 2021 | (setf (tramp-goa-name-method key) "nextcloud")) | 2274 | (setf (tramp-goa-account-method key) "nextcloud")) |
| 2022 | ;; Cache all properties. | 2275 | ;; Cache all properties. |
| 2023 | (dolist (prop (nconc account-properties files-properties)) | 2276 | (dolist (prop (nconc account-properties files-properties)) |
| 2024 | (tramp-set-connection-property key (car prop) (cdr prop))) | 2277 | (tramp-set-connection-property key (car prop) (cdr prop))) |
| @@ -2034,6 +2287,80 @@ VEC is used only for traces." | |||
| 2034 | ;; Mark, that goa accounts have been cached. | 2287 | ;; Mark, that goa accounts have been cached. |
| 2035 | "cached")) | 2288 | "cached")) |
| 2036 | 2289 | ||
| 2290 | (defun tramp-parse-goa-accounts (service) | ||
| 2291 | "Return a list of (user host) tuples allowed to access. | ||
| 2292 | It checks for registered GNOME Online Accounts." | ||
| 2293 | ;; SERVICE might be encoded as a DNS-SD service. | ||
| 2294 | (and (string-match tramp-dns-sd-service-regexp service) | ||
| 2295 | (setq service (match-string 1 service))) | ||
| 2296 | (let (result) | ||
| 2297 | (maphash | ||
| 2298 | (lambda (key _value) | ||
| 2299 | (if (and (tramp-goa-account-p key) | ||
| 2300 | (string-equal service (tramp-goa-account-method key))) | ||
| 2301 | (push (list (tramp-goa-account-user key) | ||
| 2302 | (tramp-goa-account-host key)) | ||
| 2303 | result))) | ||
| 2304 | tramp-cache-data) | ||
| 2305 | result)) | ||
| 2306 | |||
| 2307 | |||
| 2308 | ;; Media devices functions. | ||
| 2309 | |||
| 2310 | (defun tramp-get-media-device (vec) | ||
| 2311 | "Transform VEC into a `tramp-media-device' structure. | ||
| 2312 | Check, that respective cache values do exist." | ||
| 2313 | (if-let* ((media (tramp-get-connection-property vec "media-device" nil)) | ||
| 2314 | (prop (tramp-get-connection-property media "vector" nil))) | ||
| 2315 | media | ||
| 2316 | (tramp-get-media-devices vec) | ||
| 2317 | (tramp-get-connection-property vec "media-device" nil))) | ||
| 2318 | |||
| 2319 | (defun tramp-get-media-devices (vec) | ||
| 2320 | "Retrieve media devices, and cache them. | ||
| 2321 | The hash key is a `tramp-media-device' structure. | ||
| 2322 | VEC is used only for traces." | ||
| 2323 | ; (with-tramp-connection-property nil "media-devices" | ||
| 2324 | (dolist (method tramp-media-methods) | ||
| 2325 | (dolist (volume (cadr (with-tramp-dbus-call-method vec t | ||
| 2326 | :session (tramp-gvfs-service-volumemonitor method) | ||
| 2327 | tramp-gvfs-path-remotevolumemonitor | ||
| 2328 | tramp-gvfs-interface-remotevolumemonitor "List"))) | ||
| 2329 | (let* ((uri (url-generic-parse-url (nth 5 volume))) | ||
| 2330 | (vec (make-tramp-file-name | ||
| 2331 | :method "media" | ||
| 2332 | ;; A host name cannot contain spaces. | ||
| 2333 | :host (replace-regexp-in-string " " "_" (nth 1 volume)))) | ||
| 2334 | (media (make-tramp-media-device | ||
| 2335 | :method method | ||
| 2336 | :host (url-host uri) | ||
| 2337 | :port (and (url-portspec uri) | ||
| 2338 | (number-to-string (url-portspec uri)))))) | ||
| 2339 | (tramp-set-connection-property vec "activation-uri" (nth 5 volume)) | ||
| 2340 | (tramp-set-connection-property vec "media-device" media) | ||
| 2341 | (tramp-set-connection-property media "vector" vec)))) | ||
| 2342 | ;; Mark, that media devices have been cached. | ||
| 2343 | ); "cached")) | ||
| 2344 | |||
| 2345 | (defun tramp-parse-media-names (service) | ||
| 2346 | "Return a list of (user host) tuples allowed to access. | ||
| 2347 | It checks for mounted media devices." | ||
| 2348 | ;; SERVICE might be encoded as a DNS-SD service. | ||
| 2349 | (and (string-match tramp-dns-sd-service-regexp service) | ||
| 2350 | (setq service (match-string 1 service))) | ||
| 2351 | (let (result) | ||
| 2352 | (maphash | ||
| 2353 | (lambda (key _value) | ||
| 2354 | (if (and (tramp-media-device-p key) | ||
| 2355 | (string-equal service (tramp-media-device-method key)) | ||
| 2356 | (tramp-get-connection-property key "vector" nil)) | ||
| 2357 | (push | ||
| 2358 | (list nil (tramp-file-name-host | ||
| 2359 | (tramp-get-connection-property key "vector" nil))) | ||
| 2360 | result))) | ||
| 2361 | tramp-cache-data) | ||
| 2362 | result)) | ||
| 2363 | |||
| 2037 | 2364 | ||
| 2038 | ;; D-Bus zeroconf functions. | 2365 | ;; D-Bus zeroconf functions. |
| 2039 | 2366 | ||
| @@ -2078,39 +2405,61 @@ This uses \"avahi-browse\" in case D-Bus is not enabled in Avahi." | |||
| 2078 | (list user host))) | 2405 | (list user host))) |
| 2079 | result)))) | 2406 | result)))) |
| 2080 | 2407 | ||
| 2081 | ;; Add completion functions for AFP, DAV, DAVS, SFTP and SMB methods. | ||
| 2082 | (when tramp-gvfs-enabled | 2408 | (when tramp-gvfs-enabled |
| 2083 | ;; Suppress D-Bus error messages. | 2409 | ;; Suppress D-Bus error messages and Tramp traces. |
| 2084 | (let (tramp-gvfs-dbus-event-vector) | 2410 | (let (tramp-gvfs-dbus-event-vector tramp-verbose fun) |
| 2411 | ;; Add completion functions for services announced by DNS-SD. | ||
| 2412 | ;; See <http://www.dns-sd.org/ServiceTypes.html> for valid service types. | ||
| 2085 | (zeroconf-init tramp-gvfs-zeroconf-domain) | 2413 | (zeroconf-init tramp-gvfs-zeroconf-domain) |
| 2086 | (if (zeroconf-list-service-types) | 2414 | (when (setq fun (or (and (zeroconf-list-service-types) |
| 2087 | (progn | 2415 | #'tramp-zeroconf-parse-device-names) |
| 2088 | (tramp-set-completion-function | 2416 | (and (executable-find "avahi-browse") |
| 2089 | "afp" '((tramp-zeroconf-parse-device-names "_afpovertcp._tcp"))) | 2417 | #'tramp-gvfs-parse-device-names))) |
| 2090 | (tramp-set-completion-function | 2418 | (when (member "afp" tramp-gvfs-methods) |
| 2091 | "dav" '((tramp-zeroconf-parse-device-names "_webdav._tcp"))) | 2419 | (tramp-set-completion-function |
| 2092 | (tramp-set-completion-function | 2420 | "afp" `((,fun "_afpovertcp._tcp")))) |
| 2093 | "davs" '((tramp-zeroconf-parse-device-names "_webdav._tcp"))) | 2421 | (when (member "dav" tramp-gvfs-methods) |
| 2094 | (tramp-set-completion-function | 2422 | (tramp-set-completion-function |
| 2095 | "sftp" '((tramp-zeroconf-parse-device-names "_ssh._tcp") | 2423 | "dav" `((,fun "_webdav._tcp") |
| 2096 | (tramp-zeroconf-parse-device-names "_workstation._tcp"))) | 2424 | (,fun "_webdavs._tcp")))) |
| 2097 | (when (member "smb" tramp-gvfs-methods) | 2425 | (when (member "davs" tramp-gvfs-methods) |
| 2098 | (tramp-set-completion-function | ||
| 2099 | "smb" '((tramp-zeroconf-parse-device-names "_smb._tcp"))))) | ||
| 2100 | |||
| 2101 | (when (executable-find "avahi-browse") | ||
| 2102 | (tramp-set-completion-function | 2426 | (tramp-set-completion-function |
| 2103 | "afp" '((tramp-gvfs-parse-device-names "_afpovertcp._tcp"))) | 2427 | "davs" `((,fun "_webdav._tcp") |
| 2428 | (,fun "_webdavs._tcp")))) | ||
| 2429 | (when (member "ftp" tramp-gvfs-methods) | ||
| 2104 | (tramp-set-completion-function | 2430 | (tramp-set-completion-function |
| 2105 | "dav" '((tramp-gvfs-parse-device-names "_webdav._tcp"))) | 2431 | "ftp" `((,fun "_ftp._tcp")))) |
| 2432 | (when (member "http" tramp-gvfs-methods) | ||
| 2106 | (tramp-set-completion-function | 2433 | (tramp-set-completion-function |
| 2107 | "davs" '((tramp-gvfs-parse-device-names "_webdav._tcp"))) | 2434 | "http" `((,fun "_http._tcp") |
| 2435 | (,fun "_https._tcp")))) | ||
| 2436 | (when (member "https" tramp-gvfs-methods) | ||
| 2108 | (tramp-set-completion-function | 2437 | (tramp-set-completion-function |
| 2109 | "sftp" '((tramp-gvfs-parse-device-names "_ssh._tcp") | 2438 | "https" `((,fun "_http._tcp") |
| 2110 | (tramp-gvfs-parse-device-names "_workstation._tcp"))) | 2439 | (,fun "_https._tcp")))) |
| 2111 | (when (member "smb" tramp-gvfs-methods) | 2440 | (when (member "sftp" tramp-gvfs-methods) |
| 2112 | (tramp-set-completion-function | 2441 | (tramp-set-completion-function |
| 2113 | "smb" '((tramp-gvfs-parse-device-names "_smb._tcp")))))))) | 2442 | "sftp" `((,fun "_sftp-ssh._tcp") |
| 2443 | (,fun "_ssh._tcp") | ||
| 2444 | (,fun "_workstation._tcp")))) | ||
| 2445 | (when (member "smb" tramp-gvfs-methods) | ||
| 2446 | (tramp-set-completion-function | ||
| 2447 | "smb" `((,fun "_smb._tcp"))))) | ||
| 2448 | |||
| 2449 | ;; Add completion functions for GNOME Online Accounts. | ||
| 2450 | (tramp-get-goa-accounts nil) | ||
| 2451 | (dolist (method tramp-goa-methods) | ||
| 2452 | (when (member method tramp-gvfs-methods) | ||
| 2453 | (tramp-set-completion-function | ||
| 2454 | method `((tramp-parse-goa-accounts ,(format "_%s._tcp" method)))))) | ||
| 2455 | |||
| 2456 | ;; Add completion functions for media devices. | ||
| 2457 | (tramp-get-media-devices nil) | ||
| 2458 | (tramp-set-completion-function | ||
| 2459 | "media" | ||
| 2460 | (mapcar | ||
| 2461 | (lambda (method) `(tramp-parse-media-names ,(format "_%s._tcp" method))) | ||
| 2462 | tramp-media-methods)))) | ||
| 2114 | 2463 | ||
| 2115 | (add-hook 'tramp-unload-hook | 2464 | (add-hook 'tramp-unload-hook |
| 2116 | (lambda () | 2465 | (lambda () |
| @@ -2120,10 +2469,14 @@ This uses \"avahi-browse\" in case D-Bus is not enabled in Avahi." | |||
| 2120 | 2469 | ||
| 2121 | ;;; TODO: | 2470 | ;;; TODO: |
| 2122 | 2471 | ||
| 2472 | ;; * Support /media::. | ||
| 2473 | ;; | ||
| 2474 | ;; * React on media mount/unmount. | ||
| 2475 | ;; | ||
| 2123 | ;; * (Customizable) unmount when exiting Emacs. See tramp-archive.el. | 2476 | ;; * (Customizable) unmount when exiting Emacs. See tramp-archive.el. |
| 2124 | ;; | 2477 | ;; |
| 2125 | ;; * Host name completion for existing mount points (afp-server, | 2478 | ;; * Host name completion for existing mount points (afp-server, |
| 2126 | ;; smb-server, google-drive, nextcloud) or via smb-network or network. | 2479 | ;; smb-server) or via smb-network or network. |
| 2127 | ;; | 2480 | ;; |
| 2128 | ;; * Check, how two shares of the same SMB server can be mounted in | 2481 | ;; * Check, how two shares of the same SMB server can be mounted in |
| 2129 | ;; parallel. | 2482 | ;; parallel. |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 900c15ffae9..324b2a24b80 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -2059,6 +2059,9 @@ letter into the file name. This function removes it." | |||
| 2059 | 2059 | ||
| 2060 | ;;; Config Manipulation Functions: | 2060 | ;;; Config Manipulation Functions: |
| 2061 | 2061 | ||
| 2062 | (defconst tramp-dns-sd-service-regexp "^_[-[:alnum:]]+\\._tcp$" | ||
| 2063 | "DNS-SD service regexp.") | ||
| 2064 | |||
| 2062 | (defun tramp-set-completion-function (method function-list) | 2065 | (defun tramp-set-completion-function (method function-list) |
| 2063 | "Set the list of completion functions for METHOD. | 2066 | "Set the list of completion functions for METHOD. |
| 2064 | FUNCTION-LIST is a list of entries of the form (FUNCTION FILE). | 2067 | FUNCTION-LIST is a list of entries of the form (FUNCTION FILE). |
| @@ -2091,9 +2094,9 @@ Example: | |||
| 2091 | (zerop | 2094 | (zerop |
| 2092 | (tramp-call-process | 2095 | (tramp-call-process |
| 2093 | v "reg" nil nil nil "query" (nth 1 (car v)))))) | 2096 | v "reg" nil nil nil "query" (nth 1 (car v)))))) |
| 2094 | ;; Zeroconf service type. | 2097 | ;; DNS-SD service type. |
| 2095 | ((string-match-p | 2098 | ((string-match-p |
| 2096 | "^_[[:alpha:]]+\\._[[:alpha:]]+$" (nth 1 (car v)))) | 2099 | tramp-dns-sd-service-regexp (nth 1 (car v)))) |
| 2097 | ;; Configuration file or empty string. | 2100 | ;; Configuration file or empty string. |
| 2098 | (t (file-exists-p (nth 1 (car v)))))) | 2101 | (t (file-exists-p (nth 1 (car v)))))) |
| 2099 | (setq r (delete (car v) r))) | 2102 | (setq r (delete (car v) r))) |