Skip to content

Rmtree command #440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 15, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 82 additions & 40 deletions src/ios-deploy/ios-deploy.m
Original file line number Diff line number Diff line change
Expand Up @@ -1246,9 +1246,10 @@ CFStringRef copy_bundle_id(CFURLRef app_url)
return bundle_id;
}

typedef enum { READ_DIR_FILE, READ_DIR_BEFORE_DIR, READ_DIR_AFTER_DIR } read_dir_cb_reason;

void read_dir(AFCConnectionRef afc_conn_p, const char* dir,
void(*callback)(AFCConnectionRef conn, const char *dir, int file))
void(*callback)(AFCConnectionRef conn, const char *dir, read_dir_cb_reason reason))
{
char *dir_ent;

Expand All @@ -1271,13 +1272,7 @@ void read_dir(AFCConnectionRef afc_conn_p, const char* dir,
AFCKeyValueClose(afc_dict_p);

if (not_dir) {
NSLogOut(@"%@", [NSString stringWithUTF8String:dir]);
} else {
NSLogOut(@"%@/", [NSString stringWithUTF8String:dir]);
}

if (not_dir) {
if (callback) (*callback)(afc_conn_p, dir, not_dir);
if (callback) (*callback)(afc_conn_p, dir, READ_DIR_FILE);
return;
}

Expand All @@ -1287,9 +1282,13 @@ void read_dir(AFCConnectionRef afc_conn_p, const char* dir,
if (err != 0) {
// Couldn't open dir - was probably a file
return;
} else {
if (callback) (*callback)(afc_conn_p, dir, not_dir);
}

// Call the callback on the directory before processing its
// contents. This is used by copy file callback, which needs to
// create the directory on the host before attempting to copy
// files into it.
if (callback) (*callback)(afc_conn_p, dir, READ_DIR_BEFORE_DIR);

while(true) {
err = AFCDirectoryRead(afc_conn_p, afc_dir_p, &dir_ent);
Expand All @@ -1310,6 +1309,11 @@ void read_dir(AFCConnectionRef afc_conn_p, const char* dir,
}

AFCDirectoryClose(afc_conn_p, afc_dir_p);

// Call the callback on the directory after processing its
// contents. This is used by the rmtree callback because it needs
// to delete the directory's contents before the directory itself
if (callback) (*callback)(afc_conn_p, dir, READ_DIR_AFTER_DIR);
}


Expand Down Expand Up @@ -1388,11 +1392,21 @@ AFCConnectionRef start_house_arrest_service(AMDeviceRef device) {
fclose(fd);
return content;
}

void list_files_callback(AFCConnectionRef conn, const char *name, read_dir_cb_reason reason)
{
if (reason == READ_DIR_FILE) {
NSLogOut(@"%@", [NSString stringWithUTF8String:name]);
} else if (reason == READ_DIR_BEFORE_DIR) {
NSLogOut(@"%@/", [NSString stringWithUTF8String:name]);
}
}

void list_files(AMDeviceRef device)
{
AFCConnectionRef afc_conn_p = start_house_arrest_service(device);
assert(afc_conn_p);
read_dir(afc_conn_p, list_root?list_root:"/", NULL);
read_dir(afc_conn_p, list_root?list_root:"/", list_files_callback);
check_error(AFCConnectionClose(afc_conn_p));
}

Expand Down Expand Up @@ -1467,47 +1481,52 @@ void list_bundle_id(AMDeviceRef device)
check_error(AMDeviceDisconnect(device));
}

void copy_file_callback(AFCConnectionRef afc_conn_p, const char *name,int file)
void copy_file_callback(AFCConnectionRef afc_conn_p, const char *name, read_dir_cb_reason reason)
{
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 (reason == READ_DIR_FILE) {
NSLogOut(@"%@", [NSString stringWithUTF8String:name]);
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;
}
if (err) {
fprintf(stderr,"AFCFileRefOpen(\"%s\") failed: %d\n",name,err);
return;
}

FILE *fp = fopen(local_name,"w");
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;
}
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);
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);
}
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));
AFCFileRefClose(afc_conn_p,fref);
fclose(fp);

} else if (reason == READ_DIR_BEFORE_DIR) {
NSLogOut(@"%@/", [NSString stringWithUTF8String:name]);
if (mkdir(local_name,0777) && errno!=EEXIST) {
fprintf(stderr,"mkdir(\"%s\") failed: %s\n",local_name,strerror(errno));
}
}
}


void download_tree(AMDeviceRef device)
{
AFCConnectionRef afc_conn_p = start_house_arrest_service(device);
Expand Down Expand Up @@ -1547,7 +1566,6 @@ void upload_file(AMDeviceRef device)
{
AFCConnectionRef afc_conn_p = start_house_arrest_service(device);
assert(afc_conn_p);
// read_dir(houseFd, NULL, "/", NULL);

if (!target_filename)
{
Expand Down Expand Up @@ -1578,8 +1596,6 @@ void upload_single_file(AMDeviceRef device, AFCConnectionRef afc_conn_p, NSStrin

afc_file_ref file_ref;

// read_dir(houseFd, NULL, "/", NULL);

size_t file_size;
void* file_content = read_file_to_memory([sourcePath fileSystemRepresentation], &file_size);

Expand Down Expand Up @@ -1643,6 +1659,23 @@ void remove_path(AMDeviceRef device) {
check_error(AFCConnectionClose(afc_conn_p));
}

// Handles the READ_DIR_AFTER_DIR callback so that we delete the contents of the
// directory before the directory itself
void rmtree_callback(AFCConnectionRef conn, const char *name, read_dir_cb_reason reason)
{
if (reason == READ_DIR_FILE || reason == READ_DIR_AFTER_DIR) {
NSLogVerbose(@"Deleting %s", name);
check_error(AFCRemovePath(conn, name));
}
}

void rmtree(AMDeviceRef device) {
AFCConnectionRef afc_conn_p = start_house_arrest_service(device);
assert(afc_conn_p);
read_dir(afc_conn_p, target_filename, rmtree_callback);
check_error(AFCConnectionClose(afc_conn_p));
}

void uninstall_app(AMDeviceRef device) {
CFRetain(device); // don't know if this is necessary?

Expand Down Expand Up @@ -1722,6 +1755,8 @@ void handle_device(AMDeviceRef device) {
make_directory(device);
} else if (strcmp("rm", command) == 0) {
remove_path(device);
} else if (strcmp("rmtree", command) == 0) {
rmtree(device);
} else if (strcmp("exists", command) == 0) {
exit(app_exists(device));
} else if (strcmp("uninstall_only", command) == 0) {
Expand Down Expand Up @@ -1968,6 +2003,7 @@ void usage(const char* app) {
@" -2, --to <target pathname> use together with up/download file/tree. specify target\n"
@" -D, --mkdir <dir> make directory on device\n"
@" -R, --rm <path> remove file or directory on device (directories must be empty)\n"
@" -X, --rmtree <path> remove directory and all contained files recursively on device\n"
@" -V, --version print the executable version \n"
@" -e, --exists check if the app with given bundle_id is installed or not \n"
@" -B, --list_bundle_id list bundle_id \n"
Expand Down Expand Up @@ -2020,6 +2056,7 @@ int main(int argc, char *argv[]) {
{ "to", required_argument, NULL, '2'},
{ "mkdir", required_argument, NULL, 'D'},
{ "rm", required_argument, NULL, 'R'},
{ "rmtree",required_argument, NULL, 'X'},
{ "exists", no_argument, NULL, 'e'},
{ "list_bundle_id", no_argument, NULL, 'B'},
{ "no-wifi", no_argument, NULL, 'W'},
Expand All @@ -2033,7 +2070,7 @@ int main(int argc, char *argv[]) {
};
int ch;

while ((ch = getopt_long(argc, argv, "VmcdvunrILeD:R:i:b:a:t:p:1:2:o:l:w:9BWjNs:OE:CA:", longopts, NULL)) != -1)
while ((ch = getopt_long(argc, argv, "VmcdvunrILeD:R:X:i:b:a:t:p:1:2:o:l:w:9BWjNs:OE:CA:", longopts, NULL)) != -1)
{
switch (ch) {
case 'm':
Expand Down Expand Up @@ -2128,6 +2165,11 @@ int main(int argc, char *argv[]) {
target_filename = optarg;
command = "rm";
break;
case 'X':
command_only = true;
target_filename = optarg;
command = "rmtree";
break;
case 'e':
command_only = true;
command = "exists";
Expand Down