android 版 adb,Android ADB实现解析

int adb_commandline(int argc, char **argv)

{

char buf[4096];

int no_daemon = 0;

int is_daemon = 0;

int is_server = 0;

int persist = 0;

int r;

int quote;

transport_type ttype = kTransportAny;

char* serial = NULL;

char* server_port_str = NULL;

/* If defined, this should be an absolute path to

* the directory containing all of the various system images

* for a particular product. If not defined, and the adb

* command requires this information, then the user must

* specify the path using "-p".

*/

gProductOutPath = getenv("ANDROID_PRODUCT_OUT");

if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {

gProductOutPath = NULL;

}

// TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint

serial = getenv("ANDROID_SERIAL");

/* Validate and assign the server port */

server_port_str = getenv("ANDROID_ADB_SERVER_PORT");

int server_port = DEFAULT_ADB_PORT;

if (server_port_str && strlen(server_port_str) > 0) {

server_port = (int) strtol(server_port_str, NULL, 0);

if (server_port <= 0 || server_port > 65535) {

fprintf(stderr,

"adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65535. Got \"%s\"\n",

server_port_str);

return usage();

}

}

/* modifiers and flags */

while(argc > 0) {

if(!strcmp(argv[0],"server")) {

is_server = 1;

} else if(!strcmp(argv[0],"nodaemon")) {

no_daemon = 1;

} else if (!strcmp(argv[0], "fork-server")) {

/* this is a special flag used only when the ADB client launches the ADB Server */

is_daemon = 1;

} else if(!strcmp(argv[0],"persist")) {

persist = 1;

} else if(!strncmp(argv[0], "-p", 2)) {

const char *product = NULL;

if (argv[0][2] == '\0') {

if (argc < 2) return usage();

product = argv[1];

argc--;

argv++;

} else {

product = argv[0] + 2;

}

gProductOutPath = find_product_out_path(product);

if (gProductOutPath == NULL) {

fprintf(stderr, "adb: could not resolve \"-p %s\"\n",

product);

return usage();

}

} else if (argv[0][0]=='-' && argv[0][1]=='s') {

if (isdigit(argv[0][2])) {

serial = argv[0] + 2;

} else {

if(argc < 2 || argv[0][2] != '\0') return usage();

serial = argv[1];

argc--;

argv++;

}

} else if (!strcmp(argv[0],"-d")) {

ttype = kTransportUsb;

} else if (!strcmp(argv[0],"-e")) {

ttype = kTransportLocal;

} else if (!strcmp(argv[0],"-a")) {

gListenAll = 1;

} else if(!strncmp(argv[0], "-H", 2)) {

const char *hostname = NULL;

if (argv[0][2] == '\0') {

if (argc < 2) return usage();

hostname = argv[1];

argc--;

argv++;

} else {

hostname = argv[0] + 2;

}

adb_set_tcp_name(hostname);

} else if(!strncmp(argv[0], "-P", 2)) {

if (argv[0][2] == '\0') {

if (argc < 2) return usage();

server_port_str = argv[1];

argc--;

argv++;

} else {

server_port_str = argv[0] + 2;

}

if (strlen(server_port_str) > 0) {

server_port = (int) strtol(server_port_str, NULL, 0);

if (server_port <= 0 || server_port > 65535) {

fprintf(stderr,

"adb: port number must be a positive number less than 65536. Got \"%s\"\n",

server_port_str);

return usage();

}

} else {

fprintf(stderr,

"adb: port number must be a positive number less than 65536. Got empty string.\n");

return usage();

}

} else {

/* out of recognized modifiers and flags */

break;

}

argc--;

argv++;

}

adb_set_transport(ttype, serial);

adb_set_tcp_specifics(server_port);

if (is_server) {

if (no_daemon || is_daemon) {

r = adb_main(is_daemon, server_port);

} else {

r = launch_server(server_port);

}

if(r) {

fprintf(stderr,"* could not start server *\n");

}

return r;

}

top:

if(argc == 0) {

return usage();

}

/* adb_connect() commands */

if(!strcmp(argv[0], "devices")) {

char *tmp;

char *listopt;

if (argc < 2)

listopt = "";

else if (argc == 2 && !strcmp(argv[1], "-l"))

listopt = argv[1];

else {

fprintf(stderr, "Usage: adb devices [-l]\n");

return 1;

}

snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);

tmp = adb_query(buf);

if(tmp) {

printf("List of devices attached \n");

printf("%s\n", tmp);

return 0;

} else {

return 1;

}

}

if(!strcmp(argv[0], "connect")) {

char *tmp;

if (argc != 2) {

fprintf(stderr, "Usage: adb connect [:]\n");

return 1;

}

snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);

tmp = adb_query(buf);

if(tmp) {

printf("%s\n", tmp);

return 0;

} else {

return 1;

}

}

if(!strcmp(argv[0], "disconnect")) {

char *tmp;

if (argc > 2) {

fprintf(stderr, "Usage: adb disconnect [[:]]\n");

return 1;

}

if (argc == 2) {

snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);

} else {

snprintf(buf, sizeof buf, "host:disconnect:");

}

tmp = adb_query(buf);

if(tmp) {

printf("%s\n", tmp);

return 0;

} else {

return 1;

}

}

if (!strcmp(argv[0], "emu")) {

return adb_send_emulator_command(argc, argv);

}

if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {

int r;

int fd;

char h = (argv[0][0] == 'h');

if (h) {

printf("\x1b[41;33m");

fflush(stdout);

}

if(argc < 2) {

D("starting interactive shell\n");

r = interactive_shell();

if (h) {

printf("\x1b[0m");

fflush(stdout);

}

return r;

}

snprintf(buf, sizeof buf, "shell:%s", argv[1]);

argc -= 2;

argv += 2;

while(argc-- > 0) {

strcat(buf, " ");

/* quote empty strings and strings with spaces */

quote = (**argv == 0 || strchr(*argv, ' '));

if (quote)

strcat(buf, "\"");

strcat(buf, *argv++);

if (quote)

strcat(buf, "\"");

}

for(;;) {

D("interactive shell loop. buff=%s\n", buf);

fd = adb_connect(buf);

if(fd >= 0) {

D("about to read_and_dump(fd=%d)\n", fd);

read_and_dump(fd);

D("read_and_dump() done.\n");

adb_close(fd);

r = 0;

} else {

fprintf(stderr,"error: %s\n", adb_error());

r = -1;

}

if(persist) {

fprintf(stderr,"\n- waiting for device -\n");

adb_sleep_ms(1000);

do_cmd(ttype, serial, "wait-for-device", 0);

} else {

if (h) {

printf("\x1b[0m");

fflush(stdout);

}

D("interactive shell loop. return r=%d\n", r);

return r;

}

}

}

if(!strcmp(argv[0], "kill-server")) {

int fd;

fd = _adb_connect("host:kill");

if(fd == -1) {

fprintf(stderr,"* server not running *\n");

return 1;

}

return 0;

}

if(!strcmp(argv[0], "sideload")) {

if(argc != 2) return usage();

if(adb_download("sideload", argv[1], 1)) {

return 1;

} else {

return 0;

}

}

if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")

|| !strcmp(argv[0], "reboot-bootloader")

|| !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")

|| !strcmp(argv[0], "root")) {

char command[100];

if (!strcmp(argv[0], "reboot-bootloader"))

snprintf(command, sizeof(command), "reboot:bootloader");

else if (argc > 1)

snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);

else

snprintf(command, sizeof(command), "%s:", argv[0]);

int fd = adb_connect(command);

if(fd >= 0) {

read_and_dump(fd);

adb_close(fd);

return 0;

}

fprintf(stderr,"error: %s\n", adb_error());

return 1;

}

if(!strcmp(argv[0], "bugreport")) {

if (argc != 1) return usage();

do_cmd(ttype, serial, "shell", "bugreport", 0);

return 0;

}

/* adb_command() wrapper commands */

if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {

char* service = argv[0];

if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {

if (ttype == kTransportUsb) {

service = "wait-for-usb";

} else if (ttype == kTransportLocal) {

service = "wait-for-local";

} else {

service = "wait-for-any";

}

}

format_host_command(buf, sizeof buf, service, ttype, serial);

if (adb_command(buf)) {

D("failure: %s *\n",adb_error());

fprintf(stderr,"error: %s\n", adb_error());

return 1;

}

/* Allow a command to be run after wait-for-device,

* e.g. 'adb wait-for-device shell'.

*/

if(argc > 1) {

argc--;

argv++;

goto top;

}

return 0;

}

if(!strcmp(argv[0], "forward")) {

char host_prefix[64];

char remove = 0;

char remove_all = 0;

char list = 0;

char no_rebind = 0;

// Parse options here.

while (argc > 1 && argv[1][0] == '-') {

if (!strcmp(argv[1], "--list"))

list = 1;

else if (!strcmp(argv[1], "--remove"))

remove = 1;

else if (!strcmp(argv[1], "--remove-all"))

remove_all = 1;

else if (!strcmp(argv[1], "--no-rebind"))

no_rebind = 1;

else {

return usage();

}

argc--;

argv++;

}

// Ensure we can only use one option at a time.

if (list + remove + remove_all + no_rebind > 1) {

return usage();

}

// Determine the for this command.

if (serial) {

snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",

serial);

} else if (ttype == kTransportUsb) {

snprintf(host_prefix, sizeof host_prefix, "host-usb");

} else if (ttype == kTransportLocal) {

snprintf(host_prefix, sizeof host_prefix, "host-local");

} else {

snprintf(host_prefix, sizeof host_prefix, "host");

}

// Implement forward --list

if (list) {

if (argc != 1)

return usage();

snprintf(buf, sizeof buf, "%s:list-forward", host_prefix);

char* forwards = adb_query(buf);

if (forwards == NULL) {

fprintf(stderr, "error: %s\n", adb_error());

return 1;

}

printf("%s", forwards);

free(forwards);

return 0;

}

// Implement forward --remove-all

else if (remove_all) {

if (argc != 1)

return usage();

snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix);

}

// Implement forward --remove

else if (remove) {

if (argc != 2)

return usage();

snprintf(buf, sizeof buf, "%s:killforward:%s", host_prefix, argv[1]);

}

// Or implement one of:

// forward

// forward --no-rebind

else

{

if (argc != 3)

return usage();

const char* command = no_rebind ? "forward:norebind:" : "forward";

snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);

}

if(adb_command(buf)) {

fprintf(stderr,"error: %s\n", adb_error());

return 1;

}

return 0;

}

/* do_sync_*() commands */

if(!strcmp(argv[0], "ls")) {

if(argc != 2) return usage();

return do_sync_ls(argv[1]);

}

if(!strcmp(argv[0], "push")) {

if(argc != 3) return usage();

return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);

}

if(!strcmp(argv[0], "pull")) {

if (argc == 2) {

return do_sync_pull(argv[1], ".");

} else if (argc == 3) {

return do_sync_pull(argv[1], argv[2]);

} else {

return usage();

}

}

if(!strcmp(argv[0], "install")) {

if (argc < 2) return usage();

return install_app(ttype, serial, argc, argv);

}

if(!strcmp(argv[0], "uninstall")) {

if (argc < 2) return usage();

return uninstall_app(ttype, serial, argc, argv);

}

if(!strcmp(argv[0], "sync")) {

char *srcarg, *android_srcpath, *data_srcpath;

int listonly = 0;

int ret;

if(argc < 2) {

/* No local path was specified. */

srcarg = NULL;

} else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {

listonly = 1;

if (argc == 3) {

srcarg = argv[2];

} else {

srcarg = NULL;

}

} else if(argc == 2) {

/* A local path or "android"/"data" arg was specified. */

srcarg = argv[1];

} else {

return usage();

}

ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);

if(ret != 0) return usage();

if(android_srcpath != NULL)

ret = do_sync_sync(android_srcpath, "/system", listonly);

if(ret == 0 && data_srcpath != NULL)

ret = do_sync_sync(data_srcpath, "/data", listonly);

free(android_srcpath);

free(data_srcpath);

return ret;

}

/* passthrough commands */

if(!strcmp(argv[0],"get-state") ||

!strcmp(argv[0],"get-serialno") ||

!strcmp(argv[0],"get-devpath"))

{

char *tmp;

format_host_command(buf, sizeof buf, argv[0], ttype, serial);

tmp = adb_query(buf);

if(tmp) {

printf("%s\n", tmp);

return 0;

} else {

return 1;

}

}

/* other commands */

if(!strcmp(argv[0],"status-window")) {

status_window(ttype, serial);

return 0;

}

if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {

return logcat(ttype, serial, argc, argv);

}

if(!strcmp(argv[0],"ppp")) {

return ppp(argc, argv);

}

if (!strcmp(argv[0], "start-server")) {

return adb_connect("host:start-server");

}

if (!strcmp(argv[0], "backup")) {

return backup(argc, argv);

}

if (!strcmp(argv[0], "restore")) {

return restore(argc, argv);

}

if (!strcmp(argv[0], "jdwp")) {

int fd = adb_connect("jdwp");

if (fd >= 0) {

read_and_dump(fd);

adb_close(fd);

return 0;

} else {

fprintf(stderr, "error: %s\n", adb_error());

return -1;

}

}

/* "adb /?" is a common idiom under Windows */

if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {

help();

return 0;

}

if(!strcmp(argv[0], "version")) {

version(stdout);

return 0;

}

usage();

return 1;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值