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