FileType Device::getFileTypeWithAfc(afc_client_t afc, string path) { uint64_t handle = 0; if (afc_file_open(afc, path.c_str(), afc_file_mode_t::AFC_FOPEN_RDONLY, &handle) != AFC_E_SUCCESS) { return TypeInvalid; } afc_file_close(afc, handle); char **dir = NULL; if (afc_read_directory(afc, path.c_str(), &dir) != AFC_E_SUCCESS) { return TypeFile; } afc_dictionary_free(dir); return TypeDirectory; }
DeviceStatus Device::getDirectoryWithAfc(afc_client_t afc, string path, list<string> &fileList) { char **dir = NULL; if (afc_read_directory(afc, path.c_str(), &dir) != AFC_E_SUCCESS) { afc_client_free(afc); house_arrest_client_free(this->mHouseArrestClient); this->mHouseArrestClient = NULL; return StatusError; } for (int i = 0; dir[i]; i++) { if (strcmp(dir[i], ".") == 0 || strcmp(dir[i], "..") == 0) { continue; } //cout << dir[i] << endl; fileList.push_back(dir[i]); } afc_dictionary_free(dir); return StatusOK; }
static int afc_client_copy_and_remove_crash_reports(afc_client_t afc, const char* device_directory, const char* host_directory) { afc_error_t afc_error; int k; int res = -1; int crash_report_count = 0; uint64_t handle; char source_filename[512]; char target_filename[512]; if (!afc) return res; char** list = NULL; afc_error = afc_read_directory(afc, device_directory, &list); if (afc_error != AFC_E_SUCCESS) { fprintf(stderr, "ERROR: Could not read device directory '%s'\n", device_directory); return res; } /* ensure we have a trailing slash */ strcpy(source_filename, device_directory); if (source_filename[strlen(source_filename)-1] != '/') { strcat(source_filename, "/"); } int device_directory_length = strlen(source_filename); /* ensure we have a trailing slash */ strcpy(target_filename, host_directory); if (target_filename[strlen(target_filename)-1] != '/') { strcat(target_filename, "/"); } int host_directory_length = strlen(target_filename); /* loop over file entries */ for (k = 0; list[k]; k++) { if (!strcmp(list[k], ".") || !strcmp(list[k], "..")) { continue; } char **fileinfo = NULL; struct stat stbuf; stbuf.st_size = 0; /* assemble absolute source filename */ strcpy(((char*)source_filename) + device_directory_length, list[k]); /* assemble absolute target filename */ char* p = strrchr(list[k], '.'); if (p != NULL && !strncmp(p, ".synced", 7)) { /* make sure to strip ".synced" extension as seen on iOS 5 */ strncpy(((char*)target_filename) + host_directory_length, list[k], strlen(list[k]) - 7); } else { strcpy(((char*)target_filename) + host_directory_length, list[k]); } /* get file information */ afc_get_file_info(afc, source_filename, &fileinfo); if (!fileinfo) { printf("Failed to read information for '%s'. Skipping...\n", source_filename); continue; } /* parse file information */ int i; for (i = 0; fileinfo[i]; i+=2) { if (!strcmp(fileinfo[i], "st_size")) { stbuf.st_size = atoll(fileinfo[i+1]); } else if (!strcmp(fileinfo[i], "st_ifmt")) { if (!strcmp(fileinfo[i+1], "S_IFREG")) { stbuf.st_mode = S_IFREG; } else if (!strcmp(fileinfo[i+1], "S_IFDIR")) { stbuf.st_mode = S_IFDIR; } else if (!strcmp(fileinfo[i+1], "S_IFLNK")) { stbuf.st_mode = S_IFLNK; } else if (!strcmp(fileinfo[i+1], "S_IFBLK")) { stbuf.st_mode = S_IFBLK; } else if (!strcmp(fileinfo[i+1], "S_IFCHR")) { stbuf.st_mode = S_IFCHR; } else if (!strcmp(fileinfo[i+1], "S_IFIFO")) { stbuf.st_mode = S_IFIFO; } else if (!strcmp(fileinfo[i+1], "S_IFSOCK")) { stbuf.st_mode = S_IFSOCK; } } else if (!strcmp(fileinfo[i], "st_nlink")) { stbuf.st_nlink = atoi(fileinfo[i+1]); } else if (!strcmp(fileinfo[i], "st_mtime")) { stbuf.st_mtime = (time_t)(atoll(fileinfo[i+1]) / 1000000000); } else if (!strcmp(fileinfo[i], "LinkTarget")) { /* report latest crash report filename */ printf("Link: %s\n", (char*)target_filename + strlen(target_directory)); /* remove any previous symlink */ if (file_exists(target_filename)) { remove(target_filename); } #ifndef WIN32 /* use relative filename */ char* b = strrchr(fileinfo[i+1], '/'); if (b == NULL) { b = fileinfo[i+1]; } else { b++; } /* create a symlink pointing to latest log */ if (symlink(b, target_filename) < 0) { fprintf(stderr, "Can't create symlink to %s\n", b); } #endif if (!keep_crash_reports) afc_remove_path(afc, source_filename); res = 0; } } /* free file information */ afc_dictionary_free(fileinfo); /* recurse into child directories */ if (S_ISDIR(stbuf.st_mode)) { #ifdef WIN32 mkdir(target_filename); #else mkdir(target_filename, 0755); #endif res = afc_client_copy_and_remove_crash_reports(afc, source_filename, target_filename); /* remove directory from device */ if (!keep_crash_reports) afc_remove_path(afc, source_filename); } else if (S_ISREG(stbuf.st_mode)) { /* copy file to host */ afc_error = afc_file_open(afc, source_filename, AFC_FOPEN_RDONLY, &handle); if(afc_error != AFC_E_SUCCESS) { if (afc_error == AFC_E_OBJECT_NOT_FOUND) { continue; } fprintf(stderr, "Unable to open device file '%s' (%d). Skipping...\n", source_filename, afc_error); continue; } FILE* output = fopen(target_filename, "wb"); if(output == NULL) { fprintf(stderr, "Unable to open local file '%s'. Skipping...\n", target_filename); afc_file_close(afc, handle); continue; } printf("%s: %s\n", (keep_crash_reports ? "Copy": "Move") , (char*)target_filename + strlen(target_directory)); uint32_t bytes_read = 0; uint32_t bytes_total = 0; unsigned char data[0x1000]; afc_error = afc_file_read(afc, handle, (char*)data, 0x1000, &bytes_read); while(afc_error == AFC_E_SUCCESS && bytes_read > 0) { fwrite(data, 1, bytes_read, output); bytes_total += bytes_read; afc_error = afc_file_read(afc, handle, (char*)data, 0x1000, &bytes_read); } afc_file_close(afc, handle); fclose(output); if ((uint32_t)stbuf.st_size != bytes_total) { fprintf(stderr, "File size mismatch. Skipping...\n"); continue; } /* remove file from device */ if (!keep_crash_reports) { afc_remove_path(afc, source_filename); } /* extract raw crash information into separate '.crash' file */ if (extract_raw_crash_reports) { extract_raw_crash_report(target_filename); } crash_report_count++; res = 0; } } afc_dictionary_free(list); /* no reports, no error */ if (crash_report_count == 0) res = 0; return res; }