Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c74270f authored by Elliott Hughes's avatar Elliott Hughes
Browse files

More adb cleanup.

This removes adb_dirstart and adb_dirstop. It also fixes a couple of memory
leaks by switching to std::string. This also fixes the bug in the previous
change --- mkdirs is given input like "/system/bin/sh" and only expected to
create "/system/bin". In a later change, we should remove mkdirs and only
expose the intended "unlink && mkdirs && create" functionality.

Change-Id: I30289dc1b3dff575cc1b158d993652178f587552
parent 0cf93dc3
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -72,15 +72,38 @@ std::string escape_arg(const std::string& s) {
  return result;
}

bool mkdirs(const std::string& path) {
    for (size_t i = adb_dirstart(path, 1); i != std::string::npos; i = adb_dirstart(path, i + 1)) {
        if (adb_mkdir(path.substr(0, i), 0775) == -1 && errno != EEXIST) {
std::string adb_basename(const std::string& path) {
    size_t base = path.find_last_of(OS_PATH_SEPARATORS);
    return (base != std::string::npos) ? path.substr(base + 1) : path;
}

static bool real_mkdirs(const std::string& path) {
    std::vector<std::string> path_components = android::base::Split(path, OS_PATH_SEPARATOR_STR);
    // TODO: all the callers do unlink && mkdirs && adb_creat ---
    // that's probably the operation we should expose.
    path_components.pop_back();
    std::string partial_path;
    for (const auto& path_component : path_components) {
        if (partial_path.back() != OS_PATH_SEPARATOR) partial_path += OS_PATH_SEPARATOR;
        partial_path += path_component;
        if (adb_mkdir(partial_path.c_str(), 0775) == -1 && errno != EEXIST) {
            return false;
        }
    }
    return true;
}

bool mkdirs(const std::string& path) {
#if defined(_WIN32)
    // Replace '/' with '\\' so we can share the code.
    std::string clean_path = path;
    std::replace(clean_path.begin(), clean_path.end(), '/', '\\');
    return real_mkdirs(clean_path);
#else
    return real_mkdirs(path);
#endif
}

void dump_hex(const void* data, size_t byte_count) {
    byte_count = std::min(byte_count, size_t(16));

+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

bool getcwd(std::string* cwd);
bool directory_exists(const std::string& path);
std::string adb_basename(const std::string& path);

bool mkdirs(const std::string& path);

+9 −4
Original line number Diff line number Diff line
@@ -58,6 +58,11 @@ TEST(adb_utils, escape_arg) {
  ASSERT_EQ(R"('abc)')", escape_arg("abc)"));
}

TEST(adb_utils, adb_basename) {
  EXPECT_EQ("sh", adb_basename("/system/bin/sh"));
  EXPECT_EQ("sh", adb_basename("sh"));
}

TEST(adb_utils, parse_host_and_port) {
  std::string canonical_address;
  std::string host;
@@ -142,8 +147,8 @@ TEST(adb_utils, parse_host_and_port) {

TEST(adb_utils, mkdirs) {
  TemporaryDir td;
  EXPECT_TRUE(mkdirs(std::string(td.path) + "/dir/subdir/file"));
  std::string file = std::string(td.path) + "/file";
  adb_creat(file.c_str(), 0600);
  EXPECT_FALSE(mkdirs(file + "/subdir/"));
  std::string path = std::string(td.path) + "/dir/subdir/file";
  EXPECT_TRUE(mkdirs(path));
  EXPECT_NE(-1, adb_creat(path.c_str(), 0600));
  EXPECT_FALSE(mkdirs(path + "/subdir/"));
}
+12 −24
Original line number Diff line number Diff line
@@ -847,25 +847,25 @@ static int restore(int argc, const char** argv) {
 * Given <hint>, try to construct an absolute path to the
 * ANDROID_PRODUCT_OUT dir.
 */
static std::string find_product_out_path(const char* hint) {
    if (hint == NULL || hint[0] == '\0') {
static std::string find_product_out_path(const std::string& hint) {
    if (hint.empty()) {
        return "";
    }

    // If it's already absolute, don't bother doing any work.
    if (adb_is_absolute_host_path(hint)) {
    if (adb_is_absolute_host_path(hint.c_str())) {
        return hint;
    }

    // If there are any slashes in it, assume it's a relative path;
    // make it absolute.
    if (adb_dirstart(hint) != std::string::npos) {
    if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
        std::string cwd;
        if (!getcwd(&cwd)) {
            fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
            return "";
        }
        return android::base::StringPrintf("%s%s%s", cwd.c_str(), OS_PATH_SEPARATOR_STR, hint);
        return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
    }

    // It's a string without any slashes.  Try to do something with it.
@@ -889,7 +889,7 @@ static std::string find_product_out_path(const char* hint) {
    path += hint;
    if (!directory_exists(path)) {
        fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
                        "\"%s\" doesn't exist\n", hint, path.c_str());
                        "\"%s\" doesn't exist\n", hint.c_str(), path.c_str());
        return "";
    }
    return path;
@@ -999,7 +999,7 @@ int adb_commandline(int argc, const char **argv) {
            } else {
                product = argv[0] + 2;
            }
            gProductOutPath = find_product_out_path(product);
            if (product) gProductOutPath = find_product_out_path(product);
            if (gProductOutPath.empty()) {
                fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
                return usage();
@@ -1462,22 +1462,11 @@ static int uninstall_app(TransportType transport, const char* serial, int argc,
    return pm_command(transport, serial, argc, argv);
}

static int delete_file(TransportType transport, const char* serial, char* filename) {
static int delete_file(TransportType transport, const char* serial, const std::string& filename) {
    std::string cmd = "shell:rm -f " + escape_arg(filename);
    return send_shell_command(transport, serial, cmd);
}

static const char* get_basename(const std::string& filename)
{
    size_t base = adb_dirstop(filename);
    if (base != std::string::npos) {
        ++base;
    } else {
        base = 0;
    }
    return filename.c_str() + base;
}

static int install_app(TransportType transport, const char* serial, int argc, const char** argv) {
    static const char *const DATA_DEST = "/data/local/tmp/%s";
    static const char *const SD_DEST = "/sdcard/tmp/%s";
@@ -1514,13 +1503,12 @@ static int install_app(TransportType transport, const char* serial, int argc, co
    }

    const char* apk_file = argv[last_apk];
    char apk_dest[PATH_MAX];
    snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
    int err = do_sync_push(apk_file, apk_dest, 0 /* no show progress */);
    std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str());
    int err = do_sync_push(apk_file, apk_dest.c_str(), 0 /* no show progress */);
    if (err) {
        goto cleanup_apk;
    } else {
        argv[last_apk] = apk_dest; /* destination name, not source location */
        argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */
    }

    err = pm_command(transport, serial, argc, argv);
@@ -1604,7 +1592,7 @@ static int install_multiple_app(TransportType transport, const char* serial, int

        std::string cmd = android::base::StringPrintf(
                "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
                static_cast<uint64_t>(sb.st_size), session_id, i, get_basename(file));
                static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());

        int localFd = adb_open(file, O_RDONLY);
        if (localFd < 0) {
+63 −95
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#include "adb_utils.h"
#include "file_sync_service.h"

#include <base/stringprintf.h>

static unsigned long long total_bytes;
static long long start_time;

@@ -92,18 +94,14 @@ static void sync_quit(int fd) {
typedef void (*sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char *name, void *cookie);

static int sync_ls(int fd, const char* path, sync_ls_cb func, void* cookie) {
    syncmsg msg;
    char buf[257];
    int len;

    len = strlen(path);
    int len = strlen(path);
    if (len > 1024) goto fail;

    syncmsg msg;
    msg.req.id = ID_LIST;
    msg.req.namelen = htoll(len);

    if(!WriteFdExactly(fd, &msg.req, sizeof(msg.req)) ||
       !WriteFdExactly(fd, path, len)) {
    if (!WriteFdExactly(fd, &msg.req, sizeof(msg.req)) || !WriteFdExactly(fd, path, len)) {
        goto fail;
    }

@@ -115,13 +113,11 @@ static int sync_ls(int fd, const char* path, sync_ls_cb func, void* cookie) {
        len = ltohl(msg.dent.namelen);
        if (len > 256) break;

        char buf[257];
        if (!ReadFdExactly(fd, buf, len)) break;
        buf[len] = 0;

        func(ltohl(msg.dent.mode),
             ltohl(msg.dent.size),
             ltohl(msg.dent.time),
             buf, cookie);
        func(ltohl(msg.dent.mode), ltohl(msg.dent.size), ltohl(msg.dent.time), buf, cookie);
    }

fail:
@@ -220,7 +216,7 @@ static int sync_readmode(int fd, const char* path, unsigned* mode) {
    return 0;
}

static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show_progress)
static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, bool show_progress)
{
    int lfd, err = 0;
    unsigned long long size = 0;
@@ -274,7 +270,7 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show
}

static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf,
                             int show_progress)
                             bool show_progress)
{
    int err = 0;
    int total = 0;
@@ -308,9 +304,7 @@ extern int write_data_link(int fd, const char *path, syncsendbuf *sbuf) __attrib
#else
static int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
{
    int len, ret;

    len = readlink(path, sbuf->data, SYNC_DATA_MAX-1);
    int len = readlink(path, sbuf->data, SYNC_DATA_MAX-1);
    if (len < 0) {
        fprintf(stderr, "error reading link '%s': %s\n", path, strerror(errno));
        return -1;
@@ -320,9 +314,9 @@ static int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
    sbuf->size = htoll(len + 1);
    sbuf->id = ID_DATA;

    ret = !WriteFdExactly(fd, sbuf, sizeof(unsigned) * 2 + len + 1);
    if(ret)
    if (!WriteFdExactly(fd, sbuf, sizeof(unsigned) * 2 + len + 1)) {
        return -1;
    }

    total_bytes += len + 1;

@@ -331,7 +325,7 @@ static int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
#endif

static int sync_send(int fd, const char *lpath, const char *rpath,
                     unsigned mtime, mode_t mode, int show_progress)
                     unsigned mtime, mode_t mode, bool show_progress)
{
    syncmsg msg;
    int len, r;
@@ -396,7 +390,7 @@ fail:
    return -1;
}

static int sync_recv(int fd, const char* rpath, const char* lpath, int show_progress) {
static int sync_recv(int fd, const char* rpath, const char* lpath, bool show_progress) {
    syncmsg msg;
    int len;
    int lfd = -1;
@@ -525,11 +519,11 @@ int do_sync_ls(const char* path) {

    if (sync_ls(fd, path, do_sync_ls_cb, 0)) {
        return 1;
    } else {
    }

    sync_quit(fd);
    return 0;
}
}

struct copyinfo
{
@@ -712,11 +706,7 @@ static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, i
}


int do_sync_push(const char *lpath, const char *rpath, int show_progress)
{
    struct stat st;
    unsigned mode;

int do_sync_push(const char* lpath, const char* rpath, bool show_progress) {
    std::string error;
    int fd = adb_connect("sync:", &error);
    if (fd < 0) {
@@ -724,6 +714,7 @@ int do_sync_push(const char *lpath, const char *rpath, int show_progress)
        return 1;
    }

    struct stat st;
    if (stat(lpath, &st)) {
        fprintf(stderr,"cannot stat '%s': %s\n", lpath, strerror(errno));
        sync_quit(fd);
@@ -734,38 +725,27 @@ int do_sync_push(const char *lpath, const char *rpath, int show_progress)
        BEGIN();
        if (copy_local_dir_remote(fd, lpath, rpath, 0, 0)) {
            return 1;
        } else {
            END();
            sync_quit(fd);
        }
    } else {
        unsigned mode;
        if (sync_readmode(fd, rpath, &mode)) {
            return 1;
        }
        std::string path_holder;
        if ((mode != 0) && S_ISDIR(mode)) {
                /* if we're copying a local file to a remote directory,
                ** we *really* want to copy to remotedir + "/" + localfilename
                */
            size_t slash = adb_dirstop(lpath);
            const char *name = (slash == std::string::npos) ? lpath : lpath + slash + 1;

            int  tmplen = strlen(name) + strlen(rpath) + 2;
            char *tmp = reinterpret_cast<char*>(
                malloc(strlen(name) + strlen(rpath) + 2));
            if(tmp == 0) return 1;
            snprintf(tmp, tmplen, "%s/%s", rpath, name);
            rpath = tmp;
            // If we're copying a local file to a remote directory,
            // we really want to copy to remote_dir + "/" + local_filename.
            path_holder = android::base::StringPrintf("%s/%s", rpath, adb_basename(lpath).c_str());
            rpath = path_holder.c_str();
        }
        BEGIN();
        if (sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, show_progress)) {
            return 1;
        } else {
            END();
            sync_quit(fd);
            return 0;
        }
    }

    END();
    sync_quit(fd);
    return 0;
}

@@ -931,11 +911,7 @@ finish:
    return ret;
}

int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int copy_attrs)
{
    unsigned mode, time;
    struct stat st;

int do_sync_pull(const char* rpath, const char* lpath, bool show_progress, int copy_attrs) {
    std::string error;
    int fd = adb_connect("sync:", &error);
    if (fd < 0) {
@@ -943,6 +919,7 @@ int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int co
        return 1;
    }

    unsigned mode, time;
    if (sync_readtime(fd, rpath, &time, &mode)) {
        return 1;
    }
@@ -952,44 +929,36 @@ int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int co
    }

    if (S_ISREG(mode) || S_ISLNK(mode) || S_ISCHR(mode) || S_ISBLK(mode)) {
        std::string path_holder;
        struct stat st;
        if (stat(lpath, &st) == 0) {
            if (S_ISDIR(st.st_mode)) {
                    /* if we're copying a remote file to a local directory,
                    ** we *really* want to copy to localdir + "/" + remotefilename
                    */
                size_t slash = adb_dirstop(rpath);
                const char *name = (slash == std::string::npos) ? rpath : rpath + slash + 1;

                int  tmplen = strlen(name) + strlen(lpath) + 2;
                char *tmp = reinterpret_cast<char*>(malloc(tmplen));
                if(tmp == 0) return 1;
                snprintf(tmp, tmplen, "%s/%s", lpath, name);
                lpath = tmp;
                // If we're copying a remote file to a local directory,
                // we really want to copy to local_dir + "/" + basename(remote).
                path_holder = android::base::StringPrintf("%s/%s", lpath, adb_basename(rpath).c_str());
                lpath = path_holder.c_str();
            }
        }
        BEGIN();
        if (sync_recv(fd, rpath, lpath, show_progress)) {
            return 1;
        } else {
            if (copy_attrs && set_time_and_mode(lpath, time, mode))
            if (copy_attrs && set_time_and_mode(lpath, time, mode)) {
                return 1;
            END();
            sync_quit(fd);
            return 0;
            }
        }
    } else if(S_ISDIR(mode)) {
        BEGIN();
        if (copy_remote_dir_local(fd, rpath, lpath, copy_attrs)) {
            return 1;
        } else {
            END();
            sync_quit(fd);
            return 0;
        }
    } else {
        fprintf(stderr,"remote object '%s' not a file or directory\n", rpath);
        return 1;
    }
    END();
    sync_quit(fd);
    return 0;
}

int do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only)
@@ -1006,9 +975,8 @@ int do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_o
    BEGIN();
    if (copy_local_dir_remote(fd, lpath.c_str(), rpath.c_str(), 1, list_only)) {
        return 1;
    } else {
    }
    END();
    sync_quit(fd);
    return 0;
}
}
Loading