Add download option.
Unlike upload option, download pulls down whole tree. For this reason --to is expected to be directory path.
This commit is contained in:
		
							
								
								
									
										105
									
								
								ios-deploy.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								ios-deploy.c
									
									
									
									
									
								
							| @@ -1017,7 +1017,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) { | ||||
| @@ -1141,6 +1141,97 @@ void list_files(AMDeviceRef device) | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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, "/", 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 +1317,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 +1472,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); | ||||
| } | ||||
| @@ -1409,12 +1503,13 @@ int main(int argc, char *argv[]) { | ||||
|         { "list", no_argument, NULL, 'l' }, | ||||
|         { "bundle_id", required_argument, NULL, '1'}, | ||||
|         { "upload", required_argument, NULL, 'o'}, | ||||
|         { "download", no_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, "VmcdvunlrILiw:b:a:t:g:x:p:1:2:o:", longopts, NULL)) != -1) | ||||
|     { | ||||
|         switch (ch) { | ||||
|         case 'm': | ||||
| @@ -1479,6 +1574,10 @@ int main(int argc, char *argv[]) { | ||||
|             command_only = true; | ||||
|             command = "list"; | ||||
|             break; | ||||
|         case 'w': | ||||
|             command_only = true; | ||||
|             command = "download"; | ||||
|             break; | ||||
|         default: | ||||
|             usage(argv[0]); | ||||
|             return exitcode_error; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Andy Polyakov
					Andy Polyakov