summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dev/Makefile.am7
-rw-r--r--dev/filerelaytest.c108
-rw-r--r--include/Makefile.am1
-rw-r--r--include/libiphone/file_relay.h56
-rw-r--r--src/Makefile.am1
-rw-r--r--src/file_relay.c197
-rw-r--r--src/file_relay.h40
7 files changed, 409 insertions, 1 deletions
diff --git a/dev/Makefile.am b/dev/Makefile.am
index b71c212..1ca15e5 100644
--- a/dev/Makefile.am
+++ b/dev/Makefile.am
@@ -4,7 +4,7 @@ AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_C
4AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) 4AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS)
5 5
6if ENABLE_DEVTOOLS 6if ENABLE_DEVTOOLS
7noinst_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneenterrecovery 7noinst_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneenterrecovery filerelaytest
8 8
9iphoneclient_SOURCES = iphoneclient.c 9iphoneclient_SOURCES = iphoneclient.c
10iphoneclient_LDADD = ../src/libiphone.la 10iphoneclient_LDADD = ../src/libiphone.la
@@ -29,6 +29,11 @@ iphoneenterrecovery_CFLAGS = $(AM_CFLAGS)
29iphoneenterrecovery_LDFLAGS = $(AM_LDFLAGS) 29iphoneenterrecovery_LDFLAGS = $(AM_LDFLAGS)
30iphoneenterrecovery_LDADD = ../src/libiphone.la 30iphoneenterrecovery_LDADD = ../src/libiphone.la
31 31
32filerelaytest_SOURCES = filerelaytest.c
33filerelaytest_CFLAGS = $(AM_CFLAGS)
34filerelaytest_LDFLAGS = $(AM_LDFLAGS)
35filerelaytest_LDADD = ../src/libiphone.la
36
32endif # ENABLE_DEVTOOLS 37endif # ENABLE_DEVTOOLS
33 38
34EXTRA_DIST = iphoneclient.c lckdclient.c afccheck.c msyncclient.c iphoneenterrecovery.c 39EXTRA_DIST = iphoneclient.c lckdclient.c afccheck.c msyncclient.c iphoneenterrecovery.c
diff --git a/dev/filerelaytest.c b/dev/filerelaytest.c
new file mode 100644
index 0000000..f7e0d07
--- /dev/null
+++ b/dev/filerelaytest.c
@@ -0,0 +1,108 @@
1/*
2 * filerelaytest.c
3 * Simple Test program showing the usage of the file_relay interface.
4 *
5 * Copyright (c) 2010 Nikias Bassen All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
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
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#include <stdio.h>
22#include <libiphone/libiphone.h>
23#include <libiphone/lockdown.h>
24#include <libiphone/file_relay.h>
25
26int main(int argc, char **argv)
27{
28 iphone_device_t dev = NULL;
29 lockdownd_client_t client = NULL;
30 file_relay_client_t frc = NULL;
31
32 if (iphone_device_new(&dev, NULL) != IPHONE_E_SUCCESS) {
33 printf("no device connected?!\n");
34 goto leave_cleanup;
35 }
36
37 printf("connecting...\n");
38 if (lockdownd_client_new_with_handshake(dev, &client, NULL) != LOCKDOWN_E_SUCCESS) {
39 printf("could not connect to lockdownd!\n");
40 goto leave_cleanup;
41 }
42
43 uint16_t port = 0;
44 if (lockdownd_start_service(client, "com.apple.mobile.file_relay", &port) != LOCKDOWN_E_SUCCESS) {
45 printf("could not start file_relay service!\n");
46 goto leave_cleanup;
47 }
48
49 if (client) {
50 lockdownd_client_free(client);
51 client = NULL;
52 }
53
54 if (file_relay_client_new(dev, port, &frc) != FILE_RELAY_E_SUCCESS) {
55 printf("could not connect to file_relay service!\n");
56 goto leave_cleanup;
57 }
58
59 iphone_connection_t dump = NULL;
60 const char *sources[] = {"AppleSupport", "Network", "VPN", "WiFi", "UserDatabases", "CrashReporter", "tmp", "SystemConfiguration", NULL};
61
62 printf("Requesting");
63 int i = 0;
64 while (sources[i]) {
65 printf(" %s", sources[i]);
66 i++;
67 }
68 printf("\n");
69
70 if (file_relay_request_sources(frc, sources, &dump) != FILE_RELAY_E_SUCCESS) {
71 printf("could not get sources\n");
72 goto leave_cleanup;
73 }
74
75 if (!dump) {
76 printf("did not get connection!\n");
77 goto leave_cleanup;
78 }
79
80 uint32_t cnt = 0;
81 uint32_t len = 0;
82 char buf[4096];
83 FILE *f = fopen("dump.cpio.gz", "w");
84 setbuf(stdout, NULL);
85 printf("receiving ");
86 while (iphone_connection_receive(dump, buf, 4096, &len) == IPHONE_E_SUCCESS) {
87 fwrite(buf, 1, len, f);
88 cnt += len;
89 printf(".", len);
90 len = 0;
91 }
92 printf("\n");
93 fclose(f);
94 printf("total size received: %d\n", cnt);
95
96leave_cleanup:
97 if (frc) {
98 file_relay_client_free(frc);
99 }
100 if (client) {
101 lockdownd_client_free(client);
102 }
103 if (dev) {
104 iphone_device_free(dev);
105 }
106
107 return 0;
108}
diff --git a/include/Makefile.am b/include/Makefile.am
index a4246cf..aced258 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,6 +1,7 @@
1nobase_include_HEADERS = libiphone/libiphone.h \ 1nobase_include_HEADERS = libiphone/libiphone.h \
2 libiphone/lockdown.h \ 2 libiphone/lockdown.h \
3 libiphone/afc.h \ 3 libiphone/afc.h \
4 libiphone/file_relay.h \
4 libiphone/notification_proxy.h \ 5 libiphone/notification_proxy.h \
5 libiphone/installation_proxy.h \ 6 libiphone/installation_proxy.h \
6 libiphone/sbservices.h \ 7 libiphone/sbservices.h \
diff --git a/include/libiphone/file_relay.h b/include/libiphone/file_relay.h
new file mode 100644
index 0000000..672f1bd
--- /dev/null
+++ b/include/libiphone/file_relay.h
@@ -0,0 +1,56 @@
1/**
2 * @file libiphone/file_relay.h
3 * @brief file_relay Implementation
4 * \internal
5 *
6 * Copyright (c) 2010 Nikias Bassen All Rights Reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef IFILE_RELAY_H
24#define IFILE_RELAY_H
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#include <libiphone/libiphone.h>
31
32/* Error Codes */
33#define FILE_RELAY_E_SUCCESS 0
34#define FILE_RELAY_E_INVALID_ARG -1
35#define FILE_RELAY_E_PLIST_ERROR -2
36#define FILE_RELAY_E_MUX_ERROR -3
37#define FILE_RELAY_E_INVALID_SOURCE -4
38#define FILE_RELAY_E_STAGING_EMPTY -5
39
40#define FILE_RELAY_E_UNKNOWN_ERROR -256
41
42typedef int16_t file_relay_error_t;
43
44struct file_relay_client_int;
45typedef struct file_relay_client_int *file_relay_client_t;
46
47file_relay_error_t file_relay_client_new(iphone_device_t device, uint16_t port, file_relay_client_t *client);
48file_relay_error_t file_relay_client_free(file_relay_client_t client);
49
50file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, iphone_connection_t *connection);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 6c29020..93cfbaf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,7 @@ libiphone_la_SOURCES = iphone.c iphone.h \
11 device_link_service.c device_link_service.h\ 11 device_link_service.c device_link_service.h\
12 lockdown.c lockdown.h\ 12 lockdown.c lockdown.h\
13 afc.c afc.h\ 13 afc.c afc.h\
14 file_relay.c file_relay.h\
14 notification_proxy.c notification_proxy.h\ 15 notification_proxy.c notification_proxy.h\
15 installation_proxy.c installation_proxy.h\ 16 installation_proxy.c installation_proxy.h\
16 sbservices.c sbservices.h\ 17 sbservices.c sbservices.h\
diff --git a/src/file_relay.c b/src/file_relay.c
new file mode 100644
index 0000000..f0e91f7
--- /dev/null
+++ b/src/file_relay.c
@@ -0,0 +1,197 @@
1 /*
2 * file_relay.c
3 * file_relay service implementation.
4 *
5 * Copyright (c) 2010 Nikias Bassen, All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
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
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#include <string.h>
22#include <stdlib.h>
23#include "file_relay.h"
24#include "property_list_service.h"
25#include "debug.h"
26
27/**
28 * Creates a new file_relay client.
29 *
30 * @param device The device to connect to.
31 * @param port Port on device to connect to.
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(iphone_device_t device, uint16_t port, file_relay_client_t *client)
40{
41 if (!device || port == 0 || !client || *client) {
42 return FILE_RELAY_E_INVALID_ARG;
43 }
44
45 property_list_service_client_t plistclient = NULL;
46 if (property_list_service_client_new(device, port, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
47 return FILE_RELAY_E_MUX_ERROR;
48 }
49
50 /* create client object */
51 file_relay_client_t client_loc = (file_relay_client_t) malloc(sizeof(struct file_relay_client_int));
52 client_loc->parent = plistclient;
53
54 /* all done, return success */
55 *client = client_loc;
56 return FILE_RELAY_E_SUCCESS;
57}
58
59/**
60 * Frees a file_relay client.
61 *
62 * @param client The file_relay_client_t to free.
63 *
64 * @return FILE_RELAY_E_SUCCESS on success,
65 * FILE_RELAY_E_INVALID_ARG when one of client or client->parent
66 * is invalid, or FILE_RELAY_E_UNKNOWN_ERROR when the was an error
67 * freeing the parent property_list_service client.
68 */
69file_relay_error_t file_relay_client_free(file_relay_client_t client)
70{
71 if (!client)
72 return FILE_RELAY_E_INVALID_ARG;
73
74 if (property_list_service_client_free(client->parent) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
75 return FILE_RELAY_E_UNKNOWN_ERROR;
76 }
77 return FILE_RELAY_E_SUCCESS;
78}
79
80/**
81 * Request data for the given sources.
82 *
83 * @param client The connected file_relay client.
84 * @param sources A NULL-terminated list of sources to retrieve.
85 * Valid sources are:
86 * - AppleSupport
87 * - Network
88 * - VPN
89 * - WiFi
90 * - UserDatabases
91 * - CrashReporter
92 * - tmp
93 * - SystemConfiguration
94 * @param connection The connection that has to be used for receiving the
95 * data using iphone_connection_receive(). The connection will be closed
96 * automatically by the device, but use file_relay_client_free() to clean
97 * up properly.
98 *
99 * @note WARNING: Don't call this function without reading the data afterwards.
100 * A directory mobile_file_relay.XXXX used for creating the archive will
101 * remain in the /tmp directory otherwise.
102 *
103 * @return FILE_RELAY_E_SUCCESS on succes, FILE_RELAY_E_INVALID_ARG when one or
104 * more parameters are invalid, FILE_RELAY_E_MUX_ERROR if a communication
105 * error occurs, FILE_RELAY_E_PLIST_ERROR when the received result is NULL
106 * or is not a valid plist, FILE_RELAY_E_INVALID_SOURCE if one or more
107 * sources are invalid, FILE_RELAY_E_STAGING_EMPTY if no data is available
108 * for the given sources, or FILE_RELAY_E_UNKNOWN_ERROR otherwise.
109 */
110file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, iphone_connection_t *connection)
111{
112 if (!client || !client->parent || !sources || !sources[0]) {
113 return FILE_RELAY_E_INVALID_ARG;
114 }
115 *connection = NULL;
116 file_relay_error_t err = FILE_RELAY_E_UNKNOWN_ERROR;
117 /* set up request plist */
118 plist_t array = plist_new_array();
119 int i = 0;
120 while (sources[i]) {
121 plist_array_append_item(array, plist_new_string(sources[i]));
122 i++;
123 }
124 plist_t dict = plist_new_dict();
125 plist_dict_insert_item(dict, "Sources", array);
126
127 if (property_list_service_send_xml_plist(client->parent, dict) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
128 debug_info("ERROR: Could not send request to device!");
129 err = FILE_RELAY_E_MUX_ERROR;
130 goto leave;
131 }
132 plist_free(dict);
133
134 dict = NULL;
135 if (property_list_service_receive_plist_with_timeout(client->parent, &dict, 60000) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
136 debug_info("ERROR: Could not receive answer from device!");
137 err = FILE_RELAY_E_MUX_ERROR;
138 goto leave;
139 }
140
141 if (!dict) {
142 debug_info("ERROR: Did not receive any plist!");
143 err = FILE_RELAY_E_PLIST_ERROR;
144 goto leave;
145 }
146
147 plist_t error = plist_dict_get_item(dict, "Error");
148 if (error) {
149 char *errmsg = NULL;
150 plist_get_string_val(error, &errmsg);
151 if (errmsg) {
152 if (!strcmp(errmsg, "InvalidSource")) {
153 debug_info("ERROR: One or more given sources are invalid!");
154 err = FILE_RELAY_E_INVALID_SOURCE;
155 } else if (!strcmp(errmsg, "StagingEmpty")) {
156 debug_info("ERROR: StagingEmpty - No data available!");
157 err = FILE_RELAY_E_STAGING_EMPTY;
158 } else {
159 debug_info("ERROR: Unknown error '%s'", errmsg);
160 }
161 free(errmsg);
162 } else {
163 debug_info("ERROR: Could not get error message!");
164 }
165 goto leave;
166 }
167
168 plist_t status = plist_dict_get_item(dict, "Status");
169 if (!status) {
170 debug_info("ERROR: Unexpected plist received!");
171 debug_plist(dict);
172 err = FILE_RELAY_E_PLIST_ERROR;
173 goto leave;
174 }
175
176 char *ack = NULL;
177 plist_get_string_val(status, &ack);
178 if (!ack) {
179 debug_info("ERROR: Could not get 'Acknowledged' string!");
180 goto leave;
181 }
182
183 if (strcmp(ack, "Acknowledged")) {
184 debug_info("ERROR: Did not receive 'Acknowledged' but '%s'", ack);
185 goto leave;
186 }
187 free(ack);
188 err = FILE_RELAY_E_SUCCESS;
189
190 *connection = client->parent->connection;
191
192leave:
193 if (dict) {
194 plist_free(dict);
195 }
196 return err;
197}
diff --git a/src/file_relay.h b/src/file_relay.h
new file mode 100644
index 0000000..9b2488c
--- /dev/null
+++ b/src/file_relay.h
@@ -0,0 +1,40 @@
1 /*
2 * file_relay.h
3 * Definitions for the file_relay service
4 *
5 * Copyright (c) 2010 Nikias Bassen, All Rights Reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
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
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#ifndef FILE_RELAY_H
22#define FILE_RELAY_H
23
24#include "libiphone/file_relay.h"
25#include "property_list_service.h"
26
27/* Error Codes */
28#define FILE_RELAY_E_SUCCESS 0
29#define FILE_RELAY_E_INVALID_ARG -1
30#define FILE_RELAY_E_PLIST_ERROR -2
31#define FILE_RELAY_E_MUX_ERROR -3
32
33#define FILE_RELAY_E_UNKNOWN_ERROR -256
34
35
36struct file_relay_client_int {
37 property_list_service_client_t parent;
38};
39
40#endif