Exemple #1
0
int itdb_iphone_stop_sync(void *sync_ctx)
{
    lockdownd_client_t client = NULL;
    itdbprep_t prepdata = sync_ctx;

    printf("libitdbprep: %s called\n", __func__);

    if (!prepdata) {
	printf("%s called but prepdata is NULL!\n", __func__);
	return -1;
    }

    if (!prepdata->afc) {
	printf("%s called but prepdata->afc is NULL!\n", __func__);
    } else {
	/* remove .status-com.apple.itdbprep.command.runPostProcess */
	if (afc_remove_path(prepdata->afc, "/iTunes_Control/iTunes/iTunes Library.itlp/DBTemp/.status-com.apple.itdprep.command.runPostProcess") != IDEVICE_E_SUCCESS) {
	    fprintf(stderr, "Could not delete '.status-com.apple.itdprep.command.runPostProcess'\n");
	}
	/* remove ddd.itdbm */
	if (afc_remove_path(prepdata->afc, "/iTunes_Control/iTunes/iTunes Library.itlp/DBTemp/ddd.itdbm") != IDEVICE_E_SUCCESS) {
	    fprintf(stderr, "Could not delete 'ddd.itdbm'\n");
	}
	if (prepdata->lockfile) {
	    afc_file_lock(prepdata->afc, prepdata->lockfile, AFC_LOCK_UN);
	    afc_file_close(prepdata->afc, prepdata->lockfile);
	    prepdata->lockfile = 0;
	} else {
	    printf("%s called but lockfile is 0\n", __func__);
	}
	afc_client_free(prepdata->afc);
	prepdata->afc = NULL;
    }

    if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(prepdata->device, &client, "libgpod")) {
	fprintf(stderr, "Error: Could not establish lockdownd connection!\n");
	goto leave;
    }

    if(itdb_iphone_post_notification(prepdata->device, client, NP_SYNC_DID_FINISH)) {
	fprintf(stderr, "failed to post syncDidFinish\n");
    }
    printf("%s: posted syncDidFinish\n", __func__);

    lockdownd_client_free(client);

leave:
    idevice_free(prepdata->device);

    g_free(prepdata);

    return 0;

}
Exemple #2
0
int ifuse_unlink(const char *path)
{
	afc_client_t afc = fuse_get_context()->private_data;

	afc_error_t err = afc_remove_path(afc, path);
	if (err == AFC_E_SUCCESS)
		return 0;

	return -get_afc_error_as_errno(err);
}
Exemple #3
0
static afc_error_t remove_path(char *path, bool recurse)
{
	afc_error_t result;
	char **infolist = NULL;
	bool is_dir;

	result = afc_get_file_info(afc, path, &infolist);

	if (result != AFC_E_SUCCESS) {
		if (result != AFC_E_OBJECT_NOT_FOUND)
			afc_warn(result, "%s: stat failed: %s", __func__, path);
		return result;
	}

	if (recurse && is_directory(path, &is_dir) == AFC_E_SUCCESS && is_dir) {
		char **list = NULL;

		result = afc_read_directory(afc, path, &list);
		if (result != AFC_E_SUCCESS) {
			afc_warn(result, "%s", path);
			return result;
		}

		for (int i = 0; list[i] && result == AFC_E_SUCCESS; i++) {
			if (str_is_equal(list[i], "."))
				; // NOP
			else if (str_is_equal(list[i], ".."))
				; // NOP
			else {
				char *subdir_path;
				if (asprintf(&subdir_path, "%s/%s", path, list[i]) > 0) {
					result = remove_path(subdir_path, recurse);
					free(subdir_path);
				}
				else {
					warn("%s: %s", __func__, "asprintf");
				}
			}
			free(list[i]);
		}
		free(list);
	}

	if (recurse)
		printf("removing: %s\n", path);

	result = afc_remove_path(afc, path);

	if (result != AFC_E_SUCCESS)
		afc_warn(result, "%s", path);

	return result;
}
Exemple #4
0
FB::variant ibrowserAPI::uploadFile(const std::string& fileName, const boost::optional<FB::JSObjectPtr>& pcb, F_ADD)
{

    if(fileName.empty())
        return false;
    
    THREAD(&ibrowserAPI::uploadFile,fileName,pcb);
    
    const char *file_name=fileName.c_str();
    
    char target_file[1024];
    sprintf(target_file, "%s/%s",uploadFileDir.c_str(), basename((char *)file_name));
    uint64_t target_file_handle = 0;
    if (AFC_E_SUCCESS != afc_file_open(afc_client, target_file, AFC_FOPEN_WRONLY, &target_file_handle)){
        ERRO("afc_file_open error!");
    }
    
    FILE *file_handle= fopen(file_name, "r");
    if (!file_handle)
    {
        afc_remove_path(afc_client, target_file);
        ERRO("open file error!");
    }
    
    off_t fileSize = 0;
    struct stat st;
    if (stat(file_name, &st) == 0)
        fileSize = st.st_size;
    static int read_buf_size = 1024;
    char read_buf[read_buf_size];
    int bytes_read;
    uint32_t bytes_written = 0;
    uint32_t doneSize = 0;
    while((bytes_read = fread(read_buf, 1, read_buf_size, file_handle)) >0 )
    {
        if (AFC_E_SUCCESS != afc_file_write(afc_client, target_file_handle, read_buf, bytes_read, &bytes_written) || bytes_read !=bytes_written)
        {
            ERRO("afc_file_write error!");
        }
        
        memset(read_buf, 0, read_buf_size);
        
        doneSize = doneSize + bytes_read;
        if(pcb && fileSize > 0)
            (*pcb)->InvokeAsync("", FB::variant_list_of((double)doneSize/fileSize));
    }
    
    SUCC(target_file);
    
    return target_file;
}
static void check_afc(gpointer data)
{
    //prepare a buffer
    unsigned int buffersize = BUFFER_SIZE * sizeof(unsigned int);
    int *buf = (int *) malloc(buffersize);
    int *buf2 = (int *) malloc(buffersize);
    unsigned int bytes = 0;
    uint64_t position = 0;

    //fill buffer
    int i = 0;
    for (i = 0; i < BUFFER_SIZE; i++) {
        buf[i] = ((param *) data)->id * i;
    }

    //now  writes buffer on device
    uint64_t file = 0;
    char path[50];
    sprintf(path, "/Buf%i", ((param *) data)->id);
    afc_file_open(((param *) data)->afc, path, AFC_FOPEN_RW, &file);
    afc_file_write(((param *) data)->afc, file, (char *) buf, buffersize, &bytes);
    afc_file_close(((param *) data)->afc, file);
    file = 0;
    if (bytes != buffersize)
        printf("Write operation failed\n");

    //now read it
    bytes = 0;
    afc_file_open(((param *) data)->afc, path, AFC_FOPEN_RDONLY, &file);
    afc_file_read(((param *) data)->afc, file, (char *) buf2, buffersize/2, &bytes);
    afc_file_read(((param *) data)->afc, file, (char *) buf2 + (buffersize/2), buffersize/2, &bytes);
    if(AFC_E_SUCCESS != afc_file_tell(((param *) data)->afc, file, &position))
        printf("Tell operation failed\n");
    afc_file_close(((param *) data)->afc, file);
    if (position != buffersize)
        printf("Read operation failed\n");

    //compare buffers
    for (i = 0; i < BUFFER_SIZE; i++) {
        if (buf[i] != buf2[i]) {
            printf("Buffers are differents, stream corrupted\n");
            break;
        }
    }

    //cleanup
    afc_remove_path(((param *) data)->afc, path);
    g_thread_exit(0);
}
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;
}
int main(int argc, char **argv)
{
	idevice_t dev = NULL;
	lockdownd_client_t client = NULL;
	house_arrest_client_t hac = NULL;
	house_arrest_error_t res;
	int i;
	char *udid = NULL;
	const char *appid = NULL;
	int test_file_io = 0;

	/* parse cmdline args */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
			idevice_set_debug_level(1);
			continue;
		}
		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			udid = strdup(argv[i]);
			continue;
		}
		else if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--test")) {
			test_file_io = 1;
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			appid = argv[i];
			break;
		}
	}

	if (!appid) {
		print_usage(argc, argv);
		return 0;
	}

	if (idevice_new(&dev, udid) != IDEVICE_E_SUCCESS) {
		printf("no device connected?!\n");
		goto leave_cleanup;
	}

	if (lockdownd_client_new_with_handshake(dev, &client, NULL) != LOCKDOWN_E_SUCCESS) {
		printf("could not connect to lockdownd!\n");
		goto leave_cleanup;
	}

	uint16_t port = 0;
	if (lockdownd_start_service(client, "com.apple.mobile.house_arrest", &port) != LOCKDOWN_E_SUCCESS) {
		printf("could not start house_arrest service!\n");
		goto leave_cleanup;
	}

	if (client) {
		lockdownd_client_free(client);
		client = NULL;
	}

	if (house_arrest_client_new(dev, port, &hac) != HOUSE_ARREST_E_SUCCESS) {
		printf("could not connect to house_arrest service!\n");
		goto leave_cleanup;
	}

	res = house_arrest_send_command(hac, "VendDocuments", appid);
	if (res != HOUSE_ARREST_E_SUCCESS) {
		printf("error %d when trying to get VendDocuments\n", res);
		goto leave_cleanup;
	}

	plist_t dict = NULL;
	if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
		if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
			printf("hmmm....\n");
			goto leave_cleanup;
		}
	}

	plist_t node = plist_dict_get_item(dict, "Error");
	if (node) {
		char *str = NULL;
		plist_get_string_val(node, &str);
		printf("Error: %s\n", str);
		if (str) free(str);
		plist_free(dict);
		dict = NULL;
		goto leave_cleanup;
	}
	node = plist_dict_get_item(dict, "Status");
	if (node) {
		char *str = NULL;
		plist_get_string_val(node, &str);
		if (str && (strcmp(str, "Complete") != 0)) {
			printf("Warning: Status is not 'Complete' but '%s'\n", str);
		}
		if (str) free(str);
		plist_free(dict);
		dict = NULL;
	}
	if (dict) {
		plist_free(dict);
	}

	afc_client_t afc = NULL;
	afc_error_t ae = afc_client_new_from_house_arrest_client(hac, &afc);
	if (ae != AFC_E_SUCCESS) {
		printf("afc error %d\n", ae);
	}
	if (ae == AFC_E_SUCCESS) {
		char **list = NULL;
		afc_read_directory(afc, "/", &list);
		printf("Directory contents:\n");
		if (list) {
			while (list[0]) {
				if (strcmp(list[0], ".") && strcmp(list[0], "..")) {
					puts(list[0]);
				}
				list++;
			}
		}

		if (test_file_io) {
			uint64_t tf = 0;
			printf("\n==== Performing file tests ====\n");
			printf("Opening file 'foobar' for writing: ");
			if (afc_file_open(afc, "/foobar", AFC_FOPEN_RW, &tf) == AFC_E_SUCCESS) {
				uint32_t wb = 0;
				printf("OK\n");

				printf("Writing to file: ");
				if (afc_file_write(afc, tf, "test\r\n", 6, &wb) != AFC_E_SUCCESS) {
					printf("ERROR\n");
				} else {
					printf("OK\n");
				}
				afc_file_close(afc, tf);
				printf("Deleting file 'foobar': ");
				if (afc_remove_path(afc, "/foobar") == AFC_E_SUCCESS) {
					printf("OK\n");
				} else {
					printf("ERROR\n");
				}
			} else {
				printf("ERROR\n");
			}
		}
		afc_client_free(afc);
	} else {
		printf("failed to connect to afc service, error %d\n", ae);
	}

leave_cleanup:
	if (hac) {
		house_arrest_client_free(hac);
	}
	if (client) {
		lockdownd_client_free(client);
	}
	if (dev) {
		idevice_free(dev);
	}

	return 0;
}
int main(int argc, char *argv[])
{
	unsigned int bytes = 0;
	uint16_t i = 0;
	lockdownd_service_descriptor_t service = NULL;
	lockdownd_client_t client = NULL;
	idevice_t phone = NULL;
	uint64_t lockfile = 0;
	np_client_t gnp = NULL;

	if (argc > 1 && !strcasecmp(argv[1], "--debug")) {
		idevice_set_debug_level(1);
	} else {
		idevice_set_debug_level(0);
	}

	if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) {
		printf("No device found, is it plugged in?\n");
		return -1;
	}

	char *udid = NULL;
	if (IDEVICE_E_SUCCESS == idevice_get_udid(phone, &udid)) {
		printf("DeviceUniqueID : %s\n", udid);
	}
	if (udid)
		free(udid);

	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "ideviceclient")) {
		idevice_free(phone);
		printf("Exiting.\n");
		return -1;
	}

	char *nnn = NULL;
	if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name(client, &nnn)) {
		printf("DeviceName : %s\n", nnn);
		free(nnn);
	}

	lockdownd_start_service(client, "com.apple.afc", &service);

	if (service && service->port) {
		afc_client_t afc = NULL;
		afc_client_new(phone, service, &afc);

		if (afc) {
			service->port = 0;
			service->ssl_enabled = 0;
			lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &service);
			if (service->port) {
				printf("Notification Proxy started.\n");
				np_client_new(phone, service, &gnp);
			} else {
				printf("ERROR: Notification proxy could not be started.\n");
			}

			if (gnp) {
				const char *nspec[5] = {
					NP_SYNC_CANCEL_REQUEST,
					NP_SYNC_SUSPEND_REQUEST,
					NP_SYNC_RESUME_REQUEST,
					NP_ITDBPREP_DID_END,
					NULL
				};
				np_observe_notifications(gnp, nspec);
				np_set_notify_callback(gnp, notifier, NULL);
			}

			perform_notification(phone, client, NP_SYNC_WILL_START);

			afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile);
			if (lockfile) {
				printf("locking file\n");
				afc_file_lock(afc, lockfile, AFC_LOCK_EX);

				perform_notification(phone, client, NP_SYNC_DID_START);
			}

			char **dirs = NULL;
			afc_read_directory(afc, "/eafaedf", &dirs);
			if (!dirs)
				afc_read_directory(afc, "/", &dirs);
			printf("Directory time.\n");
			for (i = 0; dirs[i]; i++) {
				printf("/%s\n", dirs[i]);
				free(dirs[i]);
			}
			if (dirs)
				free(dirs);

			dirs = NULL;
			afc_get_device_info(afc, &dirs);
			if (dirs) {
				for (i = 0; dirs[i]; i += 2) {
					printf("%s: %s\n", dirs[i], dirs[i + 1]);
					free(dirs[i]);
				}
				free(dirs);
			}

			uint64_t my_file = 0;
			char **info = NULL;
			uint64_t fsize = 0;
			if (AFC_E_SUCCESS == afc_get_file_info(afc, "/readme.libimobiledevice.fx", &info) && info) {
				for (i = 0; info[i]; i += 2) {
					printf("%s: %s\n", info[i], info[i+1]);
					if (!strcmp(info[i], "st_size")) {
						fsize = atoll(info[i+1]);
					}
				}
			}

			if (AFC_E_SUCCESS ==
				afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) {
				printf("A file size: %llu\n", (long long)fsize);
				char *file_data = (char *) malloc(sizeof(char) * fsize);
				afc_file_read(afc, my_file, file_data, fsize, &bytes);
				if (bytes > 0) {
					printf("The file's data:\n");
					fwrite(file_data, 1, bytes, stdout);
				}
				printf("\nClosing my file.\n");
				afc_file_close(afc, my_file);
				free(file_data);
			} else
				printf("couldn't open a file\n");

			afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_WR, &my_file);
			if (my_file) {
				char *outdatafile = strdup("this is a bitchin text file\n");
				afc_file_write(afc, my_file, outdatafile, strlen(outdatafile), &bytes);
				free(outdatafile);
				if (bytes > 0)
					printf("Wrote a surprise. ;)\n");
				else
					printf("I wanted to write a surprise, but... :(\n");
				afc_file_close(afc, my_file);
			}
			printf("Deleting a file...\n");
			bytes = afc_remove_path(afc, "/delme");
			if (bytes)
				printf("Success.\n");
			else
				printf("Failure. (expected unless you have a /delme file on your phone)\n");

			printf("Renaming a file...\n");
			bytes = afc_rename_path(afc, "/renme", "/renme2");
			if (bytes > 0)
				printf("Success.\n");
			else
				printf("Failure. (expected unless you have a /renme file on your phone)\n");

			printf("Seek & read\n");
			afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file);
			if (AFC_E_SUCCESS != afc_file_seek(afc, my_file, 5, SEEK_CUR))
				printf("WARN: SEEK DID NOT WORK\n");
			char *threeletterword = (char *) malloc(sizeof(char) * 5);
			afc_file_read(afc, my_file, threeletterword, 3, &bytes);
			threeletterword[3] = '\0';
			if (bytes > 0)
				printf("Result: %s\n", threeletterword);
			else
				printf("Couldn't read!\n");
			free(threeletterword);
			afc_file_close(afc, my_file);
		}

		if (gnp && lockfile) {
			printf("XXX sleeping\n");
			sleep(5);

			printf("XXX unlocking file\n");
			afc_file_lock(afc, lockfile, AFC_LOCK_UN);

			printf("XXX closing file\n");
			afc_file_close(afc, lockfile);

			printf("XXX sleeping\n");
			sleep(5);
			//perform_notification(phone, client, NP_SYNC_DID_FINISH);
		}

		if (gnp) {
			np_client_free(gnp);
			gnp = NULL;
		}

		afc_client_free(afc);

		lockdownd_service_descriptor_free(service);
		service = NULL;
	} else {
		printf("Start service failure.\n");
	}

	printf("All done.\n");

	lockdownd_client_free(client);
	idevice_free(phone);

	return 0;
}