summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
Diffstat (limited to 'adb')
-rw-r--r--adb/commandline.c26
-rw-r--r--adb/file_sync_client.c56
-rw-r--r--adb/file_sync_service.h2
3 files changed, 48 insertions, 36 deletions
diff --git a/adb/commandline.c b/adb/commandline.c
index c4b5174..a3eaf43 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -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, &copy_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, &copy_attrs);
if (rpath != NULL) {
- return do_sync_pull(rpath, lpath, show_progress);
+ return do_sync_pull(rpath, lpath, show_progress, copy_attrs);
}
return usage();
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index dc4e77f..d3cb113 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -25,6 +25,7 @@
#include <limits.h>
#include <sys/types.h>
#include <zipfile/zipfile.h>
+#include <utime.h>
#include "sysdeps.h"
#include "adb.h"
@@ -139,7 +140,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 +163,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 +240,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 +934,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 utimbuf times = { time, time };
+ int r1 = utime(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 +978,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, &timestamp, &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 +985,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 +1003,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 +1016,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 +1047,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();
diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h
index 3e7e096..8ea239e 100644
--- a/adb/file_sync_service.h
+++ b/adb/file_sync_service.h
@@ -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)