/** * Connects to the mobilebackup2 service on the specified device. * * @param device The device to connect to. * @param service The service descriptor returned by lockdownd_start_service. * @param client Pointer that will be set to a newly allocated * mobilebackup2_client_t upon successful return. * * @return MOBILEBACKUP2_E_SUCCESS on success, MOBILEBACKUP2_E_INVALID ARG * if one or more parameter is invalid, or MOBILEBACKUP2_E_BAD_VERSION * if the mobilebackup2 version on the device is newer. */ mobilebackup2_error_t mobilebackup2_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilebackup2_client_t * client) { if (!device || service->port == 0 || !client || *client) return MOBILEBACKUP2_E_INVALID_ARG; device_link_service_client_t dlclient = NULL; mobilebackup2_error_t ret = mobilebackup2_error(device_link_service_client_new(device, service, &dlclient)); if (ret != MOBILEBACKUP2_E_SUCCESS) { return ret; } mobilebackup2_client_t client_loc = (mobilebackup2_client_t) malloc(sizeof(struct mobilebackup2_client_private)); client_loc->parent = dlclient; /* perform handshake */ ret = mobilebackup2_error(device_link_service_version_exchange(dlclient, MBACKUP2_VERSION_INT1, MBACKUP2_VERSION_INT2)); if (ret != MOBILEBACKUP2_E_SUCCESS) { debug_info("version exchange failed, error %d", ret); mobilebackup2_client_free(client_loc); return ret; } *client = client_loc; return ret; }
DeviceStatus Device::backup() { mobilebackup2_client_t mb_client = NULL; DeviceStatus status = StatusError; if (mobilebackup2_client_start_service(this->mDevice, &mb_client, NULL) == MOBILEBACKUP2_E_SUCCESS) { afc_client_t afc = this->getAfcFromApp(""); if (afc) { uint64_t handle; if (afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &handle) == AFC_E_SUCCESS && afc_file_lock(afc, handle, AFC_LOCK_EX) == AFC_E_SUCCESS) { if (mobilebackup2_send_request(mb_client, "Backup", this->mUdid.c_str(), this->mUdid.c_str(), NULL) == MOBILEBACKUP2_E_SUCCESS) { plist_t msg = NULL; char *dl = NULL; if (mobilebackup2_receive_message(mb_client, &msg, &dl) == MOBILEBACKUP2_E_SUCCESS) { plist_t files = plist_array_get_item(msg, 1); int count = plist_array_get_size(files); for (int i = 0; i < count; i++) { plist_t val = plist_array_get_item(files, i); if (plist_get_node_type(val) != PLIST_STRING) { continue; } char *str = NULL; plist_get_string_val(val, &str); if (!str) { continue; } uint32_t nlen = 0, bytes = 0; mobilebackup2_error_t err; err = mobilebackup2_send_raw(mb_client, (const char*)&nlen, sizeof(nlen), &bytes); const char *path = "/tmp/test"; uint32_t pathlen = strlen(path); err = mobilebackup2_send_raw(mb_client, path, pathlen, &bytes); free(str); } uint32_t zero = 0, sent = 0; mobilebackup2_send_raw(mb_client, (char*)&zero, sizeof(zero), &sent); plist_free(msg); free(dl); status = StatusOK; } } afc_file_close(afc, handle); } } mobilebackup2_client_free(mb_client); } return status; }