From d3281f4b67c36164955593ec6b7fcf16e2f95436 Mon Sep 17 00:00:00 2001 From: yangfl Date: Thu, 16 Jan 2020 02:47:34 +0800 Subject: [PATCH] Show a friendly hint for adb installation Signed-off-by: Romain Vimont --- app/src/command.c | 27 +++++++++++++++++++++++++++ app/src/command.h | 5 +++++ app/src/sys/unix/command.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/app/src/command.c b/app/src/command.c index abaa223d..81047b7a 100644 --- a/app/src/command.c +++ b/app/src/command.c @@ -55,6 +55,32 @@ argv_to_string(const char *const *argv, char *buf, size_t bufsize) { return idx; } +static void +show_adb_installation_msg() { +#ifndef __WINDOWS__ + static const struct { + const char *binary; + const char *command; + } pkg_managers[] = { + {"apt", "apt install adb"}, + {"apt-get", "apt-get install adb"}, + {"brew", "brew cask install android-platform-tools"}, + {"dnf", "dnf install android-tools"}, + {"emerge", "emerge dev-util/android-tools"}, + {"pacman", "pacman -S android-tools"}, + }; + for (size_t i = 0; i < ARRAY_LEN(pkg_managers); ++i) { + if (cmd_search(pkg_managers[i].binary)) { + LOGI("You may install 'adb' by \"%s\"", pkg_managers[i].command); + return; + } + } +#endif + + LOGI("You may download and install 'adb' from " + "https://developer.android.com/studio/releases/platform-tools"); +} + static void show_adb_err_msg(enum process_result err, const char *const argv[]) { char buf[512]; @@ -68,6 +94,7 @@ show_adb_err_msg(enum process_result err, const char *const argv[]) { LOGE("Command not found: %s", buf); LOGE("(make 'adb' accessible from your PATH or define its full" "path in the ADB environment variable)"); + show_adb_installation_msg(); break; case PROCESS_SUCCESS: // do nothing diff --git a/app/src/command.h b/app/src/command.h index 9fc81c1c..28f9fbcf 100644 --- a/app/src/command.h +++ b/app/src/command.h @@ -43,6 +43,11 @@ enum process_result { PROCESS_ERROR_MISSING_BINARY, }; +#ifndef __WINDOWS__ +bool +cmd_search(const char *file); +#endif + enum process_result cmd_execute(const char *const argv[], process_t *process); diff --git a/app/src/sys/unix/command.c b/app/src/sys/unix/command.c index af5d4b2f..a60e21bc 100644 --- a/app/src/sys/unix/command.c +++ b/app/src/sys/unix/command.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,42 @@ #include "util/log.h" +bool +cmd_search(const char *file) { + char *path = getenv("PATH"); + if (!path) + return false; + path = strdup(path); + if (!path) + return false; + + bool ret = false; + size_t file_len = strlen(file); + char *saveptr; + for (char *dir = strtok_r(path, ":", &saveptr); dir; + dir = strtok_r(NULL, ":", &saveptr)) { + size_t dir_len = strlen(dir); + char *fullpath = malloc(dir_len + file_len + 2); + if (!fullpath) + continue; + memcpy(fullpath, dir, dir_len); + fullpath[dir_len] = '/'; + memcpy(fullpath + dir_len + 1, file, file_len + 1); + + struct stat sb; + bool fullpath_executable = stat(fullpath, &sb) == 0 && + sb.st_mode & S_IXUSR; + free(fullpath); + if (fullpath_executable) { + ret = true; + break; + } + } + + free(path); + return ret; +} + enum process_result cmd_execute(const char *const argv[], pid_t *pid) { int fd[2];