15830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes/*
25830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * Copyright (C) 2015 The Android Open Source Project
35830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes *
45830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
55830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * you may not use this file except in compliance with the License.
65830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * You may obtain a copy of the License at
75830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes *
85830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
95830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes *
105830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * Unless required by applicable law or agreed to in writing, software
115830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
125830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * See the License for the specific language governing permissions and
145830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * limitations under the License.
155830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes */
165830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes
17aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui#define TRACE_TAG ADB
18e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
195830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include "adb_utils.h"
20924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gao#include "adb_unique_fd.h"
215830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes
22a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes#include <stdlib.h>
235830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include <sys/stat.h>
245830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include <sys/types.h>
255830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include <unistd.h>
265830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes
27e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#include <algorithm>
28e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao#include <vector>
29e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
3058021d15c94eb6a81d2673634956b5374af6a1e5Colin Cross#include <android-base/file.h>
314f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/logging.h>
32eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell#include <android-base/parseint.h>
334f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
344f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/strings.h>
35e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
367d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#include "adb.h"
37e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#include "adb_trace.h"
3853daee6a2b415caa0ff3e425c7fa613c834bca61Elliott Hughes#include "sysdeps.h"
3953daee6a2b415caa0ff3e425c7fa613c834bca61Elliott Hughes
40a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#ifdef _WIN32
41a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#  ifndef WIN32_LEAN_AND_MEAN
42a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#    define WIN32_LEAN_AND_MEAN
43a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#  endif
44a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#  include "windows.h"
45a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#  include "shlobj.h"
46e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao#else
47e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao#include <pwd.h>
48a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#endif
49a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi
5022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
517d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#if defined(_WIN32)
527d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaoconstexpr char kNullFileName[] = "NUL";
537d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#else
547d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaoconstexpr char kNullFileName[] = "/dev/null";
557d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#endif
567d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao
577d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaovoid close_stdin() {
587d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    int fd = unix_open(kNullFileName, O_RDONLY);
597d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    if (fd == -1) {
607d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao        fatal_errno("failed to open %s", kNullFileName);
617d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    }
627d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao
637d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    if (TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO)) == -1) {
647d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao        fatal_errno("failed to redirect stdin to %s", kNullFileName);
657d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    }
667d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    unix_close(fd);
677d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao}
687d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao
69a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughesbool getcwd(std::string* s) {
70a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  char* cwd = getcwd(nullptr, 0);
71a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  if (cwd != nullptr) *s = cwd;
72a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  free(cwd);
73a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  return (cwd != nullptr);
74a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes}
75a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes
765830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughesbool directory_exists(const std::string& path) {
775830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes  struct stat sb;
78ff468dce4c32de86aacbca4afe50a18e4aba43ceJosh Gao  return stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode);
795830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes}
805830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes
815830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughesstd::string escape_arg(const std::string& s) {
825498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  std::string result = s;
835830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes
8484b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // Escape any ' in the string (before we single-quote the whole thing).
8584b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // The correct way to do this for the shell is to replace ' with '\'' --- that is,
8684b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // close the existing single-quoted string, escape a single single-quote, and start
8784b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // a new single-quoted string. Like the C preprocessor, the shell will concatenate
8884b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // these pieces into one string.
8984b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  for (size_t i = 0; i < s.size(); ++i) {
9084b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes    if (s[i] == '\'') {
9184b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes      result.insert(i, "'\\'");
9284b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes      i += 2;
9384b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes    }
945830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes  }
955498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes
965498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  // Prefix and suffix the whole string with '.
975498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  result.insert(result.begin(), '\'');
985498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  result.push_back('\'');
995830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes  return result;
1005830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes}
101e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
10285c45bd5a185f09f24bb0d790b2038fe72b567a9Spencer Low// Given a relative or absolute filepath, create the directory hierarchy
10322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low// as needed. Returns true if the hierarchy is/was setup.
1045c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughesbool mkdirs(const std::string& path) {
10522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // TODO: all the callers do unlink && mkdirs && adb_creat ---
10622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // that's probably the operation we should expose.
10722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
10822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Implementation Notes:
10922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //
11022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Pros:
11122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - Uses dirname, so does not need to deal with OS_PATH_SEPARATOR.
11222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - On Windows, uses mingw dirname which accepts '/' and '\\', drive letters
11322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   (C:\foo), UNC paths (\\server\share\dir\dir\file), and Unicode (when
11422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   combined with our adb_mkdir() which takes UTF-8).
11522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - Is optimistic wrt thinking that a deep directory hierarchy will exist.
11622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   So it does as few stat()s as possible before doing mkdir()s.
11722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Cons:
11822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - Recursive, so it uses stack space relative to number of directory
11922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   components.
12022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
1211e611a33d524a7c7a31181aca10d1f4a4c9fc1b2Josh Gao  // If path points to a symlink to a directory, that's fine.
1221e611a33d524a7c7a31181aca10d1f4a4c9fc1b2Josh Gao  struct stat sb;
1231e611a33d524a7c7a31181aca10d1f4a4c9fc1b2Josh Gao  if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) {
12422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return true;
12522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
12622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
12758021d15c94eb6a81d2673634956b5374af6a1e5Colin Cross  const std::string parent(android::base::Dirname(path));
12885c45bd5a185f09f24bb0d790b2038fe72b567a9Spencer Low
12922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // If dirname returned the same path as what we passed in, don't go recursive.
13022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // This can happen on Windows when walking up the directory hierarchy and not
13122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // finding anything that already exists (unlike POSIX that will eventually
13222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // find . or /).
13322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  if (parent == path) {
13422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    errno = ENOENT;
13522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return false;
13622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
13722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
13845b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  // Recursively make parent directories of 'path'.
13922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  if (!mkdirs(parent)) {
14022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return false;
14122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
14222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
14345b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  // Now that the parent directory hierarchy of 'path' has been ensured,
14485c45bd5a185f09f24bb0d790b2038fe72b567a9Spencer Low  // create path itself.
14545b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  if (adb_mkdir(path, 0775) == -1) {
14622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    const int saved_errno = errno;
14785c45bd5a185f09f24bb0d790b2038fe72b567a9Spencer Low    // If someone else created the directory, that is ok.
14885c45bd5a185f09f24bb0d790b2038fe72b567a9Spencer Low    if (directory_exists(path)) {
14922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low      return true;
15022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    }
15185c45bd5a185f09f24bb0d790b2038fe72b567a9Spencer Low    // There might be a pre-existing file at 'path', or there might have been some other error.
15222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    errno = saved_errno;
15322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return false;
15422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
15522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
15622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  return true;
1575c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes}
1585c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes
159aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cuistd::string dump_hex(const void* data, size_t byte_count) {
1609893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert    size_t truncate_len = 16;
1619893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert    bool truncated = false;
1629893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert    if (byte_count > truncate_len) {
1639893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert        byte_count = truncate_len;
1649893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert        truncated = true;
1659893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert    }
166e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
167e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
168e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
169e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    std::string line;
170e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    for (size_t i = 0; i < byte_count; ++i) {
171e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        android::base::StringAppendF(&line, "%02x", p[i]);
172e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    }
173e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    line.push_back(' ');
174e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
175e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    for (size_t i = 0; i < byte_count; ++i) {
176363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low        int ch = p[i];
177363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low        line.push_back(isprint(ch) ? ch : '.');
178e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    }
179e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
1809893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert    if (truncated) {
1819893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert        line += " [truncated]";
1829893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert    }
1839893f93950cb6fce83ca3cff9cfced6ae2e9118cDan Albert
184aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui    return line;
185e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes}
1863d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes
187aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughesstd::string perror_str(const char* msg) {
188aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes    return android::base::StringPrintf("%s: %s", msg, strerror(errno));
189aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes}
1906dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui
1916dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#if !defined(_WIN32)
1923777d2ecc05d397ca501f4ee296e4e66568bb1bdJosh Gao// Windows version provided in sysdeps_win32.cpp
1936dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cuibool set_file_block_mode(int fd, bool block) {
1946dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    int flags = fcntl(fd, F_GETFL, 0);
1956dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    if (flags == -1) {
1966dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd;
1976dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        return false;
1986dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    }
1996dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
2006dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    if (fcntl(fd, F_SETFL, flags) != 0) {
2016dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd << ", flags " << flags;
2026dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        return false;
2036dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    }
2046dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    return true;
2056dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui}
2066dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#endif
207eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
208eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursellbool forward_targets_are_valid(const std::string& source, const std::string& dest,
209eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell                               std::string* error) {
210eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    if (android::base::StartsWith(source, "tcp:")) {
211eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        // The source port may be 0 to allow the system to select an open port.
212eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        int port;
213eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if (!android::base::ParseInt(&source[4], &port) || port < 0) {
214eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            *error = android::base::StringPrintf("Invalid source port: '%s'", &source[4]);
215eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            return false;
216eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        }
217eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    }
218eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
219eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    if (android::base::StartsWith(dest, "tcp:")) {
220eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        // The destination port must be > 0.
221eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        int port;
222eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if (!android::base::ParseInt(&dest[4], &port) || port <= 0) {
223eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            *error = android::base::StringPrintf("Invalid destination port: '%s'", &dest[4]);
224eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            return false;
225eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        }
226eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    }
227eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
228eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    return true;
229eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell}
230f48adf63512f1d5a4dbe40ce37e5946b434e8be9Yurii Zubrytskyi
231e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gaostd::string adb_get_homedir_path() {
232a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#ifdef _WIN32
233a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    WCHAR path[MAX_PATH];
234a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path);
235a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    if (FAILED(hr)) {
236a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        D("SHGetFolderPathW failed: %s", android::base::SystemErrorCodeToString(hr).c_str());
237a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        return {};
238a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    }
239a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    std::string home_str;
240a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    if (!android::base::WideToUTF8(path, &home_str)) {
241a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        return {};
242a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    }
243a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    return home_str;
244a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#else
245a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    if (const char* const home = getenv("HOME")) {
246a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        return home;
247a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    }
248e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao
249e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    struct passwd pwent;
250e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    struct passwd* result;
251e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    int pwent_max = sysconf(_SC_GETPW_R_SIZE_MAX);
252e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    std::vector<char> buf(pwent_max);
253e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    int rc = getpwuid_r(getuid(), &pwent, buf.data(), buf.size(), &result);
254e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    if (rc == 0 && result) {
255e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao        return result->pw_dir;
256e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    }
257e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao
258e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    LOG(FATAL) << "failed to get user home directory";
259a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    return {};
260a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#endif
261a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi}
262e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao
263e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gaostd::string adb_get_android_dir_path() {
264e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    std::string user_dir = adb_get_homedir_path();
265e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    std::string android_dir = user_dir + OS_PATH_SEPARATOR + ".android";
266e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    struct stat buf;
267e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    if (stat(android_dir.c_str(), &buf) == -1) {
268e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao        if (adb_mkdir(android_dir.c_str(), 0750) == -1) {
269e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao            PLOG(FATAL) << "Cannot mkdir '" << android_dir << "'";
270e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao        }
271e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    }
272e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    return android_dir;
273e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao}
274924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gao
275924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gaovoid AdbCloser::Close(int fd) {
276924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gao    adb_close(fd);
277924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gao}
2782ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes
2791fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughesint syntax_error(const char* fmt, ...) {
2801fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659Elliott Hughes    fprintf(stderr, "adb: usage: ");
2812ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes
2822ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    va_list ap;
2832ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    va_start(ap, fmt);
2842ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    vfprintf(stderr, fmt, ap);
2852ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    va_end(ap);
2862ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes
2872ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    fprintf(stderr, "\n");
2882ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    return 1;
2892ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes}
2906eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
2916eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughesstd::string GetLogFilePath() {
2926eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes#if defined(_WIN32)
2936eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    const char log_name[] = "adb.log";
2946eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    WCHAR temp_path[MAX_PATH];
2956eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
2966eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
2976eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
2986eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    if (nchars >= arraysize(temp_path) || nchars == 0) {
2996eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes        // If string truncation or some other error.
3006eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes        fatal("cannot retrieve temporary file path: %s\n",
3016eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes              android::base::SystemErrorCodeToString(GetLastError()).c_str());
3026eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    }
3036eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
3046eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    std::string temp_path_utf8;
3056eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
3066eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes        fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
3076eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    }
3086eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes
3096eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    return temp_path_utf8 + log_name;
3106eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes#else
3116eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    const char* tmp_dir = getenv("TMPDIR");
3126eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    if (tmp_dir == nullptr) tmp_dir = "/tmp";
3136eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes    return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
3146eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes#endif
3156eadee860798bf4e0be0293450017fbc95ff41c8Elliott Hughes}
316