adb_utils.cpp revision ff468dce4c32de86aacbca4afe50a18e4aba43ce
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) {
160e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    byte_count = std::min(byte_count, size_t(16));
161e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
162e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
163e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
164e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    std::string line;
165e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    for (size_t i = 0; i < byte_count; ++i) {
166e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        android::base::StringAppendF(&line, "%02x", p[i]);
167e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    }
168e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    line.push_back(' ');
169e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
170e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    for (size_t i = 0; i < byte_count; ++i) {
171363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low        int ch = p[i];
172363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low        line.push_back(isprint(ch) ? ch : '.');
173e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    }
174e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
175aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui    return line;
176e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes}
1773d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes
178aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughesstd::string perror_str(const char* msg) {
179aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes    return android::base::StringPrintf("%s: %s", msg, strerror(errno));
180aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes}
1816dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui
1826dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#if !defined(_WIN32)
1833777d2ecc05d397ca501f4ee296e4e66568bb1bdJosh Gao// Windows version provided in sysdeps_win32.cpp
1846dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cuibool set_file_block_mode(int fd, bool block) {
1856dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    int flags = fcntl(fd, F_GETFL, 0);
1866dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    if (flags == -1) {
1876dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd;
1886dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        return false;
1896dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    }
1906dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
1916dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    if (fcntl(fd, F_SETFL, flags) != 0) {
1926dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd << ", flags " << flags;
1936dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        return false;
1946dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    }
1956dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    return true;
1966dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui}
1976dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#endif
198eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
199eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursellbool forward_targets_are_valid(const std::string& source, const std::string& dest,
200eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell                               std::string* error) {
201eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    if (android::base::StartsWith(source, "tcp:")) {
202eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        // The source port may be 0 to allow the system to select an open port.
203eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        int port;
204eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if (!android::base::ParseInt(&source[4], &port) || port < 0) {
205eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            *error = android::base::StringPrintf("Invalid source port: '%s'", &source[4]);
206eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            return false;
207eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        }
208eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    }
209eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
210eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    if (android::base::StartsWith(dest, "tcp:")) {
211eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        // The destination port must be > 0.
212eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        int port;
213eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if (!android::base::ParseInt(&dest[4], &port) || port <= 0) {
214eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            *error = android::base::StringPrintf("Invalid destination port: '%s'", &dest[4]);
215eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            return false;
216eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        }
217eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    }
218eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
219eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    return true;
220eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell}
221f48adf63512f1d5a4dbe40ce37e5946b434e8be9Yurii Zubrytskyi
222e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gaostd::string adb_get_homedir_path() {
223a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#ifdef _WIN32
224a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    WCHAR path[MAX_PATH];
225a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path);
226a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    if (FAILED(hr)) {
227a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        D("SHGetFolderPathW failed: %s", android::base::SystemErrorCodeToString(hr).c_str());
228a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        return {};
229a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    }
230a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    std::string home_str;
231a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    if (!android::base::WideToUTF8(path, &home_str)) {
232a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        return {};
233a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    }
234a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    return home_str;
235a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#else
236a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    if (const char* const home = getenv("HOME")) {
237a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi        return home;
238a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    }
239e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao
240e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    struct passwd pwent;
241e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    struct passwd* result;
242e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    int pwent_max = sysconf(_SC_GETPW_R_SIZE_MAX);
243e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    std::vector<char> buf(pwent_max);
244e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    int rc = getpwuid_r(getuid(), &pwent, buf.data(), buf.size(), &result);
245e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    if (rc == 0 && result) {
246e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao        return result->pw_dir;
247e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    }
248e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao
249e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    LOG(FATAL) << "failed to get user home directory";
250a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi    return {};
251a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#endif
252a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi}
253e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao
254e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gaostd::string adb_get_android_dir_path() {
255e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    std::string user_dir = adb_get_homedir_path();
256e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    std::string android_dir = user_dir + OS_PATH_SEPARATOR + ".android";
257e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    struct stat buf;
258e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    if (stat(android_dir.c_str(), &buf) == -1) {
259e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao        if (adb_mkdir(android_dir.c_str(), 0750) == -1) {
260e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao            PLOG(FATAL) << "Cannot mkdir '" << android_dir << "'";
261e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao        }
262e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    }
263e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao    return android_dir;
264e0b7502c7fb12b0ac03a5903562c74820975b833Josh Gao}
265924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gao
266924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gaovoid AdbCloser::Close(int fd) {
267924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gao    adb_close(fd);
268924d35a8d5f82e2d2f7e4dcedaa60791306b5fb5Josh Gao}
2692ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes
2702ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughesint usage(const char* fmt, ...) {
2712ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    fprintf(stderr, "adb: ");
2722ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes
2732ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    va_list ap;
2742ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    va_start(ap, fmt);
2752ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    vfprintf(stderr, fmt, ap);
2762ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    va_end(ap);
2772ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes
2782ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    fprintf(stderr, "\n");
2792ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes    return 1;
2802ec36b0da00f959ed5cf47b947630fe6bfe73c9fElliott Hughes}
281