📄 commandline.c
字号:
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <limits.h>#include <stdarg.h>#include <sys/types.h>#include <sys/stat.h>#include <ctype.h>#include <assert.h>#include "sysdeps.h"#ifdef HAVE_TERMIO_H#include <termios.h>#endif#define TRACE_TAG TRACE_ADB#include "adb.h"#include "adb_client.h"#include "file_sync_service.h"#ifdef SH_HISTORY#include "shlist.h"#include "history.h"#endifenum { IGNORE_DATA, WIPE_DATA, FLASH_DATA};static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);void get_my_path(char s[PATH_MAX]);int find_sync_dirs(const char *srcarg, char **android_srcdir_out, char **data_srcdir_out);int install_app(transport_type transport, char* serial, int argc, char** argv);int uninstall_app(transport_type transport, char* serial, int argc, char** argv);static const char *gProductOutPath = NULL;static char *product_file(const char *extra){ int n; char *x; if (gProductOutPath == NULL) { fprintf(stderr, "adb: Product directory not specified; " "use -p or define ANDROID_PRODUCT_OUT\n"); exit(1); } n = strlen(gProductOutPath) + strlen(extra) + 2; x = malloc(n); if (x == 0) { fprintf(stderr, "adb: Out of memory (product_file())\n"); exit(1); } snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra); return x;}void version(FILE * out) { fprintf(out, "Android Debug Bridge version %d.%d.%d\n", ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);}void help(){ version(stderr); fprintf(stderr, "\n" " -d - directs command to the only connected USB device\n" " returns an error if more than one USB device is present.\n" " -e - directs command to the only running emulator.\n" " returns an error if more than one emulator is running.\n" " -s <serial number> - directs command to the USB device or emulator with\n" " the given serial number\n" " -p <product name or path> - simple product name like 'sooner', or\n" " a relative/absolute path to a product\n" " out directory like 'out/target/product/sooner'.\n" " If -p is not specified, the ANDROID_PRODUCT_OUT\n" " environment variable is used, which must\n" " be an absolute path.\n" " devices - list all connected devices\n" "\n" "device commands:\n" " adb push <local> <remote> - copy file/dir to device\n" " adb pull <remote> <local> - copy file/dir from device\n" " adb sync [ <directory> ] - copy host->device only if changed\n" " (see 'adb help all')\n" " adb shell - run remote shell interactively\n" " adb shell <command> - run remote shell command\n" " adb emu <command> - run emulator console command\n" " adb logcat [ <filter-spec> ] - View device log\n" " adb forward <local> <remote> - forward socket connections\n" " forward specs are one of: \n" " tcp:<port>\n" " localabstract:<unix domain socket name>\n" " localreserved:<unix domain socket name>\n" " localfilesystem:<unix domain socket name>\n" " dev:<character device name>\n" " jdwp:<process pid> (remote only)\n" " adb jdwp - list PIDs of processes hosting a JDWP transport\n" " adb install [-l] [-r] <file> - push this package file to the device and install it\n" " ('-l' means forward-lock the app)\n" " ('-r' means reinstall the app, keeping its data)\n" " adb uninstall [-k] <package> - remove this app package from the device\n" " ('-k' means keep the data and cache directories)\n" " adb bugreport - return all information from the device\n" " that should be included in a bug report.\n" "\n" " adb help - show this help message\n" " adb version - show version num\n" "\n" "DATAOPTS:\n" " (no option) - don't touch the data partition\n" " -w - wipe the data partition\n" " -d - flash the data partition\n" "\n" "scripting:\n" " adb wait-for-device - block until device is online\n" " adb start-server - ensure that there is a server running\n" " adb kill-server - kill the server if it is running\n" " adb get-state - prints: offline | bootloader | device\n" " adb get-product - prints: <product-id>\n" " adb get-serialno - prints: <serial-number>\n" " adb status-window - continuously print device status for a specified device\n" " adb remount - remounts the /system partition on the device read-write\n" "\n" "networking:\n" " adb ppp <tty> [parameters] - Run PPP over USB.\n" " Note: you should not automatically start a PDP connection.\n" " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n" " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n" "\n" "adb sync notes: adb sync [ <directory> ]\n" " <localdir> can be interpreted in several ways:\n" "\n" " - If <directory> is not specified, both /system and /data partitions will be updated.\n" "\n" " - If it is \"system\" or \"data\", only the corresponding partition\n" " is updated.\n" );}int usage(){ help(); return 1;}#ifdef HAVE_TERMIO_Hstatic struct termios tio_save;static void stdin_raw_init(int fd){ struct termios tio; if(tcgetattr(fd, &tio)) return; if(tcgetattr(fd, &tio_save)) return; tio.c_lflag = 0; /* disable CANON, ECHO*, etc */ /* no timeout but request at least one character per read */ tio.c_cc[VTIME] = 0; tio.c_cc[VMIN] = 1; tcsetattr(fd, TCSANOW, &tio); tcflush(fd, TCIFLUSH);}static void stdin_raw_restore(int fd){ tcsetattr(fd, TCSANOW, &tio_save); tcflush(fd, TCIFLUSH);}#endifstatic void read_and_dump(int fd){ char buf[4096]; int len; while(fd >= 0) { len = adb_read(fd, buf, 4096); if(len == 0) { break; } if(len < 0) { if(errno == EINTR) continue; break; } /* we want to output to stdout, so no adb_write here !! */ unix_write(1, buf, len); }}#ifdef SH_HISTORYint shItemCmp( void *val, void *idata ){ return( (strcmp( val, idata ) == 0) );}#endifstatic void *stdin_read_thread(void *x){ int fd, fdi; unsigned char buf[1024];#ifdef SH_HISTORY unsigned char realbuf[1024], *buf_ptr; SHLIST history; SHLIST *item = &history; int cmdlen = 0, ins_flag = 0;#endif int r, n; int state = 0; int *fds = (int*) x; fd = fds[0]; fdi = fds[1]; free(fds);#ifdef SH_HISTORY shListInitList( &history );#endif for(;;) { /* fdi is really the client's stdin, so use read, not adb_read here */ r = unix_read(fdi, buf, 1024); if(r == 0) break; if(r < 0) { if(errno == EINTR) continue; break; }#ifdef SH_HISTORY if( (r == 3) && /* Arrow processing */ (memcmp( (void *)buf, SH_ARROW_ANY, 2 ) == 0) ) { switch( buf[2] ) { case SH_ARROW_UP: item = shListGetNextItem( &history, item ); break; case SH_ARROW_DOWN: item = shListGetPrevItem( &history, item ); break; default: item = NULL; break; } memset( buf, SH_DEL_CHAR, cmdlen ); if( item != NULL ) { n = snprintf( (char *)(&buf[cmdlen]), sizeof buf - cmdlen, "%s", (char *)(item->data) ); memcpy( realbuf, item->data, n ); } else { /* Clean buffer */ item = &history; n = 0; } r = n + cmdlen; cmdlen = n; ins_flag = 0; if( r == 0 ) continue; } else {#endif for(n = 0; n < r; n++){ switch(buf[n]) { case '\n':#ifdef SH_HISTORY if( ins_flag && (SH_BLANK_CHAR <= realbuf[0]) ) { buf_ptr = malloc(cmdlen + 1); if( buf_ptr != NULL ) { memcpy( buf_ptr, realbuf, cmdlen ); buf_ptr[cmdlen] = '\0'; if( (item = shListFindItem( &history, (void *)buf_ptr, shItemCmp )) == NULL ) { shListInsFirstItem( &history, (void *)buf_ptr ); item = &history; } } } cmdlen = 0; ins_flag = 0;#endif state = 1; break; case '\r': state = 1; break; case '~': if(state == 1) state++; break; case '.': if(state == 2) { fprintf(stderr,"\n* disconnect *\n"); #ifdef HAVE_TERMIO_H stdin_raw_restore(fdi); #endif exit(0); } default:#ifdef SH_HISTORY if( buf[n] == SH_DEL_CHAR ) { if( cmdlen > 0 ) cmdlen--; } else { realbuf[cmdlen] = buf[n]; cmdlen++; } ins_flag = 1;#endif state = 0; } }#ifdef SH_HISTORY }#endif r = adb_write(fd, buf, r); if(r <= 0) { break; } }#ifdef SH_HISTORY shListDelAllItems( &history, (shListFree)free );#endif return 0;}int interactive_shell(void){ adb_thread_t thr; int fdi, fd; int *fds; fd = adb_connect("shell:"); if(fd < 0) { fprintf(stderr,"error: %s\n", adb_error()); return 1; } fdi = 0; //dup(0); fds = malloc(sizeof(int) * 2); fds[0] = fd; fds[1] = fdi;#ifdef HAVE_TERMIO_H stdin_raw_init(fdi);#endif adb_thread_create(&thr, stdin_read_thread, fds); read_and_dump(fd);#ifdef HAVE_TERMIO_H stdin_raw_restore(fdi);#endif return 0;}int adb_download_buffer(const char *service, const void* data, int sz, unsigned progress){ char buf[4096]; unsigned total; int fd; const unsigned char *ptr; snprintf(buf, sizeof buf, "%s:%d", service, sz); fd = adb_connect(buf); if(fd < 0) { fprintf(stderr,"error: %s\n", adb_error()); return -1; } adb_socket_setbufsize(fd, CHUNK_SIZE); total = sz; ptr = data; if(progress) { char *x = strrchr(service, ':'); if(x) service = x + 1; } while(sz > 0) { unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz; if(writex(fd, ptr, xfer)) { adb_status(fd); fprintf(stderr,"* failed to write data '%s' *\n", adb_error()); return -1; } sz -= xfer; ptr += xfer; if(progress) { int percent = 100 - (int)(100.0 * ((float)sz / (float)total)); printf("sending: '%s' %4d%% \r", service, percent); fflush(stdout); } } if(progress) { printf("\n"); } if(readx(fd, buf, 4)){ fprintf(stderr,"* error reading response *\n"); adb_close(fd); return -1; } if(memcmp(buf, "OKAY", 4)) { buf[4] = 0; fprintf(stderr,"* error response '%s' *\n", buf); adb_close(fd); return -1; } adb_close(fd); return 0;}int adb_download(const char *service, const char *fn, unsigned progress){ void *data; unsigned sz; data = load_file(fn, &sz); if(data == 0) { fprintf(stderr,"* cannot read '%s' *\n", service); return -1; } return adb_download_buffer(service, data, sz, progress);}static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial){ if (serial) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -