adb: added support for adb pull -a to preserve time stamps and mode
Added -a flag to adb pull that preserves time and mode. Mode is subjected to umask for security. We only receive modification time from adb server, so creation time will be set to the modification time as well. Change-Id: I37c0b94741ed464f19025d25dea3ff2f6ac43e7f Signed-off-by: Lajos Molnar <lajos@google.com>
This commit is contained in:
parent
b8f86480a2
commit
de8ff4adca
|
@ -110,9 +110,10 @@ void help()
|
|||
" adb push [-p] <local> <remote>\n"
|
||||
" - copy file/dir to device\n"
|
||||
" ('-p' to display the transfer progress)\n"
|
||||
" adb pull [-p] <remote> [<local>]\n"
|
||||
" adb pull [-p] [-a] <remote> [<local>]\n"
|
||||
" - copy file/dir from device\n"
|
||||
" ('-p' to display the transfer progress)\n"
|
||||
" ('-a' means copy timestamp and mode)\n"
|
||||
" adb sync [ <directory> ] - copy host->device only if changed\n"
|
||||
" (-l means list but don't copy)\n"
|
||||
" (see 'adb help all')\n"
|
||||
|
@ -927,12 +928,19 @@ static const char *find_product_out_path(const char *hint)
|
|||
}
|
||||
|
||||
|
||||
static void parse_push_pull_args(char** arg, int narg, char const** path1, char const** path2,
|
||||
int* show_progress) {
|
||||
static void parse_push_pull_args(char **arg, int narg, char const **path1, char const **path2,
|
||||
int *show_progress, int *copy_attrs) {
|
||||
*show_progress = 0;
|
||||
*copy_attrs = 0;
|
||||
|
||||
if ((narg > 0) && !strcmp(*arg, "-p")) {
|
||||
*show_progress = 1;
|
||||
while (narg > 0) {
|
||||
if (!strcmp(*arg, "-p")) {
|
||||
*show_progress = 1;
|
||||
} else if (!strcmp(*arg, "-a")) {
|
||||
*copy_attrs = 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
++arg;
|
||||
--narg;
|
||||
}
|
||||
|
@ -1396,9 +1404,10 @@ top:
|
|||
|
||||
if(!strcmp(argv[0], "push")) {
|
||||
int show_progress = 0;
|
||||
int copy_attrs = 0; // unused
|
||||
const char* lpath = NULL, *rpath = NULL;
|
||||
|
||||
parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress);
|
||||
parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, ©_attrs);
|
||||
|
||||
if ((lpath != NULL) && (rpath != NULL)) {
|
||||
return do_sync_push(lpath, rpath, 0 /* no verify APK */, show_progress);
|
||||
|
@ -1409,12 +1418,13 @@ top:
|
|||
|
||||
if(!strcmp(argv[0], "pull")) {
|
||||
int show_progress = 0;
|
||||
int copy_attrs = 0;
|
||||
const char* rpath = NULL, *lpath = ".";
|
||||
|
||||
parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress);
|
||||
parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, ©_attrs);
|
||||
|
||||
if (rpath != NULL) {
|
||||
return do_sync_pull(rpath, lpath, show_progress);
|
||||
return do_sync_pull(rpath, lpath, show_progress, copy_attrs);
|
||||
}
|
||||
|
||||
return usage();
|
||||
|
|
|
@ -139,7 +139,8 @@ struct syncsendbuf {
|
|||
|
||||
static syncsendbuf send_buffer;
|
||||
|
||||
int sync_readtime(int fd, const char *path, unsigned *timestamp)
|
||||
int sync_readtime(int fd, const char *path, unsigned int *timestamp,
|
||||
unsigned int *mode)
|
||||
{
|
||||
syncmsg msg;
|
||||
int len = strlen(path);
|
||||
|
@ -161,6 +162,7 @@ int sync_readtime(int fd, const char *path, unsigned *timestamp)
|
|||
}
|
||||
|
||||
*timestamp = ltohl(msg.stat.time);
|
||||
*mode = ltohl(msg.stat.mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -237,7 +239,7 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show
|
|||
if (show_progress) {
|
||||
// Determine local file size.
|
||||
struct stat st;
|
||||
if (lstat(path, &st)) {
|
||||
if (fstat(lfd, &st)) {
|
||||
fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -931,8 +933,21 @@ static int remote_build_list(int syncfd, copyinfo **filelist,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int set_time_and_mode(const char *lpath, unsigned int time, unsigned int mode)
|
||||
{
|
||||
struct timeval times[2] = { {time, 0}, {time, 0} };
|
||||
int r1 = utimes(lpath, times);
|
||||
|
||||
/* use umask for permissions */
|
||||
mode_t mask=umask(0000);
|
||||
umask(mask);
|
||||
int r2 = chmod(lpath, mode & ~mask);
|
||||
|
||||
return r1 ? : r2;
|
||||
}
|
||||
|
||||
static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
|
||||
int checktimestamps)
|
||||
int copy_attrs)
|
||||
{
|
||||
copyinfo *filelist = 0;
|
||||
copyinfo *ci, *next;
|
||||
|
@ -962,26 +977,6 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (checktimestamps) {
|
||||
for (ci = filelist; ci != 0; ci = ci->next) {
|
||||
if (sync_start_readtime(fd, ci->dst)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (ci = filelist; ci != 0; ci = ci->next) {
|
||||
unsigned int timestamp, mode, size;
|
||||
if (sync_finish_readtime(fd, ×tamp, &mode, &size))
|
||||
return 1;
|
||||
if (size == ci->size) {
|
||||
/* for links, we cannot update the atime/mtime */
|
||||
if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
|
||||
(S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
|
||||
ci->flag = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (ci = filelist; ci != 0; ci = next) {
|
||||
next = ci->next;
|
||||
if (ci->flag == 0) {
|
||||
|
@ -989,6 +984,10 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
|
|||
if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (copy_attrs && set_time_and_mode(ci->dst, ci->time, ci->mode)) {
|
||||
return 1;
|
||||
}
|
||||
pulled++;
|
||||
} else {
|
||||
skipped++;
|
||||
|
@ -1003,9 +1002,9 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
|
||||
int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int copy_attrs)
|
||||
{
|
||||
unsigned mode;
|
||||
unsigned mode, time;
|
||||
struct stat st;
|
||||
|
||||
int fd;
|
||||
|
@ -1016,7 +1015,7 @@ int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if(sync_readmode(fd, rpath, &mode)) {
|
||||
if(sync_readtime(fd, rpath, &time, &mode)) {
|
||||
return 1;
|
||||
}
|
||||
if(mode == 0) {
|
||||
|
@ -1047,13 +1046,15 @@ int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
|
|||
if (sync_recv(fd, rpath, lpath, show_progress)) {
|
||||
return 1;
|
||||
} else {
|
||||
if (copy_attrs && set_time_and_mode(lpath, time, mode))
|
||||
return 1;
|
||||
END();
|
||||
sync_quit(fd);
|
||||
return 0;
|
||||
}
|
||||
} else if(S_ISDIR(mode)) {
|
||||
BEGIN();
|
||||
if (copy_remote_dir_local(fd, rpath, lpath, 0)) {
|
||||
if (copy_remote_dir_local(fd, rpath, lpath, copy_attrs)) {
|
||||
return 1;
|
||||
} else {
|
||||
END();
|
||||
|
|
|
@ -80,7 +80,7 @@ void file_sync_service(int fd, void *cookie);
|
|||
int do_sync_ls(const char *path);
|
||||
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_pull(const char *rpath, const char *lpath, int show_progress);
|
||||
int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int pullTime);
|
||||
|
||||
#define SYNC_DATA_MAX (64*1024)
|
||||
|
||||
|
|
Loading…
Reference in New Issue