From 96101a1231a4ddfeb40fd738a24e108a3a904048 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Thu, 28 Jan 2010 22:18:41 +0100 Subject: Global renames due to project rename to libimobiledevice --- Makefile.am | 2 +- README | 11 +- configure.ac | 6 +- dev/Makefile.am | 24 +- dev/afccheck.c | 24 +- dev/filerelaytest.c | 16 +- dev/ideviceclient.c | 252 +++++++ dev/ideviceenterrecovery.c | 93 +++ dev/iphoneclient.c | 252 ------- dev/iphoneenterrecovery.c | 93 --- dev/lckdclient.c | 18 +- dev/msync.py | 4 +- dev/msyncclient.c | 20 +- include/Makefile.am | 18 +- include/libimobiledevice/afc.h | 117 ++++ include/libimobiledevice/file_relay.h | 56 ++ include/libimobiledevice/installation_proxy.h | 72 ++ include/libimobiledevice/libimobiledevice.h | 102 +++ include/libimobiledevice/lockdown.h | 99 +++ include/libimobiledevice/mobilebackup.h | 55 ++ include/libimobiledevice/mobilesync.h | 55 ++ include/libimobiledevice/notification_proxy.h | 88 +++ include/libimobiledevice/sbservices.h | 56 ++ include/libiphone/afc.h | 117 ---- include/libiphone/file_relay.h | 56 -- include/libiphone/installation_proxy.h | 72 -- include/libiphone/libiphone.h | 102 --- include/libiphone/lockdown.h | 99 --- include/libiphone/mobilebackup.h | 55 -- include/libiphone/mobilesync.h | 55 -- include/libiphone/notification_proxy.h | 88 --- include/libiphone/sbservices.h | 56 -- libimobiledevice-1.0.pc.in | 12 + libiphone-1.0.pc.in | 12 - src/Makefile.am | 4 +- src/afc.c | 34 +- src/afc.h | 4 +- src/debug.c | 4 +- src/device_link_service.c | 2 +- src/device_link_service.h | 2 +- src/file_relay.c | 6 +- src/file_relay.h | 2 +- src/idevice.c | 618 +++++++++++++++++ src/idevice.h | 54 ++ src/installation_proxy.c | 2 +- src/installation_proxy.h | 2 +- src/iphone.c | 618 ----------------- src/iphone.h | 54 -- src/lockdown.c | 28 +- src/lockdown.h | 2 +- src/mobilebackup.c | 6 +- src/mobilebackup.h | 2 +- src/mobilesync.c | 6 +- src/mobilesync.h | 2 +- src/notification_proxy.c | 6 +- src/notification_proxy.h | 2 +- src/property_list_service.c | 34 +- src/property_list_service.h | 6 +- src/sbservices.c | 2 +- src/sbservices.h | 2 +- src/userpref.c | 66 +- swig/Makefile.am | 32 +- swig/imobiledevice.i | 220 ++++++ swig/iphone.i | 220 ------ tools/Makefile.am | 34 +- tools/idevice_id.c | 107 +++ tools/idevicebackup.c | 953 ++++++++++++++++++++++++++ tools/ideviceinfo.c | 336 +++++++++ tools/idevicesyslog.c | 165 +++++ tools/iphone_id.c | 107 --- tools/iphonebackup.c | 953 -------------------------- tools/iphoneinfo.c | 336 --------- tools/iphonesyslog.c | 165 ----- 73 files changed, 3729 insertions(+), 3726 deletions(-) create mode 100644 dev/ideviceclient.c create mode 100644 dev/ideviceenterrecovery.c delete mode 100644 dev/iphoneclient.c delete mode 100644 dev/iphoneenterrecovery.c create mode 100644 include/libimobiledevice/afc.h create mode 100644 include/libimobiledevice/file_relay.h create mode 100644 include/libimobiledevice/installation_proxy.h create mode 100644 include/libimobiledevice/libimobiledevice.h create mode 100644 include/libimobiledevice/lockdown.h create mode 100644 include/libimobiledevice/mobilebackup.h create mode 100644 include/libimobiledevice/mobilesync.h create mode 100644 include/libimobiledevice/notification_proxy.h create mode 100644 include/libimobiledevice/sbservices.h delete mode 100644 include/libiphone/afc.h delete mode 100644 include/libiphone/file_relay.h delete mode 100644 include/libiphone/installation_proxy.h delete mode 100644 include/libiphone/libiphone.h delete mode 100644 include/libiphone/lockdown.h delete mode 100644 include/libiphone/mobilebackup.h delete mode 100644 include/libiphone/mobilesync.h delete mode 100644 include/libiphone/notification_proxy.h delete mode 100644 include/libiphone/sbservices.h create mode 100644 libimobiledevice-1.0.pc.in delete mode 100644 libiphone-1.0.pc.in create mode 100644 src/idevice.c create mode 100644 src/idevice.h delete mode 100644 src/iphone.c delete mode 100644 src/iphone.h create mode 100644 swig/imobiledevice.i delete mode 100644 swig/iphone.i create mode 100644 tools/idevice_id.c create mode 100644 tools/idevicebackup.c create mode 100644 tools/ideviceinfo.c create mode 100644 tools/idevicesyslog.c delete mode 100644 tools/iphone_id.c delete mode 100644 tools/iphonebackup.c delete mode 100644 tools/iphoneinfo.c delete mode 100644 tools/iphonesyslog.c diff --git a/Makefile.am b/Makefile.am index 04358f9..586a02e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS = src include fdi swig dev tools DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libiphone-1.0.pc +pkgconfig_DATA = libimobiledevice-1.0.pc EXTRA_DIST= docs diff --git a/README b/README index e25c8c1..46932b2 100644 --- a/README +++ b/README @@ -42,6 +42,9 @@ On Ubuntu/Debian, you can do: Who/What/Where? =============== +Home: + http://www.libimobiledevice.org/ + Wiki: http://matt.colyer.name/projects/iphone-linux/ @@ -57,10 +60,10 @@ Mailing List: Credits ======= -Apple, iPhone, iPod and iPod Touch are trademarks of Apple Inc. -libiphone is an independent software library and has not been authorized, -sponsored, or otherwise approved by Apple Inc. +Apple, iPhone, iPod, and iPod Touch are trademarks of Apple Inc. +libimobiledevice is an independent software library and has not been +authorized, sponsored, or otherwise approved by Apple Inc. README Updated on: - 2010-01-22 + 2010-01-28 diff --git a/configure.ac b/configure.ac index bb5634c..a4f68f7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT(libiphone, 0.9.6, nospam@nowhere.com) +AC_INIT(libimobiledevice, 0.9.7, nospam@nowhere.com) AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES]) AC_CONFIG_SRCDIR([src/]) @@ -27,7 +27,7 @@ PKG_CHECK_MODULES(libgnutls, gnutls >= 1.6.3 ) PKG_CHECK_MODULES(libtasn1, libtasn1 >= 1.1) PKG_CHECK_MODULES(libplist, libplist >= 0.15) PKG_CHECK_MODULES(libplistmm, libplist++ >= 0.15) -AC_CHECK_LIB(gcrypt, gcry_control, [AC_SUBST(libgcrypt_LIBS,[-lgcrypt])], ["libgcrypt is required to build libiphone"]) +AC_CHECK_LIB(gcrypt, gcry_control, [AC_SUBST(libgcrypt_LIBS,[-lgcrypt])], ["libgcrypt is required to build libimobiledevice"]) # Checks for header files. AC_HEADER_STDC @@ -137,7 +137,7 @@ fdi/Makefile dev/Makefile tools/Makefile swig/Makefile -libiphone-1.0.pc +libimobiledevice-1.0.pc ]) echo " diff --git a/dev/Makefile.am b/dev/Makefile.am index 1ca15e5..9b3ec6a 100644 --- a/dev/Makefile.am +++ b/dev/Makefile.am @@ -4,36 +4,36 @@ AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_C AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) if ENABLE_DEVTOOLS -noinst_PROGRAMS = iphoneclient lckd-client afccheck msyncclient iphoneenterrecovery filerelaytest +noinst_PROGRAMS = ideviceclient lckd-client afccheck msyncclient ideviceenterrecovery filerelaytest -iphoneclient_SOURCES = iphoneclient.c -iphoneclient_LDADD = ../src/libiphone.la +ideviceclient_SOURCES = ideviceclient.c +ideviceclient_LDADD = ../src/libimobiledevice.la lckd_client_SOURCES = lckdclient.c lckd_client_CFLAGS = $(AM_CFLAGS) lckd_client_LDFLAGS = -lreadline $(AM_LDFLAGS) -lckd_client_LDADD = ../src/libiphone.la +lckd_client_LDADD = ../src/libimobiledevice.la afccheck_SOURCES = afccheck.c afccheck_CFLAGS = $(AM_CFLAGS) afccheck_LDFLAGS = $(AM_LDFLAGS) -afccheck_LDADD = ../src/libiphone.la +afccheck_LDADD = ../src/libimobiledevice.la msyncclient_SOURCES = msyncclient.c msyncclient_CFLAGS = $(AM_CFLAGS) msyncclient_LDFLAGS = $(AM_LDFLAGS) -msyncclient_LDADD = ../src/libiphone.la +msyncclient_LDADD = ../src/libimobiledevice.la -iphoneenterrecovery_SOURCES = iphoneenterrecovery.c -iphoneenterrecovery_CFLAGS = $(AM_CFLAGS) -iphoneenterrecovery_LDFLAGS = $(AM_LDFLAGS) -iphoneenterrecovery_LDADD = ../src/libiphone.la +ideviceenterrecovery_SOURCES = ideviceenterrecovery.c +ideviceenterrecovery_CFLAGS = $(AM_CFLAGS) +ideviceenterrecovery_LDFLAGS = $(AM_LDFLAGS) +ideviceenterrecovery_LDADD = ../src/libimobiledevice.la filerelaytest_SOURCES = filerelaytest.c filerelaytest_CFLAGS = $(AM_CFLAGS) filerelaytest_LDFLAGS = $(AM_LDFLAGS) -filerelaytest_LDADD = ../src/libiphone.la +filerelaytest_LDADD = ../src/libimobiledevice.la endif # ENABLE_DEVTOOLS -EXTRA_DIST = iphoneclient.c lckdclient.c afccheck.c msyncclient.c iphoneenterrecovery.c +EXTRA_DIST = ideviceclient.c lckdclient.c afccheck.c msyncclient.c ideviceenterrecovery.c diff --git a/dev/afccheck.c b/dev/afccheck.c index 569acf1..b4d8910 100644 --- a/dev/afccheck.c +++ b/dev/afccheck.c @@ -24,9 +24,9 @@ #include #include -#include -#include -#include +#include +#include +#include #define BUFFER_SIZE 20000 #define NB_THREADS 10 @@ -53,7 +53,7 @@ static void check_afc(gpointer data) buf[i] = ((param *) data)->id * i; } - //now writes buffer on iphone + //now writes buffer on device uint64_t file = 0; char path[50]; sprintf(path, "/Buf%i", ((param *) data)->id); @@ -91,30 +91,30 @@ static void check_afc(gpointer data) int main(int argc, char *argv[]) { lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; + idevice_t phone = NULL; GError *err; uint16_t port = 0; afc_client_t afc = NULL; if (argc > 1 && !strcasecmp(argv[1], "--debug")) { - iphone_set_debug_level(1); + idevice_set_debug_level(1); } else { - iphone_set_debug_level(0); + idevice_set_debug_level(0); } - if (IPHONE_E_SUCCESS != iphone_device_new(&phone, NULL)) { - printf("No iPhone found, is it plugged in?\n"); + if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { + printf("No device found, is it plugged in?\n"); return 1; } if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "afccheck")) { - iphone_device_free(phone); + idevice_free(phone); return 1; } if (LOCKDOWN_E_SUCCESS == lockdownd_start_service(client, "com.apple.afc", &port) && !port) { lockdownd_client_free(client); - iphone_device_free(phone); + idevice_free(phone); fprintf(stderr, "Something went wrong when starting AFC."); return 1; } @@ -140,7 +140,7 @@ int main(int argc, char *argv[]) } lockdownd_client_free(client); - iphone_device_free(phone); + idevice_free(phone); return 0; } diff --git a/dev/filerelaytest.c b/dev/filerelaytest.c index f7e0d07..caaa491 100644 --- a/dev/filerelaytest.c +++ b/dev/filerelaytest.c @@ -19,17 +19,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include -#include -#include -#include +#include +#include +#include int main(int argc, char **argv) { - iphone_device_t dev = NULL; + idevice_t dev = NULL; lockdownd_client_t client = NULL; file_relay_client_t frc = NULL; - if (iphone_device_new(&dev, NULL) != IPHONE_E_SUCCESS) { + if (idevice_new(&dev, NULL) != IDEVICE_E_SUCCESS) { printf("no device connected?!\n"); goto leave_cleanup; } @@ -56,7 +56,7 @@ int main(int argc, char **argv) goto leave_cleanup; } - iphone_connection_t dump = NULL; + idevice_connection_t dump = NULL; const char *sources[] = {"AppleSupport", "Network", "VPN", "WiFi", "UserDatabases", "CrashReporter", "tmp", "SystemConfiguration", NULL}; printf("Requesting"); @@ -83,7 +83,7 @@ int main(int argc, char **argv) FILE *f = fopen("dump.cpio.gz", "w"); setbuf(stdout, NULL); printf("receiving "); - while (iphone_connection_receive(dump, buf, 4096, &len) == IPHONE_E_SUCCESS) { + while (idevice_connection_receive(dump, buf, 4096, &len) == IDEVICE_E_SUCCESS) { fwrite(buf, 1, len, f); cnt += len; printf(".", len); @@ -101,7 +101,7 @@ leave_cleanup: lockdownd_client_free(client); } if (dev) { - iphone_device_free(dev); + idevice_free(dev); } return 0; diff --git a/dev/ideviceclient.c b/dev/ideviceclient.c new file mode 100644 index 0000000..2ed93d2 --- /dev/null +++ b/dev/ideviceclient.c @@ -0,0 +1,252 @@ +/* + * main.c + * Test program for testing several services. + * + * Copyright (c) 2008 Zach C. 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +static void notifier(const char *notification) +{ + printf("---------------------------------------------------------\n"); + printf("------> Notification received: %s\n", notification); + printf("---------------------------------------------------------\n"); +} + +static void perform_notification(idevice_t phone, lockdownd_client_t client, const char *notification) +{ + uint16_t nport = 0; + np_client_t np; + + lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &nport); + if (nport) { + printf("::::::::::::::: np was started ::::::::::::\n"); + np_client_new(phone, nport, &np); + if (np) { + printf("::::::::: PostNotification %s\n", notification); + np_post_notification(np, notification); + np_client_free(np); + } + } else { + printf("::::::::::::::: np was NOT started ::::::::::::\n"); + } +} + +int main(int argc, char *argv[]) +{ + unsigned int bytes = 0; + uint16_t port = 0, i = 0; + uint16_t npp; + lockdownd_client_t client = NULL; + idevice_t phone = NULL; + uint64_t lockfile = 0; + np_client_t gnp = NULL; + + if (argc > 1 && !strcasecmp(argv[1], "--debug")) { + idevice_set_debug_level(1); + } else { + idevice_set_debug_level(0); + } + + if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { + printf("No device found, is it plugged in?\n"); + return -1; + } + + char *uuid = NULL; + if (IDEVICE_E_SUCCESS == idevice_get_uuid(phone, &uuid)) { + printf("DeviceUniqueID : %s\n", uuid); + } + if (uuid) + free(uuid); + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "ideviceclient")) { + idevice_free(phone); + printf("Exiting.\n"); + return -1; + } + + char *nnn = NULL; + if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name(client, &nnn)) { + printf("DeviceName : %s\n", nnn); + free(nnn); + } + + lockdownd_start_service(client, "com.apple.afc", &port); + + if (port) { + afc_client_t afc = NULL; + afc_client_new(phone, port, &afc); + if (afc) { + lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &npp); + if (npp) { + printf("Notification Proxy started.\n"); + np_client_new(phone, npp, &gnp); + } else { + printf("ERROR: Notification proxy could not be started.\n"); + } + if (gnp) { + const char *nspec[5] = { + NP_SYNC_CANCEL_REQUEST, + NP_SYNC_SUSPEND_REQUEST, + NP_SYNC_RESUME_REQUEST, + NP_ITDBPREP_DID_END, + NULL + }; + np_observe_notifications(gnp, nspec); + np_set_notify_callback(gnp, notifier); + } + + perform_notification(phone, client, NP_SYNC_WILL_START); + + afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); + if (lockfile) { + printf("locking file\n"); + afc_file_lock(afc, lockfile, AFC_LOCK_EX); + + perform_notification(phone, client, NP_SYNC_DID_START); + } + + char **dirs = NULL; + afc_read_directory(afc, "/eafaedf", &dirs); + if (!dirs) + afc_read_directory(afc, "/", &dirs); + printf("Directory time.\n"); + for (i = 0; dirs[i]; i++) { + printf("/%s\n", dirs[i]); + } + + g_strfreev(dirs); + + dirs = NULL; + afc_get_device_info(afc, &dirs); + if (dirs) { + for (i = 0; dirs[i]; i += 2) { + printf("%s: %s\n", dirs[i], dirs[i + 1]); + } + } + g_strfreev(dirs); + + uint64_t my_file = 0; + char **info = NULL; + uint64_t fsize = 0; + if (AFC_E_SUCCESS == afc_get_file_info(afc, "/readme.libimobiledevice.fx", &info) && info) { + for (i = 0; info[i]; i += 2) { + printf("%s: %s\n", info[i], info[i+1]); + if (!strcmp(info[i], "st_size")) { + fsize = atoll(info[i+1]); + } + } + } + + if (AFC_E_SUCCESS == + afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) { + printf("A file size: %llu\n", (long long)fsize); + char *file_data = (char *) malloc(sizeof(char) * fsize); + afc_file_read(afc, my_file, file_data, fsize, &bytes); + if (bytes > 0) { + printf("The file's data:\n"); + fwrite(file_data, 1, bytes, stdout); + } + printf("\nClosing my file.\n"); + afc_file_close(afc, my_file); + free(file_data); + } else + printf("couldn't open a file\n"); + + afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_WR, &my_file); + if (my_file) { + char *outdatafile = strdup("this is a bitchin text file\n"); + afc_file_write(afc, my_file, outdatafile, strlen(outdatafile), &bytes); + free(outdatafile); + if (bytes > 0) + printf("Wrote a surprise. ;)\n"); + else + printf("I wanted to write a surprise, but... :(\n"); + afc_file_close(afc, my_file); + } + printf("Deleting a file...\n"); + bytes = afc_remove_path(afc, "/delme"); + if (bytes) + printf("Success.\n"); + else + printf("Failure. (expected unless you have a /delme file on your phone)\n"); + + printf("Renaming a file...\n"); + bytes = afc_rename_path(afc, "/renme", "/renme2"); + if (bytes > 0) + printf("Success.\n"); + else + printf("Failure. (expected unless you have a /renme file on your phone)\n"); + + printf("Seek & read\n"); + afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file); + if (AFC_E_SUCCESS != afc_file_seek(afc, my_file, 5, SEEK_CUR)) + printf("WARN: SEEK DID NOT WORK\n"); + char *threeletterword = (char *) malloc(sizeof(char) * 5); + afc_file_read(afc, my_file, threeletterword, 3, &bytes); + threeletterword[3] = '\0'; + if (bytes > 0) + printf("Result: %s\n", threeletterword); + else + printf("Couldn't read!\n"); + free(threeletterword); + afc_file_close(afc, my_file); + } + + if (gnp && lockfile) { + printf("XXX sleeping\n"); + sleep(5); + + printf("XXX unlocking file\n"); + afc_file_lock(afc, lockfile, AFC_LOCK_UN); + + printf("XXX closing file\n"); + afc_file_close(afc, lockfile); + + printf("XXX sleeping\n"); + sleep(5); + //perform_notification(phone, client, NP_SYNC_DID_FINISH); + } + + if (gnp) { + np_client_free(gnp); + gnp = NULL; + } + + afc_client_free(afc); + } else { + printf("Start service failure.\n"); + } + + printf("All done.\n"); + + lockdownd_client_free(client); + idevice_free(phone); + + return 0; +} diff --git a/dev/ideviceenterrecovery.c b/dev/ideviceenterrecovery.c new file mode 100644 index 0000000..82ea786 --- /dev/null +++ b/dev/ideviceenterrecovery.c @@ -0,0 +1,93 @@ +/* + * ideviceenterrecovery.c + * Simple utility to make a device in normal mode enter recovery mode. + * + * Copyright (c) 2009 Martin Szulecki 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 +#include +#include +#include + +#include +#include + +static void print_usage(int argc, char **argv) +{ + char *name = NULL; + + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS] UUID\n", (name ? name + 1: argv[0])); + printf("Makes a device with the supplied 40-digit UUID enter recovery mode immediately.\n\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); +} + +int main(int argc, char *argv[]) +{ + lockdownd_client_t client = NULL; + idevice_t phone = NULL; + idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; + int i; + char uuid[41]; + uuid[0] = 0; + + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + idevice_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; + } + } + + i--; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); + + ret = idevice_new(&phone, uuid); + if (ret != IDEVICE_E_SUCCESS) { + printf("No device found with uuid %s, is it plugged in?\n", uuid); + return -1; + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "ideviceenterrecovery")) { + idevice_free(phone); + return -1; + } + + /* run query and output information */ + printf("Telling device with uuid %s to enter recovery mode.}\n", uuid); + if(lockdownd_enter_recovery(client) != LOCKDOWN_E_SUCCESS) + { + printf("Failed to enter recovery mode.\n"); + } + printf("Device is successfully switching to recovery mode.\n"); + + lockdownd_client_free(client); + idevice_free(phone); + + return 0; +} diff --git a/dev/iphoneclient.c b/dev/iphoneclient.c deleted file mode 100644 index eab903c..0000000 --- a/dev/iphoneclient.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * main.c - * Rudimentary interface to the iPhone - * - * Copyright (c) 2008 Zach C. 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 -#include -#include -#include -#include - -#include -#include -#include -#include - -static void notifier(const char *notification) -{ - printf("---------------------------------------------------------\n"); - printf("------> Notification received: %s\n", notification); - printf("---------------------------------------------------------\n"); -} - -static void perform_notification(iphone_device_t phone, lockdownd_client_t client, const char *notification) -{ - uint16_t nport = 0; - np_client_t np; - - lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &nport); - if (nport) { - printf("::::::::::::::: np was started ::::::::::::\n"); - np_client_new(phone, nport, &np); - if (np) { - printf("::::::::: PostNotification %s\n", notification); - np_post_notification(np, notification); - np_client_free(np); - } - } else { - printf("::::::::::::::: np was NOT started ::::::::::::\n"); - } -} - -int main(int argc, char *argv[]) -{ - unsigned int bytes = 0; - uint16_t port = 0, i = 0; - uint16_t npp; - lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; - uint64_t lockfile = 0; - np_client_t gnp = NULL; - - if (argc > 1 && !strcasecmp(argv[1], "--debug")) { - iphone_set_debug_level(1); - } else { - iphone_set_debug_level(0); - } - - if (IPHONE_E_SUCCESS != iphone_device_new(&phone, NULL)) { - printf("No iPhone found, is it plugged in?\n"); - return -1; - } - - char *uuid = NULL; - if (IPHONE_E_SUCCESS == iphone_device_get_uuid(phone, &uuid)) { - printf("DeviceUniqueID : %s\n", uuid); - } - if (uuid) - free(uuid); - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "iphoneclient")) { - iphone_device_free(phone); - printf("Exiting.\n"); - return -1; - } - - char *nnn = NULL; - if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name(client, &nnn)) { - printf("DeviceName : %s\n", nnn); - free(nnn); - } - - lockdownd_start_service(client, "com.apple.afc", &port); - - if (port) { - afc_client_t afc = NULL; - afc_client_new(phone, port, &afc); - if (afc) { - lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &npp); - if (npp) { - printf("Notification Proxy started.\n"); - np_client_new(phone, npp, &gnp); - } else { - printf("ERROR: Notification proxy could not be started.\n"); - } - if (gnp) { - const char *nspec[5] = { - NP_SYNC_CANCEL_REQUEST, - NP_SYNC_SUSPEND_REQUEST, - NP_SYNC_RESUME_REQUEST, - NP_ITDBPREP_DID_END, - NULL - }; - np_observe_notifications(gnp, nspec); - np_set_notify_callback(gnp, notifier); - } - - perform_notification(phone, client, NP_SYNC_WILL_START); - - afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); - if (lockfile) { - printf("locking file\n"); - afc_file_lock(afc, lockfile, AFC_LOCK_EX); - - perform_notification(phone, client, NP_SYNC_DID_START); - } - - char **dirs = NULL; - afc_read_directory(afc, "/eafaedf", &dirs); - if (!dirs) - afc_read_directory(afc, "/", &dirs); - printf("Directory time.\n"); - for (i = 0; dirs[i]; i++) { - printf("/%s\n", dirs[i]); - } - - g_strfreev(dirs); - - dirs = NULL; - afc_get_device_info(afc, &dirs); - if (dirs) { - for (i = 0; dirs[i]; i += 2) { - printf("%s: %s\n", dirs[i], dirs[i + 1]); - } - } - g_strfreev(dirs); - - uint64_t my_file = 0; - char **info = NULL; - uint64_t fsize = 0; - if (AFC_E_SUCCESS == afc_get_file_info(afc, "/readme.libiphone.fx", &info) && info) { - for (i = 0; info[i]; i += 2) { - printf("%s: %s\n", info[i], info[i+1]); - if (!strcmp(info[i], "st_size")) { - fsize = atoll(info[i+1]); - } - } - } - - if (AFC_E_SUCCESS == - afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) { - printf("A file size: %llu\n", (long long)fsize); - char *file_data = (char *) malloc(sizeof(char) * fsize); - afc_file_read(afc, my_file, file_data, fsize, &bytes); - if (bytes > 0) { - printf("The file's data:\n"); - fwrite(file_data, 1, bytes, stdout); - } - printf("\nClosing my file.\n"); - afc_file_close(afc, my_file); - free(file_data); - } else - printf("couldn't open a file\n"); - - afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_WR, &my_file); - if (my_file) { - char *outdatafile = strdup("this is a bitchin text file\n"); - afc_file_write(afc, my_file, outdatafile, strlen(outdatafile), &bytes); - free(outdatafile); - if (bytes > 0) - printf("Wrote a surprise. ;)\n"); - else - printf("I wanted to write a surprise, but... :(\n"); - afc_file_close(afc, my_file); - } - printf("Deleting a file...\n"); - bytes = afc_remove_path(afc, "/delme"); - if (bytes) - printf("Success.\n"); - else - printf("Failure. (expected unless you have a /delme file on your phone)\n"); - - printf("Renaming a file...\n"); - bytes = afc_rename_path(afc, "/renme", "/renme2"); - if (bytes > 0) - printf("Success.\n"); - else - printf("Failure. (expected unless you have a /renme file on your phone)\n"); - - printf("Seek & read\n"); - afc_file_open(afc, "/readme.libiphone.fx", AFC_FOPEN_RDONLY, &my_file); - if (AFC_E_SUCCESS != afc_file_seek(afc, my_file, 5, SEEK_CUR)) - printf("WARN: SEEK DID NOT WORK\n"); - char *threeletterword = (char *) malloc(sizeof(char) * 5); - afc_file_read(afc, my_file, threeletterword, 3, &bytes); - threeletterword[3] = '\0'; - if (bytes > 0) - printf("Result: %s\n", threeletterword); - else - printf("Couldn't read!\n"); - free(threeletterword); - afc_file_close(afc, my_file); - } - - if (gnp && lockfile) { - printf("XXX sleeping\n"); - sleep(5); - - printf("XXX unlocking file\n"); - afc_file_lock(afc, lockfile, AFC_LOCK_UN); - - printf("XXX closing file\n"); - afc_file_close(afc, lockfile); - - printf("XXX sleeping\n"); - sleep(5); - //perform_notification(phone, client, NP_SYNC_DID_FINISH); - } - - if (gnp) { - np_client_free(gnp); - gnp = NULL; - } - - afc_client_free(afc); - } else { - printf("Start service failure.\n"); - } - - printf("All done.\n"); - - lockdownd_client_free(client); - iphone_device_free(phone); - - return 0; -} diff --git a/dev/iphoneenterrecovery.c b/dev/iphoneenterrecovery.c deleted file mode 100644 index 153df15..0000000 --- a/dev/iphoneenterrecovery.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * iphoneenterrecovery.c - * Simple utility to make a device in normal mode enter recovery mode. - * - * Copyright (c) 2009 Martin Szulecki 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 -#include -#include -#include - -#include -#include - -static void print_usage(int argc, char **argv) -{ - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] UUID\n", (name ? name + 1: argv[0])); - printf("Makes a device with the supplied 40-digit UUID enter recovery mode immediately.\n\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); -} - -int main(int argc, char *argv[]) -{ - lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; - iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - int i; - char uuid[41]; - uuid[0] = 0; - - /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { - iphone_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - } - - i--; - if (!argv[i] || (strlen(argv[i]) != 40)) { - print_usage(argc, argv); - return 0; - } - strcpy(uuid, argv[i]); - - ret = iphone_device_new(&phone, uuid); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found with uuid %s, is it plugged in?\n", uuid); - return -1; - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "iphoneenterrecovery")) { - iphone_device_free(phone); - return -1; - } - - /* run query and output information */ - printf("Telling device with uuid %s to enter recovery mode.}\n", uuid); - if(lockdownd_enter_recovery(client) != LOCKDOWN_E_SUCCESS) - { - printf("Failed to enter recovery mode.\n"); - } - printf("Device is successfully switching to recovery mode.\n"); - - lockdownd_client_free(client); - iphone_device_free(phone); - - return 0; -} diff --git a/dev/lckdclient.c b/dev/lckdclient.c index 7b7604e..773de9f 100644 --- a/dev/lckdclient.c +++ b/dev/lckdclient.c @@ -26,30 +26,30 @@ #include #include -#include -#include +#include +#include int main(int argc, char *argv[]) { lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; + idevice_t phone = NULL; - iphone_set_debug_level(1); + idevice_set_debug_level(1); - if (IPHONE_E_SUCCESS != iphone_device_new(&phone, NULL)) { - printf("No iPhone found, is it plugged in?\n"); + if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { + printf("No device found, is it plugged in?\n"); return -1; } char *uuid = NULL; - if (IPHONE_E_SUCCESS == iphone_device_get_uuid(phone, &uuid)) { + if (IDEVICE_E_SUCCESS == idevice_get_uuid(phone, &uuid)) { printf("DeviceUniqueID : %s\n", uuid); } if (uuid) free(uuid); if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "lckdclient")) { - iphone_device_free(phone); + idevice_free(phone); return -1; } @@ -109,7 +109,7 @@ int main(int argc, char *argv[]) } clear_history(); lockdownd_client_free(client); - iphone_device_free(phone); + idevice_free(phone); return 0; } diff --git a/dev/msync.py b/dev/msync.py index 6bb85d7..951355c 100755 --- a/dev/msync.py +++ b/dev/msync.py @@ -1,11 +1,11 @@ #! /usr/bin/env python -from iphone import * +from imobiledevice import * from plist import * # get msync client def GetMobileSyncClient() : - phone = iPhone() + phone = idevice() if not phone.init_device() : print "Couldn't find device, is it connected ?\n" return None diff --git a/dev/msyncclient.c b/dev/msyncclient.c index 0107240..b9e39e6 100644 --- a/dev/msyncclient.c +++ b/dev/msyncclient.c @@ -1,6 +1,6 @@ /* * msyncclient.c - * Rudimentary interface to the MobileSync iPhone + * Rudimentary interface to the MobileSync service. * * Copyright (c) 2009 Jonathan Beck All Rights Reserved. * @@ -23,9 +23,9 @@ #include #include -#include -#include -#include +#include +#include +#include static char check_string(plist_t node, char* string) { @@ -143,18 +143,18 @@ int main(int argc, char *argv[]) { uint16_t port = 0; lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; + idevice_t phone = NULL; if (argc > 1 && !strcasecmp(argv[1], "--debug")) - iphone_set_debug_level(1); + idevice_set_debug_level(1); - if (IPHONE_E_SUCCESS != iphone_device_new(&phone, NULL)) { - printf("No iPhone found, is it plugged in?\n"); + if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { + printf("No device found, is it plugged in?\n"); return -1; } if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "msyncclient")) { - iphone_device_free(phone); + idevice_free(phone); return -1; } @@ -174,7 +174,7 @@ int main(int argc, char *argv[]) printf("All done.\n"); lockdownd_client_free(client); - iphone_device_free(phone); + idevice_free(phone); return 0; } diff --git a/include/Makefile.am b/include/Makefile.am index aced258..2e20332 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,9 +1,9 @@ -nobase_include_HEADERS = libiphone/libiphone.h \ - libiphone/lockdown.h \ - libiphone/afc.h \ - libiphone/file_relay.h \ - libiphone/notification_proxy.h \ - libiphone/installation_proxy.h \ - libiphone/sbservices.h \ - libiphone/mobilesync.h \ - libiphone/mobilebackup.h +nobase_include_HEADERS = libimobiledevice/libimobiledevice.h \ + libimobiledevice/lockdown.h \ + libimobiledevice/afc.h \ + libimobiledevice/file_relay.h \ + libimobiledevice/notification_proxy.h \ + libimobiledevice/installation_proxy.h \ + libimobiledevice/sbservices.h \ + libimobiledevice/mobilesync.h \ + libimobiledevice/mobilebackup.h diff --git a/include/libimobiledevice/afc.h b/include/libimobiledevice/afc.h new file mode 100644 index 0000000..5b61499 --- /dev/null +++ b/include/libimobiledevice/afc.h @@ -0,0 +1,117 @@ +/** + * @file libimobiledevice/afc.h + * @brief AFC Implementation + * \internal + * + * 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 + */ + +#ifndef AFC_H +#define AFC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error Codes */ +#define AFC_E_SUCCESS 0 +#define AFC_E_UNKNOWN_ERROR 1 +#define AFC_E_OP_HEADER_INVALID 2 +#define AFC_E_NO_RESOURCES 3 +#define AFC_E_READ_ERROR 4 +#define AFC_E_WRITE_ERROR 5 +#define AFC_E_UNKNOWN_PACKET_TYPE 6 +#define AFC_E_INVALID_ARGUMENT 7 +#define AFC_E_OBJECT_NOT_FOUND 8 +#define AFC_E_OBJECT_IS_DIR 9 +#define AFC_E_PERM_DENIED 10 +#define AFC_E_SERVICE_NOT_CONNECTED 11 +#define AFC_E_OP_TIMEOUT 12 +#define AFC_E_TOO_MUCH_DATA 13 +#define AFC_E_END_OF_DATA 14 +#define AFC_E_OP_NOT_SUPPORTED 15 +#define AFC_E_OBJECT_EXISTS 16 +#define AFC_E_OBJECT_BUSY 17 +#define AFC_E_NO_SPACE_LEFT 18 +#define AFC_E_OP_WOULD_BLOCK 19 +#define AFC_E_IO_ERROR 20 +#define AFC_E_OP_INTERRUPTED 21 +#define AFC_E_OP_IN_PROGRESS 22 +#define AFC_E_INTERNAL_ERROR 23 + +#define AFC_E_MUX_ERROR 30 +#define AFC_E_NO_MEM 31 +#define AFC_E_NOT_ENOUGH_DATA 32 +#define AFC_E_DIR_NOT_EMPTY 33 + +typedef int16_t afc_error_t; + +/* Flags */ +typedef enum { + AFC_FOPEN_RDONLY = 0x00000001, // r O_RDONLY + AFC_FOPEN_RW = 0x00000002, // r+ O_RDWR | O_CREAT + AFC_FOPEN_WRONLY = 0x00000003, // w O_WRONLY | O_CREAT | O_TRUNC + AFC_FOPEN_WR = 0x00000004, // w+ O_RDWR | O_CREAT | O_TRUNC + AFC_FOPEN_APPEND = 0x00000005, // a O_WRONLY | O_APPEND | O_CREAT + AFC_FOPEN_RDAPPEND = 0x00000006 // a+ O_RDWR | O_APPEND | O_CREAT +} afc_file_mode_t; + +typedef enum { + AFC_HARDLINK = 1, + AFC_SYMLINK = 2 +} afc_link_type_t; + +typedef enum { + AFC_LOCK_SH = 1 | 4, // shared lock + AFC_LOCK_EX = 2 | 4, // exclusive lock + AFC_LOCK_UN = 8 | 4 // unlock +} afc_lock_op_t; + +struct afc_client_int; +typedef struct afc_client_int *afc_client_t; + +/* Interface */ +afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t *client); +afc_error_t afc_client_free(afc_client_t client); +afc_error_t afc_get_device_info(afc_client_t client, char ***infos); +afc_error_t afc_read_directory(afc_client_t client, const char *dir, char ***list); +afc_error_t afc_get_file_info(afc_client_t client, const char *filename, char ***infolist); +afc_error_t afc_file_open(afc_client_t client, const char *filename, afc_file_mode_t file_mode, uint64_t *handle); +afc_error_t afc_file_close(afc_client_t client, uint64_t handle); +afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation); +afc_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read); +afc_error_t afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written); +afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence); +afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position); +afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize); +afc_error_t afc_remove_path(afc_client_t client, const char *path); +afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to); +afc_error_t afc_make_directory(afc_client_t client, const char *dir); +afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize); +afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname); +afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime); + +/* Helper functions */ +afc_error_t afc_get_device_info_key(afc_client_t client, const char *key, char **value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/file_relay.h b/include/libimobiledevice/file_relay.h new file mode 100644 index 0000000..268eed8 --- /dev/null +++ b/include/libimobiledevice/file_relay.h @@ -0,0 +1,56 @@ +/** + * @file libimobiledevice/file_relay.h + * @brief file_relay Implementation + * \internal + * + * Copyright (c) 2010 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 + */ + +#ifndef IFILE_RELAY_H +#define IFILE_RELAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error Codes */ +#define FILE_RELAY_E_SUCCESS 0 +#define FILE_RELAY_E_INVALID_ARG -1 +#define FILE_RELAY_E_PLIST_ERROR -2 +#define FILE_RELAY_E_MUX_ERROR -3 +#define FILE_RELAY_E_INVALID_SOURCE -4 +#define FILE_RELAY_E_STAGING_EMPTY -5 + +#define FILE_RELAY_E_UNKNOWN_ERROR -256 + +typedef int16_t file_relay_error_t; + +struct file_relay_client_int; +typedef struct file_relay_client_int *file_relay_client_t; + +file_relay_error_t file_relay_client_new(idevice_t device, uint16_t port, file_relay_client_t *client); +file_relay_error_t file_relay_client_free(file_relay_client_t client); + +file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, idevice_connection_t *connection); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/installation_proxy.h b/include/libimobiledevice/installation_proxy.h new file mode 100644 index 0000000..22e76b1 --- /dev/null +++ b/include/libimobiledevice/installation_proxy.h @@ -0,0 +1,72 @@ +/** + * @file libimobiledevice/installation_proxy.h + * @brief Implementation to talk to the installation proxy on a device + * \internal + * + * 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 + */ + +#ifndef INSTALLATION_PROXY_H +#define INSTALLATION_PROXY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Error Codes */ +#define INSTPROXY_E_SUCCESS 0 +#define INSTPROXY_E_INVALID_ARG -1 +#define INSTPROXY_E_PLIST_ERROR -2 +#define INSTPROXY_E_CONN_FAILED -3 +#define INSTPROXY_E_OP_IN_PROGRESS -4 +#define INSTPROXY_E_OP_FAILED -5 + +#define INSTPROXY_E_UNKNOWN_ERROR -256 + +typedef int16_t instproxy_error_t; + +struct instproxy_client_int; +typedef struct instproxy_client_int *instproxy_client_t; + +typedef void (*instproxy_status_cb_t) (const char *operation, plist_t status); + +/* Interface */ +instproxy_error_t instproxy_client_new(idevice_t device, uint16_t port, instproxy_client_t *client); +instproxy_error_t instproxy_client_free(instproxy_client_t client); + +instproxy_error_t instproxy_browse(instproxy_client_t client, plist_t client_options, plist_t *result); +instproxy_error_t instproxy_install(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb); +instproxy_error_t instproxy_upgrade(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb); +instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); + +instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t client_options, plist_t *result); +instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); +instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); +instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); + +plist_t instproxy_client_options_new(); +void instproxy_client_options_add(plist_t client_options, ...) G_GNUC_NULL_TERMINATED; +void instproxy_client_options_free(plist_t client_options); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/libimobiledevice.h b/include/libimobiledevice/libimobiledevice.h new file mode 100644 index 0000000..87b078a --- /dev/null +++ b/include/libimobiledevice/libimobiledevice.h @@ -0,0 +1,102 @@ +/** + * @file libimobiledevice/libimobiledevice.h + * @brief Common code and device handling + * \internal + * + * Copyright (c) 2008 Jonathan Beck 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 + */ + +#ifndef LIBIMOBILEDEVICE_H +#define LIBIMOBILEDEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* Error Codes */ +#define IDEVICE_E_SUCCESS 0 +#define IDEVICE_E_INVALID_ARG -1 +#define IDEVICE_E_UNKNOWN_ERROR -2 +#define IDEVICE_E_NO_DEVICE -3 +#define IDEVICE_E_NOT_ENOUGH_DATA -4 +#define IDEVICE_E_BAD_HEADER -5 +#define IDEVICE_E_SSL_ERROR -6 + +typedef int16_t idevice_error_t; + +struct idevice_int; +typedef struct idevice_int *idevice_t; + +struct idevice_connection_int; +typedef struct idevice_connection_int *idevice_connection_t; + +/* generic */ +void idevice_set_debug_level(int level); + +/* discovery (events/asynchronous) */ +// event type +enum idevice_event_type { + IDEVICE_DEVICE_ADD = 1, + IDEVICE_DEVICE_REMOVE +}; + +// event data structure +typedef struct { + enum idevice_event_type event; + const char *uuid; + int conn_type; +} idevice_event_t; + +// event callback function prototype +typedef void (*idevice_event_cb_t) (const idevice_event_t *event, void *user_data); + +// functions +idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data); +idevice_error_t idevice_event_unsubscribe(); + +/* discovery (synchronous) */ +idevice_error_t idevice_get_device_list(char ***devices, int *count); +idevice_error_t idevice_device_list_free(char **devices); + +/* device structure creation and destruction */ +idevice_error_t idevice_new(idevice_t *device, const char *uuid); +idevice_error_t idevice_free(idevice_t device); + +/* connection/disconnection */ +idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection); +idevice_error_t idevice_disconnect(idevice_connection_t connection); + +/* communication */ +idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes); +idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout); +idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes); + +/* misc */ +idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle); +idevice_error_t idevice_get_uuid(idevice_t device, char **uuid); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/libimobiledevice/lockdown.h b/include/libimobiledevice/lockdown.h new file mode 100644 index 0000000..49c708d --- /dev/null +++ b/include/libimobiledevice/lockdown.h @@ -0,0 +1,99 @@ +/** + * @file libimobiledevice/lockdown.h + * @brief Communcation with the lockdown device daemon + * \internal + * + * Copyright (c) 2008 Zach C. All Rights Reserved. + * Copyright (c) 2009 Martin S. 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 + */ + +#ifndef LOCKDOWN_H +#define LOCKDOWN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error Codes */ +#define LOCKDOWN_E_SUCCESS 0 +#define LOCKDOWN_E_INVALID_ARG -1 +#define LOCKDOWN_E_INVALID_CONF -2 +#define LOCKDOWN_E_PLIST_ERROR -3 +#define LOCKDOWN_E_PAIRING_FAILED -4 +#define LOCKDOWN_E_SSL_ERROR -5 +#define LOCKDOWN_E_DICT_ERROR -6 +#define LOCKDOWN_E_START_SERVICE_FAILED -7 +#define LOCKDOWN_E_NOT_ENOUGH_DATA -8 +#define LOCKDOWN_E_SET_VALUE_PROHIBITED -9 +#define LOCKDOWN_E_GET_VALUE_PROHIBITED -10 +#define LOCKDOWN_E_REMOVE_VALUE_PROHIBITED -11 +#define LOCKDOWN_E_MUX_ERROR -12 +#define LOCKDOWN_E_ACTIVATION_FAILED -13 +#define LOCKDOWN_E_PASSWORD_PROTECTED -14 +#define LOCKDOWN_E_NO_RUNNING_SESSION -15 +#define LOCKDOWN_E_INVALID_HOST_ID -16 +#define LOCKDOWN_E_INVALID_SERVICE -17 + +#define LOCKDOWN_E_UNKNOWN_ERROR -256 + +typedef int16_t lockdownd_error_t; + +struct lockdownd_client_int; +typedef struct lockdownd_client_int *lockdownd_client_t; + +struct lockdownd_pair_record { + char *device_certificate; + char *host_certificate; + char *host_id; + char *root_certificate; +}; +typedef struct lockdownd_pair_record *lockdownd_pair_record_t; + +/* Interface */ +lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label); +lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label); +lockdownd_error_t lockdownd_client_free(lockdownd_client_t client); + +lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type); +lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value); +lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value); +lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key); +lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *service, uint16_t *port); +lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled); +lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id); +lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist); +lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist); +lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); +lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); +lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); +lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record); +lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client); +lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client); +lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client); + +/* Helper */ +void lockdownd_client_set_label(lockdownd_client_t client, const char *label); +lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid); +lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/mobilebackup.h b/include/libimobiledevice/mobilebackup.h new file mode 100644 index 0000000..e51d4c1 --- /dev/null +++ b/include/libimobiledevice/mobilebackup.h @@ -0,0 +1,55 @@ +/** + * @file libimobiledevice/mobilebackup.h + * @brief MobileBackup Implementation + * \internal + * + * Copyright (c) 2009 Martin Szulecki 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 + */ + +#ifndef IMOBILEBACKUP_H +#define IMOBILEBACKUP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error Codes */ +#define MOBILEBACKUP_E_SUCCESS 0 +#define MOBILEBACKUP_E_INVALID_ARG -1 +#define MOBILEBACKUP_E_PLIST_ERROR -2 +#define MOBILEBACKUP_E_MUX_ERROR -3 +#define MOBILEBACKUP_E_BAD_VERSION -4 + +#define MOBILEBACKUP_E_UNKNOWN_ERROR -256 + +typedef int16_t mobilebackup_error_t; + +struct mobilebackup_client_int; +typedef struct mobilebackup_client_int *mobilebackup_client_t; + +mobilebackup_error_t mobilebackup_client_new(idevice_t device, uint16_t port, mobilebackup_client_t * client); +mobilebackup_error_t mobilebackup_client_free(mobilebackup_client_t client); +mobilebackup_error_t mobilebackup_receive(mobilebackup_client_t client, plist_t *plist); +mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist_t plist); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/mobilesync.h b/include/libimobiledevice/mobilesync.h new file mode 100644 index 0000000..349b6a3 --- /dev/null +++ b/include/libimobiledevice/mobilesync.h @@ -0,0 +1,55 @@ +/** + * @file libimobiledevice/mobilesync.h + * @brief MobileSync Implementation + * \internal + * + * Copyright (c) 2009 Jonathan Beck 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 + */ + +#ifndef IMOBILESYNC_H +#define IMOBILESYNC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error Codes */ +#define MOBILESYNC_E_SUCCESS 0 +#define MOBILESYNC_E_INVALID_ARG -1 +#define MOBILESYNC_E_PLIST_ERROR -2 +#define MOBILESYNC_E_MUX_ERROR -3 +#define MOBILESYNC_E_BAD_VERSION -4 + +#define MOBILESYNC_E_UNKNOWN_ERROR -256 + +typedef int16_t mobilesync_error_t; + +struct mobilesync_client_int; +typedef struct mobilesync_client_int *mobilesync_client_t; + +mobilesync_error_t mobilesync_client_new(idevice_t device, uint16_t port, mobilesync_client_t * client); +mobilesync_error_t mobilesync_client_free(mobilesync_client_t client); +mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t *plist); +mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/notification_proxy.h b/include/libimobiledevice/notification_proxy.h new file mode 100644 index 0000000..adbb4cc --- /dev/null +++ b/include/libimobiledevice/notification_proxy.h @@ -0,0 +1,88 @@ +/** + * @file libimobiledevice/notification_proxy.h + * @brief Implementation to talk to the notification proxy on a device + * \internal + * + * 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 + */ + +#ifndef NOTIFICATION_PROXY_H +#define NOTIFICATION_PROXY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error Codes */ +#define NP_E_SUCCESS 0 +#define NP_E_INVALID_ARG -1 +#define NP_E_PLIST_ERROR -2 +#define NP_E_CONN_FAILED -3 + +#define NP_E_UNKNOWN_ERROR -256 + +typedef int16_t np_error_t; + +/* Notification IDs for use with post_notification (client --> device) */ +#define NP_SYNC_WILL_START "com.apple.itunes-mobdev.syncWillStart" +#define NP_SYNC_DID_START "com.apple.itunes-mobdev.syncDidStart" +#define NP_SYNC_DID_FINISH "com.apple.itunes-mobdev.syncDidFinish" +#define NP_SYNC_LOCK_REQUEST "com.apple.itunes-mobdev.syncLockRequest" + +/* Notification IDs for use with observe_notification (device --> client) */ +#define NP_SYNC_CANCEL_REQUEST "com.apple.itunes-client.syncCancelRequest" +#define NP_SYNC_SUSPEND_REQUEST "com.apple.itunes-client.syncSuspendRequest" +#define NP_SYNC_RESUME_REQUEST "com.apple.itunes-client.syncResumeRequest" +#define NP_PHONE_NUMBER_CHANGED "com.apple.mobile.lockdown.phone_number_changed" +#define NP_DEVICE_NAME_CHANGED "com.apple.mobile.lockdown.device_name_changed" +#define NP_TIMEZONE_CHANGED "com.apple.mobile.lockdown.timezone_changed" +#define NP_TRUSTED_HOST_ATTACHED "com.apple.mobile.lockdown.trusted_host_attached" +#define NP_HOST_DETACHED "com.apple.mobile.lockdown.host_detached" +#define NP_HOST_ATTACHED "com.apple.mobile.lockdown.host_attached" +#define NP_REGISTRATION_FAILED "com.apple.mobile.lockdown.registration_failed" +#define NP_ACTIVATION_STATE "com.apple.mobile.lockdown.activation_state" +#define NP_BRICK_STATE "com.apple.mobile.lockdown.brick_state" +#define NP_DS_DOMAIN_CHANGED "com.apple.mobile.data_sync.domain_changed" +#define NP_BACKUP_DOMAIN_CHANGED "com.apple.mobile.backup.domain_changed" +#define NP_APP_INSTALLED "com.apple.mobile.application_installed" +#define NP_APP_UNINSTALLED "com.apple.mobile.application_uninstalled" +#define NP_DEV_IMAGE_MOUNTED "com.apple.mobile.developer_image_mounted" +#define NP_ATTEMPTACTIVATION "com.apple.springboard.attemptactivation" +#define NP_ITDBPREP_DID_END "com.apple.itdbprep.notification.didEnd" +#define NP_LANGUAGE_CHANGED "com.apple.language.changed" +#define NP_ADDRESS_BOOK_PREF_CHANGED "com.apple.AddressBook.PreferenceChanged" + +struct np_client_int; +typedef struct np_client_int *np_client_t; + +typedef void (*np_notify_cb_t) (const char *notification); + +/* Interface */ +np_error_t np_client_new(idevice_t device, uint16_t port, np_client_t *client); +np_error_t np_client_free(np_client_t client); +np_error_t np_post_notification(np_client_t client, const char *notification); +np_error_t np_observe_notification(np_client_t client, const char *notification); +np_error_t np_observe_notifications(np_client_t client, const char **notification_spec); +np_error_t np_set_notify_callback(np_client_t client, np_notify_cb_t notify_cb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/sbservices.h b/include/libimobiledevice/sbservices.h new file mode 100644 index 0000000..921d6be --- /dev/null +++ b/include/libimobiledevice/sbservices.h @@ -0,0 +1,56 @@ +/** + * @file libimobiledevice/sbservices.h + * @brief Implementation to talk to com.apple.springboardservices on a device + * \internal + * + * 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 + */ + +#ifndef SB_SERVICES_H +#define SB_SERVICES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error Codes */ +#define SBSERVICES_E_SUCCESS 0 +#define SBSERVICES_E_INVALID_ARG -1 +#define SBSERVICES_E_PLIST_ERROR -2 +#define SBSERVICES_E_CONN_FAILED -3 + +#define SBSERVICES_E_UNKNOWN_ERROR -256 + +typedef int16_t sbservices_error_t; + +struct sbservices_client_int; +typedef struct sbservices_client_int *sbservices_client_t; + +/* Interface */ +sbservices_error_t sbservices_client_new(idevice_t device, uint16_t port, sbservices_client_t *client); +sbservices_error_t sbservices_client_free(sbservices_client_t client); +sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state); +sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate); +sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libiphone/afc.h b/include/libiphone/afc.h deleted file mode 100644 index 5d09b40..0000000 --- a/include/libiphone/afc.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file libiphone/afc.h - * @brief AFC Implementation - * \internal - * - * 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 - */ - -#ifndef AFC_H -#define AFC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Error Codes */ -#define AFC_E_SUCCESS 0 -#define AFC_E_UNKNOWN_ERROR 1 -#define AFC_E_OP_HEADER_INVALID 2 -#define AFC_E_NO_RESOURCES 3 -#define AFC_E_READ_ERROR 4 -#define AFC_E_WRITE_ERROR 5 -#define AFC_E_UNKNOWN_PACKET_TYPE 6 -#define AFC_E_INVALID_ARGUMENT 7 -#define AFC_E_OBJECT_NOT_FOUND 8 -#define AFC_E_OBJECT_IS_DIR 9 -#define AFC_E_PERM_DENIED 10 -#define AFC_E_SERVICE_NOT_CONNECTED 11 -#define AFC_E_OP_TIMEOUT 12 -#define AFC_E_TOO_MUCH_DATA 13 -#define AFC_E_END_OF_DATA 14 -#define AFC_E_OP_NOT_SUPPORTED 15 -#define AFC_E_OBJECT_EXISTS 16 -#define AFC_E_OBJECT_BUSY 17 -#define AFC_E_NO_SPACE_LEFT 18 -#define AFC_E_OP_WOULD_BLOCK 19 -#define AFC_E_IO_ERROR 20 -#define AFC_E_OP_INTERRUPTED 21 -#define AFC_E_OP_IN_PROGRESS 22 -#define AFC_E_INTERNAL_ERROR 23 - -#define AFC_E_MUX_ERROR 30 -#define AFC_E_NO_MEM 31 -#define AFC_E_NOT_ENOUGH_DATA 32 -#define AFC_E_DIR_NOT_EMPTY 33 - -typedef int16_t afc_error_t; - -/* Flags */ -typedef enum { - AFC_FOPEN_RDONLY = 0x00000001, // r O_RDONLY - AFC_FOPEN_RW = 0x00000002, // r+ O_RDWR | O_CREAT - AFC_FOPEN_WRONLY = 0x00000003, // w O_WRONLY | O_CREAT | O_TRUNC - AFC_FOPEN_WR = 0x00000004, // w+ O_RDWR | O_CREAT | O_TRUNC - AFC_FOPEN_APPEND = 0x00000005, // a O_WRONLY | O_APPEND | O_CREAT - AFC_FOPEN_RDAPPEND = 0x00000006 // a+ O_RDWR | O_APPEND | O_CREAT -} afc_file_mode_t; - -typedef enum { - AFC_HARDLINK = 1, - AFC_SYMLINK = 2 -} afc_link_type_t; - -typedef enum { - AFC_LOCK_SH = 1 | 4, // shared lock - AFC_LOCK_EX = 2 | 4, // exclusive lock - AFC_LOCK_UN = 8 | 4 // unlock -} afc_lock_op_t; - -struct afc_client_int; -typedef struct afc_client_int *afc_client_t; - -/* Interface */ -afc_error_t afc_client_new(iphone_device_t device, uint16_t port, afc_client_t *client); -afc_error_t afc_client_free(afc_client_t client); -afc_error_t afc_get_device_info(afc_client_t client, char ***infos); -afc_error_t afc_read_directory(afc_client_t client, const char *dir, char ***list); -afc_error_t afc_get_file_info(afc_client_t client, const char *filename, char ***infolist); -afc_error_t afc_file_open(afc_client_t client, const char *filename, afc_file_mode_t file_mode, uint64_t *handle); -afc_error_t afc_file_close(afc_client_t client, uint64_t handle); -afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation); -afc_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read); -afc_error_t afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written); -afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence); -afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position); -afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize); -afc_error_t afc_remove_path(afc_client_t client, const char *path); -afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to); -afc_error_t afc_make_directory(afc_client_t client, const char *dir); -afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize); -afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname); -afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime); - -/* Helper functions */ -afc_error_t afc_get_device_info_key(afc_client_t client, const char *key, char **value); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libiphone/file_relay.h b/include/libiphone/file_relay.h deleted file mode 100644 index 672f1bd..0000000 --- a/include/libiphone/file_relay.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file libiphone/file_relay.h - * @brief file_relay Implementation - * \internal - * - * Copyright (c) 2010 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 - */ - -#ifndef IFILE_RELAY_H -#define IFILE_RELAY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Error Codes */ -#define FILE_RELAY_E_SUCCESS 0 -#define FILE_RELAY_E_INVALID_ARG -1 -#define FILE_RELAY_E_PLIST_ERROR -2 -#define FILE_RELAY_E_MUX_ERROR -3 -#define FILE_RELAY_E_INVALID_SOURCE -4 -#define FILE_RELAY_E_STAGING_EMPTY -5 - -#define FILE_RELAY_E_UNKNOWN_ERROR -256 - -typedef int16_t file_relay_error_t; - -struct file_relay_client_int; -typedef struct file_relay_client_int *file_relay_client_t; - -file_relay_error_t file_relay_client_new(iphone_device_t device, uint16_t port, file_relay_client_t *client); -file_relay_error_t file_relay_client_free(file_relay_client_t client); - -file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, iphone_connection_t *connection); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libiphone/installation_proxy.h b/include/libiphone/installation_proxy.h deleted file mode 100644 index b7bbb60..0000000 --- a/include/libiphone/installation_proxy.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file libiphone/installation_proxy.h - * @brief Implementation to talk to the installation proxy on a device - * \internal - * - * 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 - */ - -#ifndef INSTALLATION_PROXY_H -#define INSTALLATION_PROXY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* Error Codes */ -#define INSTPROXY_E_SUCCESS 0 -#define INSTPROXY_E_INVALID_ARG -1 -#define INSTPROXY_E_PLIST_ERROR -2 -#define INSTPROXY_E_CONN_FAILED -3 -#define INSTPROXY_E_OP_IN_PROGRESS -4 -#define INSTPROXY_E_OP_FAILED -5 - -#define INSTPROXY_E_UNKNOWN_ERROR -256 - -typedef int16_t instproxy_error_t; - -struct instproxy_client_int; -typedef struct instproxy_client_int *instproxy_client_t; - -typedef void (*instproxy_status_cb_t) (const char *operation, plist_t status); - -/* Interface */ -instproxy_error_t instproxy_client_new(iphone_device_t device, uint16_t port, instproxy_client_t *client); -instproxy_error_t instproxy_client_free(instproxy_client_t client); - -instproxy_error_t instproxy_browse(instproxy_client_t client, plist_t client_options, plist_t *result); -instproxy_error_t instproxy_install(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb); -instproxy_error_t instproxy_upgrade(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb); -instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); - -instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t client_options, plist_t *result); -instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); -instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); -instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb); - -plist_t instproxy_client_options_new(); -void instproxy_client_options_add(plist_t client_options, ...) G_GNUC_NULL_TERMINATED; -void instproxy_client_options_free(plist_t client_options); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h deleted file mode 100644 index efe9a63..0000000 --- a/include/libiphone/libiphone.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file libiphone/libiphone.h - * @brief Common code and device handling - * \internal - * - * Copyright (c) 2008 Jonathan Beck 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 - */ - -#ifndef LIBIPHONE_H -#define LIBIPHONE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - -/* Error Codes */ -#define IPHONE_E_SUCCESS 0 -#define IPHONE_E_INVALID_ARG -1 -#define IPHONE_E_UNKNOWN_ERROR -2 -#define IPHONE_E_NO_DEVICE -3 -#define IPHONE_E_NOT_ENOUGH_DATA -4 -#define IPHONE_E_BAD_HEADER -5 -#define IPHONE_E_SSL_ERROR -6 - -typedef int16_t iphone_error_t; - -struct iphone_device_int; -typedef struct iphone_device_int *iphone_device_t; - -struct iphone_connection_int; -typedef struct iphone_connection_int *iphone_connection_t; - -/* generic */ -void iphone_set_debug_level(int level); - -/* discovery (events/asynchronous) */ -// event type -enum iphone_event_type { - IPHONE_DEVICE_ADD = 1, - IPHONE_DEVICE_REMOVE -}; - -// event data structure -typedef struct { - enum iphone_event_type event; - const char *uuid; - int conn_type; -} iphone_event_t; - -// event callback function prototype -typedef void (*iphone_event_cb_t) (const iphone_event_t *event, void *user_data); - -// functions -iphone_error_t iphone_event_subscribe(iphone_event_cb_t callback, void *user_data); -iphone_error_t iphone_event_unsubscribe(); - -/* discovery (synchronous) */ -iphone_error_t iphone_get_device_list(char ***devices, int *count); -iphone_error_t iphone_device_list_free(char **devices); - -/* device structure creation and destruction */ -iphone_error_t iphone_device_new(iphone_device_t *device, const char *uuid); -iphone_error_t iphone_device_free(iphone_device_t device); - -/* connection/disconnection */ -iphone_error_t iphone_device_connect(iphone_device_t device, uint16_t port, iphone_connection_t *connection); -iphone_error_t iphone_device_disconnect(iphone_connection_t connection); - -/* communication */ -iphone_error_t iphone_connection_send(iphone_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes); -iphone_error_t iphone_connection_receive_timeout(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout); -iphone_error_t iphone_connection_receive(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes); - -/* misc */ -iphone_error_t iphone_device_get_handle(iphone_device_t device, uint32_t *handle); -iphone_error_t iphone_device_get_uuid(iphone_device_t device, char **uuid); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/include/libiphone/lockdown.h b/include/libiphone/lockdown.h deleted file mode 100644 index 003a99b..0000000 --- a/include/libiphone/lockdown.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file libiphone/lockdown.h - * @brief Communcation with the lockdown device daemon - * \internal - * - * Copyright (c) 2008 Zach C. All Rights Reserved. - * Copyright (c) 2009 Martin S. 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 - */ - -#ifndef LOCKDOWN_H -#define LOCKDOWN_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Error Codes */ -#define LOCKDOWN_E_SUCCESS 0 -#define LOCKDOWN_E_INVALID_ARG -1 -#define LOCKDOWN_E_INVALID_CONF -2 -#define LOCKDOWN_E_PLIST_ERROR -3 -#define LOCKDOWN_E_PAIRING_FAILED -4 -#define LOCKDOWN_E_SSL_ERROR -5 -#define LOCKDOWN_E_DICT_ERROR -6 -#define LOCKDOWN_E_START_SERVICE_FAILED -7 -#define LOCKDOWN_E_NOT_ENOUGH_DATA -8 -#define LOCKDOWN_E_SET_VALUE_PROHIBITED -9 -#define LOCKDOWN_E_GET_VALUE_PROHIBITED -10 -#define LOCKDOWN_E_REMOVE_VALUE_PROHIBITED -11 -#define LOCKDOWN_E_MUX_ERROR -12 -#define LOCKDOWN_E_ACTIVATION_FAILED -13 -#define LOCKDOWN_E_PASSWORD_PROTECTED -14 -#define LOCKDOWN_E_NO_RUNNING_SESSION -15 -#define LOCKDOWN_E_INVALID_HOST_ID -16 -#define LOCKDOWN_E_INVALID_SERVICE -17 - -#define LOCKDOWN_E_UNKNOWN_ERROR -256 - -typedef int16_t lockdownd_error_t; - -struct lockdownd_client_int; -typedef struct lockdownd_client_int *lockdownd_client_t; - -struct lockdownd_pair_record { - char *device_certificate; - char *host_certificate; - char *host_id; - char *root_certificate; -}; -typedef struct lockdownd_pair_record *lockdownd_pair_record_t; - -/* Interface */ -lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label); -lockdownd_error_t lockdownd_client_new_with_handshake(iphone_device_t device, lockdownd_client_t *client, const char *label); -lockdownd_error_t lockdownd_client_free(lockdownd_client_t client); - -lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type); -lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value); -lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value); -lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key); -lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *service, uint16_t *port); -lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled); -lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id); -lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist); -lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist); -lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); -lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); -lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); -lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record); -lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client); -lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client); -lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client); - -/* Helper */ -void lockdownd_client_set_label(lockdownd_client_t client, const char *label); -lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid); -lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libiphone/mobilebackup.h b/include/libiphone/mobilebackup.h deleted file mode 100644 index 8db6758..0000000 --- a/include/libiphone/mobilebackup.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @file libiphone/mobilebackup.h - * @brief MobileBackup Implementation - * \internal - * - * Copyright (c) 2009 Martin Szulecki 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 - */ - -#ifndef IMOBILEBACKUP_H -#define IMOBILEBACKUP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Error Codes */ -#define MOBILEBACKUP_E_SUCCESS 0 -#define MOBILEBACKUP_E_INVALID_ARG -1 -#define MOBILEBACKUP_E_PLIST_ERROR -2 -#define MOBILEBACKUP_E_MUX_ERROR -3 -#define MOBILEBACKUP_E_BAD_VERSION -4 - -#define MOBILEBACKUP_E_UNKNOWN_ERROR -256 - -typedef int16_t mobilebackup_error_t; - -struct mobilebackup_client_int; -typedef struct mobilebackup_client_int *mobilebackup_client_t; - -mobilebackup_error_t mobilebackup_client_new(iphone_device_t device, uint16_t port, mobilebackup_client_t * client); -mobilebackup_error_t mobilebackup_client_free(mobilebackup_client_t client); -mobilebackup_error_t mobilebackup_receive(mobilebackup_client_t client, plist_t *plist); -mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist_t plist); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libiphone/mobilesync.h b/include/libiphone/mobilesync.h deleted file mode 100644 index f85113d..0000000 --- a/include/libiphone/mobilesync.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @file libiphone/mobilesync.h - * @brief MobileSync Implementation - * \internal - * - * Copyright (c) 2009 Jonathan Beck 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 - */ - -#ifndef IMOBILESYNC_H -#define IMOBILESYNC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Error Codes */ -#define MOBILESYNC_E_SUCCESS 0 -#define MOBILESYNC_E_INVALID_ARG -1 -#define MOBILESYNC_E_PLIST_ERROR -2 -#define MOBILESYNC_E_MUX_ERROR -3 -#define MOBILESYNC_E_BAD_VERSION -4 - -#define MOBILESYNC_E_UNKNOWN_ERROR -256 - -typedef int16_t mobilesync_error_t; - -struct mobilesync_client_int; -typedef struct mobilesync_client_int *mobilesync_client_t; - -mobilesync_error_t mobilesync_client_new(iphone_device_t device, uint16_t port, mobilesync_client_t * client); -mobilesync_error_t mobilesync_client_free(mobilesync_client_t client); -mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t *plist); -mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libiphone/notification_proxy.h b/include/libiphone/notification_proxy.h deleted file mode 100644 index 962dd9b..0000000 --- a/include/libiphone/notification_proxy.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file libiphone/notification_proxy.h - * @brief Implementation to talk to the notification proxy on a device - * \internal - * - * 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 - */ - -#ifndef NOTIFICATION_PROXY_H -#define NOTIFICATION_PROXY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Error Codes */ -#define NP_E_SUCCESS 0 -#define NP_E_INVALID_ARG -1 -#define NP_E_PLIST_ERROR -2 -#define NP_E_CONN_FAILED -3 - -#define NP_E_UNKNOWN_ERROR -256 - -typedef int16_t np_error_t; - -/* Notification IDs for use with post_notification (client --> device) */ -#define NP_SYNC_WILL_START "com.apple.itunes-mobdev.syncWillStart" -#define NP_SYNC_DID_START "com.apple.itunes-mobdev.syncDidStart" -#define NP_SYNC_DID_FINISH "com.apple.itunes-mobdev.syncDidFinish" -#define NP_SYNC_LOCK_REQUEST "com.apple.itunes-mobdev.syncLockRequest" - -/* Notification IDs for use with observe_notification (device --> client) */ -#define NP_SYNC_CANCEL_REQUEST "com.apple.itunes-client.syncCancelRequest" -#define NP_SYNC_SUSPEND_REQUEST "com.apple.itunes-client.syncSuspendRequest" -#define NP_SYNC_RESUME_REQUEST "com.apple.itunes-client.syncResumeRequest" -#define NP_PHONE_NUMBER_CHANGED "com.apple.mobile.lockdown.phone_number_changed" -#define NP_DEVICE_NAME_CHANGED "com.apple.mobile.lockdown.device_name_changed" -#define NP_TIMEZONE_CHANGED "com.apple.mobile.lockdown.timezone_changed" -#define NP_TRUSTED_HOST_ATTACHED "com.apple.mobile.lockdown.trusted_host_attached" -#define NP_HOST_DETACHED "com.apple.mobile.lockdown.host_detached" -#define NP_HOST_ATTACHED "com.apple.mobile.lockdown.host_attached" -#define NP_REGISTRATION_FAILED "com.apple.mobile.lockdown.registration_failed" -#define NP_ACTIVATION_STATE "com.apple.mobile.lockdown.activation_state" -#define NP_BRICK_STATE "com.apple.mobile.lockdown.brick_state" -#define NP_DS_DOMAIN_CHANGED "com.apple.mobile.data_sync.domain_changed" -#define NP_BACKUP_DOMAIN_CHANGED "com.apple.mobile.backup.domain_changed" -#define NP_APP_INSTALLED "com.apple.mobile.application_installed" -#define NP_APP_UNINSTALLED "com.apple.mobile.application_uninstalled" -#define NP_DEV_IMAGE_MOUNTED "com.apple.mobile.developer_image_mounted" -#define NP_ATTEMPTACTIVATION "com.apple.springboard.attemptactivation" -#define NP_ITDBPREP_DID_END "com.apple.itdbprep.notification.didEnd" -#define NP_LANGUAGE_CHANGED "com.apple.language.changed" -#define NP_ADDRESS_BOOK_PREF_CHANGED "com.apple.AddressBook.PreferenceChanged" - -struct np_client_int; -typedef struct np_client_int *np_client_t; - -typedef void (*np_notify_cb_t) (const char *notification); - -/* Interface */ -np_error_t np_client_new(iphone_device_t device, uint16_t port, np_client_t *client); -np_error_t np_client_free(np_client_t client); -np_error_t np_post_notification(np_client_t client, const char *notification); -np_error_t np_observe_notification(np_client_t client, const char *notification); -np_error_t np_observe_notifications(np_client_t client, const char **notification_spec); -np_error_t np_set_notify_callback(np_client_t client, np_notify_cb_t notify_cb); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libiphone/sbservices.h b/include/libiphone/sbservices.h deleted file mode 100644 index 3e4accb..0000000 --- a/include/libiphone/sbservices.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file libiphone/sbservices.h - * @brief Implementation to talk to com.apple.springboardservices on a device - * \internal - * - * 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 - */ - -#ifndef SB_SERVICES_H -#define SB_SERVICES_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Error Codes */ -#define SBSERVICES_E_SUCCESS 0 -#define SBSERVICES_E_INVALID_ARG -1 -#define SBSERVICES_E_PLIST_ERROR -2 -#define SBSERVICES_E_CONN_FAILED -3 - -#define SBSERVICES_E_UNKNOWN_ERROR -256 - -typedef int16_t sbservices_error_t; - -struct sbservices_client_int; -typedef struct sbservices_client_int *sbservices_client_t; - -/* Interface */ -sbservices_error_t sbservices_client_new(iphone_device_t device, uint16_t port, sbservices_client_t *client); -sbservices_error_t sbservices_client_free(sbservices_client_t client); -sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state); -sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate); -sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libimobiledevice-1.0.pc.in b/libimobiledevice-1.0.pc.in new file mode 100644 index 0000000..526edcf --- /dev/null +++ b/libimobiledevice-1.0.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libimobiledevice +Description: A library to communicate with services running on Apple iPhone/iPod Touch devices. +Version: @VERSION@ +Requires: libplist >= 0.12 libusbmuxd >= 0.1.0 glib-2.0 >= 2.14.1 gthread-2.0 >= 2.14.1 gnutls >= 1.6.3 libtasn1 >= 1.1 +Libs: -L${libdir} -limobiledevice +Cflags: -I${includedir} + diff --git a/libiphone-1.0.pc.in b/libiphone-1.0.pc.in deleted file mode 100644 index 323a73d..0000000 --- a/libiphone-1.0.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libiphone -Description: A library to communicate with the Lockdown server on the iPhone -Version: @VERSION@ -Requires: libplist >= 0.12 libusbmuxd >= 0.1.0 glib-2.0 >= 2.14.1 gthread-2.0 >= 2.14.1 gnutls >= 1.6.3 libtasn1 >= 1.1 -Libs: -L${libdir} -liphone -Cflags: -I${includedir} - diff --git a/src/Makefile.am b/src/Makefile.am index 93cfbaf..69bbd9b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,8 +3,8 @@ INCLUDES = -I$(top_srcdir)/include AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusbmuxd_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS) $(libgcrypt_LIBS) -lib_LTLIBRARIES = libiphone.la -libiphone_la_SOURCES = iphone.c iphone.h \ +lib_LTLIBRARIES = libimobiledevice.la +libimobiledevice_la_SOURCES = idevice.c idevice.h \ debug.c debug.h\ userpref.c userpref.h\ property_list_service.c property_list_service.h\ diff --git a/src/afc.c b/src/afc.c index 767e460..4367add 100644 --- a/src/afc.c +++ b/src/afc.c @@ -24,7 +24,7 @@ #include #include "afc.h" -#include "iphone.h" +#include "idevice.h" #include "debug.h" // This is the maximum size an AFC data packet can be @@ -61,7 +61,7 @@ static void afc_unlock(afc_client_t client) * is invalid, AFC_E_MUX_ERROR when the connection failed, or AFC_E_NO_MEM * when there's a memory allocation problem. */ -afc_error_t afc_client_new(iphone_device_t device, uint16_t port, afc_client_t * client) +afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t * client) { /* makes sure thread environment is available */ if (!g_thread_supported()) @@ -71,8 +71,8 @@ afc_error_t afc_client_new(iphone_device_t device, uint16_t port, afc_client_t * return AFC_E_INVALID_ARGUMENT; /* attempt connection */ - iphone_connection_t connection = NULL; - if (iphone_device_connect(device, port, &connection) != IPHONE_E_SUCCESS) { + idevice_connection_t connection = NULL; + if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) { return AFC_E_MUX_ERROR; } @@ -82,7 +82,7 @@ afc_error_t afc_client_new(iphone_device_t device, uint16_t port, afc_client_t * /* allocate a packet */ client_loc->afc_packet = (AFCPacket *) malloc(sizeof(AFCPacket)); if (!client_loc->afc_packet) { - iphone_device_disconnect(client_loc->connection); + idevice_disconnect(client_loc->connection); free(client_loc); return AFC_E_NO_MEM; } @@ -108,7 +108,7 @@ afc_error_t afc_client_free(afc_client_t client) if (!client || !client->connection || !client->afc_packet) return AFC_E_INVALID_ARGUMENT; - iphone_device_disconnect(client->connection); + idevice_disconnect(client->connection); free(client->afc_packet); if (client->mutex) { g_mutex_free(client->mutex); @@ -169,7 +169,7 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, ui /* send AFC packet header */ AFCPacket_to_LE(client->afc_packet); sent = 0; - iphone_connection_send(client->connection, (void*)client->afc_packet, sizeof(AFCPacket), &sent); + idevice_connection_send(client->connection, (void*)client->afc_packet, sizeof(AFCPacket), &sent); if (sent == 0) { /* FIXME: should this be handled as success?! */ return AFC_E_SUCCESS; @@ -178,7 +178,7 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, ui /* send AFC packet data */ sent = 0; - iphone_connection_send(client->connection, data, offset, &sent); + idevice_connection_send(client->connection, data, offset, &sent); if (sent == 0) { return AFC_E_SUCCESS; } @@ -190,7 +190,7 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, ui debug_buffer(data + offset, length - offset); sent = 0; - iphone_connection_send(client->connection, data + offset, length - offset, &sent); + idevice_connection_send(client->connection, data + offset, length - offset, &sent); *bytes_sent = sent; return AFC_E_SUCCESS; @@ -203,7 +203,7 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, ui /* send AFC packet header */ AFCPacket_to_LE(client->afc_packet); sent = 0; - iphone_connection_send(client->connection, (void*)client->afc_packet, sizeof(AFCPacket), &sent); + idevice_connection_send(client->connection, (void*)client->afc_packet, sizeof(AFCPacket), &sent); if (sent == 0) { return AFC_E_SUCCESS; } @@ -213,7 +213,7 @@ static afc_error_t afc_dispatch_packet(afc_client_t client, const char *data, ui debug_info("packet data follows"); debug_buffer(data, length); - iphone_connection_send(client->connection, data, length, &sent); + idevice_connection_send(client->connection, data, length, &sent); *bytes_sent += sent; } return AFC_E_SUCCESS; @@ -241,7 +241,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 *bytes_recv = 0; /* first, read the AFC header */ - iphone_connection_receive(client->connection, (char*)&header, sizeof(AFCPacket), bytes_recv); + idevice_connection_receive(client->connection, (char*)&header, sizeof(AFCPacket), bytes_recv); AFCPacket_from_LE(&header); if (*bytes_recv == 0) { debug_info("Just didn't get enough."); @@ -295,7 +295,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 *dump_here = (char*)malloc(entire_len); if (this_len > 0) { - iphone_connection_receive(client->connection, *dump_here, this_len, bytes_recv); + idevice_connection_receive(client->connection, *dump_here, this_len, bytes_recv); if (*bytes_recv <= 0) { free(*dump_here); *dump_here = NULL; @@ -313,7 +313,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3 if (entire_len > this_len) { while (current_count < entire_len) { - iphone_connection_receive(client->connection, (*dump_here)+current_count, entire_len - current_count, bytes_recv); + idevice_connection_receive(client->connection, (*dump_here)+current_count, entire_len - current_count, bytes_recv); if (*bytes_recv <= 0) { debug_info("Error receiving data (recv returned %d)", *bytes_recv); break; @@ -701,7 +701,7 @@ afc_error_t afc_get_file_info(afc_client_t client, const char *path, char ***inf * * @return AFC_E_SUCCESS on success or an AFC_E_* error on failure. */ -iphone_error_t +idevice_error_t afc_file_open(afc_client_t client, const char *filename, afc_file_mode_t file_mode, uint64_t *handle) { @@ -760,7 +760,7 @@ afc_file_open(afc_client_t client, const char *filename, * * @return AFC_E_SUCCESS on success or an AFC_E_* error value on error. */ -iphone_error_t +idevice_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read) { char *input = NULL; @@ -833,7 +833,7 @@ afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, * * @return AFC_E_SUCCESS on success, or an AFC_E_* error value on error. */ -iphone_error_t +idevice_error_t afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written) { char *acknowledgement = NULL; diff --git a/src/afc.h b/src/afc.h index f8a5da3..ad518f6 100644 --- a/src/afc.h +++ b/src/afc.h @@ -26,7 +26,7 @@ #include #include -#include "libiphone/afc.h" +#include "libimobiledevice/afc.h" #define AFC_MAGIC "CFA6LPAA" #define AFC_MAGIC_LEN (8) @@ -58,7 +58,7 @@ typedef struct __AFCToken { } AFCToken; struct afc_client_int { - iphone_connection_t connection; + idevice_connection_t connection; AFCPacket *afc_packet; int file_handle; int lock; diff --git a/src/debug.c b/src/debug.c index b194b0d..a40c249 100644 --- a/src/debug.c +++ b/src/debug.c @@ -28,7 +28,7 @@ #include #include "debug.h" -#include "libiphone/libiphone.h" +#include "libimobiledevice/libimobiledevice.h" int debug_level = 0; @@ -38,7 +38,7 @@ int debug_level = 0; * * @param level Set to 0 for no debugging or 1 for debugging. */ -void iphone_set_debug_level(int level) +void idevice_set_debug_level(int level) { debug_level = level; } diff --git a/src/device_link_service.c b/src/device_link_service.c index 9998fd0..10e9e9c 100644 --- a/src/device_link_service.c +++ b/src/device_link_service.c @@ -78,7 +78,7 @@ static char *device_link_service_get_message(plist_t dl_msg) * DEVICE_LINK_SERVICE_E_INVALID_ARG when one of the parameters is invalid, * or DEVICE_LINK_SERVICE_E_MUX_ERROR when the connection failed. */ -device_link_service_error_t device_link_service_client_new(iphone_device_t device, uint16_t port, device_link_service_client_t *client) +device_link_service_error_t device_link_service_client_new(idevice_t device, uint16_t port, device_link_service_client_t *client) { if (!device || port == 0 || !client || *client) { return DEVICE_LINK_SERVICE_E_INVALID_ARG; diff --git a/src/device_link_service.h b/src/device_link_service.h index 8345d57..4fc9a9f 100644 --- a/src/device_link_service.h +++ b/src/device_link_service.h @@ -41,7 +41,7 @@ typedef struct device_link_service_client_int *device_link_service_client_t; typedef int16_t device_link_service_error_t; -device_link_service_error_t device_link_service_client_new(iphone_device_t device, uint16_t port, device_link_service_client_t *client); +device_link_service_error_t device_link_service_client_new(idevice_t device, uint16_t port, device_link_service_client_t *client); device_link_service_error_t device_link_service_client_free(device_link_service_client_t client); device_link_service_error_t device_link_service_version_exchange(device_link_service_client_t client, uint64_t version_major, uint64_t version_minor); device_link_service_error_t device_link_service_process_message(device_link_service_client_t client, plist_t message); diff --git a/src/file_relay.c b/src/file_relay.c index f0e91f7..dd94e53 100644 --- a/src/file_relay.c +++ b/src/file_relay.c @@ -36,7 +36,7 @@ * FILE_RELAY_E_INVALID_ARG when one of the parameters is invalid, * or FILE_RELAY_E_MUX_ERROR when the connection failed. */ -file_relay_error_t file_relay_client_new(iphone_device_t device, uint16_t port, file_relay_client_t *client) +file_relay_error_t file_relay_client_new(idevice_t device, uint16_t port, file_relay_client_t *client) { if (!device || port == 0 || !client || *client) { return FILE_RELAY_E_INVALID_ARG; @@ -92,7 +92,7 @@ file_relay_error_t file_relay_client_free(file_relay_client_t client) * - tmp * - SystemConfiguration * @param connection The connection that has to be used for receiving the - * data using iphone_connection_receive(). The connection will be closed + * data using idevice_connection_receive(). The connection will be closed * automatically by the device, but use file_relay_client_free() to clean * up properly. * @@ -107,7 +107,7 @@ file_relay_error_t file_relay_client_free(file_relay_client_t client) * sources are invalid, FILE_RELAY_E_STAGING_EMPTY if no data is available * for the given sources, or FILE_RELAY_E_UNKNOWN_ERROR otherwise. */ -file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, iphone_connection_t *connection) +file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, idevice_connection_t *connection) { if (!client || !client->parent || !sources || !sources[0]) { return FILE_RELAY_E_INVALID_ARG; diff --git a/src/file_relay.h b/src/file_relay.h index 9b2488c..7a94c89 100644 --- a/src/file_relay.h +++ b/src/file_relay.h @@ -21,7 +21,7 @@ #ifndef FILE_RELAY_H #define FILE_RELAY_H -#include "libiphone/file_relay.h" +#include "libimobiledevice/file_relay.h" #include "property_list_service.h" /* Error Codes */ diff --git a/src/idevice.c b/src/idevice.c new file mode 100644 index 0000000..c5050d5 --- /dev/null +++ b/src/idevice.c @@ -0,0 +1,618 @@ +/* + * idevice.c + * Device discovery and communication interface. + * + * Copyright (c) 2008 Zach C. All Rights Reserved. + * 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 +#include +#include +#include + +#include +#include +#include "idevice.h" +#include "debug.h" + +static idevice_event_cb_t event_cb = NULL; + +static void usbmux_event_cb(const usbmuxd_event_t *event, void *user_data) +{ + idevice_event_t ev; + + ev.event = event->event; + ev.uuid = event->device.uuid; + ev.conn_type = CONNECTION_USBMUXD; + + if (event_cb) { + event_cb(&ev, user_data); + } +} + +/** + * Register a callback function that will be called when device add/remove + * events occur. + * + * @param callback Callback function to call. + * @param user_data Application-specific data passed as parameter + * to the registered callback function. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occured. + */ +idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data) +{ + event_cb = callback; + int res = usbmuxd_subscribe(usbmux_event_cb, user_data); + if (res != 0) { + event_cb = NULL; + debug_info("Error %d when subscribing usbmux event callback!", res); + return IDEVICE_E_UNKNOWN_ERROR; + } + return IDEVICE_E_SUCCESS; +} + +/** + * Release the event callback function that has been registered with + * idevice_event_subscribe(). + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occured. + */ +idevice_error_t idevice_event_unsubscribe() +{ + event_cb = NULL; + int res = usbmuxd_unsubscribe(); + if (res != 0) { + debug_info("Error %d when unsubscribing usbmux event callback!", res); + return IDEVICE_E_UNKNOWN_ERROR; + } + return IDEVICE_E_SUCCESS; +} + +/** + * Get a list of currently available devices. + * + * @param devices List of uuids of devices that are currently available. + * This list is terminated by a NULL pointer. + * @param count Number of devices found. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occured. + */ +idevice_error_t idevice_get_device_list(char ***devices, int *count) +{ + usbmuxd_device_info_t *dev_list; + + *devices = NULL; + *count = 0; + + if (usbmuxd_get_device_list(&dev_list) < 0) { + debug_info("ERROR: usbmuxd is not running!\n", __func__); + return IDEVICE_E_NO_DEVICE; + } + + char **newlist = NULL; + int i, newcount = 0; + + for (i = 0; dev_list[i].handle > 0; i++) { + newlist = realloc(*devices, sizeof(char*) * (newcount+1)); + newlist[newcount++] = strdup(dev_list[i].uuid); + *devices = newlist; + } + usbmuxd_device_list_free(&dev_list); + + *count = newcount; + newlist = realloc(*devices, sizeof(char*) * (newcount+1)); + newlist[newcount] = NULL; + *devices = newlist; + + return IDEVICE_E_SUCCESS; +} + +/** + * Free a list of device uuids. + * + * @param devices List of uuids to free. + * + * @return Always returnes IDEVICE_E_SUCCESS. + */ +idevice_error_t idevice_device_list_free(char **devices) +{ + if (devices) { + int i = 0; + while (devices[i++]) { + free(devices[i]); + } + free(devices); + } + return IDEVICE_E_SUCCESS; +} + +/** + * Creates an idevice_t structure for the device specified by uuid, + * if the device is available. + * + * @note The resulting idevice_t structure has to be freed with + * idevice_free() if it is no longer used. + * + * @param device Upon calling this function, a pointer to a location of type + * idevice_t. On successful return, this location will be populated. + * @param uuid The UUID to match. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +idevice_error_t idevice_new(idevice_t * device, const char *uuid) +{ + usbmuxd_device_info_t muxdev; + int res = usbmuxd_get_device_by_uuid(uuid, &muxdev); + if (res > 0) { + idevice_t phone = (idevice_t) malloc(sizeof(struct idevice_int)); + phone->uuid = strdup(muxdev.uuid); + phone->conn_type = CONNECTION_USBMUXD; + phone->conn_data = (void*)muxdev.handle; + *device = phone; + return IDEVICE_E_SUCCESS; + } + /* other connection types could follow here */ + + return IDEVICE_E_NO_DEVICE; +} + +/** Cleans up an idevice structure, then frees the structure itself. + * This is a library-level function; deals directly with the device to tear + * down relations, but otherwise is mostly internal. + * + * @param device idevice_t to free. + */ +idevice_error_t idevice_free(idevice_t device) +{ + if (!device) + return IDEVICE_E_INVALID_ARG; + idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; + + ret = IDEVICE_E_SUCCESS; + + free(device->uuid); + + if (device->conn_type == CONNECTION_USBMUXD) { + device->conn_data = 0; + } + if (device->conn_data) { + free(device->conn_data); + } + free(device); + return ret; +} + +/** + * Set up a connection to the given device. + * + * @param device The device to connect to. + * @param port The destination port to connect to. + * @param connection Pointer to an idevice_connection_t that will be filled + * with the necessary data of the connection. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection) +{ + if (!device) { + return IDEVICE_E_INVALID_ARG; + } + + if (device->conn_type == CONNECTION_USBMUXD) { + int sfd = usbmuxd_connect((uint32_t)(device->conn_data), port); + if (sfd < 0) { + debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd)); + return IDEVICE_E_UNKNOWN_ERROR; + } + idevice_connection_t new_connection = (idevice_connection_t)malloc(sizeof(struct idevice_connection_int)); + new_connection->type = CONNECTION_USBMUXD; + new_connection->data = (void*)sfd; + new_connection->ssl_data = NULL; + *connection = new_connection; + return IDEVICE_E_SUCCESS; + } else { + debug_info("Unknown connection type %d", device->conn_type); + } + + return IDEVICE_E_UNKNOWN_ERROR; +} + +/** + * Disconnect from the device and clean up the connection structure. + * + * @param connection The connection to close. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +idevice_error_t idevice_disconnect(idevice_connection_t connection) +{ + if (!connection) { + return IDEVICE_E_INVALID_ARG; + } + /* shut down ssl if enabled */ + if (connection->ssl_data) { + idevice_connection_disable_ssl(connection); + } + idevice_error_t result = IDEVICE_E_UNKNOWN_ERROR; + if (connection->type == CONNECTION_USBMUXD) { + usbmuxd_disconnect((int)(connection->data)); + result = IDEVICE_E_SUCCESS; + } else { + debug_info("Unknown connection type %d", connection->type); + } + free(connection); + return result; +} + +/** + * Internally used function to send raw data over the given connection. + */ +static idevice_error_t internal_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes) +{ + if (!connection || !data) { + return IDEVICE_E_INVALID_ARG; + } + + if (connection->type == CONNECTION_USBMUXD) { + int res = usbmuxd_send((int)(connection->data), data, len, sent_bytes); + if (res < 0) { + debug_info("ERROR: usbmuxd_send returned %d (%s)", res, strerror(-res)); + return IDEVICE_E_UNKNOWN_ERROR; + } + return IDEVICE_E_SUCCESS; + } else { + debug_info("Unknown connection type %d", connection->type); + } + return IDEVICE_E_UNKNOWN_ERROR; + +} + +/** + * Send data to a device via the given connection. + * + * @param connection The connection to send data over. + * @param data Buffer with data to send. + * @param len Size of the buffer to send. + * @param sent_bytes Pointer to an uint32_t that will be filled + * with the number of bytes actually sent. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes) +{ + if (!connection || !data || (connection->ssl_data && !connection->ssl_data->session)) { + return IDEVICE_E_INVALID_ARG; + } + + if (connection->ssl_data) { + ssize_t sent = gnutls_record_send(connection->ssl_data->session, (void*)data, (size_t)len); + if ((uint32_t)sent == (uint32_t)len) { + *sent_bytes = sent; + return IDEVICE_E_SUCCESS; + } + *sent_bytes = 0; + return IDEVICE_E_SSL_ERROR; + } + return internal_connection_send(connection, data, len, sent_bytes); +} + +/** + * Internally used function for receiving raw data over the given connection + * using a timeout. + */ +static idevice_error_t internal_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) +{ + if (!connection) { + return IDEVICE_E_INVALID_ARG; + } + + if (connection->type == CONNECTION_USBMUXD) { + int res = usbmuxd_recv_timeout((int)(connection->data), data, len, recv_bytes, timeout); + if (res < 0) { + debug_info("ERROR: usbmuxd_recv_timeout returned %d (%s)", res, strerror(-res)); + return IDEVICE_E_UNKNOWN_ERROR; + } + return IDEVICE_E_SUCCESS; + } else { + debug_info("Unknown connection type %d", connection->type); + } + return IDEVICE_E_UNKNOWN_ERROR; +} + +/** + * Receive data from a device via the given connection. + * This function will return after the given timeout even if no data has been + * received. + * + * @param connection The connection to receive data from. + * @param data Buffer that will be filled with the received data. + * This buffer has to be large enough to hold len bytes. + * @param len Buffer size or number of bytes to receive. + * @param recv_bytes Number of bytes actually received. + * @param timeout Timeout in milliseconds after which this function should + * return even if no data has been received. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) +{ + if (!connection || (connection->ssl_data && !connection->ssl_data->session)) { + return IDEVICE_E_INVALID_ARG; + } + + if (connection->ssl_data) { + ssize_t received = gnutls_record_recv(connection->ssl_data->session, (void*)data, (size_t)len); + if (received > 0) { + *recv_bytes = received; + return IDEVICE_E_SUCCESS; + } + *recv_bytes = 0; + return IDEVICE_E_SSL_ERROR; + } + return internal_connection_receive_timeout(connection, data, len, recv_bytes, timeout); +} + +/** + * Internally used function for receiving raw data over the given connection. + */ +static idevice_error_t internal_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) +{ + if (!connection) { + return IDEVICE_E_INVALID_ARG; + } + + if (connection->type == CONNECTION_USBMUXD) { + int res = usbmuxd_recv((int)(connection->data), data, len, recv_bytes); + if (res < 0) { + debug_info("ERROR: usbmuxd_recv returned %d (%s)", res, strerror(-res)); + return IDEVICE_E_UNKNOWN_ERROR; + } + + return IDEVICE_E_SUCCESS; + } else { + debug_info("Unknown connection type %d", connection->type); + } + return IDEVICE_E_UNKNOWN_ERROR; +} + +/** + * Receive data from a device via the given connection. + * This function is like idevice_connection_receive_timeout, but with a + * predefined reasonable timeout. + * + * @param connection The connection to receive data from. + * @param data Buffer that will be filled with the received data. + * This buffer has to be large enough to hold len bytes. + * @param len Buffer size or number of bytes to receive. + * @param recv_bytes Number of bytes actually received. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) +{ + if (!connection || (connection->ssl_data && !connection->ssl_data->session)) { + return IDEVICE_E_INVALID_ARG; + } + + if (connection->ssl_data) { + ssize_t received = gnutls_record_recv(connection->ssl_data->session, (void*)data, (size_t)len); + if (received > 0) { + *recv_bytes = received; + return IDEVICE_E_SUCCESS; + } + *recv_bytes = 0; + return IDEVICE_E_SSL_ERROR; + } + return internal_connection_receive(connection, data, len, recv_bytes); +} + +idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle) +{ + if (!device) + return IDEVICE_E_INVALID_ARG; + + if (device->conn_type == CONNECTION_USBMUXD) { + *handle = (uint32_t)device->conn_data; + return IDEVICE_E_SUCCESS; + } else { + debug_info("Unknown connection type %d", device->conn_type); + } + return IDEVICE_E_UNKNOWN_ERROR; +} + +idevice_error_t idevice_get_uuid(idevice_t device, char **uuid) +{ + if (!device) + return IDEVICE_E_INVALID_ARG; + + *uuid = strdup(device->uuid); + return IDEVICE_E_SUCCESS; +} + +/** + * Internally used gnutls callback function for receiving encrypted data. + */ +static ssize_t internal_ssl_read(gnutls_transport_ptr_t transport, char *buffer, size_t length) +{ + int bytes = 0, pos_start_fill = 0; + size_t tbytes = 0; + int this_len = length; + idevice_error_t res; + idevice_connection_t connection = (idevice_connection_t)transport; + char *recv_buffer; + + debug_info("pre-read client wants %zi bytes", length); + + recv_buffer = (char *) malloc(sizeof(char) * this_len); + + /* repeat until we have the full data or an error occurs */ + do { + if ((res = internal_connection_receive(connection, recv_buffer, this_len, (uint32_t*)&bytes)) != IDEVICE_E_SUCCESS) { + debug_info("ERROR: idevice_connection_receive returned %d", res); + return res; + } + debug_info("post-read we got %i bytes", bytes); + + // increase read count + tbytes += bytes; + + // fill the buffer with what we got right now + memcpy(buffer + pos_start_fill, recv_buffer, bytes); + pos_start_fill += bytes; + + if (tbytes >= length) { + break; + } + + this_len = length - tbytes; + debug_info("re-read trying to read missing %i bytes", this_len); + } while (tbytes < length); + + if (recv_buffer) { + free(recv_buffer); + } + return tbytes; +} + +/** + * Internally used gnutls callback function for sending encrypted data. + */ +static ssize_t internal_ssl_write(gnutls_transport_ptr_t transport, char *buffer, size_t length) +{ + uint32_t bytes = 0; + idevice_connection_t connection = (idevice_connection_t)transport; + debug_info("pre-send length = %zi", length); + internal_connection_send(connection, buffer, length, &bytes); + debug_info("post-send sent %i bytes", bytes); + return bytes; +} + +/** + * Internally used function for cleaning up SSL stuff. + */ +static void internal_ssl_cleanup(ssl_data_t ssl_data) +{ + if (!ssl_data) + return; + + if (ssl_data->session) { + gnutls_deinit(ssl_data->session); + } + if (ssl_data->certificate) { + gnutls_certificate_free_credentials(ssl_data->certificate); + } +} + +/** + * Enables SSL for the given connection. + * + * @param connection The connection to enable SSL for. + * + * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection + * is NULL or connection->ssl_data is non-NULL, or IDEVICE_E_SSL_ERROR when + * SSL initialization, setup, or handshake fails. + */ +idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) +{ + if (!connection || connection->ssl_data) + return IDEVICE_E_INVALID_ARG; + + idevice_error_t ret = IDEVICE_E_SSL_ERROR; + uint32_t return_me = 0; + + ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_int)); + + // Set up GnuTLS... + debug_info("enabling SSL mode"); + errno = 0; + gnutls_global_init(); + gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); + gnutls_certificate_set_x509_trust_file(ssl_data_loc->certificate, "hostcert.pem", GNUTLS_X509_FMT_PEM); + gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); + { + int protocol_priority[16] = { GNUTLS_SSL3, 0 }; + int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 }; + int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 }; + int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 }; + int comp_priority[16] = { GNUTLS_COMP_NULL, 0 }; + + gnutls_cipher_set_priority(ssl_data_loc->session, cipher_priority); + gnutls_compression_set_priority(ssl_data_loc->session, comp_priority); + gnutls_kx_set_priority(ssl_data_loc->session, kx_priority); + gnutls_protocol_set_priority(ssl_data_loc->session, protocol_priority); + gnutls_mac_set_priority(ssl_data_loc->session, mac_priority); + } + gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); // this part is killing me. + + debug_info("GnuTLS step 1..."); + gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); + debug_info("GnuTLS step 2..."); + gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write); + debug_info("GnuTLS step 3..."); + gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read); + debug_info("GnuTLS step 4 -- now handshaking..."); + if (errno) + debug_info("WARN: errno says %s before handshake!", strerror(errno)); + return_me = gnutls_handshake(ssl_data_loc->session); + debug_info("GnuTLS handshake done..."); + + if (return_me != GNUTLS_E_SUCCESS) { + internal_ssl_cleanup(ssl_data_loc); + free(ssl_data_loc); + debug_info("GnuTLS reported something wrong."); + gnutls_perror(return_me); + debug_info("oh.. errno says %s", strerror(errno)); + } else { + connection->ssl_data = ssl_data_loc; + ret = IDEVICE_E_SUCCESS; + debug_info("SSL mode enabled"); + } + return ret; +} + +/** + * Disable SSL for the given connection. + * + * @param connection The connection to disable SSL for. + * + * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection + * is NULL. This function also returns IDEVICE_E_SUCCESS when SSL is not + * enabled and does no further error checking on cleanup. + */ +idevice_error_t idevice_connection_disable_ssl(idevice_connection_t connection) +{ + if (!connection) + return IDEVICE_E_INVALID_ARG; + if (!connection->ssl_data) { + /* ignore if ssl is not enabled */ + return IDEVICE_E_SUCCESS; + } + + if (connection->ssl_data->session) { + gnutls_bye(connection->ssl_data->session, GNUTLS_SHUT_RDWR); + } + internal_ssl_cleanup(connection->ssl_data); + free(connection->ssl_data); + connection->ssl_data = NULL; + + debug_info("SSL mode disabled"); + + return IDEVICE_E_SUCCESS; +} + diff --git a/src/idevice.h b/src/idevice.h new file mode 100644 index 0000000..4aab440 --- /dev/null +++ b/src/idevice.h @@ -0,0 +1,54 @@ +/* + * idevice.h + * Device discovery and communication interface -- header file. + * + * Copyright (c) 2008 Zach C. 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 + */ +#ifndef IDEVICE_H +#define IDEVICE_H + +#include +#include + +#include "libimobiledevice/libimobiledevice.h" + +enum connection_type { + CONNECTION_USBMUXD = 1 +}; + +struct ssl_data_int { + gnutls_certificate_credentials_t certificate; + gnutls_session_t session; +}; +typedef struct ssl_data_int *ssl_data_t; + +struct idevice_connection_int { + enum connection_type type; + void *data; + ssl_data_t ssl_data; +}; + +struct idevice_int { + char *uuid; + enum connection_type conn_type; + void *conn_data; +}; + +idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection); +idevice_error_t idevice_connection_disable_ssl(idevice_connection_t connection); + +#endif diff --git a/src/installation_proxy.c b/src/installation_proxy.c index e0bccd3..3a6d22a 100644 --- a/src/installation_proxy.c +++ b/src/installation_proxy.c @@ -92,7 +92,7 @@ static instproxy_error_t instproxy_error(property_list_service_error_t err) * @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) +instproxy_error_t instproxy_client_new(idevice_t device, uint16_t port, instproxy_client_t *client) { /* makes sure thread environment is available */ if (!g_thread_supported()) diff --git a/src/installation_proxy.h b/src/installation_proxy.h index 0204533..78128b2 100644 --- a/src/installation_proxy.h +++ b/src/installation_proxy.h @@ -23,7 +23,7 @@ #include -#include "libiphone/installation_proxy.h" +#include "libimobiledevice/installation_proxy.h" #include "property_list_service.h" struct instproxy_client_int { diff --git a/src/iphone.c b/src/iphone.c deleted file mode 100644 index b471e35..0000000 --- a/src/iphone.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - * iphone.c - * Device discovery and communication interface. - * - * Copyright (c) 2008 Zach C. All Rights Reserved. - * 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 -#include -#include -#include - -#include -#include -#include "iphone.h" -#include "debug.h" - -static iphone_event_cb_t event_cb = NULL; - -static void usbmux_event_cb(const usbmuxd_event_t *event, void *user_data) -{ - iphone_event_t ev; - - ev.event = event->event; - ev.uuid = event->device.uuid; - ev.conn_type = CONNECTION_USBMUXD; - - if (event_cb) { - event_cb(&ev, user_data); - } -} - -/** - * Register a callback function that will be called when device add/remove - * events occur. - * - * @param callback Callback function to call. - * @param user_data Application-specific data passed as parameter - * to the registered callback function. - * - * @return IPHONE_E_SUCCESS on success or an error value when an error occured. - */ -iphone_error_t iphone_event_subscribe(iphone_event_cb_t callback, void *user_data) -{ - event_cb = callback; - int res = usbmuxd_subscribe(usbmux_event_cb, user_data); - if (res != 0) { - event_cb = NULL; - debug_info("Error %d when subscribing usbmux event callback!", res); - return IPHONE_E_UNKNOWN_ERROR; - } - return IPHONE_E_SUCCESS; -} - -/** - * Release the event callback function that has been registered with - * iphone_event_subscribe(). - * - * @return IPHONE_E_SUCCESS on success or an error value when an error occured. - */ -iphone_error_t iphone_event_unsubscribe() -{ - event_cb = NULL; - int res = usbmuxd_unsubscribe(); - if (res != 0) { - debug_info("Error %d when unsubscribing usbmux event callback!", res); - return IPHONE_E_UNKNOWN_ERROR; - } - return IPHONE_E_SUCCESS; -} - -/** - * Get a list of currently available devices. - * - * @param devices List of uuids of devices that are currently available. - * This list is terminated by a NULL pointer. - * @param count Number of devices found. - * - * @return IPHONE_E_SUCCESS on success or an error value when an error occured. - */ -iphone_error_t iphone_get_device_list(char ***devices, int *count) -{ - usbmuxd_device_info_t *dev_list; - - *devices = NULL; - *count = 0; - - if (usbmuxd_get_device_list(&dev_list) < 0) { - debug_info("ERROR: usbmuxd is not running!\n", __func__); - return IPHONE_E_NO_DEVICE; - } - - char **newlist = NULL; - int i, newcount = 0; - - for (i = 0; dev_list[i].handle > 0; i++) { - newlist = realloc(*devices, sizeof(char*) * (newcount+1)); - newlist[newcount++] = strdup(dev_list[i].uuid); - *devices = newlist; - } - usbmuxd_device_list_free(&dev_list); - - *count = newcount; - newlist = realloc(*devices, sizeof(char*) * (newcount+1)); - newlist[newcount] = NULL; - *devices = newlist; - - return IPHONE_E_SUCCESS; -} - -/** - * Free a list of device uuids. - * - * @param devices List of uuids to free. - * - * @return Always returnes IPHONE_E_SUCCESS. - */ -iphone_error_t iphone_device_list_free(char **devices) -{ - if (devices) { - int i = 0; - while (devices[i++]) { - free(devices[i]); - } - free(devices); - } - return IPHONE_E_SUCCESS; -} - -/** - * Creates an iphone_device_t structure for the device specified by uuid, - * if the device is available. - * - * @note The resulting iphone_device_t structure has to be freed with - * iphone_device_free() if it is no longer used. - * - * @param device Upon calling this function, a pointer to a location of type - * iphone_device_t. On successful return, this location will be populated. - * @param uuid The UUID to match. - * - * @return IPHONE_E_SUCCESS if ok, otherwise an error code. - */ -iphone_error_t iphone_device_new(iphone_device_t * device, const char *uuid) -{ - usbmuxd_device_info_t muxdev; - int res = usbmuxd_get_device_by_uuid(uuid, &muxdev); - if (res > 0) { - iphone_device_t phone = (iphone_device_t) malloc(sizeof(struct iphone_device_int)); - phone->uuid = strdup(muxdev.uuid); - phone->conn_type = CONNECTION_USBMUXD; - phone->conn_data = (void*)muxdev.handle; - *device = phone; - return IPHONE_E_SUCCESS; - } - /* other connection types could follow here */ - - return IPHONE_E_NO_DEVICE; -} - -/** Cleans up an iPhone structure, then frees the structure itself. - * This is a library-level function; deals directly with the iPhone to tear - * down relations, but otherwise is mostly internal. - * - * @param device A pointer to an iPhone structure. - */ -iphone_error_t iphone_device_free(iphone_device_t device) -{ - if (!device) - return IPHONE_E_INVALID_ARG; - iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - - ret = IPHONE_E_SUCCESS; - - free(device->uuid); - - if (device->conn_type == CONNECTION_USBMUXD) { - device->conn_data = 0; - } - if (device->conn_data) { - free(device->conn_data); - } - free(device); - return ret; -} - -/** - * Set up a connection to the given device. - * - * @param device The device to connect to. - * @param port The destination port to connect to. - * @param connection Pointer to an iphone_connection_t that will be filled - * with the necessary data of the connection. - * - * @return IPHONE_E_SUCCESS if ok, otherwise an error code. - */ -iphone_error_t iphone_device_connect(iphone_device_t device, uint16_t port, iphone_connection_t *connection) -{ - if (!device) { - return IPHONE_E_INVALID_ARG; - } - - if (device->conn_type == CONNECTION_USBMUXD) { - int sfd = usbmuxd_connect((uint32_t)(device->conn_data), port); - if (sfd < 0) { - debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd)); - return IPHONE_E_UNKNOWN_ERROR; - } - iphone_connection_t new_connection = (iphone_connection_t)malloc(sizeof(struct iphone_connection_int)); - new_connection->type = CONNECTION_USBMUXD; - new_connection->data = (void*)sfd; - new_connection->ssl_data = NULL; - *connection = new_connection; - return IPHONE_E_SUCCESS; - } else { - debug_info("Unknown connection type %d", device->conn_type); - } - - return IPHONE_E_UNKNOWN_ERROR; -} - -/** - * Disconnect from the device and clean up the connection structure. - * - * @param connection The connection to close. - * - * @return IPHONE_E_SUCCESS if ok, otherwise an error code. - */ -iphone_error_t iphone_device_disconnect(iphone_connection_t connection) -{ - if (!connection) { - return IPHONE_E_INVALID_ARG; - } - /* shut down ssl if enabled */ - if (connection->ssl_data) { - iphone_connection_disable_ssl(connection); - } - iphone_error_t result = IPHONE_E_UNKNOWN_ERROR; - if (connection->type == CONNECTION_USBMUXD) { - usbmuxd_disconnect((int)(connection->data)); - result = IPHONE_E_SUCCESS; - } else { - debug_info("Unknown connection type %d", connection->type); - } - free(connection); - return result; -} - -/** - * Internally used function to send raw data over the given connection. - */ -static iphone_error_t internal_connection_send(iphone_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes) -{ - if (!connection || !data) { - return IPHONE_E_INVALID_ARG; - } - - if (connection->type == CONNECTION_USBMUXD) { - int res = usbmuxd_send((int)(connection->data), data, len, sent_bytes); - if (res < 0) { - debug_info("ERROR: usbmuxd_send returned %d (%s)", res, strerror(-res)); - return IPHONE_E_UNKNOWN_ERROR; - } - return IPHONE_E_SUCCESS; - } else { - debug_info("Unknown connection type %d", connection->type); - } - return IPHONE_E_UNKNOWN_ERROR; - -} - -/** - * Send data to a device via the given connection. - * - * @param connection The connection to send data over. - * @param data Buffer with data to send. - * @param len Size of the buffer to send. - * @param sent_bytes Pointer to an uint32_t that will be filled - * with the number of bytes actually sent. - * - * @return IPHONE_E_SUCCESS if ok, otherwise an error code. - */ -iphone_error_t iphone_connection_send(iphone_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes) -{ - if (!connection || !data || (connection->ssl_data && !connection->ssl_data->session)) { - return IPHONE_E_INVALID_ARG; - } - - if (connection->ssl_data) { - ssize_t sent = gnutls_record_send(connection->ssl_data->session, (void*)data, (size_t)len); - if ((uint32_t)sent == (uint32_t)len) { - *sent_bytes = sent; - return IPHONE_E_SUCCESS; - } - *sent_bytes = 0; - return IPHONE_E_SSL_ERROR; - } - return internal_connection_send(connection, data, len, sent_bytes); -} - -/** - * Internally used function for receiving raw data over the given connection - * using a timeout. - */ -static iphone_error_t internal_connection_receive_timeout(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) -{ - if (!connection) { - return IPHONE_E_INVALID_ARG; - } - - if (connection->type == CONNECTION_USBMUXD) { - int res = usbmuxd_recv_timeout((int)(connection->data), data, len, recv_bytes, timeout); - if (res < 0) { - debug_info("ERROR: usbmuxd_recv_timeout returned %d (%s)", res, strerror(-res)); - return IPHONE_E_UNKNOWN_ERROR; - } - return IPHONE_E_SUCCESS; - } else { - debug_info("Unknown connection type %d", connection->type); - } - return IPHONE_E_UNKNOWN_ERROR; -} - -/** - * Receive data from a device via the given connection. - * This function will return after the given timeout even if no data has been - * received. - * - * @param connection The connection to receive data from. - * @param data Buffer that will be filled with the received data. - * This buffer has to be large enough to hold len bytes. - * @param len Buffer size or number of bytes to receive. - * @param recv_bytes Number of bytes actually received. - * @param timeout Timeout in milliseconds after which this function should - * return even if no data has been received. - * - * @return IPHONE_E_SUCCESS if ok, otherwise an error code. - */ -iphone_error_t iphone_connection_receive_timeout(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) -{ - if (!connection || (connection->ssl_data && !connection->ssl_data->session)) { - return IPHONE_E_INVALID_ARG; - } - - if (connection->ssl_data) { - ssize_t received = gnutls_record_recv(connection->ssl_data->session, (void*)data, (size_t)len); - if (received > 0) { - *recv_bytes = received; - return IPHONE_E_SUCCESS; - } - *recv_bytes = 0; - return IPHONE_E_SSL_ERROR; - } - return internal_connection_receive_timeout(connection, data, len, recv_bytes, timeout); -} - -/** - * Internally used function for receiving raw data over the given connection. - */ -static iphone_error_t internal_connection_receive(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) -{ - if (!connection) { - return IPHONE_E_INVALID_ARG; - } - - if (connection->type == CONNECTION_USBMUXD) { - int res = usbmuxd_recv((int)(connection->data), data, len, recv_bytes); - if (res < 0) { - debug_info("ERROR: usbmuxd_recv returned %d (%s)", res, strerror(-res)); - return IPHONE_E_UNKNOWN_ERROR; - } - - return IPHONE_E_SUCCESS; - } else { - debug_info("Unknown connection type %d", connection->type); - } - return IPHONE_E_UNKNOWN_ERROR; -} - -/** - * Receive data from a device via the given connection. - * This function is like iphone_connection_receive_timeout, but with a predefined - * reasonable timeout. - * - * @param connection The connection to receive data from. - * @param data Buffer that will be filled with the received data. - * This buffer has to be large enough to hold len bytes. - * @param len Buffer size or number of bytes to receive. - * @param recv_bytes Number of bytes actually received. - * - * @return IPHONE_E_SUCCESS if ok, otherwise an error code. - */ -iphone_error_t iphone_connection_receive(iphone_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) -{ - if (!connection || (connection->ssl_data && !connection->ssl_data->session)) { - return IPHONE_E_INVALID_ARG; - } - - if (connection->ssl_data) { - ssize_t received = gnutls_record_recv(connection->ssl_data->session, (void*)data, (size_t)len); - if (received > 0) { - *recv_bytes = received; - return IPHONE_E_SUCCESS; - } - *recv_bytes = 0; - return IPHONE_E_SSL_ERROR; - } - return internal_connection_receive(connection, data, len, recv_bytes); -} - -iphone_error_t iphone_device_get_handle(iphone_device_t device, uint32_t *handle) -{ - if (!device) - return IPHONE_E_INVALID_ARG; - - if (device->conn_type == CONNECTION_USBMUXD) { - *handle = (uint32_t)device->conn_data; - return IPHONE_E_SUCCESS; - } else { - debug_info("Unknown connection type %d", device->conn_type); - } - return IPHONE_E_UNKNOWN_ERROR; -} - -iphone_error_t iphone_device_get_uuid(iphone_device_t device, char **uuid) -{ - if (!device) - return IPHONE_E_INVALID_ARG; - - *uuid = strdup(device->uuid); - return IPHONE_E_SUCCESS; -} - -/** - * Internally used gnutls callback function for receiving encrypted data. - */ -static ssize_t internal_ssl_read(gnutls_transport_ptr_t transport, char *buffer, size_t length) -{ - int bytes = 0, pos_start_fill = 0; - size_t tbytes = 0; - int this_len = length; - iphone_error_t res; - iphone_connection_t connection = (iphone_connection_t)transport; - char *recv_buffer; - - debug_info("pre-read client wants %zi bytes", length); - - recv_buffer = (char *) malloc(sizeof(char) * this_len); - - /* repeat until we have the full data or an error occurs */ - do { - if ((res = internal_connection_receive(connection, recv_buffer, this_len, (uint32_t*)&bytes)) != IPHONE_E_SUCCESS) { - debug_info("ERROR: iphone_connection_receive returned %d", res); - return res; - } - debug_info("post-read we got %i bytes", bytes); - - // increase read count - tbytes += bytes; - - // fill the buffer with what we got right now - memcpy(buffer + pos_start_fill, recv_buffer, bytes); - pos_start_fill += bytes; - - if (tbytes >= length) { - break; - } - - this_len = length - tbytes; - debug_info("re-read trying to read missing %i bytes", this_len); - } while (tbytes < length); - - if (recv_buffer) { - free(recv_buffer); - } - return tbytes; -} - -/** - * Internally used gnutls callback function for sending encrypted data. - */ -static ssize_t internal_ssl_write(gnutls_transport_ptr_t transport, char *buffer, size_t length) -{ - uint32_t bytes = 0; - iphone_connection_t connection = (iphone_connection_t)transport; - debug_info("pre-send length = %zi", length); - internal_connection_send(connection, buffer, length, &bytes); - debug_info("post-send sent %i bytes", bytes); - return bytes; -} - -/** - * Internally used function for cleaning up SSL stuff. - */ -static void internal_ssl_cleanup(ssl_data_t ssl_data) -{ - if (!ssl_data) - return; - - if (ssl_data->session) { - gnutls_deinit(ssl_data->session); - } - if (ssl_data->certificate) { - gnutls_certificate_free_credentials(ssl_data->certificate); - } -} - -/** - * Enables SSL for the given connection. - * - * @param connection The connection to enable SSL for. - * - * @return IPHONE_E_SUCCESS on success, IPHONE_E_INVALID_ARG when connection - * is NULL or connection->ssl_data is non-NULL, or IPHONE_E_SSL_ERROR when - * SSL initialization, setup, or handshake fails. - */ -iphone_error_t iphone_connection_enable_ssl(iphone_connection_t connection) -{ - if (!connection || connection->ssl_data) - return IPHONE_E_INVALID_ARG; - - iphone_error_t ret = IPHONE_E_SSL_ERROR; - uint32_t return_me = 0; - - ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_int)); - - // Set up GnuTLS... - debug_info("enabling SSL mode"); - errno = 0; - gnutls_global_init(); - gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); - gnutls_certificate_set_x509_trust_file(ssl_data_loc->certificate, "hostcert.pem", GNUTLS_X509_FMT_PEM); - gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); - { - int protocol_priority[16] = { GNUTLS_SSL3, 0 }; - int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 }; - int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 }; - int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 }; - int comp_priority[16] = { GNUTLS_COMP_NULL, 0 }; - - gnutls_cipher_set_priority(ssl_data_loc->session, cipher_priority); - gnutls_compression_set_priority(ssl_data_loc->session, comp_priority); - gnutls_kx_set_priority(ssl_data_loc->session, kx_priority); - gnutls_protocol_set_priority(ssl_data_loc->session, protocol_priority); - gnutls_mac_set_priority(ssl_data_loc->session, mac_priority); - } - gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); // this part is killing me. - - debug_info("GnuTLS step 1..."); - gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); - debug_info("GnuTLS step 2..."); - gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write); - debug_info("GnuTLS step 3..."); - gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read); - debug_info("GnuTLS step 4 -- now handshaking..."); - if (errno) - debug_info("WARN: errno says %s before handshake!", strerror(errno)); - return_me = gnutls_handshake(ssl_data_loc->session); - debug_info("GnuTLS handshake done..."); - - if (return_me != GNUTLS_E_SUCCESS) { - internal_ssl_cleanup(ssl_data_loc); - free(ssl_data_loc); - debug_info("GnuTLS reported something wrong."); - gnutls_perror(return_me); - debug_info("oh.. errno says %s", strerror(errno)); - } else { - connection->ssl_data = ssl_data_loc; - ret = IPHONE_E_SUCCESS; - debug_info("SSL mode enabled"); - } - return ret; -} - -/** - * Disable SSL for the given connection. - * - * @param connection The connection to disable SSL for. - * - * @return IPHONE_E_SUCCESS on success, IPHONE_E_INVALID_ARG when connection - * is NULL. This function also returns IPHONE_E_SUCCESS when SSL is not - * enabled and does no further error checking on cleanup. - */ -iphone_error_t iphone_connection_disable_ssl(iphone_connection_t connection) -{ - if (!connection) - return IPHONE_E_INVALID_ARG; - if (!connection->ssl_data) { - /* ignore if ssl is not enabled */ - return IPHONE_E_SUCCESS; - } - - if (connection->ssl_data->session) { - gnutls_bye(connection->ssl_data->session, GNUTLS_SHUT_RDWR); - } - internal_ssl_cleanup(connection->ssl_data); - free(connection->ssl_data); - connection->ssl_data = NULL; - - debug_info("SSL mode disabled"); - - return IPHONE_E_SUCCESS; -} - diff --git a/src/iphone.h b/src/iphone.h deleted file mode 100644 index 2755349..0000000 --- a/src/iphone.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * iphone.h - * Device discovery and communication interface -- header file. - * - * Copyright (c) 2008 Zach C. 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 - */ -#ifndef IPHONE_H -#define IPHONE_H - -#include -#include - -#include "libiphone/libiphone.h" - -enum connection_type { - CONNECTION_USBMUXD = 1 -}; - -struct ssl_data_int { - gnutls_certificate_credentials_t certificate; - gnutls_session_t session; -}; -typedef struct ssl_data_int *ssl_data_t; - -struct iphone_connection_int { - enum connection_type type; - void *data; - ssl_data_t ssl_data; -}; - -struct iphone_device_int { - char *uuid; - enum connection_type conn_type; - void *conn_data; -}; - -iphone_error_t iphone_connection_enable_ssl(iphone_connection_t connection); -iphone_error_t iphone_connection_disable_ssl(iphone_connection_t connection); - -#endif diff --git a/src/lockdown.c b/src/lockdown.c index 108b558..13f3d48 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -1,6 +1,6 @@ /* * lockdown.c - * libiphone built-in lockdownd client + * libimobiledevice built-in lockdownd client * * Copyright (c) 2008 Zach C. All Rights Reserved. * @@ -30,7 +30,7 @@ #include "property_list_service.h" #include "lockdown.h" -#include "iphone.h" +#include "idevice.h" #include "debug.h" #include "userpref.h" @@ -229,7 +229,7 @@ void lockdownd_client_set_label(lockdownd_client_t client, const char *label) } } -/** Polls the iPhone for lockdownd data. +/** Polls the device for lockdownd data. * * @param control The lockdownd client * @param plist The plist to store the received data @@ -254,7 +254,7 @@ lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist) return ret; } -/** Sends lockdownd data to the iPhone +/** Sends lockdownd data to the device * * @note This function is low-level and should only be used if you need to send * a new type of message. @@ -270,7 +270,7 @@ lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist) return LOCKDOWN_E_INVALID_ARG; lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; - iphone_error_t err; + idevice_error_t err; err = property_list_service_send_xml_plist(client->parent, plist); if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) { @@ -578,7 +578,7 @@ lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **de * * @return an error code (LOCKDOWN_E_SUCCESS on success) */ -lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label) +lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label) { if (!client) return LOCKDOWN_E_INVALID_ARG; @@ -619,7 +619,7 @@ lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_ * * @return an error code (LOCKDOWN_E_SUCCESS on success) */ -lockdownd_error_t lockdownd_client_new_with_handshake(iphone_device_t device, lockdownd_client_t *client, const char *label) +lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label) { if (!client) return LOCKDOWN_E_INVALID_ARG; @@ -644,7 +644,7 @@ lockdownd_error_t lockdownd_client_new_with_handshake(iphone_device_t device, lo free(type); } - ret = iphone_device_get_uuid(device, &client_loc->uuid); + ret = idevice_get_uuid(device, &client_loc->uuid); if (LOCKDOWN_E_SUCCESS != ret) { debug_info("failed to get device uuid."); } @@ -759,7 +759,7 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ plist_t dict = NULL; plist_t dict_record = NULL; gnutls_datum_t public_key = { NULL, 0 }; - int pairing_mode = 0; /* 0 = libiphone, 1 = external */ + int pairing_mode = 0; /* 0 = libimobiledevice, 1 = external */ if (pair_record && pair_record->host_id) { /* valid pair_record passed? */ @@ -780,7 +780,7 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ return ret; } debug_info("device public key follows:\n%s", public_key.data); - /* get libiphone pair_record */ + /* get libimobiledevice pair_record */ ret = generate_pair_record_plist(public_key, NULL, &dict_record); if (ret != LOCKDOWN_E_SUCCESS) { if (dict_record) @@ -795,7 +795,7 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ plist_dict_insert_item(dict,"PairRecord", dict_record); plist_dict_insert_item(dict, "Request", plist_new_string(verb)); - /* send to iPhone */ + /* send to device */ ret = lockdownd_send(client, dict); plist_free(dict); dict = NULL; @@ -803,7 +803,7 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ if (ret != LOCKDOWN_E_SUCCESS) return ret; - /* Now get iPhone's answer */ + /* Now get device's answer */ ret = lockdownd_receive(client, &dict); if (ret != LOCKDOWN_E_SUCCESS) @@ -1116,7 +1116,7 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu return ret; } -/** Starts communication with lockdownd after the iPhone has been paired, +/** Starts communication with lockdownd after the device has been paired, * and if the device requires it, switches to SSL mode. * * @param client The lockdownd client @@ -1244,7 +1244,7 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char plist_dict_insert_item(dict,"Request", plist_new_string("StartService")); plist_dict_insert_item(dict,"Service", plist_new_string(service)); - /* send to iPhone */ + /* send to device */ ret = lockdownd_send(client, dict); plist_free(dict); dict = NULL; diff --git a/src/lockdown.h b/src/lockdown.h index 82ea01f..f515f7f 100644 --- a/src/lockdown.h +++ b/src/lockdown.h @@ -25,7 +25,7 @@ #include #include -#include "libiphone/lockdown.h" +#include "libimobiledevice/lockdown.h" #include "property_list_service.h" struct lockdownd_client_int { diff --git a/src/mobilebackup.c b/src/mobilebackup.c index 5b81c7f..91b9e73 100644 --- a/src/mobilebackup.c +++ b/src/mobilebackup.c @@ -59,7 +59,7 @@ static mobilebackup_error_t mobilebackup_error(device_link_service_error_t err) return MOBILEBACKUP_E_UNKNOWN_ERROR; } -mobilebackup_error_t mobilebackup_client_new(iphone_device_t device, uint16_t port, +mobilebackup_error_t mobilebackup_client_new(idevice_t device, uint16_t port, mobilebackup_client_t * client) { if (!device || port == 0 || !client || *client) @@ -97,7 +97,7 @@ mobilebackup_error_t mobilebackup_client_free(mobilebackup_client_t client) return err; } -/** Polls the iPhone for MobileBackup data. +/** Polls the device for MobileBackup data. * * @param client The MobileBackup client * @param plist A pointer to the location where the plist should be stored @@ -112,7 +112,7 @@ mobilebackup_error_t mobilebackup_receive(mobilebackup_client_t client, plist_t return ret; } -/** Sends MobileBackup data to the iPhone +/** Sends MobileBackup data to the device * * @note This function is low-level and should only be used if you need to send * a new type of message. diff --git a/src/mobilebackup.h b/src/mobilebackup.h index 04ebc45..8f58236 100644 --- a/src/mobilebackup.h +++ b/src/mobilebackup.h @@ -21,7 +21,7 @@ #ifndef MOBILEBACKUP_H #define MOBILEBACKUP_H -#include "libiphone/mobilebackup.h" +#include "libimobiledevice/mobilebackup.h" #include "device_link_service.h" struct mobilebackup_client_int { diff --git a/src/mobilesync.c b/src/mobilesync.c index 15614b5..fec97bc 100644 --- a/src/mobilesync.c +++ b/src/mobilesync.c @@ -59,7 +59,7 @@ static mobilesync_error_t mobilesync_error(device_link_service_error_t err) return MOBILESYNC_E_UNKNOWN_ERROR; } -mobilesync_error_t mobilesync_client_new(iphone_device_t device, uint16_t port, +mobilesync_error_t mobilesync_client_new(idevice_t device, uint16_t port, mobilesync_client_t * client) { if (!device || port == 0 || !client || *client) @@ -97,7 +97,7 @@ mobilesync_error_t mobilesync_client_free(mobilesync_client_t client) return err; } -/** Polls the iPhone for MobileSync data. +/** Polls the device for MobileSync data. * * @param client The MobileSync client * @param plist A pointer to the location where the plist should be stored @@ -112,7 +112,7 @@ mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t * plis return ret; } -/** Sends MobileSync data to the iPhone +/** Sends MobileSync data to the device * * @note This function is low-level and should only be used if you need to send * a new type of message. diff --git a/src/mobilesync.h b/src/mobilesync.h index e69cb25..defb3f4 100644 --- a/src/mobilesync.h +++ b/src/mobilesync.h @@ -21,7 +21,7 @@ #ifndef MOBILESYNC_H #define MOBILESYNC_H -#include "libiphone/mobilesync.h" +#include "libimobiledevice/mobilesync.h" #include "device_link_service.h" struct mobilesync_client_int { diff --git a/src/notification_proxy.c b/src/notification_proxy.c index 0969985..eb5e6b2 100644 --- a/src/notification_proxy.c +++ b/src/notification_proxy.c @@ -92,7 +92,7 @@ static np_error_t np_error(property_list_service_error_t err) * or NP_E_CONN_FAILED when the connection to the device could not be * established. */ -np_error_t np_client_new(iphone_device_t device, uint16_t port, np_client_t *client) +np_error_t np_client_new(idevice_t device, uint16_t port, np_client_t *client) { /* makes sure thread environment is available */ if (!g_thread_supported()) @@ -177,7 +177,7 @@ np_error_t np_post_notification(np_client_t client, const char *notification) return res; } -/** Notifies the iphone to send a notification on the specified event. +/** Notifies the device to send a notification on the specified event. * * @param client The client to send to * @param notification The notifications that should be observed. @@ -206,7 +206,7 @@ np_error_t np_observe_notification( np_client_t client, const char *notification return res; } -/** Notifies the iphone to send a notification on specified events. +/** Notifies the device to send a notification on specified events. * * @param client The client to send to * @param notification_spec Specification of the notifications that should be diff --git a/src/notification_proxy.h b/src/notification_proxy.h index 6ff2cde..6f2dc99 100644 --- a/src/notification_proxy.h +++ b/src/notification_proxy.h @@ -23,7 +23,7 @@ #include -#include "libiphone/notification_proxy.h" +#include "libimobiledevice/notification_proxy.h" #include "property_list_service.h" struct np_client_int { diff --git a/src/property_list_service.c b/src/property_list_service.c index dbf02d6..68aa455 100644 --- a/src/property_list_service.c +++ b/src/property_list_service.c @@ -24,26 +24,26 @@ #include #include "property_list_service.h" -#include "iphone.h" +#include "idevice.h" #include "debug.h" /** - * Convert an iphone_error_t value to an property_list_service_error_t value. + * Convert an idevice_error_t value to an property_list_service_error_t value. * Used internally to get correct error codes. * - * @param err An iphone_error_t error code + * @param err An idevice_error_t error code * * @return A matching property_list_service_error_t error code, * PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. */ -static property_list_service_error_t iphone_to_property_list_service_error(iphone_error_t err) +static property_list_service_error_t idevice_to_property_list_service_error(idevice_error_t err) { switch (err) { - case IPHONE_E_SUCCESS: + case IDEVICE_E_SUCCESS: return PROPERTY_LIST_SERVICE_E_SUCCESS; - case IPHONE_E_INVALID_ARG: + case IDEVICE_E_INVALID_ARG: return PROPERTY_LIST_SERVICE_E_INVALID_ARG; - case IPHONE_E_SSL_ERROR: + case IDEVICE_E_SSL_ERROR: return PROPERTY_LIST_SERVICE_E_SSL_ERROR; default: break; @@ -64,14 +64,14 @@ static property_list_service_error_t iphone_to_property_list_service_error(iphon * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one of the arguments is invalid, * or PROPERTY_LIST_SERVICE_E_MUX_ERROR when connecting to the device failed. */ -property_list_service_error_t property_list_service_client_new(iphone_device_t device, uint16_t port, property_list_service_client_t *client) +property_list_service_error_t property_list_service_client_new(idevice_t device, uint16_t port, property_list_service_client_t *client) { if (!device || port == 0 || !client || *client) return PROPERTY_LIST_SERVICE_E_INVALID_ARG; /* Attempt connection */ - iphone_connection_t connection = NULL; - if (iphone_device_connect(device, port, &connection) != IPHONE_E_SUCCESS) { + idevice_connection_t connection = NULL; + if (idevice_connect(device, port, &connection) != IDEVICE_E_SUCCESS) { return PROPERTY_LIST_SERVICE_E_MUX_ERROR; } @@ -98,7 +98,7 @@ property_list_service_error_t property_list_service_client_free(property_list_se if (!client) return PROPERTY_LIST_SERVICE_E_INVALID_ARG; - property_list_service_error_t err = iphone_to_property_list_service_error(iphone_device_disconnect(client->connection)); + property_list_service_error_t err = idevice_to_property_list_service_error(idevice_disconnect(client->connection)); free(client); return err; } @@ -141,9 +141,9 @@ static property_list_service_error_t internal_plist_send(property_list_service_c nlen = htonl(length); debug_info("sending %d bytes", length); - iphone_connection_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); + idevice_connection_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); if (bytes == sizeof(nlen)) { - iphone_connection_send(client->connection, content, length, (uint32_t*)&bytes); + idevice_connection_send(client->connection, content, length, (uint32_t*)&bytes); if (bytes > 0) { debug_info("sent %d bytes", bytes); debug_plist(plist); @@ -221,7 +221,7 @@ static property_list_service_error_t internal_plist_receive_timeout(property_lis return PROPERTY_LIST_SERVICE_E_INVALID_ARG; } - iphone_connection_receive_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); + idevice_connection_receive_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); debug_info("initial read=%i", bytes); if (bytes < 4) { debug_info("initial read failed!"); @@ -235,7 +235,7 @@ static property_list_service_error_t internal_plist_receive_timeout(property_lis content = (char*)malloc(pktlen); while (curlen < pktlen) { - iphone_connection_receive(client->connection, content+curlen, pktlen-curlen, &bytes); + idevice_connection_receive(client->connection, content+curlen, pktlen-curlen, &bytes); if (bytes <= 0) { res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; break; @@ -324,7 +324,7 @@ property_list_service_error_t property_list_service_enable_ssl(property_list_ser { if (!client || !client->connection) return PROPERTY_LIST_SERVICE_E_INVALID_ARG; - return iphone_to_property_list_service_error(iphone_connection_enable_ssl(client->connection)); + return idevice_to_property_list_service_error(idevice_connection_enable_ssl(client->connection)); } /** @@ -341,6 +341,6 @@ property_list_service_error_t property_list_service_disable_ssl(property_list_se { if (!client || !client->connection) return PROPERTY_LIST_SERVICE_E_INVALID_ARG; - return iphone_to_property_list_service_error(iphone_connection_disable_ssl(client->connection)); + return idevice_to_property_list_service_error(idevice_connection_disable_ssl(client->connection)); } diff --git a/src/property_list_service.h b/src/property_list_service.h index bc3122b..70d8793 100644 --- a/src/property_list_service.h +++ b/src/property_list_service.h @@ -21,7 +21,7 @@ #ifndef PROPERTY_LIST_SERVICE_H #define PROPERTY_LIST_SERVICE_H -#include "iphone.h" +#include "idevice.h" /* Error Codes */ #define PROPERTY_LIST_SERVICE_E_SUCCESS 0 @@ -33,7 +33,7 @@ #define PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR -256 struct property_list_service_client_int { - iphone_connection_t connection; + idevice_connection_t connection; }; typedef struct property_list_service_client_int *property_list_service_client_t; @@ -41,7 +41,7 @@ typedef struct property_list_service_client_int *property_list_service_client_t; typedef int16_t property_list_service_error_t; /* creation and destruction */ -property_list_service_error_t property_list_service_client_new(iphone_device_t device, uint16_t port, property_list_service_client_t *client); +property_list_service_error_t property_list_service_client_new(idevice_t device, uint16_t port, property_list_service_client_t *client); property_list_service_error_t property_list_service_client_free(property_list_service_client_t client); /* sending */ diff --git a/src/sbservices.c b/src/sbservices.c index 2254c64..8cf8b26 100644 --- a/src/sbservices.c +++ b/src/sbservices.c @@ -86,7 +86,7 @@ static sbservices_error_t sbservices_error(property_list_service_error_t err) * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when * client is NULL, or an SBSERVICES_E_* error code otherwise. */ -sbservices_error_t sbservices_client_new(iphone_device_t device, uint16_t port, sbservices_client_t *client) +sbservices_error_t sbservices_client_new(idevice_t device, uint16_t port, sbservices_client_t *client) { /* makes sure thread environment is available */ if (!g_thread_supported()) diff --git a/src/sbservices.h b/src/sbservices.h index 5c95eaf..4ade579 100644 --- a/src/sbservices.h +++ b/src/sbservices.h @@ -23,7 +23,7 @@ #include -#include "libiphone/sbservices.h" +#include "libimobiledevice/sbservices.h" #include "property_list_service.h" struct sbservices_client_int { diff --git a/src/userpref.c b/src/userpref.c index 6eff534..3a8a9d6 100644 --- a/src/userpref.c +++ b/src/userpref.c @@ -33,20 +33,20 @@ #include "userpref.h" #include "debug.h" -#define LIBIPHONE_CONF_DIR "libiphone" -#define LIBIPHONE_CONF_FILE "libiphonerc" +#define LIBIMOBILEDEVICE_CONF_DIR "libimobiledevice" +#define LIBIMOBILEDEVICE_CONF_FILE "libimobiledevicerc" -#define LIBIPHONE_ROOT_PRIVKEY "RootPrivateKey.pem" -#define LIBIPHONE_HOST_PRIVKEY "HostPrivateKey.pem" -#define LIBIPHONE_ROOT_CERTIF "RootCertificate.pem" -#define LIBIPHONE_HOST_CERTIF "HostCertificate.pem" +#define LIBIMOBILEDEVICE_ROOT_PRIVKEY "RootPrivateKey.pem" +#define LIBIMOBILEDEVICE_HOST_PRIVKEY "HostPrivateKey.pem" +#define LIBIMOBILEDEVICE_ROOT_CERTIF "RootCertificate.pem" +#define LIBIMOBILEDEVICE_HOST_CERTIF "HostCertificate.pem" -/** Creates a freedesktop compatible configuration directory for libiphone. +/** Creates a freedesktop compatible configuration directory. */ static void userpref_create_config_dir(void) { - gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, NULL); + gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, NULL); if (!g_file_test(config_dir, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) g_mkdir_with_parents(config_dir, 0755); @@ -112,7 +112,7 @@ static int userpref_set_host_id(const char *host_id) /* Write config file on disk */ buf = g_key_file_to_data(key_file, &length, NULL); config_file = - g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_CONF_FILE, NULL); + g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_CONF_FILE, NULL); file = g_io_channel_new_file(config_file, "w", NULL); g_free(config_file); g_io_channel_write_chars(file, buf, length, NULL, NULL); @@ -136,7 +136,7 @@ void userpref_get_host_id(char **host_id) gchar *loc_host_id; config_file = - g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_CONF_FILE, NULL); + g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_CONF_FILE, NULL); /* now parse file to get the HostID */ key_file = g_key_file_new(); @@ -158,11 +158,11 @@ void userpref_get_host_id(char **host_id) debug_info("Using %s as HostID", *host_id); } -/** Determines whether this iPhone has been connected to this system before. +/** Determines whether this device has been connected to this system before. * - * @param uid The device uid as given by the iPhone. + * @param uid The device uid as given by the device. * - * @return 1 if the iPhone has been connected previously to this configuration + * @return 1 if the device has been connected previously to this configuration * or 0 otherwise. */ int userpref_has_device_public_key(const char *uuid) @@ -172,7 +172,7 @@ int userpref_has_device_public_key(const char *uuid) /* first get config file */ gchar *device_file = g_strconcat(uuid, ".pem", NULL); - config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); + config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) ret = 1; g_free(config_file); @@ -180,10 +180,10 @@ int userpref_has_device_public_key(const char *uuid) return ret; } -/** Mark the iPhone (as represented by the key) as having connected to this +/** Mark the device (as represented by the key) as having connected to this * configuration. * - * @param public_key The public key given by the iPhone + * @param public_key The public key given by the device * * @return 1 on success and 0 if no public key is given or if it has already * been marked as connected previously. @@ -201,7 +201,7 @@ userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t /* build file path */ gchar *device_file = g_strconcat(uuid, ".pem", NULL); - gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); + gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); /* store file */ FILE *pFile = fopen(pem, "wb"); @@ -226,7 +226,7 @@ userpref_error_t userpref_remove_device_public_key(const char *uuid) /* build file path */ gchar *device_file = g_strconcat(uuid, ".pem", NULL); - gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); + gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); /* remove file */ g_remove(pem); @@ -255,7 +255,7 @@ static int userpref_get_file_contents(const char *file, gnutls_datum_t * data) return 0; /* Read file */ - filepath = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, file, NULL); + filepath = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, file, NULL); success = g_file_get_contents(filepath, &content, &size, NULL); g_free(filepath); @@ -392,7 +392,7 @@ static userpref_error_t userpref_import_key(const char* key_name, gnutls_x509_pr * @param crt_name The filename of the certificate to import. * @param cert the gnutls certificate structure. * - * @return IPHONE_E_SUCCESS if the certificate was successfully imported. + * @return IDEVICE_E_SUCCESS if the certificate was successfully imported. */ static userpref_error_t userpref_import_crt(const char* crt_name, gnutls_x509_crt_t cert) { @@ -426,16 +426,16 @@ userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, userpref_error_t ret = USERPREF_E_SUCCESS; if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); + ret = userpref_import_key(LIBIMOBILEDEVICE_ROOT_PRIVKEY, root_privkey); if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); + ret = userpref_import_key(LIBIMOBILEDEVICE_HOST_PRIVKEY, host_privkey); if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); + ret = userpref_import_crt(LIBIMOBILEDEVICE_ROOT_CERTIF, root_crt); if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_crt(LIBIPHONE_HOST_CERTIF, host_crt); + ret = userpref_import_crt(LIBIMOBILEDEVICE_HOST_CERTIF, host_crt); if (USERPREF_E_SUCCESS != ret) { @@ -444,16 +444,16 @@ userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, ret = userpref_gen_keys_and_cert(); if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); + ret = userpref_import_key(LIBIMOBILEDEVICE_ROOT_PRIVKEY, root_privkey); if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); + ret = userpref_import_key(LIBIMOBILEDEVICE_HOST_PRIVKEY, host_privkey); if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); + ret = userpref_import_crt(LIBIMOBILEDEVICE_ROOT_CERTIF, root_crt); if (ret == USERPREF_E_SUCCESS) - ret = userpref_import_crt(LIBIPHONE_HOST_CERTIF, host_crt); + ret = userpref_import_crt(LIBIMOBILEDEVICE_HOST_CERTIF, host_crt); } return ret; @@ -471,7 +471,7 @@ userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls if (!pem_root_cert || !pem_host_cert) return USERPREF_E_INVALID_ARG; - if (userpref_get_file_contents(LIBIPHONE_ROOT_CERTIF, pem_root_cert) && userpref_get_file_contents(LIBIPHONE_HOST_CERTIF, pem_host_cert)) + if (userpref_get_file_contents(LIBIMOBILEDEVICE_ROOT_CERTIF, pem_root_cert) && userpref_get_file_contents(LIBIMOBILEDEVICE_HOST_CERTIF, pem_host_cert)) return USERPREF_E_SUCCESS; else { g_free(pem_root_cert->data); @@ -503,25 +503,25 @@ userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_d userpref_create_config_dir(); /* Now write keys and certificates to disk */ - pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_PRIVKEY, NULL); + pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_ROOT_PRIVKEY, NULL); pFile = fopen(pem, "wb"); fwrite(root_key->data, 1, root_key->size, pFile); fclose(pFile); g_free(pem); - pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_HOST_PRIVKEY, NULL); + pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_HOST_PRIVKEY, NULL); pFile = fopen(pem, "wb"); fwrite(host_key->data, 1, host_key->size, pFile); fclose(pFile); g_free(pem); - pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_CERTIF, NULL); + pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_ROOT_CERTIF, NULL); pFile = fopen(pem, "wb"); fwrite(root_cert->data, 1, root_cert->size, pFile); fclose(pFile); g_free(pem); - pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_HOST_CERTIF, NULL); + pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_HOST_CERTIF, NULL); pFile = fopen(pem, "wb"); fwrite(host_cert->data, 1, host_cert->size, pFile); fclose(pFile); diff --git a/swig/Makefile.am b/swig/Makefile.am index ef87733..6852aad 100644 --- a/swig/Makefile.am +++ b/swig/Makefile.am @@ -1,33 +1,33 @@ INCLUDES = -I$(top_srcdir)/include $(libplist_CFLAGS) $(SWIG_PYTHON_CPPFLAGS) -I$(oldincludedir) if HAVE_SWIG -BUILT_SOURCES = iphone_wrap.cxx -SWIG_SOURCES = iphone.i +BUILT_SOURCES = imobiledevice_wrap.cxx +SWIG_SOURCES = imobiledevice.i CLEANFILES = \ *.pyc \ *.pyo \ - _iphone.so \ - iphone.py \ - iphone_wrap.cxx + _imobiledevice.so \ + imobiledevice.py \ + imobiledevice_wrap.cxx EXTRA_DIST = \ __init__.py \ - iphone.i + imobiledevice.i -swigincludedir =$(includedir)/libiphone/swig +swigincludedir =$(includedir)/libimobiledevice/swig swiginclude_HEADERS = $(SWIG_SOURCES) -iphonedir = $(pyexecdir)/iphone -iphone_PYTHON = __init__.py -nodist_iphone_PYTHON = iphone.py -iphone_LTLIBRARIES = _iphone.la -nodist__iphone_la_SOURCES = iphone_wrap.cxx $(SWIG_SOURCES) -_iphone_la_CFLAGS = $(PYTHON_CPPFLAGS) -I$(top_srcdir)/src -_iphone_la_LDFLAGS = -module -avoid-version $(PYTHON_LDFLAGS) -_iphone_la_LIBADD = $(top_builddir)/src/libiphone.la $(libplistmm_LIBS) +imobiledevicedir = $(pyexecdir)/imobiledevice +imobiledevice_PYTHON = __init__.py +nodist_imobiledevice_PYTHON = imobiledevice.py +imobiledevice_LTLIBRARIES = _imobiledevice.la +nodist__imobiledevice_la_SOURCES = imobiledevice_wrap.cxx $(SWIG_SOURCES) +_imobiledevice_la_CFLAGS = $(PYTHON_CPPFLAGS) -I$(top_srcdir)/src +_imobiledevice_la_LDFLAGS = -module -avoid-version $(PYTHON_LDFLAGS) +_imobiledevice_la_LIBADD = $(top_builddir)/src/libimobiledevice.la $(libplistmm_LIBS) -iphone_wrap.cxx : $(SWIG_SOURCES) +imobiledevice_wrap.cxx : $(SWIG_SOURCES) $(SWIG) $(SWIG_PYTHON_OPT) $(INCLUDES) -I$(top_srcdir)/src -o $@ $< endif # HAVE_SWIG diff --git a/swig/imobiledevice.i b/swig/imobiledevice.i new file mode 100644 index 0000000..f978c8e --- /dev/null +++ b/swig/imobiledevice.i @@ -0,0 +1,220 @@ + /* swig.i */ + %module imobiledevice + %feature("autodoc", "1"); + %{ + /* Includes the header in the wrapper code */ + #include + #include + #include + #include + #include + #include "../src/debug.h" + typedef struct { + idevice_t dev; + } idevice; + + typedef struct { + idevice* dev; + lockdownd_client_t client; + } Lockdownd; + + typedef struct { + idevice* dev; + mobilesync_client_t client; + } MobileSync; + +//now declare funtions to handle creation and deletion of objects +void my_delete_idevice(idevice* dev); +Lockdownd* my_new_Lockdownd(idevice* device); +void my_delete_Lockdownd(Lockdownd* lckd); +MobileSync* my_new_MobileSync(Lockdownd* lckd); +PList::Node* new_node_from_plist(plist_t node); + + %} +/* Parse the header file to generate wrappers */ +%include "stdint.i" +%include "cstring.i" +%include "plist/swig/plist.i" + +typedef struct { + idevice_t dev; +} idevice; + +typedef struct { + idevice* dev; + lockdownd_client_t client; +} Lockdownd; + +typedef struct { + idevice* dev; + mobilesync_client_t client; +} MobileSync; + +%inline %{ +//now define funtions to handle creation and deletion of objects + + +void my_delete_idevice(idevice* dev) { + if (dev) { + idevice_free(dev->dev); + free(dev); + } +} + +Lockdownd* my_new_Lockdownd(idevice* device) { + if (!device) return NULL; + Lockdownd* client = (Lockdownd*) malloc(sizeof(Lockdownd)); + client->dev = device; + client->client = NULL; + if (LOCKDOWN_E_SUCCESS == lockdownd_client_new_with_handshake(device->dev , &(client->client), NULL)) { + return client; + } + else { + free(client); + return NULL; + } +} + +void my_delete_Lockdownd(Lockdownd* lckd) { + if (lckd) { + lockdownd_client_free(lckd->client); + free(lckd); + } +} + +MobileSync* my_new_MobileSync(Lockdownd* lckd) { + if (!lckd || !lckd->dev) return NULL; + MobileSync* client = NULL; + uint16_t port = 0; + if (LOCKDOWN_E_SUCCESS == lockdownd_start_service(lckd->client, "com.apple.mobilesync", &port)) { + client = (MobileSync*) malloc(sizeof(MobileSync)); + client->dev = lckd->dev; + client->client = NULL; + mobilesync_client_new(lckd->dev->dev, port, &(client->client)); + } + return client; +} + +PList::Node* new_node_from_plist(plist_t node) +{ + PList::Node* ret = NULL; + plist_type subtype = plist_get_node_type(node); + switch(subtype) + { + case PLIST_DICT: + ret = new PList::Dictionary(node); + break; + case PLIST_ARRAY: + ret = new PList::Array(node); + break; + case PLIST_BOOLEAN: + ret = new PList::Boolean(node); + break; + case PLIST_UINT: + ret = new PList::Integer(node); + break; + case PLIST_REAL: + ret = new PList::Real(node); + break; + case PLIST_STRING: + ret = new PList::String(node); + break; + case PLIST_DATE: + ret = new PList::Date(node); + break; + case PLIST_DATA: + ret = new PList::Data(node); + break; + default: + break; + } + return ret; +} +%} + + +%extend idevice { // Attach these functions to struct idevice + idevice() { + idevice* device = (idevice*) malloc(sizeof(idevice)); + device->dev = NULL; + return device; + } + + ~idevice() { + my_delete_idevice($self); + } + + void set_debug_level(int level) { + idevice_set_debug_level(level); + } + + int init_device_by_uuid(char* uuid) { + if (IDEVICE_E_SUCCESS == idevice_new(&($self->dev), uuid)) + return 1; + return 0; + } + + int init_device() { + if (IDEVICE_E_SUCCESS == idevice_new(&($self->dev), NULL)) + return 1; + return 0; + } + + %newobject get_uuid; + char* get_uuid(){ + char* uuid = NULL; + idevice_get_uuid($self->dev, &uuid); + return uuid; + } + + Lockdownd* get_lockdown_client() { + return my_new_Lockdownd($self); + } +}; + + +%extend Lockdownd { // Attach these functions to struct Lockdownd + Lockdownd(idevice* device) { + return my_new_Lockdownd(device); + } + + ~Lockdownd() { + my_delete_Lockdownd($self); + } + + void send(PList::Node* node) { + lockdownd_send($self->client, node->GetPlist()); + } + + PList::Node* receive() { + plist_t node = NULL; + lockdownd_receive($self->client, &node); + return new_node_from_plist(node); + } + + MobileSync* get_mobilesync_client() { + return my_new_MobileSync($self); + } +}; + +%extend MobileSync { // Attach these functions to struct MobileSync + MobileSync(Lockdownd* lckd) { + return my_new_MobileSync(lckd); + } + + ~MobileSync() { + mobilesync_client_free($self->client); + free($self); + } + + void send(PList::Node* node) { + mobilesync_send($self->client, node->GetPlist()); + } + + PList::Node* receive() { + plist_t node = NULL; + mobilesync_receive($self->client, &node); + return new_node_from_plist(node); + } +}; + diff --git a/swig/iphone.i b/swig/iphone.i deleted file mode 100644 index 81ef488..0000000 --- a/swig/iphone.i +++ /dev/null @@ -1,220 +0,0 @@ - /* swig.i */ - %module iphone - %feature("autodoc", "1"); - %{ - /* Includes the header in the wrapper code */ - #include - #include - #include - #include - #include - #include "../src/debug.h" - typedef struct { - iphone_device_t dev; - } iPhone; - - typedef struct { - iPhone* dev; - lockdownd_client_t client; - } Lockdownd; - - typedef struct { - iPhone* dev; - mobilesync_client_t client; - } MobileSync; - -//now declare funtions to handle creation and deletion of objects -void my_delete_iPhone(iPhone* dev); -Lockdownd* my_new_Lockdownd(iPhone* phone); -void my_delete_Lockdownd(Lockdownd* lckd); -MobileSync* my_new_MobileSync(Lockdownd* lckd); -PList::Node* new_node_from_plist(plist_t node); - - %} -/* Parse the header file to generate wrappers */ -%include "stdint.i" -%include "cstring.i" -%include "plist/swig/plist.i" - -typedef struct { - iphone_device_t dev; -} iPhone; - -typedef struct { - iPhone* dev; - lockdownd_client_t client; -} Lockdownd; - -typedef struct { - iPhone* dev; - mobilesync_client_t client; -} MobileSync; - -%inline %{ -//now define funtions to handle creation and deletion of objects - - -void my_delete_iPhone(iPhone* dev) { - if (dev) { - iphone_device_free(dev->dev); - free(dev); - } -} - -Lockdownd* my_new_Lockdownd(iPhone* phone) { - if (!phone) return NULL; - Lockdownd* client = (Lockdownd*) malloc(sizeof(Lockdownd)); - client->dev = phone; - client->client = NULL; - if (LOCKDOWN_E_SUCCESS == lockdownd_client_new_with_handshake(phone->dev , &(client->client), NULL)) { - return client; - } - else { - free(client); - return NULL; - } -} - -void my_delete_Lockdownd(Lockdownd* lckd) { - if (lckd) { - lockdownd_client_free(lckd->client); - free(lckd); - } -} - -MobileSync* my_new_MobileSync(Lockdownd* lckd) { - if (!lckd || !lckd->dev) return NULL; - MobileSync* client = NULL; - uint16_t port = 0; - if (LOCKDOWN_E_SUCCESS == lockdownd_start_service(lckd->client, "com.apple.mobilesync", &port)) { - client = (MobileSync*) malloc(sizeof(MobileSync)); - client->dev = lckd->dev; - client->client = NULL; - mobilesync_client_new(lckd->dev->dev, port, &(client->client)); - } - return client; -} - -PList::Node* new_node_from_plist(plist_t node) -{ - PList::Node* ret = NULL; - plist_type subtype = plist_get_node_type(node); - switch(subtype) - { - case PLIST_DICT: - ret = new PList::Dictionary(node); - break; - case PLIST_ARRAY: - ret = new PList::Array(node); - break; - case PLIST_BOOLEAN: - ret = new PList::Boolean(node); - break; - case PLIST_UINT: - ret = new PList::Integer(node); - break; - case PLIST_REAL: - ret = new PList::Real(node); - break; - case PLIST_STRING: - ret = new PList::String(node); - break; - case PLIST_DATE: - ret = new PList::Date(node); - break; - case PLIST_DATA: - ret = new PList::Data(node); - break; - default: - break; - } - return ret; -} -%} - - -%extend iPhone { // Attach these functions to struct iPhone - iPhone() { - iPhone* phone = (iPhone*) malloc(sizeof(iPhone)); - phone->dev = NULL; - return phone; - } - - ~iPhone() { - my_delete_iPhone($self); - } - - void set_debug_level(int level) { - iphone_set_debug_level(level); - } - - int init_device_by_uuid(char* uuid) { - if (IPHONE_E_SUCCESS == iphone_device_new(&($self->dev), uuid)) - return 1; - return 0; - } - - int init_device() { - if (IPHONE_E_SUCCESS == iphone_device_new(&($self->dev), NULL)) - return 1; - return 0; - } - - %newobject get_uuid; - char* get_uuid(){ - char* uuid = NULL; - iphone_device_get_uuid($self->dev, &uuid); - return uuid; - } - - Lockdownd* get_lockdown_client() { - return my_new_Lockdownd($self); - } -}; - - -%extend Lockdownd { // Attach these functions to struct Lockdownd - Lockdownd(iPhone* phone) { - return my_new_Lockdownd(phone); - } - - ~Lockdownd() { - my_delete_Lockdownd($self); - } - - void send(PList::Node* node) { - lockdownd_send($self->client, node->GetPlist()); - } - - PList::Node* receive() { - plist_t node = NULL; - lockdownd_receive($self->client, &node); - return new_node_from_plist(node); - } - - MobileSync* get_mobilesync_client() { - return my_new_MobileSync($self); - } -}; - -%extend MobileSync { // Attach these functions to struct MobileSync - MobileSync(Lockdownd* lckd) { - return my_new_MobileSync(lckd); - } - - ~MobileSync() { - mobilesync_client_free($self->client); - free($self); - } - - void send(PList::Node* node) { - mobilesync_send($self->client, node->GetPlist()); - } - - PList::Node* receive() { - plist_t node = NULL; - mobilesync_receive($self->client, &node); - return new_node_from_plist(node); - } -}; - diff --git a/tools/Makefile.am b/tools/Makefile.am index d19ef0c..9b6a6e8 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -3,25 +3,25 @@ INCLUDES = -I$(top_srcdir)/include AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) -bin_PROGRAMS = iphone_id iphoneinfo iphonesyslog iphonebackup +bin_PROGRAMS = idevice_id ideviceinfo idevicesyslog idevicebackup -iphoneinfo_SOURCES = iphoneinfo.c -iphoneinfo_CFLAGS = $(AM_CFLAGS) -iphoneinfo_LDFLAGS = $(AM_LDFLAGS) -iphoneinfo_LDADD = ../src/libiphone.la +ideviceinfo_SOURCES = ideviceinfo.c +ideviceinfo_CFLAGS = $(AM_CFLAGS) +ideviceinfo_LDFLAGS = $(AM_LDFLAGS) +ideviceinfo_LDADD = ../src/libimobiledevice.la -iphonesyslog_SOURCES = iphonesyslog.c -iphonesyslog_CFLAGS = $(AM_CFLAGS) -iphonesyslog_LDFLAGS = $(AM_LDFLAGS) -iphonesyslog_LDADD = ../src/libiphone.la +idevicesyslog_SOURCES = idevicesyslog.c +idevicesyslog_CFLAGS = $(AM_CFLAGS) +idevicesyslog_LDFLAGS = $(AM_LDFLAGS) +idevicesyslog_LDADD = ../src/libimobiledevice.la -iphone_id_SOURCES = iphone_id.c -iphone_id_CFLAGS = $(AM_CFLAGS) -iphone_id_LDFLAGS = $(AM_LDFLAGS) -iphone_id_LDADD = ../src/libiphone.la +idevice_id_SOURCES = idevice_id.c +idevice_id_CFLAGS = $(AM_CFLAGS) +idevice_id_LDFLAGS = $(AM_LDFLAGS) +idevice_id_LDADD = ../src/libimobiledevice.la -iphonebackup_SOURCES = iphonebackup.c -iphonebackup_CFLAGS = $(AM_CFLAGS) -iphonebackup_LDFLAGS = $(AM_LDFLAGS) -iphonebackup_LDADD = ../src/libiphone.la +idevicebackup_SOURCES = idevicebackup.c +idevicebackup_CFLAGS = $(AM_CFLAGS) +idevicebackup_LDFLAGS = $(AM_LDFLAGS) +idevicebackup_LDADD = ../src/libimobiledevice.la diff --git a/tools/idevice_id.c b/tools/idevice_id.c new file mode 100644 index 0000000..1facb60 --- /dev/null +++ b/tools/idevice_id.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include + +#define MODE_NONE 0 +#define MODE_SHOW_ID 1 +#define MODE_LIST_DEVICES 2 + +static void print_usage(int argc, char **argv) +{ + char *name = NULL; + + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS] [UUID]\n", (name ? name + 1: argv[0])); + printf("Prints device name or a list of attached iPhone/iPod Touch devices.\n\n"); + printf(" The UUID is a 40-digit hexadecimal number of the device\n"); + printf(" for which the name should be retrieved.\n\n"); + printf(" -l, --list\t\tlist UUID of all attached devices\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); +} + +int main(int argc, char **argv) +{ + idevice_t phone = NULL; + lockdownd_client_t client = NULL; + char **dev_list = NULL; + char *devname = NULL; + int ret = 0; + int i; + int mode = MODE_SHOW_ID; + char uuid[41]; + uuid[0] = 0; + + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + idevice_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list")) { + mode = MODE_LIST_DEVICES; + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; + } + } + + /* check if uuid was passed */ + if (mode == MODE_SHOW_ID) { + i--; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); + } + + switch (mode) { + case MODE_SHOW_ID: + idevice_new(&phone, uuid); + if (!phone) { + fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", uuid); + return -2; + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "idevice_id")) { + idevice_free(phone); + fprintf(stderr, "ERROR: Connecting to device failed!\n"); + return -2; + } + + if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &devname)) || !devname) { + fprintf(stderr, "ERROR: Could not get device name!\n"); + ret = -2; + } + + lockdownd_client_free(client); + idevice_free(phone); + + if (ret == 0) { + printf("%s\n", devname); + } + + if (devname) { + free(devname); + } + + return ret; + case MODE_LIST_DEVICES: + default: + if (idevice_get_device_list(&dev_list, &i) < 0) { + fprintf(stderr, "ERROR: Unable to retrieve device list!\n"); + return -1; + } + for (i = 0; dev_list[i] != NULL; i++) { + printf("%s\n", dev_list[i]); + } + idevice_device_list_free(dev_list); + return 0; + } +} diff --git a/tools/idevicebackup.c b/tools/idevicebackup.c new file mode 100644 index 0000000..d3b3ccc --- /dev/null +++ b/tools/idevicebackup.c @@ -0,0 +1,953 @@ +/* + * idevicebackup.c + * Command line interface to use the device's backup and restore service + * + * Copyright (c) 2009-2010 Martin Szulecki All Rights Reserved. + * Copyright (c) 2010 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MOBILEBACKUP_SERVICE_NAME "com.apple.mobilebackup" +#define NP_SERVICE_NAME "com.apple.mobile.notification_proxy" + +static mobilebackup_client_t mobilebackup = NULL; +static lockdownd_client_t client = NULL; +static idevice_t phone = NULL; + +static int quit_flag = 0; + +enum cmd_mode { + CMD_BACKUP, + CMD_RESTORE, + CMD_LEAVE +}; + +enum plist_format_t { + PLIST_FORMAT_XML, + PLIST_FORMAT_BINARY +}; + +enum device_link_file_status_t { + DEVICE_LINK_FILE_STATUS_NONE = 0, + DEVICE_LINK_FILE_STATUS_HUNK, + DEVICE_LINK_FILE_STATUS_LAST_HUNK +}; + +static void notify_cb(const char *notification) +{ + if (!strcmp(notification, NP_SYNC_CANCEL_REQUEST)) { + printf("User has aborted on-device\n"); + quit_flag++; + } else { + printf("unhandled notification '%s' (TODO: implement)\n", notification); + } +} + +static plist_t mobilebackup_factory_info_plist_new() +{ + /* gather data from lockdown */ + GTimeVal tv = {0, 0}; + plist_t value_node = NULL; + plist_t root_node = NULL; + char *uuid = NULL; + char *uuid_uppercase = NULL; + + plist_t ret = plist_new_dict(); + + /* get basic device information in one go */ + lockdownd_get_value(client, NULL, NULL, &root_node); + + /* set fields we understand */ + value_node = plist_dict_get_item(root_node, "BuildVersion"); + plist_dict_insert_item(ret, "Build Version", plist_copy(value_node)); + + value_node = plist_dict_get_item(root_node, "DeviceName"); + plist_dict_insert_item(ret, "Device Name", plist_copy(value_node)); + plist_dict_insert_item(ret, "Display Name", plist_copy(value_node)); + + /* FIXME: How is the GUID generated? */ + plist_dict_insert_item(ret, "GUID", plist_new_string("---")); + + value_node = plist_dict_get_item(root_node, "InternationalMobileEquipmentIdentity"); + if (value_node) + plist_dict_insert_item(ret, "IMEI", plist_copy(value_node)); + + g_get_current_time(&tv); + plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(tv.tv_sec, tv.tv_usec)); + + value_node = plist_dict_get_item(root_node, "ProductType"); + plist_dict_insert_item(ret, "Product Type", plist_copy(value_node)); + + value_node = plist_dict_get_item(root_node, "ProductVersion"); + plist_dict_insert_item(ret, "Product Version", plist_copy(value_node)); + + value_node = plist_dict_get_item(root_node, "SerialNumber"); + plist_dict_insert_item(ret, "Serial Number", plist_copy(value_node)); + + value_node = plist_dict_get_item(root_node, "UniqueDeviceID"); + idevice_get_uuid(phone, &uuid); + plist_dict_insert_item(ret, "Target Identifier", plist_new_string(uuid)); + + /* uppercase */ + uuid_uppercase = g_ascii_strup(uuid, -1); + plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase)); + free(uuid_uppercase); + free(uuid); + + /* FIXME: Embed files as nodes */ + plist_t files = plist_new_dict(); + plist_dict_insert_item(ret, "iTunes Files", files); + plist_dict_insert_item(ret, "iTunes Version", plist_new_string("9.0.2")); + + plist_free(root_node); + + return ret; +} + +static void mobilebackup_info_update_last_backup_date(plist_t info_plist) +{ + GTimeVal tv = {0, 0}; + plist_t node = NULL; + + if (!info_plist) + return; + + g_get_current_time(&tv); + node = plist_dict_get_item(info_plist, "Last Backup Date"); + plist_set_date_val(node, tv.tv_sec, tv.tv_usec); + + node = NULL; +} + +static void buffer_read_from_filename(const char *filename, char **buffer, uint32_t *length) +{ + FILE *f; + uint64_t size; + + f = fopen(filename, "rb"); + + fseek(f, 0, SEEK_END); + size = ftell(f); + rewind(f); + + *buffer = (char*)malloc(sizeof(char)*size); + fread(*buffer, sizeof(char), size, f); + fclose(f); + + *length = size; +} + +static void buffer_write_to_filename(const char *filename, const char *buffer, uint32_t length) +{ + FILE *f; + + f = fopen(filename, "ab"); + fwrite(buffer, sizeof(char), length, f); + fclose(f); +} + +static int plist_read_from_filename(plist_t *plist, const char *filename) +{ + char *buffer = NULL; + uint32_t length; + + if (!filename) + return 0; + + buffer_read_from_filename(filename, &buffer, &length); + + if (!buffer) { + return 0; + } + + if (memcmp(buffer, "bplist00", 8) == 0) { + plist_from_bin(buffer, length, plist); + } else { + plist_from_xml(buffer, length, plist); + } + + free(buffer); + + return 1; +} + +static int plist_write_to_filename(plist_t plist, const char *filename, enum plist_format_t format) +{ + char *buffer = NULL; + uint32_t length; + + if (!plist || !filename) + return 0; + + if (format == PLIST_FORMAT_XML) + plist_to_xml(plist, &buffer, &length); + else if (format == PLIST_FORMAT_BINARY) + plist_to_bin(plist, &buffer, &length); + else + return 0; + + buffer_write_to_filename(filename, buffer, length); + + free(buffer); + + return 1; +} + +static int plist_strcmp(plist_t node, const char *str) +{ + char *buffer = NULL; + int ret = 0; + + if (plist_get_node_type(node) != PLIST_STRING) + return ret; + + plist_get_string_val(node, &buffer); + ret = strcmp(buffer, str); + free(buffer); + + return ret; +} + +static plist_t device_link_message_factory_process_message_new(plist_t content) +{ + plist_t ret = plist_new_array(); + plist_array_append_item(ret, plist_new_string("DLMessageProcessMessage")); + plist_array_append_item(ret, content); + return ret; +} + +static void mobilebackup_cancel_backup_with_error(const char *reason) +{ + plist_t node = plist_new_dict(); + plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("BackupMessageError")); + plist_dict_insert_item(node, "BackupErrorReasonKey", plist_new_string(reason)); + + plist_t message = device_link_message_factory_process_message_new(node); + + mobilebackup_send(mobilebackup, message); + + plist_free(message); + message = NULL; +} + +static plist_t mobilebackup_factory_backup_file_received_new() +{ + plist_t node = plist_new_dict(); + plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("kBackupMessageBackupFileReceived")); + return device_link_message_factory_process_message_new(node); +} + +static gchar *mobilebackup_build_path(const char *backup_directory, const char *name, const char *extension) +{ + gchar *filename = g_strconcat(name, extension, NULL); + gchar *path = g_build_path(G_DIR_SEPARATOR_S, backup_directory, filename, NULL); + g_free(filename); + return path; +} + +static void mobilebackup_write_status(const char *path, int status) +{ + struct stat st; + plist_t status_plist = plist_new_dict(); + plist_dict_insert_item(status_plist, "Backup Success", plist_new_bool(status)); + gchar *file_path = mobilebackup_build_path(path, "Status", ".plist"); + + if (stat(file_path, &st) == 0) + remove(file_path); + + plist_write_to_filename(status_plist, file_path, PLIST_FORMAT_XML); + + plist_free(status_plist); + status_plist = NULL; + + g_free(file_path); +} + +static int mobilebackup_info_is_current_device(plist_t info) +{ + plist_t value_node = NULL; + plist_t node = NULL; + plist_t root_node = NULL; + int ret = 0; + + if (!info) + return ret; + + if (plist_get_node_type(info) != PLIST_DICT) + return ret; + + /* get basic device information in one go */ + lockdownd_get_value(client, NULL, NULL, &root_node); + + /* verify UUID */ + value_node = plist_dict_get_item(root_node, "UniqueDeviceID"); + node = plist_dict_get_item(info, "Target Identifier"); + + if(plist_compare_node_value(value_node, node)) + ret = 1; + else { + printf("Info.plist: UniqueDeviceID does not match.\n"); + } + + /* verify SerialNumber */ + if (ret == 1) { + value_node = plist_dict_get_item(root_node, "SerialNumber"); + node = plist_dict_get_item(info, "Serial Number"); + + if(plist_compare_node_value(value_node, node)) + ret = 1; + else { + printf("Info.plist: SerialNumber does not match.\n"); + ret = 0; + } + } + + /* verify ProductVersion to prevent using backup with different OS version */ + if (ret == 1) { + value_node = plist_dict_get_item(root_node, "ProductVersion"); + node = plist_dict_get_item(info, "Product Version"); + + if(plist_compare_node_value(value_node, node)) + ret = 1; + else { + printf("Info.plist: ProductVersion does not match.\n"); + ret = 0; + } + } + + plist_free(root_node); + root_node = NULL; + + value_node = NULL; + node = NULL; + + return ret; +} + +static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory, const char *hash) +{ + int ret = 0; + gchar *path = mobilebackup_build_path(backup_directory, hash, ".mddata"); + printf("Removing \"%s\"... ", path); + if (!remove( path )) + ret = 1; + else + ret = 0; + + g_free(path); + + if (!ret) + return ret; + + path = mobilebackup_build_path(backup_directory, hash, ".mdinfo"); + printf("Removing \"%s\"... ", path); + if (!remove( path )) + ret = 1; + else + ret = 0; + + g_free(path); + + return ret; +} + +static void do_post_notification(const char *notification) +{ + uint16_t nport = 0; + np_client_t np; + + if (!client) { + if (lockdownd_client_new_with_handshake(phone, &client, "idevicebackup") != LOCKDOWN_E_SUCCESS) { + return; + } + } + + lockdownd_start_service(client, NP_SERVICE_NAME, &nport); + if (nport) { + np_client_new(phone, nport, &np); + if (np) { + np_post_notification(np, notification); + np_client_free(np); + } + } else { + printf("Could not start %s\n", NP_SERVICE_NAME); + } +} + +/** + * signal handler function for cleaning up properly + */ +static void clean_exit(int sig) +{ + fprintf(stderr, "Exiting...\n"); + quit_flag++; +} + +static void print_usage(int argc, char **argv) +{ + char *name = NULL; + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS] CMD [DIRECTORY]\n", (name ? name + 1: argv[0])); + printf("Create or restore backup from the current or specified directory.\n\n"); + printf("commands:\n"); + printf(" backup\tSaves a device backup into DIRECTORY\n"); + printf(" restore\tRestores a device backup from DIRECTORY.\n\n"); + printf("options:\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); +} + +int main(int argc, char *argv[]) +{ + idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; + int i; + char uuid[41]; + uint16_t port = 0; + uuid[0] = 0; + int cmd = -1; + int is_full_backup = 0; + char *backup_directory = NULL; + struct stat st; + plist_t node = NULL; + plist_t node_tmp = NULL; + plist_t manifest_plist = NULL; + plist_t info_plist = NULL; + char *buffer = NULL; + uint64_t length = 0; + uint64_t backup_total_size = 0; + enum device_link_file_status_t file_status; + uint64_t c = 0; + + /* we need to exit cleanly on running backups and restores or we cause havok */ + signal(SIGINT, clean_exit); + signal(SIGQUIT, clean_exit); + signal(SIGTERM, clean_exit); + signal(SIGPIPE, SIG_IGN); + + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + idevice_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { + i++; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; + } + else if (!strcmp(argv[i], "backup")) { + cmd = CMD_BACKUP; + } + else if (!strcmp(argv[i], "restore")) { + cmd = CMD_RESTORE; + } + else if (backup_directory == NULL) { + backup_directory = argv[i]; + } + else { + print_usage(argc, argv); + return 0; + } + } + + /* verify options */ + if (cmd == -1) { + printf("No command specified.\n"); + print_usage(argc, argv); + return -1; + } + + if (backup_directory == NULL) { + printf("No target backup directory specified.\n"); + print_usage(argc, argv); + return -1; + } + + /* verify if passed backup directory exists */ + if (stat(backup_directory, &st) != 0) { + printf("ERROR: Backup directory \"%s\" does not exist!\n", backup_directory); + return -1; + } + + /* restore directory must contain an Info.plist */ + char *info_path = mobilebackup_build_path(backup_directory, "Info", ".plist"); + if (cmd == CMD_RESTORE) { + if (stat(info_path, &st) != 0) { + g_free(info_path); + printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found.\n", backup_directory); + return -1; + } + } + + printf("Backup directory is \"%s\"\n", backup_directory); + + if (uuid[0] != 0) { + ret = idevice_new(&phone, uuid); + if (ret != IDEVICE_E_SUCCESS) { + printf("No device found with uuid %s, is it plugged in?\n", uuid); + return -1; + } + } + else + { + ret = idevice_new(&phone, NULL); + if (ret != IDEVICE_E_SUCCESS) { + printf("No device found, is it plugged in?\n"); + return -1; + } + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "idevicebackup")) { + idevice_free(phone); + return -1; + } + + /* start notification_proxy */ + np_client_t np = NULL; + ret = lockdownd_start_service(client, NP_SERVICE_NAME, &port); + if ((ret == LOCKDOWN_E_SUCCESS) && port) { + np_client_new(phone, port, &np); + np_set_notify_callback(np, notify_cb); + const char *noties[5] = { + NP_SYNC_CANCEL_REQUEST, + NP_SYNC_SUSPEND_REQUEST, + NP_SYNC_RESUME_REQUEST, + NP_BACKUP_DOMAIN_CHANGED, + NULL + }; + np_observe_notifications(np, noties); + } else { + printf("ERROR: Could not start service %s.\n", NP_SERVICE_NAME); + } + + /* start AFC, we need this for the lock file */ + afc_client_t afc = NULL; + port = 0; + ret = lockdownd_start_service(client, "com.apple.afc", &port); + if ((ret == LOCKDOWN_E_SUCCESS) && port) { + afc_client_new(phone, port, &afc); + } + + /* start syslog_relay service and retrieve port */ + port = 0; + ret = lockdownd_start_service(client, MOBILEBACKUP_SERVICE_NAME, &port); + if ((ret == LOCKDOWN_E_SUCCESS) && port) { + printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, port); + mobilebackup_client_new(phone, port, &mobilebackup); + + /* check abort conditions */ + if (quit_flag > 0) { + printf("Aborting backup. Cancelled by user.\n"); + cmd = CMD_LEAVE; + } + + /* verify existing Info.plist */ + if (stat(info_path, &st) == 0) { + printf("Reading Info.plist from backup.\n"); + plist_read_from_filename(&info_plist, info_path); + + if (cmd == CMD_BACKUP) { + if (mobilebackup_info_is_current_device(info_plist)) { + /* update the last backup time within Info.plist */ + mobilebackup_info_update_last_backup_date(info_plist); + remove(info_path); + plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); + } else { + printf("Aborting backup. Backup is not compatible with the current device.\n"); + cmd = CMD_LEAVE; + } + } + } else { + is_full_backup = 1; + } + + do_post_notification(NP_SYNC_WILL_START); + uint64_t lockfile = 0; + afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); + if (lockfile) { + do_post_notification(NP_SYNC_LOCK_REQUEST); + if (afc_file_lock(afc, lockfile, AFC_LOCK_EX) == AFC_E_SUCCESS) { + do_post_notification(NP_SYNC_DID_START); + } else { + afc_file_close(afc, lockfile); + lockfile = 0; + } + } + + switch(cmd) { + case CMD_BACKUP: + printf("Starting backup...\n"); + /* TODO: check domain com.apple.mobile.backup key RequiresEncrypt and WillEncrypt with lockdown */ + /* TODO: verify battery on AC enough battery remaining */ + + /* Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */ + /* create new Info.plist on new backups */ + if (is_full_backup) { + printf("Creating Info.plist for new backup.\n"); + info_plist = mobilebackup_factory_info_plist_new(); + plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); + } + + g_free(info_path); + + /* Manifest.plist (backup manifest (backup state)) */ + char *manifest_path = mobilebackup_build_path(backup_directory, "Manifest", ".plist"); + + /* read the last Manifest.plist */ + if (!is_full_backup) { + printf("Reading existing Manifest.\n"); + plist_read_from_filename(&manifest_plist, manifest_path); + } + + plist_free(info_plist); + info_plist = NULL; + + /* close down the lockdown connection as it is no longer needed */ + if (client) { + lockdownd_client_free(client); + client = NULL; + } + + /* create Status.plist with failed status for now */ + mobilebackup_write_status(backup_directory, 0); + + /* request backup from device with manifest from last backup */ + printf("Requesting backup from device...\n"); + + node = plist_new_dict(); + + if (manifest_plist) + plist_dict_insert_item(node, "BackupManifestKey", manifest_plist); + + plist_dict_insert_item(node, "BackupComputerBasePathKey", plist_new_string("/")); + plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("BackupMessageBackupRequest")); + plist_dict_insert_item(node, "BackupProtocolVersion", plist_new_string("1.6")); + + plist_t message = device_link_message_factory_process_message_new(node); + mobilebackup_send(mobilebackup, message); + plist_free(message); + message = NULL; + node = NULL; + + /* get response */ + int backup_ok = 0; + mobilebackup_receive(mobilebackup, &message); + + node = plist_array_get_item(message, 0); + if (!plist_strcmp(node, "DLMessageProcessMessage")) { + node = plist_array_get_item(message, 1); + node = plist_dict_get_item(node, "BackupMessageTypeKey"); + if (node && !plist_strcmp(node, "BackupMessageBackupReplyOK")) { + printf("Device accepts manifest and will send backup data now...\n"); + backup_ok = 1; + printf("Acknowledging...\n"); + if (is_full_backup) + printf("Full backup mode.\n"); + else + printf("Incremental backup mode.\n"); + printf("Please wait. Device prepares backup data...\n"); + /* send it back for ACK */ + mobilebackup_send(mobilebackup, message); + } + } else { + printf("ERROR: Unhandled message received!\n"); + } + plist_free(message); + message = NULL; + + if (!backup_ok) { + printf("ERROR: Device rejected to start the backup process.\n"); + break; + } + + /* reset backup status */ + backup_ok = 0; + + /* receive and save DLSendFile files and metadata, ACK each */ + int file_index = 0; + int hunk_index = 0; + uint64_t backup_real_size = 0; + char *file_path = NULL; + char *file_ext = NULL; + char *filename_mdinfo = NULL; + char *filename_mddata = NULL; + char *filename_source = NULL; + char *format_size = NULL; + gboolean is_manifest = FALSE; + uint8_t b = 0; + + /* process series of DLSendFile messages */ + do { + mobilebackup_receive(mobilebackup, &message); + node = plist_array_get_item(message, 0); + + /* get out if we don't get a DLSendFile */ + if (plist_strcmp(node, "DLSendFile")) + break; + + node_tmp = plist_array_get_item(message, 2); + + /* first message hunk contains total backup size */ + if (hunk_index == 0) { + node = plist_dict_get_item(node_tmp, "BackupTotalSizeKey"); + if (node) { + plist_get_uint_val(node, &backup_total_size); + format_size = g_format_size_for_display(backup_total_size); + printf("Backup data requires %s on the disk.\n", format_size); + g_free(format_size); + } + } + + /* check DLFileStatusKey (codes: 1 = Hunk, 2 = Last Hunk) */ + node = plist_dict_get_item(node_tmp, "DLFileStatusKey"); + plist_get_uint_val(node, &c); + file_status = c; + + /* get source filename */ + node = plist_dict_get_item(node_tmp, "BackupManifestKey"); + b = 0; + if (node) { + plist_get_bool_val(node, &b); + } + is_manifest = (b == 1) ? TRUE: FALSE; + + /* check if we completed a file */ + if ((file_status == DEVICE_LINK_FILE_STATUS_LAST_HUNK) && (!is_manifest)) { + /* get source filename */ + node = plist_dict_get_item(node_tmp, "DLFileSource"); + plist_get_string_val(node, &filename_source); + + /* increase received size */ + node = plist_dict_get_item(node_tmp, "DLFileAttributesKey"); + node = plist_dict_get_item(node, "FileSize"); + plist_get_uint_val(node, &length); + backup_real_size += length; + + format_size = g_format_size_for_display(backup_real_size); + printf("(%s", format_size); + g_free(format_size); + + format_size = g_format_size_for_display(backup_total_size); + printf("/%s): ", format_size); + g_free(format_size); + + printf("Received file %s... ", filename_source); + + if (filename_source) + free(filename_source); + + /* save .mdinfo */ + node = plist_dict_get_item(node_tmp, "BackupFileInfo"); + if (node) { + node = plist_dict_get_item(node_tmp, "DLFileDest"); + plist_get_string_val(node, &file_path); + + filename_mdinfo = mobilebackup_build_path(backup_directory, file_path, ".mdinfo"); + + /* remove any existing file */ + if (stat(filename_mdinfo, &st) != 0) + remove(filename_mdinfo); + + node = plist_dict_get_item(node_tmp, "BackupFileInfo"); + plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY); + + g_free(filename_mdinfo); + } + + file_index++; + } + + /* save .mddata */ + node = plist_dict_get_item(node_tmp, "BackupFileInfo"); + if (node_tmp && file_path) { + node = plist_dict_get_item(node_tmp, "DLFileDest"); + plist_get_string_val(node, &file_path); + + filename_mddata = mobilebackup_build_path(backup_directory, file_path, is_manifest ? NULL: ".mddata"); + + /* if this is the first hunk, remove any existing file */ + if (stat(filename_mddata, &st) != 0) + remove(filename_mddata); + + /* get file data hunk */ + node_tmp = plist_array_get_item(message, 1); + plist_get_data_val(node_tmp, &buffer, &length); + + buffer_write_to_filename(filename_mddata, buffer, length); + + /* activate currently sent manifest */ + if ((file_status == DEVICE_LINK_FILE_STATUS_LAST_HUNK) && (is_manifest)) { + rename(filename_mddata, manifest_path); + } + + free(buffer); + buffer = NULL; + + g_free(filename_mddata); + } + + hunk_index++; + + if (file_ext) + free(file_ext); + + if (message) + plist_free(message); + message = NULL; + + if (file_status == DEVICE_LINK_FILE_STATUS_LAST_HUNK) { + if (!is_manifest) + printf("DONE\n"); + + /* acknowlegdge that we received the file */ + message = mobilebackup_factory_backup_file_received_new(); + mobilebackup_send(mobilebackup, message); + plist_free(message); + message = NULL; + } + + if (quit_flag > 0) { + /* need to cancel the backup here */ + mobilebackup_cancel_backup_with_error("Cancelling DLSendFile"); + + /* remove any atomic Manifest.plist.tmp */ + if (manifest_path) + g_free(manifest_path); + + manifest_path = mobilebackup_build_path(backup_directory, "Manifest", ".plist.tmp"); + if (stat(manifest_path, &st) == 0) + remove(manifest_path); + break; + } + } while (1); + + printf("Received %d files from device.\n", file_index); + + if (!quit_flag && !plist_strcmp(node, "DLMessageProcessMessage")) { + node_tmp = plist_array_get_item(message, 1); + node = plist_dict_get_item(node_tmp, "BackupMessageTypeKey"); + /* check if we received the final "backup finished" message */ + if (node && !plist_strcmp(node, "BackupMessageBackupFinished")) { + /* backup finished */ + + /* process BackupFilesToDeleteKey */ + node = plist_dict_get_item(node_tmp, "BackupFilesToDeleteKey"); + if (node) { + length = plist_array_get_size(node); + i = 0; + while ((node_tmp = plist_array_get_item(node, i++)) != NULL) { + plist_get_string_val(node_tmp, &file_path); + + if (mobilebackup_delete_backup_file_by_hash(backup_directory, file_path)) { + printf("DONE\n"); + } else + printf("FAILED\n"); + } + } + + /* save last valid Manifest.plist */ + node_tmp = plist_array_get_item(message, 1); + manifest_plist = plist_dict_get_item(node_tmp, "BackupManifestKey"); + if (manifest_plist) { + remove(manifest_path); + printf("Storing Manifest.plist...\n"); + plist_write_to_filename(manifest_plist, manifest_path, PLIST_FORMAT_XML); + } + + backup_ok = 1; + } + } + + if (backup_ok) { + /* Status.plist (Info on how the backup process turned out) */ + printf("Backup Successful.\n"); + mobilebackup_write_status(backup_directory, 1); + } else { + printf("Backup Failed.\n"); + } + + if (manifest_path) + g_free(manifest_path); + + break; + case CMD_RESTORE: + printf("Restoring backup is NOT IMPLEMENTED.\n"); + /* verify battery on AC enough battery remaining */ + /* request restore from device with manifest (BackupMessageRestoreMigrate) */ + /* read mddata/mdinfo files and send to devices using DLSendFile */ + /* signal restore finished message to device */ + /* close down lockdown connection as it is no longer needed */ + lockdownd_client_free(client); + client = NULL; + break; + case CMD_LEAVE: + default: + break; + } + if (lockfile) { + afc_file_lock(afc, lockfile, AFC_LOCK_UN); + afc_file_close(afc, lockfile); + lockfile = 0; + do_post_notification(NP_SYNC_DID_FINISH); + } + } else { + printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME); + lockdownd_client_free(client); + client = NULL; + } + + if (client) { + lockdownd_client_free(client); + client = NULL; + } + + if (afc) + afc_client_free(afc); + + if (np) + np_client_free(np); + + if (mobilebackup) + mobilebackup_client_free(mobilebackup); + + idevice_free(phone); + + return 0; +} + diff --git a/tools/ideviceinfo.c b/tools/ideviceinfo.c new file mode 100644 index 0000000..9183d92 --- /dev/null +++ b/tools/ideviceinfo.c @@ -0,0 +1,336 @@ +/* + * ideviceinfo.c + * Simple utility to show information about an attached device + * + * Copyright (c) 2009 Martin Szulecki 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 +#include +#include +#include +#include + +#include +#include + +#define FORMAT_KEY_VALUE 1 +#define FORMAT_XML 2 + +static const char *domains[] = { + "com.apple.disk_usage", + "com.apple.mobile.battery", +/* FIXME: For some reason lockdownd segfaults on this, works sometimes though + "com.apple.mobile.debug",. */ + "com.apple.xcode.developerdomain", + "com.apple.international", + "com.apple.mobile.data_sync", + "com.apple.mobile.tethered_sync", + "com.apple.mobile.mobile_application_usage", + "com.apple.mobile.backup", + "com.apple.mobile.nikita", + "com.apple.mobile.restriction", + "com.apple.mobile.user_preferences", + "com.apple.mobile.sync_data_class", + "com.apple.mobile.software_behavior", + "com.apple.mobile.iTunes.SQLMusicLibraryPostProcessCommands", + "com.apple.mobile.iTunes.accessories", + "com.apple.fairplay", + "com.apple.iTunes", + "com.apple.mobile.iTunes.store", + "com.apple.mobile.iTunes", + NULL +}; + +static int indent_level = 0; + +static int is_domain_known(char *domain) +{ + int i = 0; + while (domains[i] != NULL) { + if (strstr(domain, domains[i++])) { + return 1; + } + } + return 0; +} + +static void plist_node_to_string(plist_t node); + +static void plist_array_to_string(plist_t node) +{ + /* iterate over items */ + int i, count; + plist_t subnode = NULL; + + count = plist_array_get_size(node); + + for (i = 0; i < count; i++) { + subnode = plist_array_get_item(node, i); + printf("%*s", indent_level, ""); + printf("%d: ", i); + plist_node_to_string(subnode); + } +} + +static void plist_dict_to_string(plist_t node) +{ + /* iterate over key/value pairs */ + plist_dict_iter it = NULL; + + char* key = NULL; + plist_t subnode = NULL; + plist_dict_new_iter(node, &it); + plist_dict_next_item(node, it, &key, &subnode); + while (subnode) + { + printf("%*s", indent_level, ""); + printf("%s", key); + if (plist_get_node_type(subnode) == PLIST_ARRAY) + printf("[%d]: ", plist_array_get_size(subnode)); + else + printf(": "); + free(key); + key = NULL; + plist_node_to_string(subnode); + plist_dict_next_item(node, it, &key, &subnode); + } + free(it); +} + +static void plist_node_to_string(plist_t node) +{ + char *s = NULL; + char *data = NULL; + double d; + uint8_t b; + uint64_t u = 0; + GTimeVal tv = { 0, 0 }; + + plist_type t; + + if (!node) + return; + + t = plist_get_node_type(node); + + switch (t) { + case PLIST_BOOLEAN: + plist_get_bool_val(node, &b); + printf("%s\n", (b ? "true" : "false")); + break; + + case PLIST_UINT: + plist_get_uint_val(node, &u); + printf("%llu\n", (long long)u); + break; + + case PLIST_REAL: + plist_get_real_val(node, &d); + printf("%f\n", d); + break; + + case PLIST_STRING: + plist_get_string_val(node, &s); + printf("%s\n", s); + free(s); + break; + + case PLIST_KEY: + plist_get_key_val(node, &s); + printf("%s: ", s); + free(s); + break; + + case PLIST_DATA: + plist_get_data_val(node, &data, &u); + s = g_base64_encode((guchar *)data, u); + free(data); + printf("%s\n", s); + g_free(s); + break; + + case PLIST_DATE: + plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec); + s = g_time_val_to_iso8601(&tv); + printf("%s\n", s); + free(s); + break; + + case PLIST_ARRAY: + printf("\n"); + indent_level++; + plist_array_to_string(node); + indent_level--; + break; + + case PLIST_DICT: + printf("\n"); + indent_level++; + plist_dict_to_string(node); + indent_level--; + break; + + default: + break; + } +} + +static void print_usage(int argc, char **argv) +{ + int i = 0; + char *name = NULL; + + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); + printf("Show information about a connected iPhone/iPod Touch.\n\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); + printf(" -q, --domain NAME\tset domain of query to NAME. Default: None\n"); + printf(" -k, --key NAME\tonly query key specified by NAME. Default: All keys.\n"); + printf(" -x, --xml\t\toutput information as xml plist instead of key/value pairs\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); + printf(" Known domains are:\n\n"); + while (domains[i] != NULL) { + printf(" %s\n", domains[i++]); + } + printf("\n"); +} + +int main(int argc, char *argv[]) +{ + lockdownd_client_t client = NULL; + idevice_t phone = NULL; + idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; + int i; + int format = FORMAT_KEY_VALUE; + char uuid[41]; + char *domain = NULL; + char *key = NULL; + char *xml_doc = NULL; + uint32_t xml_length; + plist_t node = NULL; + plist_type node_type; + uuid[0] = 0; + + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + idevice_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { + i++; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); + continue; + } + else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) { + i++; + if (!argv[i] || (strlen(argv[i]) < 4)) { + print_usage(argc, argv); + return 0; + } + if (!is_domain_known(argv[i])) { + fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]); + } + domain = strdup(argv[i]); + continue; + } + else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) { + i++; + if (!argv[i] || (strlen(argv[i]) <= 1)) { + print_usage(argc, argv); + return 0; + } + key = strdup(argv[i]); + continue; + } + else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { + format = FORMAT_XML; + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; + } + else { + print_usage(argc, argv); + return 0; + } + } + + if (uuid[0] != 0) { + ret = idevice_new(&phone, uuid); + if (ret != IDEVICE_E_SUCCESS) { + printf("No device found with uuid %s, is it plugged in?\n", uuid); + return -1; + } + } + else + { + ret = idevice_new(&phone, NULL); + if (ret != IDEVICE_E_SUCCESS) { + printf("No device found, is it plugged in?\n"); + return -1; + } + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "ideviceinfo")) { + idevice_free(phone); + return -1; + } + + /* run query and output information */ + if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) { + if (node) { + switch (format) { + case FORMAT_XML: + plist_to_xml(node, &xml_doc, &xml_length); + printf("%s", xml_doc); + free(xml_doc); + break; + case FORMAT_KEY_VALUE: + node_type = plist_get_node_type(node); + if (node_type == PLIST_DICT) { + plist_dict_to_string(node); + } else if (node_type == PLIST_ARRAY) { + plist_array_to_string(node); + break; + } + default: + if (key != NULL) + plist_node_to_string(node); + break; + } + plist_free(node); + node = NULL; + } + } + + if (domain != NULL) + free(domain); + lockdownd_client_free(client); + idevice_free(phone); + + return 0; +} + diff --git a/tools/idevicesyslog.c b/tools/idevicesyslog.c new file mode 100644 index 0000000..32b9711 --- /dev/null +++ b/tools/idevicesyslog.c @@ -0,0 +1,165 @@ +/* + * idevicesyslog.c + * Relay the syslog of a device to stdout + * + * Copyright (c) 2009 Martin Szulecki 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 +#include +#include +#include +#include +#include + +#include +#include + +static int quit_flag = 0; + +void print_usage(int argc, char **argv); + +/** + * signal handler function for cleaning up properly + */ +static void clean_exit(int sig) +{ + fprintf(stderr, "Exiting...\n"); + quit_flag++; +} + +int main(int argc, char *argv[]) +{ + lockdownd_client_t client = NULL; + idevice_t phone = NULL; + idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; + int i; + char uuid[41]; + uint16_t port = 0; + uuid[0] = 0; + + signal(SIGINT, clean_exit); + signal(SIGQUIT, clean_exit); + signal(SIGTERM, clean_exit); + signal(SIGPIPE, SIG_IGN); + + /* parse cmdline args */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { + idevice_set_debug_level(1); + continue; + } + else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { + i++; + if (!argv[i] || (strlen(argv[i]) != 40)) { + print_usage(argc, argv); + return 0; + } + strcpy(uuid, argv[i]); + continue; + } + else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + print_usage(argc, argv); + return 0; + } + else { + print_usage(argc, argv); + return 0; + } + } + + if (uuid[0] != 0) { + ret = idevice_new(&phone, uuid); + if (ret != IDEVICE_E_SUCCESS) { + printf("No device found with uuid %s, is it plugged in?\n", uuid); + return -1; + } + } + else + { + ret = idevice_new(&phone, NULL); + if (ret != IDEVICE_E_SUCCESS) { + printf("No device found, is it plugged in?\n"); + return -1; + } + } + + if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "idevicesyslog")) { + idevice_free(phone); + return -1; + } + + /* start syslog_relay service and retrieve port */ + ret = lockdownd_start_service(client, "com.apple.syslog_relay", &port); + if ((ret == LOCKDOWN_E_SUCCESS) && port) { + lockdownd_client_free(client); + + /* connect to socket relay messages */ + idevice_connection_t conn = NULL; + if ((idevice_connect(phone, port, &conn) != IDEVICE_E_SUCCESS) || !conn) { + printf("ERROR: Could not open usbmux connection.\n"); + } else { + while (!quit_flag) { + char *receive = NULL; + uint32_t datalen = 0, bytes = 0, recv_bytes = 0; + + ret = idevice_connection_receive(conn, (char *) &datalen, sizeof(datalen), &bytes); + datalen = ntohl(datalen); + + if (datalen == 0) + continue; + + recv_bytes += bytes; + receive = (char *) malloc(sizeof(char) * datalen); + + while (!quit_flag && (recv_bytes <= datalen)) { + ret = idevice_connection_receive(conn, receive, datalen, &bytes); + + if (bytes == 0) + break; + + recv_bytes += bytes; + + fwrite(receive, sizeof(char), bytes, stdout); + } + + free(receive); + } + } + idevice_disconnect(conn); + } else { + printf("ERROR: Could not start service com.apple.syslog_relay.\n"); + } + + idevice_free(phone); + + return 0; +} + +void print_usage(int argc, char **argv) +{ + char *name = NULL; + + name = strrchr(argv[0], '/'); + printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); + printf("Relay syslog of a connected iPhone/iPod Touch.\n\n"); + printf(" -d, --debug\t\tenable communication debugging\n"); + printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); + printf(" -h, --help\t\tprints usage information\n"); + printf("\n"); +} + diff --git a/tools/iphone_id.c b/tools/iphone_id.c deleted file mode 100644 index 4a2c3af..0000000 --- a/tools/iphone_id.c +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include -#include - -#define MODE_NONE 0 -#define MODE_SHOW_ID 1 -#define MODE_LIST_DEVICES 2 - -static void print_usage(int argc, char **argv) -{ - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] [UUID]\n", (name ? name + 1: argv[0])); - printf("Prints device name or a list of attached iPhone/iPod Touch devices.\n\n"); - printf(" The UUID is a 40-digit hexadecimal number of the device\n"); - printf(" for which the name should be retrieved.\n\n"); - printf(" -l, --list\t\tlist UUID of all attached devices\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); -} - -int main(int argc, char **argv) -{ - iphone_device_t phone = NULL; - lockdownd_client_t client = NULL; - char **dev_list = NULL; - char *devname = NULL; - int ret = 0; - int i; - int mode = MODE_SHOW_ID; - char uuid[41]; - uuid[0] = 0; - - /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { - iphone_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list")) { - mode = MODE_LIST_DEVICES; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - } - - /* check if uuid was passed */ - if (mode == MODE_SHOW_ID) { - i--; - if (!argv[i] || (strlen(argv[i]) != 40)) { - print_usage(argc, argv); - return 0; - } - strcpy(uuid, argv[i]); - } - - switch (mode) { - case MODE_SHOW_ID: - iphone_device_new(&phone, uuid); - if (!phone) { - fprintf(stderr, "ERROR: No device with UUID=%s attached.\n", uuid); - return -2; - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new(phone, &client, "iphone_id")) { - iphone_device_free(phone); - fprintf(stderr, "ERROR: Connecting to device failed!\n"); - return -2; - } - - if ((LOCKDOWN_E_SUCCESS != lockdownd_get_device_name(client, &devname)) || !devname) { - fprintf(stderr, "ERROR: Could not get device name!\n"); - ret = -2; - } - - lockdownd_client_free(client); - iphone_device_free(phone); - - if (ret == 0) { - printf("%s\n", devname); - } - - if (devname) { - free(devname); - } - - return ret; - case MODE_LIST_DEVICES: - default: - if (iphone_get_device_list(&dev_list, &i) < 0) { - fprintf(stderr, "ERROR: Unable to retrieve device list!\n"); - return -1; - } - for (i = 0; dev_list[i] != NULL; i++) { - printf("%s\n", dev_list[i]); - } - iphone_device_list_free(dev_list); - return 0; - } -} diff --git a/tools/iphonebackup.c b/tools/iphonebackup.c deleted file mode 100644 index bc61347..0000000 --- a/tools/iphonebackup.c +++ /dev/null @@ -1,953 +0,0 @@ -/* - * iphonebackup.c - * Command line interface to use the device's backup and restore service - * - * Copyright (c) 2009-2010 Martin Szulecki All Rights Reserved. - * Copyright (c) 2010 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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define MOBILEBACKUP_SERVICE_NAME "com.apple.mobilebackup" -#define NP_SERVICE_NAME "com.apple.mobile.notification_proxy" - -static mobilebackup_client_t mobilebackup = NULL; -static lockdownd_client_t client = NULL; -static iphone_device_t phone = NULL; - -static int quit_flag = 0; - -enum cmd_mode { - CMD_BACKUP, - CMD_RESTORE, - CMD_LEAVE -}; - -enum plist_format_t { - PLIST_FORMAT_XML, - PLIST_FORMAT_BINARY -}; - -enum device_link_file_status_t { - DEVICE_LINK_FILE_STATUS_NONE = 0, - DEVICE_LINK_FILE_STATUS_HUNK, - DEVICE_LINK_FILE_STATUS_LAST_HUNK -}; - -static void notify_cb(const char *notification) -{ - if (!strcmp(notification, NP_SYNC_CANCEL_REQUEST)) { - printf("User has aborted on-device\n"); - quit_flag++; - } else { - printf("unhandled notification '%s' (TODO: implement)\n", notification); - } -} - -static plist_t mobilebackup_factory_info_plist_new() -{ - /* gather data from lockdown */ - GTimeVal tv = {0, 0}; - plist_t value_node = NULL; - plist_t root_node = NULL; - char *uuid = NULL; - char *uuid_uppercase = NULL; - - plist_t ret = plist_new_dict(); - - /* get basic device information in one go */ - lockdownd_get_value(client, NULL, NULL, &root_node); - - /* set fields we understand */ - value_node = plist_dict_get_item(root_node, "BuildVersion"); - plist_dict_insert_item(ret, "Build Version", plist_copy(value_node)); - - value_node = plist_dict_get_item(root_node, "DeviceName"); - plist_dict_insert_item(ret, "Device Name", plist_copy(value_node)); - plist_dict_insert_item(ret, "Display Name", plist_copy(value_node)); - - /* FIXME: How is the GUID generated? */ - plist_dict_insert_item(ret, "GUID", plist_new_string("---")); - - value_node = plist_dict_get_item(root_node, "InternationalMobileEquipmentIdentity"); - if (value_node) - plist_dict_insert_item(ret, "IMEI", plist_copy(value_node)); - - g_get_current_time(&tv); - plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(tv.tv_sec, tv.tv_usec)); - - value_node = plist_dict_get_item(root_node, "ProductType"); - plist_dict_insert_item(ret, "Product Type", plist_copy(value_node)); - - value_node = plist_dict_get_item(root_node, "ProductVersion"); - plist_dict_insert_item(ret, "Product Version", plist_copy(value_node)); - - value_node = plist_dict_get_item(root_node, "SerialNumber"); - plist_dict_insert_item(ret, "Serial Number", plist_copy(value_node)); - - value_node = plist_dict_get_item(root_node, "UniqueDeviceID"); - iphone_device_get_uuid(phone, &uuid); - plist_dict_insert_item(ret, "Target Identifier", plist_new_string(uuid)); - - /* uppercase */ - uuid_uppercase = g_ascii_strup(uuid, -1); - plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase)); - free(uuid_uppercase); - free(uuid); - - /* FIXME: Embed files as nodes */ - plist_t files = plist_new_dict(); - plist_dict_insert_item(ret, "iTunes Files", files); - plist_dict_insert_item(ret, "iTunes Version", plist_new_string("9.0.2")); - - plist_free(root_node); - - return ret; -} - -static void mobilebackup_info_update_last_backup_date(plist_t info_plist) -{ - GTimeVal tv = {0, 0}; - plist_t node = NULL; - - if (!info_plist) - return; - - g_get_current_time(&tv); - node = plist_dict_get_item(info_plist, "Last Backup Date"); - plist_set_date_val(node, tv.tv_sec, tv.tv_usec); - - node = NULL; -} - -static void buffer_read_from_filename(const char *filename, char **buffer, uint32_t *length) -{ - FILE *f; - uint64_t size; - - f = fopen(filename, "rb"); - - fseek(f, 0, SEEK_END); - size = ftell(f); - rewind(f); - - *buffer = (char*)malloc(sizeof(char)*size); - fread(*buffer, sizeof(char), size, f); - fclose(f); - - *length = size; -} - -static void buffer_write_to_filename(const char *filename, const char *buffer, uint32_t length) -{ - FILE *f; - - f = fopen(filename, "ab"); - fwrite(buffer, sizeof(char), length, f); - fclose(f); -} - -static int plist_read_from_filename(plist_t *plist, const char *filename) -{ - char *buffer = NULL; - uint32_t length; - - if (!filename) - return 0; - - buffer_read_from_filename(filename, &buffer, &length); - - if (!buffer) { - return 0; - } - - if (memcmp(buffer, "bplist00", 8) == 0) { - plist_from_bin(buffer, length, plist); - } else { - plist_from_xml(buffer, length, plist); - } - - free(buffer); - - return 1; -} - -static int plist_write_to_filename(plist_t plist, const char *filename, enum plist_format_t format) -{ - char *buffer = NULL; - uint32_t length; - - if (!plist || !filename) - return 0; - - if (format == PLIST_FORMAT_XML) - plist_to_xml(plist, &buffer, &length); - else if (format == PLIST_FORMAT_BINARY) - plist_to_bin(plist, &buffer, &length); - else - return 0; - - buffer_write_to_filename(filename, buffer, length); - - free(buffer); - - return 1; -} - -static int plist_strcmp(plist_t node, const char *str) -{ - char *buffer = NULL; - int ret = 0; - - if (plist_get_node_type(node) != PLIST_STRING) - return ret; - - plist_get_string_val(node, &buffer); - ret = strcmp(buffer, str); - free(buffer); - - return ret; -} - -static plist_t device_link_message_factory_process_message_new(plist_t content) -{ - plist_t ret = plist_new_array(); - plist_array_append_item(ret, plist_new_string("DLMessageProcessMessage")); - plist_array_append_item(ret, content); - return ret; -} - -static void mobilebackup_cancel_backup_with_error(const char *reason) -{ - plist_t node = plist_new_dict(); - plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("BackupMessageError")); - plist_dict_insert_item(node, "BackupErrorReasonKey", plist_new_string(reason)); - - plist_t message = device_link_message_factory_process_message_new(node); - - mobilebackup_send(mobilebackup, message); - - plist_free(message); - message = NULL; -} - -static plist_t mobilebackup_factory_backup_file_received_new() -{ - plist_t node = plist_new_dict(); - plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("kBackupMessageBackupFileReceived")); - return device_link_message_factory_process_message_new(node); -} - -static gchar *mobilebackup_build_path(const char *backup_directory, const char *name, const char *extension) -{ - gchar *filename = g_strconcat(name, extension, NULL); - gchar *path = g_build_path(G_DIR_SEPARATOR_S, backup_directory, filename, NULL); - g_free(filename); - return path; -} - -static void mobilebackup_write_status(const char *path, int status) -{ - struct stat st; - plist_t status_plist = plist_new_dict(); - plist_dict_insert_item(status_plist, "Backup Success", plist_new_bool(status)); - gchar *file_path = mobilebackup_build_path(path, "Status", ".plist"); - - if (stat(file_path, &st) == 0) - remove(file_path); - - plist_write_to_filename(status_plist, file_path, PLIST_FORMAT_XML); - - plist_free(status_plist); - status_plist = NULL; - - g_free(file_path); -} - -static int mobilebackup_info_is_current_device(plist_t info) -{ - plist_t value_node = NULL; - plist_t node = NULL; - plist_t root_node = NULL; - int ret = 0; - - if (!info) - return ret; - - if (plist_get_node_type(info) != PLIST_DICT) - return ret; - - /* get basic device information in one go */ - lockdownd_get_value(client, NULL, NULL, &root_node); - - /* verify UUID */ - value_node = plist_dict_get_item(root_node, "UniqueDeviceID"); - node = plist_dict_get_item(info, "Target Identifier"); - - if(plist_compare_node_value(value_node, node)) - ret = 1; - else { - printf("Info.plist: UniqueDeviceID does not match.\n"); - } - - /* verify SerialNumber */ - if (ret == 1) { - value_node = plist_dict_get_item(root_node, "SerialNumber"); - node = plist_dict_get_item(info, "Serial Number"); - - if(plist_compare_node_value(value_node, node)) - ret = 1; - else { - printf("Info.plist: SerialNumber does not match.\n"); - ret = 0; - } - } - - /* verify ProductVersion to prevent using backup with different OS version */ - if (ret == 1) { - value_node = plist_dict_get_item(root_node, "ProductVersion"); - node = plist_dict_get_item(info, "Product Version"); - - if(plist_compare_node_value(value_node, node)) - ret = 1; - else { - printf("Info.plist: ProductVersion does not match.\n"); - ret = 0; - } - } - - plist_free(root_node); - root_node = NULL; - - value_node = NULL; - node = NULL; - - return ret; -} - -static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory, const char *hash) -{ - int ret = 0; - gchar *path = mobilebackup_build_path(backup_directory, hash, ".mddata"); - printf("Removing \"%s\"... ", path); - if (!remove( path )) - ret = 1; - else - ret = 0; - - g_free(path); - - if (!ret) - return ret; - - path = mobilebackup_build_path(backup_directory, hash, ".mdinfo"); - printf("Removing \"%s\"... ", path); - if (!remove( path )) - ret = 1; - else - ret = 0; - - g_free(path); - - return ret; -} - -static void do_post_notification(const char *notification) -{ - uint16_t nport = 0; - np_client_t np; - - if (!client) { - if (lockdownd_client_new_with_handshake(phone, &client, "iphonebackup") != LOCKDOWN_E_SUCCESS) { - return; - } - } - - lockdownd_start_service(client, NP_SERVICE_NAME, &nport); - if (nport) { - np_client_new(phone, nport, &np); - if (np) { - np_post_notification(np, notification); - np_client_free(np); - } - } else { - printf("Could not start %s\n", NP_SERVICE_NAME); - } -} - -/** - * signal handler function for cleaning up properly - */ -static void clean_exit(int sig) -{ - fprintf(stderr, "Exiting...\n"); - quit_flag++; -} - -static void print_usage(int argc, char **argv) -{ - char *name = NULL; - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS] CMD [DIRECTORY]\n", (name ? name + 1: argv[0])); - printf("Create or restore backup from the current or specified directory.\n\n"); - printf("commands:\n"); - printf(" backup\tSaves a device backup into DIRECTORY\n"); - printf(" restore\tRestores a device backup from DIRECTORY.\n\n"); - printf("options:\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); -} - -int main(int argc, char *argv[]) -{ - iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - int i; - char uuid[41]; - uint16_t port = 0; - uuid[0] = 0; - int cmd = -1; - int is_full_backup = 0; - char *backup_directory = NULL; - struct stat st; - plist_t node = NULL; - plist_t node_tmp = NULL; - plist_t manifest_plist = NULL; - plist_t info_plist = NULL; - char *buffer = NULL; - uint64_t length = 0; - uint64_t backup_total_size = 0; - enum device_link_file_status_t file_status; - uint64_t c = 0; - - /* we need to exit cleanly on running backups and restores or we cause havok */ - signal(SIGINT, clean_exit); - signal(SIGQUIT, clean_exit); - signal(SIGTERM, clean_exit); - signal(SIGPIPE, SIG_IGN); - - /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { - iphone_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { - i++; - if (!argv[i] || (strlen(argv[i]) != 40)) { - print_usage(argc, argv); - return 0; - } - strcpy(uuid, argv[i]); - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - else if (!strcmp(argv[i], "backup")) { - cmd = CMD_BACKUP; - } - else if (!strcmp(argv[i], "restore")) { - cmd = CMD_RESTORE; - } - else if (backup_directory == NULL) { - backup_directory = argv[i]; - } - else { - print_usage(argc, argv); - return 0; - } - } - - /* verify options */ - if (cmd == -1) { - printf("No command specified.\n"); - print_usage(argc, argv); - return -1; - } - - if (backup_directory == NULL) { - printf("No target backup directory specified.\n"); - print_usage(argc, argv); - return -1; - } - - /* verify if passed backup directory exists */ - if (stat(backup_directory, &st) != 0) { - printf("ERROR: Backup directory \"%s\" does not exist!\n", backup_directory); - return -1; - } - - /* restore directory must contain an Info.plist */ - char *info_path = mobilebackup_build_path(backup_directory, "Info", ".plist"); - if (cmd == CMD_RESTORE) { - if (stat(info_path, &st) != 0) { - g_free(info_path); - printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found.\n", backup_directory); - return -1; - } - } - - printf("Backup directory is \"%s\"\n", backup_directory); - - if (uuid[0] != 0) { - ret = iphone_device_new(&phone, uuid); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found with uuid %s, is it plugged in?\n", uuid); - return -1; - } - } - else - { - ret = iphone_device_new(&phone, NULL); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found, is it plugged in?\n"); - return -1; - } - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "iphonebackup")) { - iphone_device_free(phone); - return -1; - } - - /* start notification_proxy */ - np_client_t np = NULL; - ret = lockdownd_start_service(client, NP_SERVICE_NAME, &port); - if ((ret == LOCKDOWN_E_SUCCESS) && port) { - np_client_new(phone, port, &np); - np_set_notify_callback(np, notify_cb); - const char *noties[5] = { - NP_SYNC_CANCEL_REQUEST, - NP_SYNC_SUSPEND_REQUEST, - NP_SYNC_RESUME_REQUEST, - NP_BACKUP_DOMAIN_CHANGED, - NULL - }; - np_observe_notifications(np, noties); - } else { - printf("ERROR: Could not start service %s.\n", NP_SERVICE_NAME); - } - - /* start AFC, we need this for the lock file */ - afc_client_t afc = NULL; - port = 0; - ret = lockdownd_start_service(client, "com.apple.afc", &port); - if ((ret == LOCKDOWN_E_SUCCESS) && port) { - afc_client_new(phone, port, &afc); - } - - /* start syslog_relay service and retrieve port */ - port = 0; - ret = lockdownd_start_service(client, MOBILEBACKUP_SERVICE_NAME, &port); - if ((ret == LOCKDOWN_E_SUCCESS) && port) { - printf("Started \"%s\" service on port %d.\n", MOBILEBACKUP_SERVICE_NAME, port); - mobilebackup_client_new(phone, port, &mobilebackup); - - /* check abort conditions */ - if (quit_flag > 0) { - printf("Aborting backup. Cancelled by user.\n"); - cmd = CMD_LEAVE; - } - - /* verify existing Info.plist */ - if (stat(info_path, &st) == 0) { - printf("Reading Info.plist from backup.\n"); - plist_read_from_filename(&info_plist, info_path); - - if (cmd == CMD_BACKUP) { - if (mobilebackup_info_is_current_device(info_plist)) { - /* update the last backup time within Info.plist */ - mobilebackup_info_update_last_backup_date(info_plist); - remove(info_path); - plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); - } else { - printf("Aborting backup. Backup is not compatible with the current device.\n"); - cmd = CMD_LEAVE; - } - } - } else { - is_full_backup = 1; - } - - do_post_notification(NP_SYNC_WILL_START); - uint64_t lockfile = 0; - afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); - if (lockfile) { - do_post_notification(NP_SYNC_LOCK_REQUEST); - if (afc_file_lock(afc, lockfile, AFC_LOCK_EX) == AFC_E_SUCCESS) { - do_post_notification(NP_SYNC_DID_START); - } else { - afc_file_close(afc, lockfile); - lockfile = 0; - } - } - - switch(cmd) { - case CMD_BACKUP: - printf("Starting backup...\n"); - /* TODO: check domain com.apple.mobile.backup key RequiresEncrypt and WillEncrypt with lockdown */ - /* TODO: verify battery on AC enough battery remaining */ - - /* Info.plist (Device infos, IC-Info.sidb, photos, app_ids, iTunesPrefs) */ - /* create new Info.plist on new backups */ - if (is_full_backup) { - printf("Creating Info.plist for new backup.\n"); - info_plist = mobilebackup_factory_info_plist_new(); - plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); - } - - g_free(info_path); - - /* Manifest.plist (backup manifest (backup state)) */ - char *manifest_path = mobilebackup_build_path(backup_directory, "Manifest", ".plist"); - - /* read the last Manifest.plist */ - if (!is_full_backup) { - printf("Reading existing Manifest.\n"); - plist_read_from_filename(&manifest_plist, manifest_path); - } - - plist_free(info_plist); - info_plist = NULL; - - /* close down the lockdown connection as it is no longer needed */ - if (client) { - lockdownd_client_free(client); - client = NULL; - } - - /* create Status.plist with failed status for now */ - mobilebackup_write_status(backup_directory, 0); - - /* request backup from device with manifest from last backup */ - printf("Requesting backup from device...\n"); - - node = plist_new_dict(); - - if (manifest_plist) - plist_dict_insert_item(node, "BackupManifestKey", manifest_plist); - - plist_dict_insert_item(node, "BackupComputerBasePathKey", plist_new_string("/")); - plist_dict_insert_item(node, "BackupMessageTypeKey", plist_new_string("BackupMessageBackupRequest")); - plist_dict_insert_item(node, "BackupProtocolVersion", plist_new_string("1.6")); - - plist_t message = device_link_message_factory_process_message_new(node); - mobilebackup_send(mobilebackup, message); - plist_free(message); - message = NULL; - node = NULL; - - /* get response */ - int backup_ok = 0; - mobilebackup_receive(mobilebackup, &message); - - node = plist_array_get_item(message, 0); - if (!plist_strcmp(node, "DLMessageProcessMessage")) { - node = plist_array_get_item(message, 1); - node = plist_dict_get_item(node, "BackupMessageTypeKey"); - if (node && !plist_strcmp(node, "BackupMessageBackupReplyOK")) { - printf("Device accepts manifest and will send backup data now...\n"); - backup_ok = 1; - printf("Acknowledging...\n"); - if (is_full_backup) - printf("Full backup mode.\n"); - else - printf("Incremental backup mode.\n"); - printf("Please wait. Device prepares backup data...\n"); - /* send it back for ACK */ - mobilebackup_send(mobilebackup, message); - } - } else { - printf("ERROR: Unhandled message received!\n"); - } - plist_free(message); - message = NULL; - - if (!backup_ok) { - printf("ERROR: Device rejected to start the backup process.\n"); - break; - } - - /* reset backup status */ - backup_ok = 0; - - /* receive and save DLSendFile files and metadata, ACK each */ - int file_index = 0; - int hunk_index = 0; - uint64_t backup_real_size = 0; - char *file_path = NULL; - char *file_ext = NULL; - char *filename_mdinfo = NULL; - char *filename_mddata = NULL; - char *filename_source = NULL; - char *format_size = NULL; - gboolean is_manifest = FALSE; - uint8_t b = 0; - - /* process series of DLSendFile messages */ - do { - mobilebackup_receive(mobilebackup, &message); - node = plist_array_get_item(message, 0); - - /* get out if we don't get a DLSendFile */ - if (plist_strcmp(node, "DLSendFile")) - break; - - node_tmp = plist_array_get_item(message, 2); - - /* first message hunk contains total backup size */ - if (hunk_index == 0) { - node = plist_dict_get_item(node_tmp, "BackupTotalSizeKey"); - if (node) { - plist_get_uint_val(node, &backup_total_size); - format_size = g_format_size_for_display(backup_total_size); - printf("Backup data requires %s on the disk.\n", format_size); - g_free(format_size); - } - } - - /* check DLFileStatusKey (codes: 1 = Hunk, 2 = Last Hunk) */ - node = plist_dict_get_item(node_tmp, "DLFileStatusKey"); - plist_get_uint_val(node, &c); - file_status = c; - - /* get source filename */ - node = plist_dict_get_item(node_tmp, "BackupManifestKey"); - b = 0; - if (node) { - plist_get_bool_val(node, &b); - } - is_manifest = (b == 1) ? TRUE: FALSE; - - /* check if we completed a file */ - if ((file_status == DEVICE_LINK_FILE_STATUS_LAST_HUNK) && (!is_manifest)) { - /* get source filename */ - node = plist_dict_get_item(node_tmp, "DLFileSource"); - plist_get_string_val(node, &filename_source); - - /* increase received size */ - node = plist_dict_get_item(node_tmp, "DLFileAttributesKey"); - node = plist_dict_get_item(node, "FileSize"); - plist_get_uint_val(node, &length); - backup_real_size += length; - - format_size = g_format_size_for_display(backup_real_size); - printf("(%s", format_size); - g_free(format_size); - - format_size = g_format_size_for_display(backup_total_size); - printf("/%s): ", format_size); - g_free(format_size); - - printf("Received file %s... ", filename_source); - - if (filename_source) - free(filename_source); - - /* save .mdinfo */ - node = plist_dict_get_item(node_tmp, "BackupFileInfo"); - if (node) { - node = plist_dict_get_item(node_tmp, "DLFileDest"); - plist_get_string_val(node, &file_path); - - filename_mdinfo = mobilebackup_build_path(backup_directory, file_path, ".mdinfo"); - - /* remove any existing file */ - if (stat(filename_mdinfo, &st) != 0) - remove(filename_mdinfo); - - node = plist_dict_get_item(node_tmp, "BackupFileInfo"); - plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY); - - g_free(filename_mdinfo); - } - - file_index++; - } - - /* save .mddata */ - node = plist_dict_get_item(node_tmp, "BackupFileInfo"); - if (node_tmp && file_path) { - node = plist_dict_get_item(node_tmp, "DLFileDest"); - plist_get_string_val(node, &file_path); - - filename_mddata = mobilebackup_build_path(backup_directory, file_path, is_manifest ? NULL: ".mddata"); - - /* if this is the first hunk, remove any existing file */ - if (stat(filename_mddata, &st) != 0) - remove(filename_mddata); - - /* get file data hunk */ - node_tmp = plist_array_get_item(message, 1); - plist_get_data_val(node_tmp, &buffer, &length); - - buffer_write_to_filename(filename_mddata, buffer, length); - - /* activate currently sent manifest */ - if ((file_status == DEVICE_LINK_FILE_STATUS_LAST_HUNK) && (is_manifest)) { - rename(filename_mddata, manifest_path); - } - - free(buffer); - buffer = NULL; - - g_free(filename_mddata); - } - - hunk_index++; - - if (file_ext) - free(file_ext); - - if (message) - plist_free(message); - message = NULL; - - if (file_status == DEVICE_LINK_FILE_STATUS_LAST_HUNK) { - if (!is_manifest) - printf("DONE\n"); - - /* acknowlegdge that we received the file */ - message = mobilebackup_factory_backup_file_received_new(); - mobilebackup_send(mobilebackup, message); - plist_free(message); - message = NULL; - } - - if (quit_flag > 0) { - /* need to cancel the backup here */ - mobilebackup_cancel_backup_with_error("Cancelling DLSendFile"); - - /* remove any atomic Manifest.plist.tmp */ - if (manifest_path) - g_free(manifest_path); - - manifest_path = mobilebackup_build_path(backup_directory, "Manifest", ".plist.tmp"); - if (stat(manifest_path, &st) == 0) - remove(manifest_path); - break; - } - } while (1); - - printf("Received %d files from device.\n", file_index); - - if (!quit_flag && !plist_strcmp(node, "DLMessageProcessMessage")) { - node_tmp = plist_array_get_item(message, 1); - node = plist_dict_get_item(node_tmp, "BackupMessageTypeKey"); - /* check if we received the final "backup finished" message */ - if (node && !plist_strcmp(node, "BackupMessageBackupFinished")) { - /* backup finished */ - - /* process BackupFilesToDeleteKey */ - node = plist_dict_get_item(node_tmp, "BackupFilesToDeleteKey"); - if (node) { - length = plist_array_get_size(node); - i = 0; - while ((node_tmp = plist_array_get_item(node, i++)) != NULL) { - plist_get_string_val(node_tmp, &file_path); - - if (mobilebackup_delete_backup_file_by_hash(backup_directory, file_path)) { - printf("DONE\n"); - } else - printf("FAILED\n"); - } - } - - /* save last valid Manifest.plist */ - node_tmp = plist_array_get_item(message, 1); - manifest_plist = plist_dict_get_item(node_tmp, "BackupManifestKey"); - if (manifest_plist) { - remove(manifest_path); - printf("Storing Manifest.plist...\n"); - plist_write_to_filename(manifest_plist, manifest_path, PLIST_FORMAT_XML); - } - - backup_ok = 1; - } - } - - if (backup_ok) { - /* Status.plist (Info on how the backup process turned out) */ - printf("Backup Successful.\n"); - mobilebackup_write_status(backup_directory, 1); - } else { - printf("Backup Failed.\n"); - } - - if (manifest_path) - g_free(manifest_path); - - break; - case CMD_RESTORE: - printf("Restoring backup is NOT IMPLEMENTED.\n"); - /* verify battery on AC enough battery remaining */ - /* request restore from device with manifest (BackupMessageRestoreMigrate) */ - /* read mddata/mdinfo files and send to devices using DLSendFile */ - /* signal restore finished message to device */ - /* close down lockdown connection as it is no longer needed */ - lockdownd_client_free(client); - client = NULL; - break; - case CMD_LEAVE: - default: - break; - } - if (lockfile) { - afc_file_lock(afc, lockfile, AFC_LOCK_UN); - afc_file_close(afc, lockfile); - lockfile = 0; - do_post_notification(NP_SYNC_DID_FINISH); - } - } else { - printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME); - lockdownd_client_free(client); - client = NULL; - } - - if (client) { - lockdownd_client_free(client); - client = NULL; - } - - if (afc) - afc_client_free(afc); - - if (np) - np_client_free(np); - - if (mobilebackup) - mobilebackup_client_free(mobilebackup); - - iphone_device_free(phone); - - return 0; -} - diff --git a/tools/iphoneinfo.c b/tools/iphoneinfo.c deleted file mode 100644 index 5ee92f5..0000000 --- a/tools/iphoneinfo.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * iphoneinfo.c - * Simple utility to show information about an attached device - * - * Copyright (c) 2009 Martin Szulecki 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 -#include -#include -#include -#include - -#include -#include - -#define FORMAT_KEY_VALUE 1 -#define FORMAT_XML 2 - -static const char *domains[] = { - "com.apple.disk_usage", - "com.apple.mobile.battery", -/* FIXME: For some reason lockdownd segfaults on this, works sometimes though - "com.apple.mobile.debug",. */ - "com.apple.xcode.developerdomain", - "com.apple.international", - "com.apple.mobile.data_sync", - "com.apple.mobile.tethered_sync", - "com.apple.mobile.mobile_application_usage", - "com.apple.mobile.backup", - "com.apple.mobile.nikita", - "com.apple.mobile.restriction", - "com.apple.mobile.user_preferences", - "com.apple.mobile.sync_data_class", - "com.apple.mobile.software_behavior", - "com.apple.mobile.iTunes.SQLMusicLibraryPostProcessCommands", - "com.apple.mobile.iTunes.accessories", - "com.apple.fairplay", - "com.apple.iTunes", - "com.apple.mobile.iTunes.store", - "com.apple.mobile.iTunes", - NULL -}; - -static int indent_level = 0; - -static int is_domain_known(char *domain) -{ - int i = 0; - while (domains[i] != NULL) { - if (strstr(domain, domains[i++])) { - return 1; - } - } - return 0; -} - -static void plist_node_to_string(plist_t node); - -static void plist_array_to_string(plist_t node) -{ - /* iterate over items */ - int i, count; - plist_t subnode = NULL; - - count = plist_array_get_size(node); - - for (i = 0; i < count; i++) { - subnode = plist_array_get_item(node, i); - printf("%*s", indent_level, ""); - printf("%d: ", i); - plist_node_to_string(subnode); - } -} - -static void plist_dict_to_string(plist_t node) -{ - /* iterate over key/value pairs */ - plist_dict_iter it = NULL; - - char* key = NULL; - plist_t subnode = NULL; - plist_dict_new_iter(node, &it); - plist_dict_next_item(node, it, &key, &subnode); - while (subnode) - { - printf("%*s", indent_level, ""); - printf("%s", key); - if (plist_get_node_type(subnode) == PLIST_ARRAY) - printf("[%d]: ", plist_array_get_size(subnode)); - else - printf(": "); - free(key); - key = NULL; - plist_node_to_string(subnode); - plist_dict_next_item(node, it, &key, &subnode); - } - free(it); -} - -static void plist_node_to_string(plist_t node) -{ - char *s = NULL; - char *data = NULL; - double d; - uint8_t b; - uint64_t u = 0; - GTimeVal tv = { 0, 0 }; - - plist_type t; - - if (!node) - return; - - t = plist_get_node_type(node); - - switch (t) { - case PLIST_BOOLEAN: - plist_get_bool_val(node, &b); - printf("%s\n", (b ? "true" : "false")); - break; - - case PLIST_UINT: - plist_get_uint_val(node, &u); - printf("%llu\n", (long long)u); - break; - - case PLIST_REAL: - plist_get_real_val(node, &d); - printf("%f\n", d); - break; - - case PLIST_STRING: - plist_get_string_val(node, &s); - printf("%s\n", s); - free(s); - break; - - case PLIST_KEY: - plist_get_key_val(node, &s); - printf("%s: ", s); - free(s); - break; - - case PLIST_DATA: - plist_get_data_val(node, &data, &u); - s = g_base64_encode((guchar *)data, u); - free(data); - printf("%s\n", s); - g_free(s); - break; - - case PLIST_DATE: - plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec); - s = g_time_val_to_iso8601(&tv); - printf("%s\n", s); - free(s); - break; - - case PLIST_ARRAY: - printf("\n"); - indent_level++; - plist_array_to_string(node); - indent_level--; - break; - - case PLIST_DICT: - printf("\n"); - indent_level++; - plist_dict_to_string(node); - indent_level--; - break; - - default: - break; - } -} - -static void print_usage(int argc, char **argv) -{ - int i = 0; - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); - printf("Show information about the first connected iPhone/iPod Touch.\n\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); - printf(" -q, --domain NAME\tset domain of query to NAME. Default: None\n"); - printf(" -k, --key NAME\tonly query key specified by NAME. Default: All keys.\n"); - printf(" -x, --xml\t\toutput information as xml plist instead of key/value pairs\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); - printf(" Known domains are:\n\n"); - while (domains[i] != NULL) { - printf(" %s\n", domains[i++]); - } - printf("\n"); -} - -int main(int argc, char *argv[]) -{ - lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; - iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - int i; - int format = FORMAT_KEY_VALUE; - char uuid[41]; - char *domain = NULL; - char *key = NULL; - char *xml_doc = NULL; - uint32_t xml_length; - plist_t node = NULL; - plist_type node_type; - uuid[0] = 0; - - /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { - iphone_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { - i++; - if (!argv[i] || (strlen(argv[i]) != 40)) { - print_usage(argc, argv); - return 0; - } - strcpy(uuid, argv[i]); - continue; - } - else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) { - i++; - if (!argv[i] || (strlen(argv[i]) < 4)) { - print_usage(argc, argv); - return 0; - } - if (!is_domain_known(argv[i])) { - fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]); - } - domain = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) { - i++; - if (!argv[i] || (strlen(argv[i]) <= 1)) { - print_usage(argc, argv); - return 0; - } - key = strdup(argv[i]); - continue; - } - else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { - format = FORMAT_XML; - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - else { - print_usage(argc, argv); - return 0; - } - } - - if (uuid[0] != 0) { - ret = iphone_device_new(&phone, uuid); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found with uuid %s, is it plugged in?\n", uuid); - return -1; - } - } - else - { - ret = iphone_device_new(&phone, NULL); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found, is it plugged in?\n"); - return -1; - } - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "iphoneinfo")) { - iphone_device_free(phone); - return -1; - } - - /* run query and output information */ - if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) { - if (node) { - switch (format) { - case FORMAT_XML: - plist_to_xml(node, &xml_doc, &xml_length); - printf("%s", xml_doc); - free(xml_doc); - break; - case FORMAT_KEY_VALUE: - node_type = plist_get_node_type(node); - if (node_type == PLIST_DICT) { - plist_dict_to_string(node); - } else if (node_type == PLIST_ARRAY) { - plist_array_to_string(node); - break; - } - default: - if (key != NULL) - plist_node_to_string(node); - break; - } - plist_free(node); - node = NULL; - } - } - - if (domain != NULL) - free(domain); - lockdownd_client_free(client); - iphone_device_free(phone); - - return 0; -} - diff --git a/tools/iphonesyslog.c b/tools/iphonesyslog.c deleted file mode 100644 index 41e490f..0000000 --- a/tools/iphonesyslog.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * syslog_relay.c - * Relay the syslog of a device to stdout - * - * Copyright (c) 2009 Martin Szulecki 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 -#include -#include -#include -#include -#include - -#include -#include - -static int quit_flag = 0; - -void print_usage(int argc, char **argv); - -/** - * signal handler function for cleaning up properly - */ -static void clean_exit(int sig) -{ - fprintf(stderr, "Exiting...\n"); - quit_flag++; -} - -int main(int argc, char *argv[]) -{ - lockdownd_client_t client = NULL; - iphone_device_t phone = NULL; - iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; - int i; - char uuid[41]; - uint16_t port = 0; - uuid[0] = 0; - - signal(SIGINT, clean_exit); - signal(SIGQUIT, clean_exit); - signal(SIGTERM, clean_exit); - signal(SIGPIPE, SIG_IGN); - - /* parse cmdline args */ - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { - iphone_set_debug_level(1); - continue; - } - else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { - i++; - if (!argv[i] || (strlen(argv[i]) != 40)) { - print_usage(argc, argv); - return 0; - } - strcpy(uuid, argv[i]); - continue; - } - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { - print_usage(argc, argv); - return 0; - } - else { - print_usage(argc, argv); - return 0; - } - } - - if (uuid[0] != 0) { - ret = iphone_device_new(&phone, uuid); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found with uuid %s, is it plugged in?\n", uuid); - return -1; - } - } - else - { - ret = iphone_device_new(&phone, NULL); - if (ret != IPHONE_E_SUCCESS) { - printf("No device found, is it plugged in?\n"); - return -1; - } - } - - if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "iphonesyslog")) { - iphone_device_free(phone); - return -1; - } - - /* start syslog_relay service and retrieve port */ - ret = lockdownd_start_service(client, "com.apple.syslog_relay", &port); - if ((ret == LOCKDOWN_E_SUCCESS) && port) { - lockdownd_client_free(client); - - /* connect to socket relay messages */ - iphone_connection_t conn = NULL; - if ((iphone_device_connect(phone, port, &conn) != IPHONE_E_SUCCESS) || !conn) { - printf("ERROR: Could not open usbmux connection.\n"); - } else { - while (!quit_flag) { - char *receive = NULL; - uint32_t datalen = 0, bytes = 0, recv_bytes = 0; - - ret = iphone_connection_receive(conn, (char *) &datalen, sizeof(datalen), &bytes); - datalen = ntohl(datalen); - - if (datalen == 0) - continue; - - recv_bytes += bytes; - receive = (char *) malloc(sizeof(char) * datalen); - - while (!quit_flag && (recv_bytes <= datalen)) { - ret = iphone_connection_receive(conn, receive, datalen, &bytes); - - if (bytes == 0) - break; - - recv_bytes += bytes; - - fwrite(receive, sizeof(char), bytes, stdout); - } - - free(receive); - } - } - iphone_device_disconnect(conn); - } else { - printf("ERROR: Could not start service com.apple.syslog_relay.\n"); - } - - iphone_device_free(phone); - - return 0; -} - -void print_usage(int argc, char **argv) -{ - char *name = NULL; - - name = strrchr(argv[0], '/'); - printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); - printf("Relay syslog of a connected iPhone/iPod Touch.\n\n"); - printf(" -d, --debug\t\tenable communication debugging\n"); - printf(" -u, --uuid UUID\ttarget specific device by its 40-digit device UUID\n"); - printf(" -h, --help\t\tprints usage information\n"); - printf("\n"); -} - -- cgit v1.1-32-gdbae