diff options
| author | 2010-01-13 15:08:14 +0100 | |
|---|---|---|
| committer | 2010-01-13 15:08:14 +0100 | |
| commit | c9e2217059f561f87cf8b6af5067505f827c7297 (patch) | |
| tree | b3e46b6ed89035f9ad0ee696cf46c57445cabbf7 /src/InstallationProxy.c | |
| parent | 0ea52d01b817e35e4d4fceb57c9267124e60dab3 (diff) | |
| download | libimobiledevice-c9e2217059f561f87cf8b6af5067505f827c7297.tar.gz libimobiledevice-c9e2217059f561f87cf8b6af5067505f827c7297.tar.bz2 | |
Rename service implementation sources to lowercase for consistency
Diffstat (limited to 'src/InstallationProxy.c')
| -rw-r--r-- | src/InstallationProxy.c | 740 | 
1 files changed, 0 insertions, 740 deletions
| diff --git a/src/InstallationProxy.c b/src/InstallationProxy.c deleted file mode 100644 index 9ada994..0000000 --- a/src/InstallationProxy.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - * InstallationProxy.c - * Installation Proxy implementation. - * - * Copyright (c) 2009 Nikias Bassen, All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  - */ - -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <plist/plist.h> - -#include "InstallationProxy.h" -#include "property_list_service.h" -#include "debug.h" - -struct instproxy_status_data { -	instproxy_client_t client; -	instproxy_status_cb_t cbfunc; -	char *operation; -}; - -/** Locks an installation_proxy client, done for thread safety stuff. - * - * @param client The installation_proxy client to lock - */ -static void instproxy_lock(instproxy_client_t client) -{ -	debug_info("InstallationProxy: Locked"); -	g_mutex_lock(client->mutex); -} - -/** Unlocks an installation_proxy client, done for thread safety stuff. - *  - * @param client The installation_proxy client to lock - */ -static void instproxy_unlock(instproxy_client_t client) -{ -	debug_info("InstallationProxy: Unlocked"); -	g_mutex_unlock(client->mutex); -} - -/** - * Convert a property_list_service_error_t value to an instproxy_error_t value. - * Used internally to get correct error codes. - * - * @param err A property_list_service_error_t error code - * - * @return A matching instproxy_error_t error code, - *     INSTPROXY_E_UNKNOWN_ERROR otherwise. - */ -static instproxy_error_t instproxy_error(property_list_service_error_t err) -{ -	switch (err) { -		case PROPERTY_LIST_SERVICE_E_SUCCESS: -			return INSTPROXY_E_SUCCESS; -		case PROPERTY_LIST_SERVICE_E_INVALID_ARG: -			return INSTPROXY_E_INVALID_ARG; -		case PROPERTY_LIST_SERVICE_E_PLIST_ERROR: -			return INSTPROXY_E_PLIST_ERROR; -		case PROPERTY_LIST_SERVICE_E_MUX_ERROR: -			return INSTPROXY_E_CONN_FAILED; -		default: -			break; -	} -	return INSTPROXY_E_UNKNOWN_ERROR; -} - -/** - * Creates a new installation_proxy client - * - * @param device The device to connect to - * @param port Destination port (usually given by lockdownd_start_service). - * @param client Pointer that will be set to a newly allocated - *     instproxy_client_t upon successful return. - * - * @return INSTPROXY_E_SUCCESS on success, or an INSTPROXY_E_* error value - *     when an error occured. - */ -instproxy_error_t instproxy_client_new(iphone_device_t device, uint16_t port, instproxy_client_t *client) -{ -	/* makes sure thread environment is available */ -	if (!g_thread_supported()) -		g_thread_init(NULL); - -	if (!device) -		return INSTPROXY_E_INVALID_ARG; - -	property_list_service_client_t plistclient = NULL; -	if (property_list_service_client_new(device, port, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) { -		return INSTPROXY_E_CONN_FAILED; -	} - -	instproxy_client_t client_loc = (instproxy_client_t) malloc(sizeof(struct instproxy_client_int)); -	client_loc->parent = plistclient; -	client_loc->mutex = g_mutex_new(); -	client_loc->status_updater = NULL; - -	*client = client_loc; -	return INSTPROXY_E_SUCCESS; -} - -/** - * Frees an installation_proxy client. - * - * @param client The installation_proxy client to free. - * - * @return INSTPROXY_E_SUCCESS on success - *      or INSTPROXY_E_INVALID_ARG if client is NULL. - */ -instproxy_error_t instproxy_client_free(instproxy_client_t client) -{ -	if (!client) -		return INSTPROXY_E_INVALID_ARG; - -	property_list_service_client_free(client->parent); -	client->parent = NULL; -	if (client->status_updater) { -		debug_info("joining status_updater"); -		g_thread_join(client->status_updater); -	} -	if (client->mutex) { -		g_mutex_free(client->mutex); -	} -	free(client); - -	return INSTPROXY_E_SUCCESS; -} - -/** - * List installed applications. This function runs synchronously. - * - * @param client The connected installation_proxy client - * @param apptype The type of applications to list. - * @param result Pointer that will be set to a plist that will hold an array - *        of PLIST_DICT holding information about the applications found. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - */ -instproxy_error_t instproxy_browse(instproxy_client_t client, instproxy_apptype_t apptype, plist_t *result) -{ -	if (!client || !client->parent || !result) -		return INSTPROXY_E_INVALID_ARG; - -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; -	int browsing = 0; -	plist_t apps_array = NULL; - -	plist_t dict = plist_new_dict(); -	if (apptype != INSTPROXY_APPTYPE_ALL) { -		plist_t client_opts = plist_new_dict(); -		plist_t p_apptype = NULL; -		switch (apptype) { -			case INSTPROXY_APPTYPE_SYSTEM: -				p_apptype = plist_new_string("System"); -				break; -			case INSTPROXY_APPTYPE_USER: -				p_apptype = plist_new_string("User"); -				break; -			default: -				debug_info("unknown apptype %d given, using INSTPROXY_APPTYPE_USER instead", apptype); -				p_apptype = plist_new_string("User"); -				break; -		} -		plist_dict_insert_item(client_opts, "ApplicationType", p_apptype); -		plist_dict_insert_item(dict, "ClientOptions", client_opts); -	} -	plist_dict_insert_item(dict, "Command", plist_new_string("Browse")); - -	instproxy_lock(client); -	res = instproxy_error(property_list_service_send_xml_plist(client->parent, dict)); -	plist_free(dict); -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not send plist"); -		goto leave_unlock; -	} - -	apps_array = plist_new_array(); - -	do { -		browsing = 0; -		dict = NULL; -		res = instproxy_error(property_list_service_receive_plist(client->parent, &dict)); -		if (res != INSTPROXY_E_SUCCESS) { -			break; -		} -		if (dict) { -			uint64_t i; -			uint64_t current_amount = 0; -			char *status = NULL; -			plist_t camount = plist_dict_get_item(dict, "CurrentAmount"); -			plist_t pstatus = plist_dict_get_item(dict, "Status"); -			if (camount) { -				plist_get_uint_val(camount, ¤t_amount); -			} -			if (current_amount > 0) { -				plist_t current_list = plist_dict_get_item(dict, "CurrentList"); -				for (i = 0; current_list && (i < current_amount); i++) { -					plist_t item = plist_array_get_item(current_list, i); -					plist_array_append_item(apps_array, plist_copy(item)); -				} -			} -			if (pstatus) { -				plist_get_string_val(pstatus, &status); -			} -			if (status) { -				if (!strcmp(status, "BrowsingApplications")) { -					browsing = 1; -				} else if (!strcmp(status, "Complete")) { -					debug_info("Browsing applications completed"); -					res = INSTPROXY_E_SUCCESS; -				} -				free(status); -			} -			plist_free(dict); -		} -	} while (browsing); - -	if (res == INSTPROXY_E_SUCCESS) { -		*result = apps_array; -	} - -leave_unlock: -	instproxy_unlock(client); -	return res; -} - -/** - * Internally used function that will synchronously receive messages from - * the specified installation_proxy until it completes or an error occurs. - * - * If status_cb is not NULL, the callback function will be called each time - * a status update or error message is received. - * - * @param client The connected installation proxy client - * @param status_cb Pointer to a callback function or NULL - * @param operation Operation name. Will be passed to the callback function - *        in async mode or shown in debug messages in sync mode.  - */ -static instproxy_error_t instproxy_perform_operation(instproxy_client_t client, instproxy_status_cb_t status_cb, const char *operation) -{ -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; -	int ok = 1; -	plist_t dict = NULL; - -	do { -		instproxy_lock(client); -		res = instproxy_error(property_list_service_receive_plist_with_timeout(client->parent, &dict, 30000)); -		instproxy_unlock(client); -		if (res != INSTPROXY_E_SUCCESS) { -			debug_info("could not receive plist, error %d", res); -			break; -		} -		if (dict) { -			/* invoke callback function */ -			if (status_cb) { -				status_cb(operation, dict); -			} -			/* check for 'Error', so we can abort cleanly */ -			plist_t err = plist_dict_get_item(dict, "Error"); -			if (err) { -#ifndef STRIP_DEBUG_CODE -				char *err_msg = NULL; -				plist_get_string_val(err, &err_msg); -				if (err_msg) { -					debug_info("(%s): ERROR: %s", operation, err_msg); -					free(err_msg); -				} -#endif -				ok = 0; -				res = INSTPROXY_E_OP_FAILED; -			} -			/* get 'Status' */ -			plist_t status = plist_dict_get_item(dict, "Status"); -			if (status) { -				char *status_msg = NULL; -				plist_get_string_val(status, &status_msg); -				if (status_msg) { -					if (!strcmp(status_msg, "Complete")) { -						ok = 0; -						res = INSTPROXY_E_SUCCESS; -					} -#ifndef STRIP_DEBUG_CODE -					plist_t npercent = plist_dict_get_item(dict, "PercentComplete"); -					if (npercent) { -						uint64_t val = 0; -						int percent; -						plist_get_uint_val(npercent, &val); -						percent = val; -						debug_info("(%s): %s (%d%%)", operation, status_msg, percent); -					} else { -						debug_info("(%s): %s", operation, status_msg); -					} -#endif -					free(status_msg); -				} -			} -			plist_free(dict); -			dict = NULL; -		} -	} while (ok && client->parent); - -	return res; -} - -/** - * Internally used status updater thread function that will call the specified - * callback function when status update messages (or error messages) are - * received. - * - * @param arg Pointer to an allocated struct instproxy_status_data that holds - *     the required data about the connected client and the callback function. - * - * @return Always NULL. - */ -static gpointer instproxy_status_updater(gpointer arg) -{	 -	struct instproxy_status_data *data = (struct instproxy_status_data*)arg; - -	/* run until the operation is complete or an error occurs */ -	(void)instproxy_perform_operation(data->client, data->cbfunc, data->operation); - -	/* cleanup */ -	instproxy_lock(data->client); -	debug_info("done, cleaning up."); -	if (data->operation) { -	    free(data->operation); -	} -	data->client->status_updater = NULL; -	instproxy_unlock(data->client); -	free(data); - -	return NULL; -} - -/** - * Internally used helper function that creates a status updater thread which - * will call the passed callback function when status updates occur. - * If status_cb is NULL no thread will be created, but the operation will - * run synchronously until it completes or an error occurs. - * - * @param client The connected installation proxy client - * @param status_cb Pointer to a callback function or NULL - * @param operation Operation name. Will be passed to the callback function - *        in async mode or shown in debug messages in sync mode. - * - * @return INSTPROXY_E_SUCCESS when the thread was created (async mode), or - *         when the operation completed successfully (sync). - *         An INSTPROXY_E_* error value is returned if an error occured. - */ -static instproxy_error_t instproxy_create_status_updater(instproxy_client_t client, instproxy_status_cb_t status_cb, const char *operation) -{ -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; -	if (status_cb) { -		/* async mode */ -		struct instproxy_status_data *data = (struct instproxy_status_data*)malloc(sizeof(struct instproxy_status_data)); -		if (data) { -			data->client = client; -			data->cbfunc = status_cb; -			data->operation = strdup(operation); - -			client->status_updater = g_thread_create(instproxy_status_updater, data, TRUE, NULL); -			if (client->status_updater) { -				res = INSTPROXY_E_SUCCESS; -			} -		} -	} else { -		/* sync mode */ -		res = instproxy_perform_operation(client, NULL, operation); -	} -	return res; -} - - -/** - * Internal function used by instproxy_install and instproxy_upgrade. - * - * @param client The connected installation_proxy client - * @param pkg_path Path of the installation package (inside the AFC jail) - * @param sinf PLIST_DATA node holding the package's SINF data or NULL. - * @param metadata PLIST_DATA node holding the packages's Metadata or NULL. - * @param status_cb Callback function for progress and status information. If - *        NULL is passed, this function will run synchronously. - * @param command The command to execute. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured.  - */ -static instproxy_error_t instproxy_install_or_upgrade(instproxy_client_t client, const char *pkg_path, plist_t sinf, plist_t metadata, instproxy_status_cb_t status_cb, const char *command) -{ -	if (!client || !client->parent || !pkg_path) { -		return INSTPROXY_E_INVALID_ARG; -	} -	if (sinf && (plist_get_node_type(sinf) != PLIST_DATA)) { -		debug_info("(%s): ERROR: sinf data is not a PLIST_DATA node!", command); -		return INSTPROXY_E_INVALID_ARG; -	} -	if (metadata && (plist_get_node_type(metadata) != PLIST_DATA)) { -		debug_info("(%s): ERROR: metadata is not a PLIST_DATA node!", command); -		return INSTPROXY_E_INVALID_ARG; -	} - -	if (client->status_updater) { -		return INSTPROXY_E_OP_IN_PROGRESS; -	} - -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; - -	plist_t dict = plist_new_dict(); -	if (sinf && metadata) { -		plist_t client_opts = plist_new_dict(); -		plist_dict_insert_item(client_opts, "ApplicationSINF", plist_copy(sinf)); -		plist_dict_insert_item(client_opts, "iTunesMetadata", plist_copy(metadata)); -		plist_dict_insert_item(dict, "ClientOptions", client_opts); -	} -	plist_dict_insert_item(dict, "Command", plist_new_string(command)); -	plist_dict_insert_item(dict, "PackagePath", plist_new_string(pkg_path)); - -	instproxy_lock(client); -	res = instproxy_error(property_list_service_send_xml_plist(client->parent, dict)); -	instproxy_unlock(client); - -	plist_free(dict); - -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not send plist, error %d", res); -		return res; -	} - -	return instproxy_create_status_updater(client, status_cb, command); -} - -/** - * Install an application on the device. - * - * @param client The connected installation_proxy client - * @param pkg_path Path of the installation package (inside the AFC jail) - * @param sinf PLIST_DATA node holding the package's SINF data or NULL. - * @param metadata PLIST_DATA node holding the packages's Metadata or NULL. - * @param status_cb Callback function for progress and status information. If - *        NULL is passed, this function will run synchronously. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - * - * @note If a callback function is given (async mode), this function returns - *     INSTPROXY_E_SUCCESS immediately if the status updater thread has been - *     created successfully; any error occuring during the operation has to be - *     handled inside the specified callback function. - */ -instproxy_error_t instproxy_install(instproxy_client_t client, const char *pkg_path, plist_t sinf, plist_t metadata, instproxy_status_cb_t status_cb) -{ -	return instproxy_install_or_upgrade(client, pkg_path, sinf, metadata, status_cb, "Install"); -} - -/** - * Upgrade an application on the device. This function is nearly the same as - * instproxy_install; the difference is that the installation progress on the - * device is faster if the application is already installed. - * - * @param client The connected installation_proxy client - * @param pkg_path Path of the installation package (inside the AFC jail) - * @param sinf PLIST_DATA node holding the package's SINF data or NULL. - * @param metadata PLIST_DATA node holding the packages's Metadata or NULL. - * @param status_cb Callback function for progress and status information. If - *        NULL is passed, this function will run synchronously. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - * - * @note If a callback function is given (async mode), this function returns - *     INSTPROXY_E_SUCCESS immediately if the status updater thread has been - *     created successfully; any error occuring during the operation has to be - *     handled inside the specified callback function. - */ -instproxy_error_t instproxy_upgrade(instproxy_client_t client, const char *pkg_path, plist_t sinf, plist_t metadata, instproxy_status_cb_t status_cb) -{ -	return instproxy_install_or_upgrade(client, pkg_path, sinf, metadata, status_cb, "Upgrade"); -} - -/** - * Uninstall an application from the device. - * - * @param client The connected installation proxy client - * @param appid ApplicationIdentifier of the app to uninstall - * @param status_cb Callback function for progress and status information. If - *        NULL is passed, this function will run synchronously. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - * - * @note If a callback function is given (async mode), this function returns - *     INSTPROXY_E_SUCCESS immediately if the status updater thread has been - *     created successfully; any error occuring during the operation has to be - *     handled inside the specified callback function. - */ -instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *appid, instproxy_status_cb_t status_cb) -{ -	if (!client || !client->parent || !appid) { -		return INSTPROXY_E_INVALID_ARG; -	} - -	if (client->status_updater) { -		return INSTPROXY_E_OP_IN_PROGRESS; -	} - -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; -	plist_t dict = plist_new_dict(); -	plist_dict_insert_item(dict, "ApplicationIdentifier", plist_new_string(appid)); -	plist_dict_insert_item(dict, "Command", plist_new_string("Uninstall")); - -	instproxy_lock(client); -	res = instproxy_error(property_list_service_send_xml_plist(client->parent, dict)); -	instproxy_unlock(client); - -	plist_free(dict); - -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not send plist, error %d", res); -		return res; -	} - -	return instproxy_create_status_updater(client, status_cb, "Uninstall"); -} - -/** - * List archived applications. This function runs synchronously. - * - * @see instproxy_archive - * - * @param client The connected installation_proxy client - * @param result Pointer that will be set to a plist containing a PLIST_DICT - *        holding information about the archived applications found. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - */ -instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t *result) -{ -	if (!client || !client->parent || !result) -		return INSTPROXY_E_INVALID_ARG; - -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; - -	plist_t dict = plist_new_dict(); -	plist_dict_insert_item(dict, "Command", plist_new_string("LookupArchives")); - -	instproxy_lock(client); - -	res = instproxy_error(property_list_service_send_xml_plist(client->parent, dict)); -	plist_free(dict); - -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not send plist, error %d", res); -		goto leave_unlock; -	} - -	res = instproxy_error(property_list_service_receive_plist(client->parent, result)); -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not receive plist, error %d", res); -		goto leave_unlock; -	} - -	res = INSTPROXY_E_SUCCESS; - -leave_unlock: -	instproxy_unlock(client); -	return res; -} - -/** - * Archive an application on the device. - * This function tells the device to make an archive of the specified - * application. This results in the device creating a ZIP archive in the - * 'ApplicationArchives' directory and uninstalling the application. - * - * @param client The connected installation proxy client - * @param appid ApplicationIdentifier of the app to archive. - * @param options This is either 0 for default behaviour (make an archive - *        including app/user settings etc. AND uninstall the application), - *        or one or a combination of the following options: - *        INSTPROXY_ARCHIVE_APP_ONLY (1) - *        INSTPROXY_ARCHIVE_SKIP_UNINSTALL (2) - * @param status_cb Callback function for progress and status information. If - *        NULL is passed, this function will run synchronously. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - * - * @note If a callback function is given (async mode), this function returns - *     INSTPROXY_E_SUCCESS immediately if the status updater thread has been - *     created successfully; any error occuring during the operation has to be - *     handled inside the specified callback function. - */ -instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid, uint32_t options, instproxy_status_cb_t status_cb) -{ -	if (!client || !client->parent || !appid) -		return INSTPROXY_E_INVALID_ARG; - -	if (client->status_updater) { -		return INSTPROXY_E_OP_IN_PROGRESS; -	} - -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; - -	plist_t dict = plist_new_dict(); -	plist_dict_insert_item(dict, "ApplicationIdentifier", plist_new_string(appid)); -	if (options > 0) { -		plist_t client_opts = plist_new_dict(); -		if (options & INSTPROXY_ARCHIVE_APP_ONLY) { -			plist_dict_insert_item(client_opts, "ArchiveType", plist_new_string("ApplicationOnly")); -		} -		if (options & INSTPROXY_ARCHIVE_SKIP_UNINSTALL) { -			plist_dict_insert_item(client_opts, "SkipUninstall", plist_new_bool(1)); -		} -		plist_dict_insert_item(dict, "ClientOptions", client_opts); -	} -	plist_dict_insert_item(dict, "Command", plist_new_string("Archive")); - -	instproxy_lock(client); -	res = instproxy_error(property_list_service_send_xml_plist(client->parent, dict)); -	instproxy_unlock(client); - -	plist_free(dict); - -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not send plist, error %d", res); -		return res; -	} -	return instproxy_create_status_updater(client, status_cb, "Archive"); -} - -/** - * Restore a previously archived application on the device. - * This function is the counterpart to instproxy_archive. - * @see instproxy_archive - * - * @param client The connected installation proxy client - * @param appid ApplicationIdentifier of the app to restore. - * @param status_cb Callback function for progress and status information. If - *        NULL is passed, this function will run synchronously. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - * - * @note If a callback function is given (async mode), this function returns - *     INSTPROXY_E_SUCCESS immediately if the status updater thread has been - *     created successfully; any error occuring during the operation has to be - *     handled inside the specified callback function. - */ -instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid, instproxy_status_cb_t status_cb) -{ -	if (!client || !client->parent || !appid) -		return INSTPROXY_E_INVALID_ARG; - -	if (client->status_updater) { -		return INSTPROXY_E_OP_IN_PROGRESS; -	} - -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; - -	plist_t dict = plist_new_dict(); -	plist_dict_insert_item(dict, "ApplicationIdentifier", plist_new_string(appid)); -	plist_dict_insert_item(dict, "Command", plist_new_string("Restore")); - -	instproxy_lock(client); -	res = instproxy_error(property_list_service_send_xml_plist(client->parent, dict)); -	instproxy_unlock(client); - -	plist_free(dict); - -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not send plist, error %d", res); -		return res; -	} -	return instproxy_create_status_updater(client, status_cb, "Restore"); -} - -/** - * Removes a previously archived application from the device. - * This function removes the ZIP archive from the 'ApplicationArchives' - * directory. - * - * @param client The connected installation proxy client - * @param appid ApplicationIdentifier of the archived app to remove. - * @param status_cb Callback function for progress and status information. If - *        NULL is passed, this function will run synchronously. - * - * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if - *     an error occured. - * - * @note If a callback function is given (async mode), this function returns - *     INSTPROXY_E_SUCCESS immediately if the status updater thread has been - *     created successfully; any error occuring during the operation has to be - *     handled inside the specified callback function. - */ -instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, instproxy_status_cb_t status_cb) -{ -	if (!client || !client->parent || !appid) -		return INSTPROXY_E_INVALID_ARG; - -	if (client->status_updater) { -		return INSTPROXY_E_OP_IN_PROGRESS; -	} - -	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; - -	plist_t dict = plist_new_dict(); -	plist_dict_insert_item(dict, "ApplicationIdentifier", plist_new_string(appid)); -	plist_dict_insert_item(dict, "Command", plist_new_string("RemoveArchive")); - -	instproxy_lock(client); -	res = instproxy_error(property_list_service_send_xml_plist(client->parent, dict)); -	instproxy_unlock(client); - -	plist_free(dict); - -	if (res != INSTPROXY_E_SUCCESS) { -		debug_info("could not send plist, error %d", res); -		return res; -	} -	return instproxy_create_status_updater(client, status_cb, "RemoveArchive"); -} - | 
