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;
}
|