am 5fb1a34a: Merge "Added transfer progress reporting for push and pull commands."
* commit '5fb1a34af4128bfe7332b02e31b146a82bc2872d': Added transfer progress reporting for push and pull commands.
This commit is contained in:
commit
73690b24c6
3 changed files with 128 additions and 27 deletions
|
|
@ -107,8 +107,12 @@ void help()
|
||||||
" will disconnect from all connected TCP/IP devices.\n"
|
" will disconnect from all connected TCP/IP devices.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"device commands:\n"
|
"device commands:\n"
|
||||||
" adb push <local> <remote> - copy file/dir to device\n"
|
" adb push [-p] <local> <remote>\n"
|
||||||
" adb pull <remote> [<local>] - copy file/dir from device\n"
|
" - copy file/dir to device\n"
|
||||||
|
" ('-p' to display the transfer progress)\n"
|
||||||
|
" adb pull [-p] <remote> [<local>]\n"
|
||||||
|
" - copy file/dir from device\n"
|
||||||
|
" ('-p' to display the transfer progress)\n"
|
||||||
" adb sync [ <directory> ] - copy host->device only if changed\n"
|
" adb sync [ <directory> ] - copy host->device only if changed\n"
|
||||||
" (-l means list but don't copy)\n"
|
" (-l means list but don't copy)\n"
|
||||||
" (see 'adb help all')\n"
|
" (see 'adb help all')\n"
|
||||||
|
|
@ -921,6 +925,28 @@ static const char *find_product_out_path(const char *hint)
|
||||||
return path_buf;
|
return path_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void parse_push_pull_args(char** arg, int narg, char const** path1, char const** path2,
|
||||||
|
int* show_progress) {
|
||||||
|
*show_progress = 0;
|
||||||
|
|
||||||
|
if ((narg > 0) && !strcmp(*arg, "-p")) {
|
||||||
|
*show_progress = 1;
|
||||||
|
++arg;
|
||||||
|
--narg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (narg > 0) {
|
||||||
|
*path1 = *arg;
|
||||||
|
++arg;
|
||||||
|
--narg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (narg > 0) {
|
||||||
|
*path2 = *arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int adb_commandline(int argc, char **argv)
|
int adb_commandline(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
|
|
@ -1368,18 +1394,29 @@ top:
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(argv[0], "push")) {
|
if(!strcmp(argv[0], "push")) {
|
||||||
if(argc != 3) return usage();
|
int show_progress = 0;
|
||||||
return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
|
const char* lpath = NULL, *rpath = NULL;
|
||||||
|
|
||||||
|
parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress);
|
||||||
|
|
||||||
|
if ((lpath != NULL) && (rpath != NULL)) {
|
||||||
|
return do_sync_push(lpath, rpath, 0 /* no verify APK */, show_progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
return usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(argv[0], "pull")) {
|
if(!strcmp(argv[0], "pull")) {
|
||||||
if (argc == 2) {
|
int show_progress = 0;
|
||||||
return do_sync_pull(argv[1], ".");
|
const char* rpath = NULL, *lpath = ".";
|
||||||
} else if (argc == 3) {
|
|
||||||
return do_sync_pull(argv[1], argv[2]);
|
parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress);
|
||||||
} else {
|
|
||||||
return usage();
|
if (rpath != NULL) {
|
||||||
|
return do_sync_pull(rpath, lpath, show_progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(argv[0], "install")) {
|
if(!strcmp(argv[0], "install")) {
|
||||||
|
|
@ -1717,7 +1754,7 @@ int install_app(transport_type transport, char* serial, int argc, char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = do_sync_push(apk_file, apk_dest, verify_apk);
|
err = do_sync_push(apk_file, apk_dest, verify_apk, 0 /* no show progress */);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto cleanup_apk;
|
goto cleanup_apk;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1725,7 +1762,8 @@ int install_app(transport_type transport, char* serial, int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verification_file != NULL) {
|
if (verification_file != NULL) {
|
||||||
err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */);
|
err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */,
|
||||||
|
0 /* no show progress */);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto cleanup_apk;
|
goto cleanup_apk;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,22 @@ static void END()
|
||||||
total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL);
|
total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* transfer_progress_format = "\rTransferring: %llu/%llu (%d%%)";
|
||||||
|
|
||||||
|
static void print_transfer_progress(unsigned long long bytes_current,
|
||||||
|
unsigned long long bytes_total) {
|
||||||
|
if (bytes_total == 0) return;
|
||||||
|
|
||||||
|
fprintf(stderr, transfer_progress_format, bytes_current, bytes_total,
|
||||||
|
(int) (bytes_current * 100 / bytes_total));
|
||||||
|
|
||||||
|
if (bytes_current == bytes_total) {
|
||||||
|
fputc('\n', stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
void sync_quit(int fd)
|
void sync_quit(int fd)
|
||||||
{
|
{
|
||||||
syncmsg msg;
|
syncmsg msg;
|
||||||
|
|
@ -207,9 +223,10 @@ int sync_readmode(int fd, const char *path, unsigned *mode)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
|
static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show_progress)
|
||||||
{
|
{
|
||||||
int lfd, err = 0;
|
int lfd, err = 0;
|
||||||
|
unsigned long long size = 0;
|
||||||
|
|
||||||
lfd = adb_open(path, O_RDONLY);
|
lfd = adb_open(path, O_RDONLY);
|
||||||
if(lfd < 0) {
|
if(lfd < 0) {
|
||||||
|
|
@ -217,6 +234,17 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (show_progress) {
|
||||||
|
// Determine local file size.
|
||||||
|
struct stat st;
|
||||||
|
if (lstat(path, &st)) {
|
||||||
|
fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = st.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
sbuf->id = ID_DATA;
|
sbuf->id = ID_DATA;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -238,13 +266,18 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
total_bytes += ret;
|
total_bytes += ret;
|
||||||
|
|
||||||
|
if (show_progress) {
|
||||||
|
print_transfer_progress(total_bytes, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
adb_close(lfd);
|
adb_close(lfd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf)
|
static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf,
|
||||||
|
int show_progress)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
|
@ -264,6 +297,10 @@ static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *s
|
||||||
}
|
}
|
||||||
total += count;
|
total += count;
|
||||||
total_bytes += count;
|
total_bytes += count;
|
||||||
|
|
||||||
|
if (show_progress) {
|
||||||
|
print_transfer_progress(total, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -295,7 +332,7 @@ static int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int sync_send(int fd, const char *lpath, const char *rpath,
|
static int sync_send(int fd, const char *lpath, const char *rpath,
|
||||||
unsigned mtime, mode_t mode, int verifyApk)
|
unsigned mtime, mode_t mode, int verifyApk, int show_progress)
|
||||||
{
|
{
|
||||||
syncmsg msg;
|
syncmsg msg;
|
||||||
int len, r;
|
int len, r;
|
||||||
|
|
@ -377,10 +414,10 @@ static int sync_send(int fd, const char *lpath, const char *rpath,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_buffer) {
|
if (file_buffer) {
|
||||||
write_data_buffer(fd, file_buffer, size, sbuf);
|
write_data_buffer(fd, file_buffer, size, sbuf, show_progress);
|
||||||
free(file_buffer);
|
free(file_buffer);
|
||||||
} else if (S_ISREG(mode))
|
} else if (S_ISREG(mode))
|
||||||
write_data_file(fd, lpath, sbuf);
|
write_data_file(fd, lpath, sbuf, show_progress);
|
||||||
#ifdef HAVE_SYMLINKS
|
#ifdef HAVE_SYMLINKS
|
||||||
else if (S_ISLNK(mode))
|
else if (S_ISLNK(mode))
|
||||||
write_data_link(fd, lpath, sbuf);
|
write_data_link(fd, lpath, sbuf);
|
||||||
|
|
@ -438,17 +475,38 @@ static int mkdirs(char *name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sync_recv(int fd, const char *rpath, const char *lpath)
|
int sync_recv(int fd, const char *rpath, const char *lpath, int show_progress)
|
||||||
{
|
{
|
||||||
syncmsg msg;
|
syncmsg msg;
|
||||||
int len;
|
int len;
|
||||||
int lfd = -1;
|
int lfd = -1;
|
||||||
char *buffer = send_buffer.data;
|
char *buffer = send_buffer.data;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
unsigned long long size = 0;
|
||||||
|
|
||||||
len = strlen(rpath);
|
len = strlen(rpath);
|
||||||
if(len > 1024) return -1;
|
if(len > 1024) return -1;
|
||||||
|
|
||||||
|
if (show_progress) {
|
||||||
|
// Determine remote file size.
|
||||||
|
syncmsg stat_msg;
|
||||||
|
stat_msg.req.id = ID_STAT;
|
||||||
|
stat_msg.req.namelen = htoll(len);
|
||||||
|
|
||||||
|
if (writex(fd, &stat_msg.req, sizeof(stat_msg.req)) ||
|
||||||
|
writex(fd, rpath, len)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readx(fd, &stat_msg.stat, sizeof(stat_msg.stat))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat_msg.stat.id != ID_STAT) return -1;
|
||||||
|
|
||||||
|
size = ltohl(stat_msg.stat.size);
|
||||||
|
}
|
||||||
|
|
||||||
msg.req.id = ID_RECV;
|
msg.req.id = ID_RECV;
|
||||||
msg.req.namelen = htoll(len);
|
msg.req.namelen = htoll(len);
|
||||||
if(writex(fd, &msg.req, sizeof(msg.req)) ||
|
if(writex(fd, &msg.req, sizeof(msg.req)) ||
|
||||||
|
|
@ -502,6 +560,10 @@ int sync_recv(int fd, const char *rpath, const char *lpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
total_bytes += len;
|
total_bytes += len;
|
||||||
|
|
||||||
|
if (show_progress) {
|
||||||
|
print_transfer_progress(total_bytes, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
adb_close(lfd);
|
adb_close(lfd);
|
||||||
|
|
@ -721,7 +783,8 @@ static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, i
|
||||||
if(ci->flag == 0) {
|
if(ci->flag == 0) {
|
||||||
fprintf(stderr,"%spush: %s -> %s\n", listonly ? "would " : "", ci->src, ci->dst);
|
fprintf(stderr,"%spush: %s -> %s\n", listonly ? "would " : "", ci->src, ci->dst);
|
||||||
if(!listonly &&
|
if(!listonly &&
|
||||||
sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */)){
|
sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */,
|
||||||
|
0 /* no show progress */)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
pushed++;
|
pushed++;
|
||||||
|
|
@ -739,7 +802,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 verifyApk)
|
int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_progress)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
unsigned mode;
|
unsigned mode;
|
||||||
|
|
@ -786,7 +849,7 @@ int do_sync_push(const char *lpath, const char *rpath, int verifyApk)
|
||||||
rpath = tmp;
|
rpath = tmp;
|
||||||
}
|
}
|
||||||
BEGIN();
|
BEGIN();
|
||||||
if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk)) {
|
if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk, show_progress)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
END();
|
END();
|
||||||
|
|
@ -923,7 +986,7 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
|
||||||
next = ci->next;
|
next = ci->next;
|
||||||
if (ci->flag == 0) {
|
if (ci->flag == 0) {
|
||||||
fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst);
|
fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst);
|
||||||
if (sync_recv(fd, ci->src, ci->dst)) {
|
if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
pulled++;
|
pulled++;
|
||||||
|
|
@ -940,7 +1003,7 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_sync_pull(const char *rpath, const char *lpath)
|
int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
|
||||||
{
|
{
|
||||||
unsigned mode;
|
unsigned mode;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
@ -981,7 +1044,7 @@ int do_sync_pull(const char *rpath, const char *lpath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BEGIN();
|
BEGIN();
|
||||||
if(sync_recv(fd, rpath, lpath)) {
|
if (sync_recv(fd, rpath, lpath, show_progress)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
END();
|
END();
|
||||||
|
|
|
||||||
|
|
@ -72,15 +72,15 @@ typedef union {
|
||||||
struct {
|
struct {
|
||||||
unsigned id;
|
unsigned id;
|
||||||
unsigned msglen;
|
unsigned msglen;
|
||||||
} status;
|
} status;
|
||||||
} syncmsg;
|
} syncmsg;
|
||||||
|
|
||||||
|
|
||||||
void file_sync_service(int fd, void *cookie);
|
void file_sync_service(int fd, void *cookie);
|
||||||
int do_sync_ls(const char *path);
|
int do_sync_ls(const char *path);
|
||||||
int do_sync_push(const char *lpath, const char *rpath, int verifyApk);
|
int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_progress);
|
||||||
int do_sync_sync(const char *lpath, const char *rpath, int listonly);
|
int do_sync_sync(const char *lpath, const char *rpath, int listonly);
|
||||||
int do_sync_pull(const char *rpath, const char *lpath);
|
int do_sync_pull(const char *rpath, const char *lpath, int show_progress);
|
||||||
|
|
||||||
#define SYNC_DATA_MAX (64*1024)
|
#define SYNC_DATA_MAX (64*1024)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue