Merge pull request #67 from dot-asm/master

Add download option.
This commit is contained in:
Shazron Abdullah 2014-10-07 11:04:10 -07:00
commit 0b89be65bd

View File

@ -154,6 +154,7 @@ bool justlaunch = false;
char *app_path = NULL;
char *device_id = NULL;
char *args = NULL;
char *list_root = NULL;
int timeout = 0;
int port = 12345;
CFStringRef last_path = NULL;
@ -1017,7 +1018,7 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir,
afc_dictionary* afc_dict_p;
char *key, *val;
int not_dir;
int not_dir = 0;
AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p);
while((AFCKeyValueRead(afc_dict_p,&key,&val) == 0) && key && val) {
@ -1136,11 +1137,102 @@ void list_files(AMDeviceRef device)
afc_connection* afc_conn_p;
if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) {
read_dir(houseFd, afc_conn_p, "/", NULL);
read_dir(houseFd, afc_conn_p, list_root?list_root:"/", NULL);
AFCConnectionClose(afc_conn_p);
}
}
void copy_file_callback(afc_connection* afc_conn_p, const char *name,int file)
{
const char *local_name=name;
if (*local_name=='/') local_name++;
if (*local_name=='\0') return;
if (file) {
afc_file_ref fref;
int err = AFCFileRefOpen(afc_conn_p,name,1,&fref);
if (err) {
fprintf(stderr,"AFCFileRefOpen(\"%s\") failed: %d\n",name,err);
return;
}
FILE *fp = fopen(local_name,"w");
if (fp==NULL) {
fprintf(stderr,"fopen(\"%s\",\"w\") failer: %s\n",local_name,strerror(errno));
AFCFileRefClose(afc_conn_p,fref);
return;
}
char buf[4096];
size_t sz=sizeof(buf);
while (AFCFileRefRead(afc_conn_p,fref,buf,&sz)==0 && sz) {
fwrite(buf,sz,1,fp);
sz = sizeof(buf);
}
AFCFileRefClose(afc_conn_p,fref);
fclose(fp);
} else {
if (mkdir(local_name,0777) && errno!=EEXIST)
fprintf(stderr,"mkdir(\"%s\") failed: %s\n",local_name,strerror(errno));
}
}
void mkdirhier(char *path)
{
char *slash;
struct stat buf;
if (path[0]=='.' && path[1]=='/') path+=2;
if ((slash = strrchr(path,'/'))) {
*slash = '\0';
if (stat(path,&buf)==0) {
*slash = '/';
return;
}
mkdirhier(path);
mkdir (path,0777);
*slash = '/';
}
return;
}
void download_tree(AMDeviceRef device)
{
service_conn_t houseFd = start_house_arrest_service(device);
afc_connection* afc_conn_p = NULL;
char *dirname = NULL;
if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) do {
if (target_filename) {
dirname = strdup(target_filename);
mkdirhier(dirname);
if (mkdir(dirname,0777) && errno!=EEXIST) {
fprintf(stderr,"mkdir(\"%s\") failed: %s\n",dirname,strerror(errno));
break;
}
if (chdir(dirname)) {
fprintf(stderr,"chdir(\"%s\") failed: %s\n",dirname,strerror(errno));
break;
}
}
read_dir(houseFd, afc_conn_p, list_root?list_root:"/", copy_file_callback);
} while(0);
if (dirname) free(dirname);
if (afc_conn_p) AFCConnectionClose(afc_conn_p);
}
void upload_file(AMDeviceRef device) {
service_conn_t houseFd = start_house_arrest_service(device);
@ -1226,6 +1318,8 @@ void handle_device(AMDeviceRef device) {
list_files(device);
} else if (strcmp("upload", command) == 0) {
upload_file(device);
} else if (strcmp("download", command) == 0) {
download_tree(device);
}
exit(0);
}
@ -1379,7 +1473,8 @@ void usage(const char* app) {
" -1, --bundle_id <bundle id> specify bundle id for list and upload\n"
" -l, --list list files\n"
" -o, --upload <file> upload file\n"
" -2, --to <target pathname> use together with upload file. specify target for upload\n"
" -w, --download download app tree\n"
" -2, --to <target pathname> use together with up/download file/tree. specify target\n"
" -V, --version print the executable version \n",
app);
}
@ -1406,15 +1501,16 @@ int main(int argc, char *argv[]) {
{ "noinstall", no_argument, NULL, 'm' },
{ "port", required_argument, NULL, 'p' },
{ "uninstall", no_argument, NULL, 'r' },
{ "list", no_argument, NULL, 'l' },
{ "list", optional_argument, NULL, 'l' },
{ "bundle_id", required_argument, NULL, '1'},
{ "upload", required_argument, NULL, 'o'},
{ "download", optional_argument, NULL, 'w'},
{ "to", required_argument, NULL, '2'},
{ NULL, 0, NULL, 0 },
};
char ch;
while ((ch = getopt_long(argc, argv, "VmcdvunlrILi:b:a:t:g:x:p:1:2:o:", longopts, NULL)) != -1)
while ((ch = getopt_long(argc, argv, "VmcdvunrILib:a:t:g:x:p:1:2:o:l::w::", longopts, NULL)) != -1)
{
switch (ch) {
case 'm':
@ -1478,6 +1574,12 @@ int main(int argc, char *argv[]) {
case 'l':
command_only = true;
command = "list";
list_root = optarg;
break;
case 'w':
command_only = true;
command = "download";
list_root = optarg;
break;
default:
usage(argv[0]);