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:
parent
c57f208422
commit
9f0c8a85c6
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;
|
afc_dictionary* afc_dict_p;
|
||||||
char *key, *val;
|
char *key, *val;
|
||||||
int not_dir;
|
int not_dir = 0;
|
||||||
|
|
||||||
AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p);
|
AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p);
|
||||||
while((AFCKeyValueRead(afc_dict_p,&key,&val) == 0) && key && val) {
|
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) {
|
void upload_file(AMDeviceRef device) {
|
||||||
service_conn_t houseFd = start_house_arrest_service(device);
|
service_conn_t houseFd = start_house_arrest_service(device);
|
||||||
|
|
||||||
@ -1226,6 +1317,8 @@ void handle_device(AMDeviceRef device) {
|
|||||||
list_files(device);
|
list_files(device);
|
||||||
} else if (strcmp("upload", command) == 0) {
|
} else if (strcmp("upload", command) == 0) {
|
||||||
upload_file(device);
|
upload_file(device);
|
||||||
|
} else if (strcmp("download", command) == 0) {
|
||||||
|
download_tree(device);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@ -1379,7 +1472,8 @@ void usage(const char* app) {
|
|||||||
" -1, --bundle_id <bundle id> specify bundle id for list and upload\n"
|
" -1, --bundle_id <bundle id> specify bundle id for list and upload\n"
|
||||||
" -l, --list list files\n"
|
" -l, --list list files\n"
|
||||||
" -o, --upload <file> upload file\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",
|
" -V, --version print the executable version \n",
|
||||||
app);
|
app);
|
||||||
}
|
}
|
||||||
@ -1409,12 +1503,13 @@ int main(int argc, char *argv[]) {
|
|||||||
{ "list", no_argument, NULL, 'l' },
|
{ "list", no_argument, NULL, 'l' },
|
||||||
{ "bundle_id", required_argument, NULL, '1'},
|
{ "bundle_id", required_argument, NULL, '1'},
|
||||||
{ "upload", required_argument, NULL, 'o'},
|
{ "upload", required_argument, NULL, 'o'},
|
||||||
|
{ "download", no_argument, NULL, 'w'},
|
||||||
{ "to", required_argument, NULL, '2'},
|
{ "to", required_argument, NULL, '2'},
|
||||||
{ NULL, 0, NULL, 0 },
|
{ NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
char ch;
|
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) {
|
switch (ch) {
|
||||||
case 'm':
|
case 'm':
|
||||||
@ -1479,6 +1574,10 @@ int main(int argc, char *argv[]) {
|
|||||||
command_only = true;
|
command_only = true;
|
||||||
command = "list";
|
command = "list";
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
command_only = true;
|
||||||
|
command = "download";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
return exitcode_error;
|
return exitcode_error;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user