diff --git a/lisp/tramp-adb.el b/lisp/tramp-adb.el index 1a7a34f..172389a 100644 --- a/lisp/tramp-adb.el +++ b/lisp/tramp-adb.el @@ -991,11 +991,58 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (tramp-set-connection-property v "process-buffer" nil)))))) ;; Helper functions. +(defun tramp-adb-get-host-port-from-device-name (host device-names) + "Returns host:name string by searching host in the device-names list. If +failed, return nil" + (if (null device-names) nil + (if (string-match host (car device-names)) + (car device-names) + (tramp-adb-get-host-port-from-device-name (host (cdr device-names)))))) + +(defun tramp-adb-get-host-for-execution (vec) + "Returns host name and port from VEC to be used in shell exceution. +E.g. a host name \"192.168.1.1#5555\" returns \"192.168.1.1:5555\" + a host name \"R38273882DE\" returns \"R38273882DE\"." + (let ((port (tramp-file-name-port vec)) + (host (tramp-file-name-real-host vec))) + ;; Check ADB is in which kind mode: TCP mode or USB mode by the host name + (if (tramp-ipv4-addr-p host) + ;; In TCP mode, if port is provided, get port from ADB devices command + (if port + (format "%s:%s" host port) + ;; If port is not provided, get host:port from device-names + (let ((host-port (tramp-adb-get-host-port-from-device-name + host (mapcar + 'cadr + (tramp-adb-parse-device-names nil))))) + (if host-port + host-port + (tramp-error vec 'file-error "Couldn't find device")))) + ;; In USB mode, no port is needed. + (if port + ;; TODO Tramp doesn't show the message here, what's the proper way + ;; showing message to user? + (tramp-error vec 'file-error "ADB USB mode needs not port number") + host)))) + +(defun tramp-adb-get-real-host (host) + "Returns real host (with port or without port) from tramp host format +e.g. input: 192.168.1.1#5555 return 192.168.1.1:5555 + input: R38273882DE return R38273882DE" + (let ((l-port) + (l-host) + (real-host)) + (if (string-match tramp-host-with-port-regexp host) + (setq l-port (match-string 2 host) + l-host (match-string 1 host) + real-host (concat l-host ":" l-port)) + (setq real-host host)))) (defun tramp-adb-execute-adb-command (vec &rest args) "Returns nil on success error-output on failure." - (when (> (length (tramp-file-name-host vec)) 0) - (setq args (append (list "-s" (tramp-file-name-host vec)) args))) + (let ((host (tramp-file-name-host vec))) + (when (> (length host) 0) + (setq args (append (list "-s" (tramp-adb-get-host-for-execution vec)) args)))) (with-temp-buffer (prog1 (unless @@ -1097,6 +1144,7 @@ connection if a previous connection has died for some reason." (let* ((buf (tramp-get-connection-buffer vec)) (p (get-buffer-process buf)) (host (tramp-file-name-host vec)) + (exe-host (tramp-adb-get-host-for-execution vec)) (user (tramp-file-name-user vec)) devices) @@ -1113,7 +1161,7 @@ connection if a previous connection has died for some reason." (setq devices (mapcar 'cadr (tramp-adb-parse-device-names nil))) (if (not devices) (tramp-error vec 'file-error "No device connected")) - (if (and (> (length host) 0) (not (member host devices))) + (if (and (> (length host) 0) (not (member exe-host devices))) (tramp-error vec 'file-error "Device %s not connected" host)) (if (and (> (length devices) 1) (zerop (length host))) (tramp-error @@ -1123,7 +1171,7 @@ connection if a previous connection has died for some reason." (let* ((coding-system-for-read 'utf-8-dos) ;is this correct? (process-connection-type tramp-process-connection-type) (args (if (> (length host) 0) - (list "-s" host "shell") + (list "-s" exe-host "shell") (list "shell"))) (p (let ((default-directory (tramp-compat-temporary-file-directory))) diff --git a/lisp/tramp.el b/lisp/tramp.el index 969172b..72449d3 100644 --- a/lisp/tramp.el +++ b/lisp/tramp.el @@ -785,6 +785,12 @@ Derived from `tramp-postfix-user-format'.") (defconst tramp-host-regexp "[a-zA-Z0-9_.-]+" "Regexp matching host names.") +;; The following regexp is a big sloppy. But it should be OK +;; to detect the difference between x.x.x.x and xxxx patterns. +(defconst tramp-ipv4-regexp + "[0-9]+\.[0-9]+.[0-9]+.[0-9]+" + "Regexp matching ipv4 address.") + (defconst tramp-prefix-ipv6-format (cond ((equal tramp-syntax 'ftp) "[") ((equal tramp-syntax 'sep) "") @@ -1204,6 +1210,12 @@ If the `tramp-methods' entry does not exist, return nil." (and (stringp name) (string-match tramp-file-name-regexp name)))) +(defun tramp-ipv4-addr-p (name) + "Return t if NAME is a string with IP address syntax." + (save-match-data + (and (stringp name) + (string-match tramp-ipv4-regexp name)))) + ;; Obsoleted with Tramp 2.2.7. (defconst tramp-obsolete-methods '("ssh1" "ssh2" "scp1" "scp2" "scpc" "rsyncc" "plink1")