Android adb push是怎样被实现的? |
CODE: commandline.c
PATH: <ANDROID_PROJECT>/system/core/adb/commandline.c
FUNC: do_sync_push() @adb_commandline()
LINE: 1147
-
do_sync_push() body is at
@ <ANDROID_PROJECT>/system/core/adb/file_sync_client.c
L
-
int
do_sync_push(
const
char
*lpath,
const
char
*rpath,
int
verifyApk)
{
struct
stat st;
unsigned
mode;
int
fd;
if
(fd < 0) {
fprintf(stderr,
"error: %s\n"
, adb_error());
return
1;
}
if
(stat(lpath, &st)) {
fprintf(stderr,
"cannot stat '%s': %s\n"
, lpath, strerror(errno));
sync_quit(fd);
return
1;
}
if
(S_ISDIR(st.
st_mode
)) {
BEGIN();
if
(copy_local_dir_remote(fd, lpath, rpath, 0, 0)) {
return
1;
}
else
{
END();
sync_quit(fd);
}
}
else
{
if
(sync_readmode(fd, rpath, &mode)) {
return
1;
}
if
((mode != 0) && S_ISDIR(mode)) {
/* if we're copying a local file to a remote directory,
** we *really* want to copy to remotedir + "/" + localfilename
*/
const
char
*name = adb_dirstop(lpath);
if
(name == 0) {
name = lpath;
}
else
{
name++;
}
int
tmplen = strlen(name) + strlen(rpath) + 2;
char
*tmp = malloc(strlen(name) + strlen(rpath) + 2);
if
(tmp == 0)
return
1;
snprintf(tmp, tmplen,
"%s/%s"
, rpath, name);
rpath = tmp;
}
BEGIN();
if
(sync_send(fd, lpath, rpath, st.
st_mtime
, st.
st_mode
, verifyApk)) {
return
1;
}
else
{
END();
sync_quit(fd);
return
0;
}
}
return
0;
}
|
-
接着查看sync_send()函数的实现部分
-
@ <ANDROID_PROJECT>/system/core/adb/file_sync_client.c
L 297
-
static
int
sync_send (
int
fd,
const
char
*lpath,
const
char
*rpath,
unsigned
mtime, mode_t mode,
int
verifyApk)
{
syncmsg msg;
int
len, r;
syncsendbuf
*sbuf = &send_buffer;
char
* file_buffer = NULL;
int
size = 0;
char
tmp[64];
len = strlen(rpath);
if
(len > 1024)
goto
fail;
snprintf(tmp,
sizeof
(tmp),
",%d"
, mode);
r = strlen(tmp);
if
(verifyApk) {
int
lfd;
zipfile_t zip;
zipentry_t entry;
int
amt;
// if we are transferring an APK file, then sanity check to make sure
// we have a real zip file that contains an AndroidManifest.xml
// this requires that we read the entire file into memory.
lfd = adb_open(lpath, O_RDONLY);
if
(lfd < 0) {
fprintf(stderr,
"cannot open '%s': %s\n"
, lpath, strerror(errno));
return
-1;
}
size = adb_lseek(lfd, 0, SEEK_END);
if
(size == -1 || -1 == adb_lseek(lfd, 0, SEEK_SET)) {
fprintf(stderr,
"error seeking in file '%s'\n"
, lpath);
adb_close(lfd);
return
1;
}
file_buffer = (
char
*)malloc(size);
if
(file_buffer == NULL) {
fprintf(stderr,
"could not allocate buffer for '%s'\n"
,
lpath);
adb_close(lfd);
return
1;
}
amt = adb_read(lfd, file_buffer, size);
if
(amt != size) {
fprintf(stderr,
"error reading from file: '%s'\n"
, lpath);
adb_close(lfd);
free(file_buffer);
return
1;
}
adb_close(lfd);
zip = init_zipfile(file_buffer, size);
if
(zip == NULL) {
fprintf(stderr,
"file '%s' is not a valid zip file\n"
,
lpath);
free(file_buffer);
return
1;
}
entry = lookup_zipentry(zip,
"AndroidManifest.xml"
);
release_zipfile(zip);
if
(entry == NULL) {
fprintf(stderr,
"file '%s' does not contain AndroidManifest.xml\n"
,
lpath);
free(file_buffer);
return
1;
}
}
msg.req.id = ID_SEND;
msg.req.namelen = htoll(len + r);
if
(file_buffer) {
write_data_buffer(fd, file_buffer, size, sbuf);
free(file_buffer);
}
else
if
(S_ISREG(mode))
write_data_file(fd, lpath, sbuf);
#ifdef
HAVE_SYMLINKS
else
if
(S_ISLNK(mode))
write_data_link(fd, lpath, sbuf);
#endif
else
goto
fail;
msg.data.id = ID_DONE;
msg.data.size = htoll(mtime);
if
(writex(fd, &msg.data,
sizeof
(msg.data)))
goto
fail;
if
(readx(fd, &msg.status,
sizeof
(msg.status)))
return
-1;
if
(msg.status.id != ID_OKAY) {
if
(msg.status.id == ID_FAIL) {
len = ltohl(msg.status.msglen);
if
(len > 256) len = 256;
if
(readx(fd, sbuf->
data
, len)) {
return
-1;
}
sbuf->
data
[len] = 0;
}
else
strcpy(sbuf->
data
,
"unknown reason"
);
fprintf(stderr,
"failed to copy '%s' to '%s': %s\n"
, lpath, rpath, sbuf->
data
);
return
-1;
}
return
0;
fail:
fprintf(stderr,
"protocol failure\n"
);
adb_close(fd);
return
-1;
}
|