remote_access.sh: enclose IPv6 address with brackets for rsync

Unlike ssh, rsync expects IPv6 addresses to be enclosed in brackets.

Compared to IPv4, IPv6 addresses rarely change which makes
automation more predictable and generally easier; especially
useful when debugging graphical issues.

As a special and even better case, IPv6 *link-local* addresses
never ever change and do not require any kind of network server or
configuration. They are always available even on isolated,
ad-hoc networks and direct back-to-back connections.

BUG=None
TEST=Use IPv6 addresses as the --remote argument, for instance:
./update_kernel.sh --remote fe80::20e:c6ff:fe88:ffa7%eth0

Change-Id: Ic5d30b1a81c7c8aed35ecaa439c8767fbe61f443
Signed-off-by: Marc Herbert <marc.herbert@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/277390
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/remote_access.sh b/remote_access.sh
index 3e0c6e9..5b70154 100644
--- a/remote_access.sh
+++ b/remote_access.sh
@@ -17,6 +17,23 @@
 DEFINE_integer ssh_connection_attempts 4 \
   "SSH connection attempts"
 
+# Returns true if $1 has at least two colons.
+has_two_colons_or_more() {
+  # IPv6 addresses have at least two colons while IPv4 addresses and
+  # hostnames have none.
+  [[ "$1" == *:*:* ]]
+}
+
+# Prints $1 enclosed with brackets if it looks like an IPv6 address
+# and unchanged otherwise.
+brackets_enclosed_if_ipv6() {
+  local rem="$1"
+  if has_two_colons_or_more "${rem}"; then
+    rem="[${rem}]"
+  fi
+  echo "${rem}"
+}
+
 ssh_connect_settings() {
   if [[ -n "$SSH_CONNECT_SETTINGS" ]]; then
     # If connection settings were fixed in an environment variable, just return
@@ -55,7 +72,10 @@
 # Copies a list of remote files specified in file $1 to local location
 # $2.  Directory paths in $1 are collapsed into $2.
 remote_rsync_from() {
-  remote_rsync_raw --no-R --files-from="$1" root@${FLAGS_remote}:/ "$2"
+  local rsync_rem
+  rsync_rem="$(brackets_enclosed_if_ipv6 "${FLAGS_remote}")"
+  remote_rsync_raw --no-R --files-from="$1" \
+    root@"${rsync_rem}:/" "$2"
 }
 
 # Send a directory from $1 to $2 on remote host
@@ -65,12 +85,14 @@
 #
 # Use like: remote_send_to /build/board/lib/modules/ /lib/modules/
 remote_send_to() {
+  local rsync_rem
   if [ ! -d "$1" ]; then
     die "$1 must be a directory"
   fi
 
   if remote_sh rsync --version >/dev/null 2>&1; then
-    remote_rsync_raw -a "$1/" root@${FLAGS_remote}:"$2/"
+    rsync_rem="$(brackets_enclosed_if_ipv6 "${FLAGS_remote}")"
+    remote_rsync_raw -a "$1/" root@"${rsync_rem}:$2/"
   else
     tar -C "$1" -cz . | remote_sh tar -C "$2" -xz
   fi