2017-12-12 22:12:07 +08:00
|
|
|
#include "command.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2018-02-13 17:10:18 +08:00
|
|
|
|
2018-03-25 21:23:00 +08:00
|
|
|
#include "common.h"
|
2018-02-13 17:10:18 +08:00
|
|
|
#include "log.h"
|
2018-10-05 02:47:53 +08:00
|
|
|
#include "str_util.h"
|
2017-12-12 22:12:07 +08:00
|
|
|
|
2018-02-01 01:46:56 +08:00
|
|
|
static const char *adb_command;
|
|
|
|
|
2018-10-04 23:03:24 +08:00
|
|
|
static inline const char *get_adb_command(void) {
|
2018-02-01 01:46:56 +08:00
|
|
|
if (!adb_command) {
|
|
|
|
adb_command = getenv("ADB");
|
|
|
|
if (!adb_command)
|
|
|
|
adb_command = "adb";
|
|
|
|
}
|
|
|
|
return adb_command;
|
|
|
|
}
|
|
|
|
|
2018-09-04 14:42:25 +08:00
|
|
|
static void show_adb_err_msg(enum process_result err) {
|
2018-09-01 09:18:06 +08:00
|
|
|
switch (err) {
|
2018-09-04 14:42:25 +08:00
|
|
|
case PROCESS_ERROR_GENERIC:
|
2018-09-01 09:18:06 +08:00
|
|
|
LOGE("Failed to execute adb");
|
|
|
|
break;
|
2018-09-04 14:42:25 +08:00
|
|
|
case PROCESS_ERROR_MISSING_BINARY:
|
2018-09-01 09:18:06 +08:00
|
|
|
LOGE("'adb' command not found (make it accessible from your PATH "
|
|
|
|
"or define its full path in the ADB environment variable)");
|
|
|
|
break;
|
2018-09-04 14:42:25 +08:00
|
|
|
case PROCESS_SUCCESS:
|
|
|
|
/* do nothing */
|
2018-09-01 09:18:06 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-12 22:12:07 +08:00
|
|
|
process_t adb_execute(const char *serial, const char *const adb_cmd[], int len) {
|
|
|
|
const char *cmd[len + 4];
|
|
|
|
int i;
|
2018-09-01 09:18:06 +08:00
|
|
|
process_t process;
|
2018-02-01 01:46:56 +08:00
|
|
|
cmd[0] = get_adb_command();
|
2017-12-12 22:12:07 +08:00
|
|
|
if (serial) {
|
|
|
|
cmd[1] = "-s";
|
|
|
|
cmd[2] = serial;
|
|
|
|
i = 3;
|
|
|
|
} else {
|
|
|
|
i = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(&cmd[i], adb_cmd, len * sizeof(const char *));
|
|
|
|
cmd[len + i] = NULL;
|
2018-09-04 14:42:25 +08:00
|
|
|
enum process_result r = cmd_execute(cmd[0], cmd, &process);
|
|
|
|
if (r != PROCESS_SUCCESS) {
|
|
|
|
show_adb_err_msg(r);
|
2018-09-01 09:18:06 +08:00
|
|
|
return PROCESS_NONE;
|
|
|
|
}
|
|
|
|
return process;
|
2017-12-12 22:12:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
process_t adb_forward(const char *serial, uint16_t local_port, const char *device_socket_name) {
|
|
|
|
char local[4 + 5 + 1]; // tcp:PORT
|
|
|
|
char remote[108 + 14 + 1]; // localabstract:NAME
|
|
|
|
sprintf(local, "tcp:%" PRIu16, local_port);
|
|
|
|
snprintf(remote, sizeof(remote), "localabstract:%s", device_socket_name);
|
|
|
|
const char *const adb_cmd[] = {"forward", local, remote};
|
|
|
|
return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
|
|
|
}
|
|
|
|
|
2018-03-12 15:35:51 +08:00
|
|
|
process_t adb_forward_remove(const char *serial, uint16_t local_port) {
|
|
|
|
char local[4 + 5 + 1]; // tcp:PORT
|
|
|
|
sprintf(local, "tcp:%" PRIu16, local_port);
|
|
|
|
const char *const adb_cmd[] = {"forward", "--remove", local};
|
|
|
|
return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
|
|
|
}
|
|
|
|
|
2017-12-12 22:12:07 +08:00
|
|
|
process_t adb_reverse(const char *serial, const char *device_socket_name, uint16_t local_port) {
|
|
|
|
char local[4 + 5 + 1]; // tcp:PORT
|
|
|
|
char remote[108 + 14 + 1]; // localabstract:NAME
|
|
|
|
sprintf(local, "tcp:%" PRIu16, local_port);
|
|
|
|
snprintf(remote, sizeof(remote), "localabstract:%s", device_socket_name);
|
|
|
|
const char *const adb_cmd[] = {"reverse", remote, local};
|
|
|
|
return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
|
|
|
}
|
|
|
|
|
|
|
|
process_t adb_reverse_remove(const char *serial, const char *device_socket_name) {
|
|
|
|
char remote[108 + 14 + 1]; // localabstract:NAME
|
|
|
|
snprintf(remote, sizeof(remote), "localabstract:%s", device_socket_name);
|
|
|
|
const char *const adb_cmd[] = {"reverse", "--remove", remote};
|
|
|
|
return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
|
|
|
}
|
|
|
|
|
|
|
|
process_t adb_push(const char *serial, const char *local, const char *remote) {
|
2018-10-05 02:47:53 +08:00
|
|
|
#ifdef __WINDOWS__
|
|
|
|
// Windows will parse the string, so the paths must be quoted
|
|
|
|
// (see sys/win/command.c)
|
|
|
|
local = strquote(local);
|
|
|
|
if (!local) {
|
|
|
|
return PROCESS_NONE;
|
|
|
|
}
|
|
|
|
remote = strquote(remote);
|
|
|
|
if (!remote) {
|
|
|
|
free((void *) local);
|
|
|
|
return PROCESS_NONE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-02-28 22:02:51 +08:00
|
|
|
const char *const adb_cmd[] = {"push", local, remote};
|
2018-10-05 02:47:53 +08:00
|
|
|
process_t proc = adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
|
|
|
|
|
|
|
#ifdef __WINDOWS__
|
|
|
|
free((void *) remote);
|
|
|
|
free((void *) local);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return proc;
|
2017-12-12 22:12:07 +08:00
|
|
|
}
|
2018-02-08 22:16:27 +08:00
|
|
|
|
2018-04-29 06:17:34 +08:00
|
|
|
process_t adb_install(const char *serial, const char *local) {
|
2018-05-26 20:43:42 +08:00
|
|
|
#ifdef __WINDOWS__
|
2018-10-05 02:47:53 +08:00
|
|
|
// Windows will parse the string, so the local name must be quoted
|
|
|
|
// (see sys/win/command.c)
|
|
|
|
local = strquote(local);
|
|
|
|
if (!local) {
|
|
|
|
return PROCESS_NONE;
|
|
|
|
}
|
2018-05-26 20:43:42 +08:00
|
|
|
#endif
|
2018-10-05 02:47:53 +08:00
|
|
|
|
2018-04-29 06:17:34 +08:00
|
|
|
const char *const adb_cmd[] = {"install", "-r", local};
|
2018-10-05 02:47:53 +08:00
|
|
|
process_t proc = adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
|
|
|
|
|
|
|
#ifdef __WINDOWS__
|
|
|
|
free((void *) local);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return proc;
|
2018-04-29 06:17:34 +08:00
|
|
|
}
|
|
|
|
|
2018-02-08 22:16:27 +08:00
|
|
|
SDL_bool process_check_success(process_t proc, const char *name) {
|
|
|
|
if (proc == PROCESS_NONE) {
|
2018-02-13 17:10:18 +08:00
|
|
|
LOGE("Could not execute \"%s\"", name);
|
2018-02-08 22:16:27 +08:00
|
|
|
return SDL_FALSE;
|
|
|
|
}
|
|
|
|
exit_code_t exit_code;
|
|
|
|
if (!cmd_simple_wait(proc, &exit_code)) {
|
|
|
|
if (exit_code != NO_EXIT_CODE) {
|
2018-02-13 17:10:18 +08:00
|
|
|
LOGE("\"%s\" returned with value %" PRIexitcode, name, exit_code);
|
2018-02-08 22:16:27 +08:00
|
|
|
} else {
|
2018-02-13 17:10:18 +08:00
|
|
|
LOGE("\"%s\" exited unexpectedly", name);
|
2018-02-08 22:16:27 +08:00
|
|
|
}
|
|
|
|
return SDL_FALSE;
|
|
|
|
}
|
|
|
|
return SDL_TRUE;
|
|
|
|
}
|