summaryrefslogtreecommitdiffstats
path: root/src/file_relay.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/file_relay.c')
-rw-r--r--src/file_relay.c103
1 files changed, 35 insertions, 68 deletions
diff --git a/src/file_relay.c b/src/file_relay.c
index 680e28d..fbe7cbf 100644
--- a/src/file_relay.c
+++ b/src/file_relay.c
@@ -1,49 +1,41 @@
1 /* 1/*
2 * file_relay.c 2 * file_relay.c
3 * com.apple.mobile.file_relay service implementation. 3 * com.apple.mobile.file_relay service implementation.
4 * 4 *
5 * Copyright (c) 2010 Nikias Bassen, All Rights Reserved. 5 * Copyright (c) 2010 Nikias Bassen, All Rights Reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details. 15 * Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public 17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software 18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
21#include <string.h> 25#include <string.h>
22#include <stdlib.h> 26#include <stdlib.h>
23#include "file_relay.h" 27#include "file_relay.h"
24#include "property_list_service.h" 28#include "property_list_service.h"
25#include "debug.h" 29#include "common/debug.h"
26 30
27/** 31file_relay_error_t file_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, file_relay_client_t *client)
28 * Connects to the file_relay service on the specified device.
29 *
30 * @param device The device to connect to.
31 * @param port Destination port (usually given by lockdownd_start_service).
32 * @param client Reference that will point to a newly allocated
33 * file_relay_client_t upon successful return.
34 *
35 * @return FILE_RELAY_E_SUCCESS on success,
36 * FILE_RELAY_E_INVALID_ARG when one of the parameters is invalid,
37 * or FILE_RELAY_E_MUX_ERROR when the connection failed.
38 */
39file_relay_error_t file_relay_client_new(idevice_t device, uint16_t port, file_relay_client_t *client)
40{ 32{
41 if (!device || port == 0 || !client || *client) { 33 if (!device || !service || service->port == 0 || !client || *client) {
42 return FILE_RELAY_E_INVALID_ARG; 34 return FILE_RELAY_E_INVALID_ARG;
43 } 35 }
44 36
45 property_list_service_client_t plistclient = NULL; 37 property_list_service_client_t plistclient = NULL;
46 if (property_list_service_client_new(device, port, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) { 38 if (property_list_service_client_new(device, service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
47 return FILE_RELAY_E_MUX_ERROR; 39 return FILE_RELAY_E_MUX_ERROR;
48 } 40 }
49 41
@@ -56,17 +48,13 @@ file_relay_error_t file_relay_client_new(idevice_t device, uint16_t port, file_r
56 return FILE_RELAY_E_SUCCESS; 48 return FILE_RELAY_E_SUCCESS;
57} 49}
58 50
59/** 51file_relay_error_t file_relay_client_start_service(idevice_t device, file_relay_client_t * client, const char* label)
60 * Disconnects a file_relay client from the device and frees up the file_relay 52{
61 * client data. 53 file_relay_error_t err = FILE_RELAY_E_UNKNOWN_ERROR;
62 * 54 service_client_factory_start_service(device, FILE_RELAY_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(file_relay_client_new), &err);
63 * @param client The file_relay client to disconnect and free. 55 return err;
64 * 56}
65 * @return FILE_RELAY_E_SUCCESS on success, 57
66 * FILE_RELAY_E_INVALID_ARG when one of client or client->parent
67 * is invalid, or FILE_RELAY_E_UNKNOWN_ERROR when the was an error
68 * freeing the parent property_list_service client.
69 */
70file_relay_error_t file_relay_client_free(file_relay_client_t client) 58file_relay_error_t file_relay_client_free(file_relay_client_t client)
71{ 59{
72 if (!client) 60 if (!client)
@@ -75,40 +63,11 @@ file_relay_error_t file_relay_client_free(file_relay_client_t client)
75 if (property_list_service_client_free(client->parent) != PROPERTY_LIST_SERVICE_E_SUCCESS) { 63 if (property_list_service_client_free(client->parent) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
76 return FILE_RELAY_E_UNKNOWN_ERROR; 64 return FILE_RELAY_E_UNKNOWN_ERROR;
77 } 65 }
66 free(client);
78 return FILE_RELAY_E_SUCCESS; 67 return FILE_RELAY_E_SUCCESS;
79} 68}
80 69
81/** 70file_relay_error_t file_relay_request_sources_timeout(file_relay_client_t client, const char **sources, idevice_connection_t *connection, unsigned int timeout)
82 * Request data for the given sources.
83 *
84 * @param client The connected file_relay client.
85 * @param sources A NULL-terminated list of sources to retrieve.
86 * Valid sources are:
87 * - AppleSupport
88 * - Network
89 * - VPN
90 * - WiFi
91 * - UserDatabases
92 * - CrashReporter
93 * - tmp
94 * - SystemConfiguration
95 * @param connection The connection that has to be used for receiving the
96 * data using idevice_connection_receive(). The connection will be closed
97 * automatically by the device, but use file_relay_client_free() to clean
98 * up properly.
99 *
100 * @note WARNING: Don't call this function without reading the data afterwards.
101 * A directory mobile_file_relay.XXXX used for creating the archive will
102 * remain in the /tmp directory otherwise.
103 *
104 * @return FILE_RELAY_E_SUCCESS on succes, FILE_RELAY_E_INVALID_ARG when one or
105 * more parameters are invalid, FILE_RELAY_E_MUX_ERROR if a communication
106 * error occurs, FILE_RELAY_E_PLIST_ERROR when the received result is NULL
107 * or is not a valid plist, FILE_RELAY_E_INVALID_SOURCE if one or more
108 * sources are invalid, FILE_RELAY_E_STAGING_EMPTY if no data is available
109 * for the given sources, or FILE_RELAY_E_UNKNOWN_ERROR otherwise.
110 */
111file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, idevice_connection_t *connection)
112{ 71{
113 if (!client || !client->parent || !sources || !sources[0]) { 72 if (!client || !client->parent || !sources || !sources[0]) {
114 return FILE_RELAY_E_INVALID_ARG; 73 return FILE_RELAY_E_INVALID_ARG;
@@ -121,9 +80,9 @@ file_relay_error_t file_relay_request_sources(file_relay_client_t client, const
121 while (sources[i]) { 80 while (sources[i]) {
122 plist_array_append_item(array, plist_new_string(sources[i])); 81 plist_array_append_item(array, plist_new_string(sources[i]));
123 i++; 82 i++;
124 } 83 }
125 plist_t dict = plist_new_dict(); 84 plist_t dict = plist_new_dict();
126 plist_dict_insert_item(dict, "Sources", array); 85 plist_dict_set_item(dict, "Sources", array);
127 86
128 if (property_list_service_send_xml_plist(client->parent, dict) != PROPERTY_LIST_SERVICE_E_SUCCESS) { 87 if (property_list_service_send_xml_plist(client->parent, dict) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
129 debug_info("ERROR: Could not send request to device!"); 88 debug_info("ERROR: Could not send request to device!");
@@ -133,7 +92,7 @@ file_relay_error_t file_relay_request_sources(file_relay_client_t client, const
133 plist_free(dict); 92 plist_free(dict);
134 93
135 dict = NULL; 94 dict = NULL;
136 if (property_list_service_receive_plist_with_timeout(client->parent, &dict, 60000) != PROPERTY_LIST_SERVICE_E_SUCCESS) { 95 if (property_list_service_receive_plist_with_timeout(client->parent, &dict, timeout) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
137 debug_info("ERROR: Could not receive answer from device!"); 96 debug_info("ERROR: Could not receive answer from device!");
138 err = FILE_RELAY_E_MUX_ERROR; 97 err = FILE_RELAY_E_MUX_ERROR;
139 goto leave; 98 goto leave;
@@ -156,6 +115,9 @@ file_relay_error_t file_relay_request_sources(file_relay_client_t client, const
156 } else if (!strcmp(errmsg, "StagingEmpty")) { 115 } else if (!strcmp(errmsg, "StagingEmpty")) {
157 debug_info("ERROR: StagingEmpty - No data available!"); 116 debug_info("ERROR: StagingEmpty - No data available!");
158 err = FILE_RELAY_E_STAGING_EMPTY; 117 err = FILE_RELAY_E_STAGING_EMPTY;
118 } else if (!strcmp(errmsg, "PermissionDenied")) {
119 debug_info("ERROR: Permission denied.");
120 err = FILE_RELAY_E_PERMISSION_DENIED;
159 } else { 121 } else {
160 debug_info("ERROR: Unknown error '%s'", errmsg); 122 debug_info("ERROR: Unknown error '%s'", errmsg);
161 } 123 }
@@ -181,14 +143,14 @@ file_relay_error_t file_relay_request_sources(file_relay_client_t client, const
181 goto leave; 143 goto leave;
182 } 144 }
183 145
184 if (strcmp(ack, "Acknowledged")) { 146 if (strcmp(ack, "Acknowledged") != 0) {
185 debug_info("ERROR: Did not receive 'Acknowledged' but '%s'", ack); 147 debug_info("ERROR: Did not receive 'Acknowledged' but '%s'", ack);
186 goto leave; 148 goto leave;
187 } 149 }
188 free(ack); 150 free(ack);
189 err = FILE_RELAY_E_SUCCESS; 151 err = FILE_RELAY_E_SUCCESS;
190 152
191 *connection = client->parent->connection; 153 *connection = client->parent->parent->connection;
192 154
193leave: 155leave:
194 if (dict) { 156 if (dict) {
@@ -196,3 +158,8 @@ leave:
196 } 158 }
197 return err; 159 return err;
198} 160}
161
162file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, idevice_connection_t *connection)
163{
164 return file_relay_request_sources_timeout(client, sources, connection, 60000);
165}