summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mobilebackup.c90
1 files changed, 69 insertions, 21 deletions
diff --git a/src/mobilebackup.c b/src/mobilebackup.c
index 0005284..234ad8f 100644
--- a/src/mobilebackup.c
+++ b/src/mobilebackup.c
@@ -152,6 +152,72 @@ mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist_t pli
152} 152}
153 153
154/** 154/**
155 * Receives a plist from the device and checks if the value for the
156 * BackupMessageTypeKey matches the value passed in the message parameter.
157 *
158 * @param client The connected MobileBackup client to use.
159 * @param message The expected message to check.
160 * @param result Pointer to a plist_t that will be set to the received plist
161 * for further processing. The caller has to free it using plist_free().
162 * Note that it will be set to NULL if the operation itself fails due to
163 * a communication or plist error.
164 * If this parameter is NULL, it will be ignored.
165 *
166 * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if
167 * client or message is invalid, MOBILEBACKUP_E_REPLY_NOT_OK if the
168 * expected message could not be received, MOBILEBACKUP_E_PLIST_ERROR if
169 * the received message is not a valid backup message plist (i.e. the
170 * BackupMessageTypeKey is not present), or MOBILEBACKUP_E_MUX_ERROR
171 * if a communication error occurs.
172 */
173static mobilebackup_error_t mobilebackup_receive_message(mobilebackup_client_t client, const char *message, plist_t *result)
174{
175 if (!client || !client->parent || !message)
176 return MOBILEBACKUP_E_INVALID_ARG;
177
178 if (result)
179 *result = NULL;
180 mobilebackup_error_t err;
181
182 plist_t dict = NULL;
183
184 /* receive DLMessageProcessMessage */
185 err = mobilebackup_error(device_link_service_receive_process_message(client->parent, &dict));
186 if (err != MOBILEBACKUP_E_SUCCESS) {
187 goto leave;
188 }
189
190 plist_t node = plist_dict_get_item(dict, "BackupMessageTypeKey");
191 if (!node) {
192 debug_info("ERROR: BackupMessageTypeKey not found in plist!");
193 err = MOBILEBACKUP_E_PLIST_ERROR;
194 goto leave;
195 }
196
197 char *str = NULL;
198 plist_get_string_val(node, &str);
199 if (str && (strcmp(str, message) == 0)) {
200 err = MOBILEBACKUP_E_SUCCESS;
201 } else {
202 debug_info("ERROR: BackupMessageTypeKey value does not match '%s'!", message);
203 err = MOBILEBACKUP_E_REPLY_NOT_OK;
204 }
205 if (str)
206 free(str);
207
208 if (result) {
209 *result = dict;
210 dict = NULL;
211 }
212leave:
213 if (dict) {
214 plist_free(dict);
215 }
216
217 return err;
218}
219
220/**
155 * Request a backup from the connected device. 221 * Request a backup from the connected device.
156 * 222 *
157 * @param client The connected MobileBackup client to use. 223 * @param client The connected MobileBackup client to use.
@@ -196,33 +262,15 @@ mobilebackup_error_t mobilebackup_request_backup(mobilebackup_client_t client, p
196 } 262 }
197 263
198 /* now receive and hopefully get a BackupMessageBackupReplyOK */ 264 /* now receive and hopefully get a BackupMessageBackupReplyOK */
199 err = mobilebackup_error(device_link_service_receive_process_message(client->parent, &dict)); 265 err = mobilebackup_receive_message(client, "BackupMessageBackupReplyOK", &dict);
200 if (err != MOBILEBACKUP_E_SUCCESS) { 266 if (err != MOBILEBACKUP_E_SUCCESS) {
201 debug_info("ERROR: Could not receive BackupReplyOK message (%d)!", err); 267 debug_info("ERROR: Could not receive BackupReplyOK message (%d)!", err);
202 goto leave; 268 goto leave;
203 } 269 }
204 270
205 plist_t node = plist_dict_get_item(dict, "BackupMessageTypeKey"); 271 plist_t node = plist_dict_get_item(dict, "BackupProtocolVersion");
206 if (!node) {
207 debug_info("ERROR: BackupMessageTypeKey not found in BackupReplyOK message!");
208 err = MOBILEBACKUP_E_PLIST_ERROR;
209 goto leave;
210 }
211
212 char *str = NULL;
213 plist_get_string_val(node, &str);
214 if (!str || (strcmp(str, "BackupMessageBackupReplyOK") != 0)) {
215 debug_info("ERROR: BackupMessageTypeKey value does not match 'BackupMessageBackupReplyOK'");
216 err = MOBILEBACKUP_E_REPLY_NOT_OK;
217 if (str)
218 free(str);
219 goto leave;
220 }
221 free(str);
222 str = NULL;
223
224 node = plist_dict_get_item(dict, "BackupProtocolVersion");
225 if (node) { 272 if (node) {
273 char *str = NULL;
226 plist_get_string_val(node, &str); 274 plist_get_string_val(node, &str);
227 if (str) { 275 if (str) {
228 if (strcmp(str, proto_version) != 0) { 276 if (strcmp(str, proto_version) != 0) {