diff options
| -rw-r--r-- | Makefile.am | 6 | ||||
| -rw-r--r-- | configure.ac | 22 | ||||
| -rw-r--r-- | dev/Makefile.am | 41 | ||||
| -rw-r--r-- | dev/afccheck.c | 147 | ||||
| -rw-r--r-- | dev/filerelaytest.c | 151 | ||||
| -rw-r--r-- | dev/housearresttest.c | 219 | ||||
| -rw-r--r-- | dev/ideviceclient.c | 272 | ||||
| -rw-r--r-- | dev/ideviceheartbeat.c | 157 | ||||
| -rw-r--r-- | dev/lckdclient.c | 163 |
9 files changed, 2 insertions, 1176 deletions
diff --git a/Makefile.am b/Makefile.am index c2644e4..fdd273f 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | AUTOMAKE_OPTIONS = foreign | 1 | AUTOMAKE_OPTIONS = foreign |
| 2 | ACLOCAL_AMFLAGS = -I m4 | 2 | ACLOCAL_AMFLAGS = -I m4 |
| 3 | SUBDIRS = common src include $(CYTHON_SUB) $(DEV_SUB) tools docs | 3 | SUBDIRS = common src include $(CYTHON_SUB) tools docs |
| 4 | |||
| 5 | DISTCHECK_CONFIGURE_FLAGS = --enable-dev-tools | ||
| 6 | 4 | ||
| 7 | pkgconfigdir = $(libdir)/pkgconfig | 5 | pkgconfigdir = $(libdir)/pkgconfig |
| 8 | pkgconfig_DATA = libimobiledevice-1.0.pc | 6 | pkgconfig_DATA = libimobiledevice-1.0.pc |
| @@ -16,5 +14,5 @@ docs/html: $(top_builddir)/doxygen.cfg $(top_srcdir)/src/*.c $(top_srcdir)/src/* | |||
| 16 | docs: doxygen.cfg docs/html | 14 | docs: doxygen.cfg docs/html |
| 17 | 15 | ||
| 18 | indent: | 16 | indent: |
| 19 | indent -kr -ut -ts4 -l120 src/*.c src/*.h dev/*.c | 17 | indent -kr -ut -ts4 -l120 src/*.c src/*.h |
| 20 | 18 | ||
diff --git a/configure.ac b/configure.ac index 79e1590..c2678f8 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -156,26 +156,6 @@ else | |||
| 156 | AC_SUBST(ssl_requires) | 156 | AC_SUBST(ssl_requires) |
| 157 | fi | 157 | fi |
| 158 | 158 | ||
| 159 | AC_ARG_ENABLE([dev-tools], | ||
| 160 | [AS_HELP_STRING([--enable-dev-tools], | ||
| 161 | [build development helper tools (default is no)])], | ||
| 162 | [build_dev_tools=true], | ||
| 163 | [build_dev_tools=false]) | ||
| 164 | if test "$build_dev_tools" = true; then | ||
| 165 | DEV_SUB=dev | ||
| 166 | AC_CHECK_HEADERS([readline/readline.h], | ||
| 167 | [], | ||
| 168 | [AC_MSG_ERROR([Please install readline development headers])] | ||
| 169 | ) | ||
| 170 | building_dev_tools=yes | ||
| 171 | else | ||
| 172 | DEV_SUB= | ||
| 173 | building_dev_tools=no | ||
| 174 | fi | ||
| 175 | |||
| 176 | AM_CONDITIONAL([ENABLE_DEVTOOLS],[test "x$DEV_SUB" = "xdev"]) | ||
| 177 | AC_SUBST([DEV_SUB]) | ||
| 178 | |||
| 179 | AC_ARG_ENABLE([debug-code], | 159 | AC_ARG_ENABLE([debug-code], |
| 180 | [AS_HELP_STRING([--enable-debug-code], | 160 | [AS_HELP_STRING([--enable-debug-code], |
| 181 | [enable debug message reporting in library (default is no)])], | 161 | [enable debug message reporting in library (default is no)])], |
| @@ -230,7 +210,6 @@ Makefile | |||
| 230 | common/Makefile | 210 | common/Makefile |
| 231 | src/Makefile | 211 | src/Makefile |
| 232 | include/Makefile | 212 | include/Makefile |
| 233 | dev/Makefile | ||
| 234 | tools/Makefile | 213 | tools/Makefile |
| 235 | cython/Makefile | 214 | cython/Makefile |
| 236 | docs/Makefile | 215 | docs/Makefile |
| @@ -244,7 +223,6 @@ Configuration for $PACKAGE $VERSION: | |||
| 244 | 223 | ||
| 245 | Install prefix: .........: $prefix | 224 | Install prefix: .........: $prefix |
| 246 | Debug code ..............: $building_debug_code | 225 | Debug code ..............: $building_debug_code |
| 247 | Dev tools ...............: $building_dev_tools | ||
| 248 | Python bindings .........: $cython_python_bindings | 226 | Python bindings .........: $cython_python_bindings |
| 249 | SSL support backend .....: $ssl_provider | 227 | SSL support backend .....: $ssl_provider |
| 250 | 228 | ||
diff --git a/dev/Makefile.am b/dev/Makefile.am deleted file mode 100644 index 89ef75b..0000000 --- a/dev/Makefile.am +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | AM_CPPFLAGS = -I$(top_srcdir)/include | ||
| 2 | |||
| 3 | AM_CFLAGS = $(GLOBAL_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(openssl_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) | ||
| 4 | AM_LDFLAGS = $(libgnutls_LIBS) $(libtasn1_LIBS) $(openssl_LIBS) $(libplist_LIBS) | ||
| 5 | |||
| 6 | if ENABLE_DEVTOOLS | ||
| 7 | noinst_PROGRAMS = ideviceclient afccheck filerelaytest housearresttest lckd-client ideviceheartbeat | ||
| 8 | |||
| 9 | ideviceclient_SOURCES = ideviceclient.c | ||
| 10 | ideviceclient_CFLAGS = $(AM_CFLAGS) | ||
| 11 | ideviceclient_LDFLAGS = $(AM_LDFLAGS) | ||
| 12 | ideviceclient_LDADD = $(top_builddir)/src/libimobiledevice.la | ||
| 13 | |||
| 14 | lckd_client_SOURCES = lckdclient.c | ||
| 15 | lckd_client_CFLAGS = $(AM_CFLAGS) $(libglib2_CFLAGS) | ||
| 16 | lckd_client_LDFLAGS = -lreadline $(AM_LDFLAGS) $(libglib2_LIBS) | ||
| 17 | lckd_client_LDADD = $(top_builddir)/src/libimobiledevice.la | ||
| 18 | |||
| 19 | afccheck_SOURCES = afccheck.c | ||
| 20 | afccheck_CFLAGS = -I$(top_srcdir) $(AM_CFLAGS) | ||
| 21 | afccheck_LDFLAGS = $(top_builddir)/common/libinternalcommon.la $(AM_LDFLAGS) | ||
| 22 | afccheck_LDADD = $(top_builddir)/src/libimobiledevice.la | ||
| 23 | |||
| 24 | filerelaytest_SOURCES = filerelaytest.c | ||
| 25 | filerelaytest_CFLAGS = $(AM_CFLAGS) | ||
| 26 | filerelaytest_LDFLAGS = $(AM_LDFLAGS) | ||
| 27 | filerelaytest_LDADD = $(top_builddir)/src/libimobiledevice.la | ||
| 28 | |||
| 29 | housearresttest_SOURCES = housearresttest.c | ||
| 30 | housearresttest_CFLAGS = $(AM_CFLAGS) | ||
| 31 | housearresttest_LDFLAGS = $(AM_LDFLAGS) | ||
| 32 | housearresttest_LDADD = $(top_builddir)/src/libimobiledevice.la | ||
| 33 | |||
| 34 | ideviceheartbeat_SOURCES = ideviceheartbeat.c | ||
| 35 | ideviceheartbeat_CFLAGS = $(AM_CFLAGS) | ||
| 36 | ideviceheartbeat_LDFLAGS = $(AM_LDFLAGS) | ||
| 37 | ideviceheartbeat_LDADD = $(top_builddir)/src/libimobiledevice.la | ||
| 38 | |||
| 39 | endif # ENABLE_DEVTOOLS | ||
| 40 | |||
| 41 | EXTRA_DIST = ideviceclient.c lckdclient.c afccheck.c filerelaytest.c housearresttest.c ideviceheartbeat.c | ||
diff --git a/dev/afccheck.c b/dev/afccheck.c deleted file mode 100644 index fed8538..0000000 --- a/dev/afccheck.c +++ /dev/null | |||
| @@ -1,147 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * afccheck.c | ||
| 3 | * creates threads and check communication through AFC is done rigth | ||
| 4 | * | ||
| 5 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <stdlib.h> | ||
| 23 | #include <stdio.h> | ||
| 24 | #include <string.h> | ||
| 25 | |||
| 26 | #include <libimobiledevice/libimobiledevice.h> | ||
| 27 | #include <libimobiledevice/lockdown.h> | ||
| 28 | #include <libimobiledevice/afc.h> | ||
| 29 | #include "common/thread.h" | ||
| 30 | |||
| 31 | #define BUFFER_SIZE 20000 | ||
| 32 | #define NB_THREADS 10 | ||
| 33 | |||
| 34 | |||
| 35 | typedef struct { | ||
| 36 | afc_client_t afc; | ||
| 37 | int id; | ||
| 38 | } param; | ||
| 39 | |||
| 40 | |||
| 41 | static void* check_afc(void *data) | ||
| 42 | { | ||
| 43 | //prepare a buffer | ||
| 44 | unsigned int buffersize = BUFFER_SIZE * sizeof(unsigned int); | ||
| 45 | int *buf = (int *) malloc(buffersize); | ||
| 46 | int *buf2 = (int *) malloc(buffersize); | ||
| 47 | unsigned int bytes = 0; | ||
| 48 | uint64_t position = 0; | ||
| 49 | |||
| 50 | //fill buffer | ||
| 51 | int i = 0; | ||
| 52 | for (i = 0; i < BUFFER_SIZE; i++) { | ||
| 53 | buf[i] = ((param *) data)->id * i; | ||
| 54 | } | ||
| 55 | |||
| 56 | //now writes buffer on device | ||
| 57 | uint64_t file = 0; | ||
| 58 | char path[50]; | ||
| 59 | sprintf(path, "/Buf%i", ((param *) data)->id); | ||
| 60 | afc_file_open(((param *) data)->afc, path, AFC_FOPEN_RW, &file); | ||
| 61 | afc_file_write(((param *) data)->afc, file, (char *) buf, buffersize, &bytes); | ||
| 62 | afc_file_close(((param *) data)->afc, file); | ||
| 63 | file = 0; | ||
| 64 | if (bytes != buffersize) | ||
| 65 | printf("Write operation failed\n"); | ||
| 66 | |||
| 67 | //now read it | ||
| 68 | bytes = 0; | ||
| 69 | afc_file_open(((param *) data)->afc, path, AFC_FOPEN_RDONLY, &file); | ||
| 70 | afc_file_read(((param *) data)->afc, file, (char *) buf2, buffersize/2, &bytes); | ||
| 71 | afc_file_read(((param *) data)->afc, file, (char *) buf2 + (buffersize/2), buffersize/2, &bytes); | ||
| 72 | if(AFC_E_SUCCESS != afc_file_tell(((param *) data)->afc, file, &position)) | ||
| 73 | printf("Tell operation failed\n"); | ||
| 74 | afc_file_close(((param *) data)->afc, file); | ||
| 75 | if (position != buffersize) | ||
| 76 | printf("Read operation failed\n"); | ||
| 77 | |||
| 78 | //compare buffers | ||
| 79 | for (i = 0; i < BUFFER_SIZE; i++) { | ||
| 80 | if (buf[i] != buf2[i]) { | ||
| 81 | printf("Buffers are differents, stream corrupted\n"); | ||
| 82 | break; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | //cleanup | ||
| 87 | afc_remove_path(((param *) data)->afc, path); | ||
| 88 | return NULL; | ||
| 89 | } | ||
| 90 | |||
| 91 | int main(int argc, char *argv[]) | ||
| 92 | { | ||
| 93 | lockdownd_client_t client = NULL; | ||
| 94 | idevice_t phone = NULL; | ||
| 95 | lockdownd_service_descriptor_t service = NULL; | ||
| 96 | afc_client_t afc = NULL; | ||
| 97 | |||
| 98 | if (argc > 1 && !strcasecmp(argv[1], "--debug")) { | ||
| 99 | idevice_set_debug_level(1); | ||
| 100 | } else { | ||
| 101 | idevice_set_debug_level(0); | ||
| 102 | } | ||
| 103 | |||
| 104 | if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { | ||
| 105 | printf("No device found, is it plugged in?\n"); | ||
| 106 | return 1; | ||
| 107 | } | ||
| 108 | |||
| 109 | if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "afccheck")) { | ||
| 110 | idevice_free(phone); | ||
| 111 | return 1; | ||
| 112 | } | ||
| 113 | |||
| 114 | if (LOCKDOWN_E_SUCCESS != lockdownd_start_service(client, "com.apple.afc", &service) || !service || !service->port) { | ||
| 115 | lockdownd_client_free(client); | ||
| 116 | idevice_free(phone); | ||
| 117 | fprintf(stderr, "Something went wrong when starting AFC."); | ||
| 118 | return 1; | ||
| 119 | } | ||
| 120 | |||
| 121 | afc_client_new(phone, service, &afc); | ||
| 122 | |||
| 123 | if (service) { | ||
| 124 | lockdownd_service_descriptor_free(service); | ||
| 125 | service = NULL; | ||
| 126 | } | ||
| 127 | |||
| 128 | thread_t threads[NB_THREADS]; | ||
| 129 | param data[NB_THREADS]; | ||
| 130 | |||
| 131 | int i = 0; | ||
| 132 | for (i = 0; i < NB_THREADS; i++) { | ||
| 133 | data[i].afc = afc; | ||
| 134 | data[i].id = i + 1; | ||
| 135 | thread_new(&threads[i], check_afc, data + i); | ||
| 136 | } | ||
| 137 | |||
| 138 | for (i = 0; i < NB_THREADS; i++) { | ||
| 139 | thread_join(threads[i]); | ||
| 140 | thread_free(threads[i]); | ||
| 141 | } | ||
| 142 | |||
| 143 | lockdownd_client_free(client); | ||
| 144 | idevice_free(phone); | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | } | ||
diff --git a/dev/filerelaytest.c b/dev/filerelaytest.c deleted file mode 100644 index 6983f1d..0000000 --- a/dev/filerelaytest.c +++ /dev/null | |||
| @@ -1,151 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * filerelaytest.c | ||
| 3 | * Simple Test program showing the usage of the file_relay interface. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2010 Nikias Bassen All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | #include <errno.h> | ||
| 22 | #include <stdio.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <string.h> | ||
| 25 | #include <libimobiledevice/libimobiledevice.h> | ||
| 26 | #include <libimobiledevice/lockdown.h> | ||
| 27 | #include <libimobiledevice/file_relay.h> | ||
| 28 | |||
| 29 | int main(int argc, char **argv) | ||
| 30 | { | ||
| 31 | idevice_t dev = NULL; | ||
| 32 | lockdownd_client_t client = NULL; | ||
| 33 | lockdownd_service_descriptor_t service = NULL; | ||
| 34 | file_relay_client_t frc = NULL; | ||
| 35 | file_relay_error_t frc_error = FILE_RELAY_E_SUCCESS; | ||
| 36 | idevice_connection_t dump = NULL; | ||
| 37 | const char **sources; | ||
| 38 | const char *default_sources[] = {"AppleSupport", "Network", "VPN", "WiFi", "UserDatabases", "CrashReporter", "tmp", "SystemConfiguration", NULL}; | ||
| 39 | int i = 0; | ||
| 40 | |||
| 41 | if (idevice_new(&dev, NULL) != IDEVICE_E_SUCCESS) { | ||
| 42 | printf("No device connected?!\n"); | ||
| 43 | goto leave_cleanup; | ||
| 44 | } | ||
| 45 | |||
| 46 | printf("Connecting...\n"); | ||
| 47 | if (lockdownd_client_new_with_handshake(dev, &client, NULL) != LOCKDOWN_E_SUCCESS) { | ||
| 48 | printf("Could not connect to lockdownd!\n"); | ||
| 49 | goto leave_cleanup; | ||
| 50 | } | ||
| 51 | |||
| 52 | if (lockdownd_start_service(client, FILE_RELAY_SERVICE_NAME, &service) != LOCKDOWN_E_SUCCESS) { | ||
| 53 | printf("Could not start file_relay service!\n"); | ||
| 54 | goto leave_cleanup; | ||
| 55 | } | ||
| 56 | |||
| 57 | if (client) { | ||
| 58 | lockdownd_client_free(client); | ||
| 59 | client = NULL; | ||
| 60 | } | ||
| 61 | |||
| 62 | if (file_relay_client_new(dev, service, &frc) != FILE_RELAY_E_SUCCESS) { | ||
| 63 | printf("Could not connect to file_relay service!\n"); | ||
| 64 | goto leave_cleanup; | ||
| 65 | } | ||
| 66 | |||
| 67 | if (service) { | ||
| 68 | lockdownd_service_descriptor_free(service); | ||
| 69 | service = NULL; | ||
| 70 | } | ||
| 71 | |||
| 72 | if (argc > 1) { | ||
| 73 | sources = calloc(1, argc * sizeof(char *)); | ||
| 74 | argc--; | ||
| 75 | argv++; | ||
| 76 | for (i = 0; i < argc; i++) { | ||
| 77 | sources[i] = argv[i]; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | else { | ||
| 81 | sources = default_sources; | ||
| 82 | } | ||
| 83 | |||
| 84 | printf("Requesting "); | ||
| 85 | i = 0; | ||
| 86 | while (sources[i]) { | ||
| 87 | printf(" %s", sources[i]); | ||
| 88 | i++; | ||
| 89 | if (sources[i]) | ||
| 90 | printf(","); | ||
| 91 | } | ||
| 92 | printf("\n"); | ||
| 93 | |||
| 94 | frc_error = file_relay_request_sources(frc, sources, &dump); | ||
| 95 | if (frc_error != FILE_RELAY_E_SUCCESS) { | ||
| 96 | printf("Could not request sources.\n"); | ||
| 97 | switch (frc_error) { | ||
| 98 | case FILE_RELAY_E_INVALID_SOURCE: | ||
| 99 | printf("At least one of the given sources is invalid and was rejected.\n"); | ||
| 100 | break; | ||
| 101 | case FILE_RELAY_E_STAGING_EMPTY: | ||
| 102 | printf("Staging is empty. Perhaps there is no data for the requested sources available.\n"); | ||
| 103 | break; | ||
| 104 | case FILE_RELAY_E_PERMISSION_DENIED: | ||
| 105 | printf("Permission denied by device. Possibly missing a signed preferences profile.\n"); | ||
| 106 | break; | ||
| 107 | default: | ||
| 108 | printf("An unknown error occoured.\n"); | ||
| 109 | break; | ||
| 110 | } | ||
| 111 | goto leave_cleanup; | ||
| 112 | } | ||
| 113 | |||
| 114 | if (!dump) { | ||
| 115 | printf("Did not get connection!\n"); | ||
| 116 | goto leave_cleanup; | ||
| 117 | } | ||
| 118 | |||
| 119 | uint32_t cnt = 0; | ||
| 120 | uint32_t len = 0; | ||
| 121 | char buf[4096]; | ||
| 122 | FILE *f = fopen("dump.cpio.gz", "wb"); | ||
| 123 | if (!f) { | ||
| 124 | fprintf(stderr, "dump.cpio.gz: %s\n", strerror(errno)); | ||
| 125 | return EXIT_FAILURE; | ||
| 126 | } | ||
| 127 | setbuf(stdout, NULL); | ||
| 128 | printf("Receiving "); | ||
| 129 | while (idevice_connection_receive(dump, buf, 4096, &len) == IDEVICE_E_SUCCESS) { | ||
| 130 | fwrite(buf, 1, len, f); | ||
| 131 | cnt += len; | ||
| 132 | printf("."); | ||
| 133 | len = 0; | ||
| 134 | } | ||
| 135 | printf("\n"); | ||
| 136 | fclose(f); | ||
| 137 | printf("Total size received: %d\n", cnt); | ||
| 138 | |||
| 139 | leave_cleanup: | ||
| 140 | if (frc) { | ||
| 141 | file_relay_client_free(frc); | ||
| 142 | } | ||
| 143 | if (client) { | ||
| 144 | lockdownd_client_free(client); | ||
| 145 | } | ||
| 146 | if (dev) { | ||
| 147 | idevice_free(dev); | ||
| 148 | } | ||
| 149 | |||
| 150 | return 0; | ||
| 151 | } | ||
diff --git a/dev/housearresttest.c b/dev/housearresttest.c deleted file mode 100644 index 6586787..0000000 --- a/dev/housearresttest.c +++ /dev/null | |||
| @@ -1,219 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * housearresttest.c | ||
| 3 | * Simple Test program showing the usage of the house_arrest interface. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2010 Nikias Bassen All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | #include <stdio.h> | ||
| 22 | #include <stdlib.h> | ||
| 23 | #include <string.h> | ||
| 24 | |||
| 25 | #include <libimobiledevice/libimobiledevice.h> | ||
| 26 | #include <libimobiledevice/lockdown.h> | ||
| 27 | #include <libimobiledevice/house_arrest.h> | ||
| 28 | #include <libimobiledevice/afc.h> | ||
| 29 | |||
| 30 | static void print_usage(int argc, char **argv) | ||
| 31 | { | ||
| 32 | char *name = NULL; | ||
| 33 | |||
| 34 | name = strrchr(argv[0], '/'); | ||
| 35 | printf("Usage: %s [OPTIONS] APPID\n", (name ? name + 1: argv[0])); | ||
| 36 | printf("Test the house_arrest service.\n\n"); | ||
| 37 | printf(" -d, --debug\t\tenable communication debugging\n"); | ||
| 38 | printf(" -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n"); | ||
| 39 | printf(" -t, --test\t\ttest creating, writing, and deleting a file\n"); | ||
| 40 | printf(" -h, --help\t\tprints usage information\n"); | ||
| 41 | printf("\n"); | ||
| 42 | } | ||
| 43 | |||
| 44 | int main(int argc, char **argv) | ||
| 45 | { | ||
| 46 | idevice_t dev = NULL; | ||
| 47 | lockdownd_client_t client = NULL; | ||
| 48 | house_arrest_client_t hac = NULL; | ||
| 49 | house_arrest_error_t res; | ||
| 50 | int i; | ||
| 51 | char *udid = NULL; | ||
| 52 | const char *appid = NULL; | ||
| 53 | int test_file_io = 0; | ||
| 54 | |||
| 55 | /* parse cmdline args */ | ||
| 56 | for (i = 1; i < argc; i++) { | ||
| 57 | if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { | ||
| 58 | idevice_set_debug_level(1); | ||
| 59 | continue; | ||
| 60 | } | ||
| 61 | else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { | ||
| 62 | i++; | ||
| 63 | if (!argv[i] || (strlen(argv[i]) != 40)) { | ||
| 64 | print_usage(argc, argv); | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | udid = strdup(argv[i]); | ||
| 68 | continue; | ||
| 69 | } | ||
| 70 | else if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--test")) { | ||
| 71 | test_file_io = 1; | ||
| 72 | continue; | ||
| 73 | } | ||
| 74 | else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { | ||
| 75 | print_usage(argc, argv); | ||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | else { | ||
| 79 | appid = argv[i]; | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | if (!appid) { | ||
| 85 | print_usage(argc, argv); | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (idevice_new(&dev, udid) != IDEVICE_E_SUCCESS) { | ||
| 90 | printf("no device connected?!\n"); | ||
| 91 | goto leave_cleanup; | ||
| 92 | } | ||
| 93 | |||
| 94 | if (lockdownd_client_new_with_handshake(dev, &client, NULL) != LOCKDOWN_E_SUCCESS) { | ||
| 95 | printf("could not connect to lockdownd!\n"); | ||
| 96 | goto leave_cleanup; | ||
| 97 | } | ||
| 98 | |||
| 99 | lockdownd_service_descriptor_t service = NULL; | ||
| 100 | if (lockdownd_start_service(client, "com.apple.mobile.house_arrest", &service) != LOCKDOWN_E_SUCCESS) { | ||
| 101 | printf("could not start house_arrest service!\n"); | ||
| 102 | goto leave_cleanup; | ||
| 103 | } | ||
| 104 | |||
| 105 | if (client) { | ||
| 106 | lockdownd_client_free(client); | ||
| 107 | client = NULL; | ||
| 108 | } | ||
| 109 | |||
| 110 | if (house_arrest_client_new(dev, service, &hac) != HOUSE_ARREST_E_SUCCESS) { | ||
| 111 | printf("could not connect to house_arrest service!\n"); | ||
| 112 | goto leave_cleanup; | ||
| 113 | } | ||
| 114 | |||
| 115 | if (service) { | ||
| 116 | lockdownd_service_descriptor_free(service); | ||
| 117 | service = NULL; | ||
| 118 | } | ||
| 119 | |||
| 120 | res = house_arrest_send_command(hac, "VendDocuments", appid); | ||
| 121 | if (res != HOUSE_ARREST_E_SUCCESS) { | ||
| 122 | printf("error %d when trying to get VendDocuments\n", res); | ||
| 123 | goto leave_cleanup; | ||
| 124 | } | ||
| 125 | |||
| 126 | plist_t dict = NULL; | ||
| 127 | if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) { | ||
| 128 | if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) { | ||
| 129 | printf("hmmm....\n"); | ||
| 130 | goto leave_cleanup; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | plist_t node = plist_dict_get_item(dict, "Error"); | ||
| 135 | if (node) { | ||
| 136 | char *str = NULL; | ||
| 137 | plist_get_string_val(node, &str); | ||
| 138 | printf("Error: %s\n", str); | ||
| 139 | if (str) free(str); | ||
| 140 | plist_free(dict); | ||
| 141 | dict = NULL; | ||
| 142 | goto leave_cleanup; | ||
| 143 | } | ||
| 144 | node = plist_dict_get_item(dict, "Status"); | ||
| 145 | if (node) { | ||
| 146 | char *str = NULL; | ||
| 147 | plist_get_string_val(node, &str); | ||
| 148 | if (str && (strcmp(str, "Complete") != 0)) { | ||
| 149 | printf("Warning: Status is not 'Complete' but '%s'\n", str); | ||
| 150 | } | ||
| 151 | if (str) free(str); | ||
| 152 | plist_free(dict); | ||
| 153 | dict = NULL; | ||
| 154 | } | ||
| 155 | if (dict) { | ||
| 156 | plist_free(dict); | ||
| 157 | } | ||
| 158 | |||
| 159 | afc_client_t afc = NULL; | ||
| 160 | afc_error_t ae = afc_client_new_from_house_arrest_client(hac, &afc); | ||
| 161 | if (ae != AFC_E_SUCCESS) { | ||
| 162 | printf("afc error %d\n", ae); | ||
| 163 | } | ||
| 164 | if (ae == AFC_E_SUCCESS) { | ||
| 165 | char **list = NULL; | ||
| 166 | afc_read_directory(afc, "/", &list); | ||
| 167 | printf("Directory contents:\n"); | ||
| 168 | if (list) { | ||
| 169 | while (list[0]) { | ||
| 170 | if (strcmp(list[0], ".") && strcmp(list[0], "..")) { | ||
| 171 | puts(list[0]); | ||
| 172 | } | ||
| 173 | list++; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | if (test_file_io) { | ||
| 178 | uint64_t tf = 0; | ||
| 179 | printf("\n==== Performing file tests ====\n"); | ||
| 180 | printf("Opening file 'foobar' for writing: "); | ||
| 181 | if (afc_file_open(afc, "/foobar", AFC_FOPEN_RW, &tf) == AFC_E_SUCCESS) { | ||
| 182 | uint32_t wb = 0; | ||
| 183 | printf("OK\n"); | ||
| 184 | |||
| 185 | printf("Writing to file: "); | ||
| 186 | if (afc_file_write(afc, tf, "test\r\n", 6, &wb) != AFC_E_SUCCESS) { | ||
| 187 | printf("ERROR\n"); | ||
| 188 | } else { | ||
| 189 | printf("OK\n"); | ||
| 190 | } | ||
| 191 | afc_file_close(afc, tf); | ||
| 192 | printf("Deleting file 'foobar': "); | ||
| 193 | if (afc_remove_path(afc, "/foobar") == AFC_E_SUCCESS) { | ||
| 194 | printf("OK\n"); | ||
| 195 | } else { | ||
| 196 | printf("ERROR\n"); | ||
| 197 | } | ||
| 198 | } else { | ||
| 199 | printf("ERROR\n"); | ||
| 200 | } | ||
| 201 | } | ||
| 202 | afc_client_free(afc); | ||
| 203 | } else { | ||
| 204 | printf("failed to connect to afc service, error %d\n", ae); | ||
| 205 | } | ||
| 206 | |||
| 207 | leave_cleanup: | ||
| 208 | if (hac) { | ||
| 209 | house_arrest_client_free(hac); | ||
| 210 | } | ||
| 211 | if (client) { | ||
| 212 | lockdownd_client_free(client); | ||
| 213 | } | ||
| 214 | if (dev) { | ||
| 215 | idevice_free(dev); | ||
| 216 | } | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
diff --git a/dev/ideviceclient.c b/dev/ideviceclient.c deleted file mode 100644 index b92ae94..0000000 --- a/dev/ideviceclient.c +++ /dev/null | |||
| @@ -1,272 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * main.c | ||
| 3 | * Test program for testing several services. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2008 Zach C. All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <stdio.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <string.h> | ||
| 25 | #include <errno.h> | ||
| 26 | |||
| 27 | #ifdef WIN32 | ||
| 28 | #include <windows.h> | ||
| 29 | #define sleep(x) Sleep(x*1000) | ||
| 30 | #else | ||
| 31 | #include <unistd.h> | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #include <libimobiledevice/libimobiledevice.h> | ||
| 35 | #include <libimobiledevice/lockdown.h> | ||
| 36 | #include <libimobiledevice/afc.h> | ||
| 37 | #include <libimobiledevice/notification_proxy.h> | ||
| 38 | |||
| 39 | static void notifier(const char *notification, void *userdata) | ||
| 40 | { | ||
| 41 | printf("---------------------------------------------------------\n"); | ||
| 42 | printf("------> Notification received: %s\n", notification); | ||
| 43 | printf("---------------------------------------------------------\n"); | ||
| 44 | } | ||
| 45 | |||
| 46 | static void perform_notification(idevice_t phone, lockdownd_client_t client, const char *notification) | ||
| 47 | { | ||
| 48 | lockdownd_service_descriptor_t service = NULL; | ||
| 49 | np_client_t np; | ||
| 50 | |||
| 51 | lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &service); | ||
| 52 | if (service && service->port) { | ||
| 53 | printf("::::::::::::::: np was started ::::::::::::\n"); | ||
| 54 | np_client_new(phone, service, &np); | ||
| 55 | if (np) { | ||
| 56 | printf("::::::::: PostNotification %s\n", notification); | ||
| 57 | np_post_notification(np, notification); | ||
| 58 | np_client_free(np); | ||
| 59 | } | ||
| 60 | } else { | ||
| 61 | printf("::::::::::::::: np was NOT started ::::::::::::\n"); | ||
| 62 | } | ||
| 63 | |||
| 64 | if (service) { | ||
| 65 | lockdownd_service_descriptor_free(service); | ||
| 66 | service = NULL; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | int main(int argc, char *argv[]) | ||
| 71 | { | ||
| 72 | unsigned int bytes = 0; | ||
| 73 | uint16_t i = 0; | ||
| 74 | lockdownd_service_descriptor_t service = NULL; | ||
| 75 | lockdownd_client_t client = NULL; | ||
| 76 | idevice_t phone = NULL; | ||
| 77 | uint64_t lockfile = 0; | ||
| 78 | np_client_t gnp = NULL; | ||
| 79 | |||
| 80 | if (argc > 1 && !strcasecmp(argv[1], "--debug")) { | ||
| 81 | idevice_set_debug_level(1); | ||
| 82 | } else { | ||
| 83 | idevice_set_debug_level(0); | ||
| 84 | } | ||
| 85 | |||
| 86 | if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { | ||
| 87 | printf("No device found, is it plugged in?\n"); | ||
| 88 | return -1; | ||
| 89 | } | ||
| 90 | |||
| 91 | char *udid = NULL; | ||
| 92 | if (IDEVICE_E_SUCCESS == idevice_get_udid(phone, &udid)) { | ||
| 93 | printf("DeviceUniqueID : %s\n", udid); | ||
| 94 | } | ||
| 95 | if (udid) | ||
| 96 | free(udid); | ||
| 97 | |||
| 98 | if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "ideviceclient")) { | ||
| 99 | idevice_free(phone); | ||
| 100 | printf("Exiting.\n"); | ||
| 101 | return -1; | ||
| 102 | } | ||
| 103 | |||
| 104 | char *nnn = NULL; | ||
| 105 | if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name(client, &nnn)) { | ||
| 106 | printf("DeviceName : %s\n", nnn); | ||
| 107 | free(nnn); | ||
| 108 | } | ||
| 109 | |||
| 110 | lockdownd_start_service(client, "com.apple.afc", &service); | ||
| 111 | |||
| 112 | if (service && service->port) { | ||
| 113 | afc_client_t afc = NULL; | ||
| 114 | afc_client_new(phone, service, &afc); | ||
| 115 | |||
| 116 | if (afc) { | ||
| 117 | service->port = 0; | ||
| 118 | service->ssl_enabled = 0; | ||
| 119 | lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &service); | ||
| 120 | if (service->port) { | ||
| 121 | printf("Notification Proxy started.\n"); | ||
| 122 | np_client_new(phone, service, &gnp); | ||
| 123 | } else { | ||
| 124 | printf("ERROR: Notification proxy could not be started.\n"); | ||
| 125 | } | ||
| 126 | |||
| 127 | if (gnp) { | ||
| 128 | const char *nspec[5] = { | ||
| 129 | NP_SYNC_CANCEL_REQUEST, | ||
| 130 | NP_SYNC_SUSPEND_REQUEST, | ||
| 131 | NP_SYNC_RESUME_REQUEST, | ||
| 132 | NP_ITDBPREP_DID_END, | ||
| 133 | NULL | ||
| 134 | }; | ||
| 135 | np_observe_notifications(gnp, nspec); | ||
| 136 | np_set_notify_callback(gnp, notifier, NULL); | ||
| 137 | } | ||
| 138 | |||
| 139 | perform_notification(phone, client, NP_SYNC_WILL_START); | ||
| 140 | |||
| 141 | afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); | ||
| 142 | if (lockfile) { | ||
| 143 | printf("locking file\n"); | ||
| 144 | afc_file_lock(afc, lockfile, AFC_LOCK_EX); | ||
| 145 | |||
| 146 | perform_notification(phone, client, NP_SYNC_DID_START); | ||
| 147 | } | ||
| 148 | |||
| 149 | char **dirs = NULL; | ||
| 150 | afc_read_directory(afc, "/eafaedf", &dirs); | ||
| 151 | if (!dirs) | ||
| 152 | afc_read_directory(afc, "/", &dirs); | ||
| 153 | printf("Directory time.\n"); | ||
| 154 | for (i = 0; dirs[i]; i++) { | ||
| 155 | printf("/%s\n", dirs[i]); | ||
| 156 | free(dirs[i]); | ||
| 157 | } | ||
| 158 | if (dirs) | ||
| 159 | free(dirs); | ||
| 160 | |||
| 161 | dirs = NULL; | ||
| 162 | afc_get_device_info(afc, &dirs); | ||
| 163 | if (dirs) { | ||
| 164 | for (i = 0; dirs[i]; i += 2) { | ||
| 165 | printf("%s: %s\n", dirs[i], dirs[i + 1]); | ||
| 166 | free(dirs[i]); | ||
| 167 | } | ||
| 168 | free(dirs); | ||
| 169 | } | ||
| 170 | |||
| 171 | uint64_t my_file = 0; | ||
| 172 | char **info = NULL; | ||
| 173 | uint64_t fsize = 0; | ||
| 174 | if (AFC_E_SUCCESS == afc_get_file_info(afc, "/readme.libimobiledevice.fx", &info) && info) { | ||
| 175 | for (i = 0; info[i]; i += 2) { | ||
| 176 | printf("%s: %s\n", info[i], info[i+1]); | ||
| 177 | if (!strcmp(info[i], "st_size")) { | ||
| 178 | fsize = atoll(info[i+1]); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | if (AFC_E_SUCCESS == | ||
| 184 | afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) { | ||
| 185 | printf("A file size: %llu\n", (long long)fsize); | ||
| 186 | char *file_data = (char *) malloc(sizeof(char) * fsize); | ||
| 187 | afc_file_read(afc, my_file, file_data, fsize, &bytes); | ||
| 188 | if (bytes > 0) { | ||
| 189 | printf("The file's data:\n"); | ||
| 190 | fwrite(file_data, 1, bytes, stdout); | ||
| 191 | } | ||
| 192 | printf("\nClosing my file.\n"); | ||
| 193 | afc_file_close(afc, my_file); | ||
| 194 | free(file_data); | ||
| 195 | } else | ||
| 196 | printf("couldn't open a file\n"); | ||
| 197 | |||
| 198 | afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_WR, &my_file); | ||
| 199 | if (my_file) { | ||
| 200 | char *outdatafile = strdup("this is a bitchin text file\n"); | ||
| 201 | afc_file_write(afc, my_file, outdatafile, strlen(outdatafile), &bytes); | ||
| 202 | free(outdatafile); | ||
| 203 | if (bytes > 0) | ||
| 204 | printf("Wrote a surprise. ;)\n"); | ||
| 205 | else | ||
| 206 | printf("I wanted to write a surprise, but... :(\n"); | ||
| 207 | afc_file_close(afc, my_file); | ||
| 208 | } | ||
| 209 | printf("Deleting a file...\n"); | ||
| 210 | bytes = afc_remove_path(afc, "/delme"); | ||
| 211 | if (bytes) | ||
| 212 | printf("Success.\n"); | ||
| 213 | else | ||
| 214 | printf("Failure. (expected unless you have a /delme file on your phone)\n"); | ||
| 215 | |||
| 216 | printf("Renaming a file...\n"); | ||
| 217 | bytes = afc_rename_path(afc, "/renme", "/renme2"); | ||
| 218 | if (bytes > 0) | ||
| 219 | printf("Success.\n"); | ||
| 220 | else | ||
| 221 | printf("Failure. (expected unless you have a /renme file on your phone)\n"); | ||
| 222 | |||
| 223 | printf("Seek & read\n"); | ||
| 224 | afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file); | ||
| 225 | if (AFC_E_SUCCESS != afc_file_seek(afc, my_file, 5, SEEK_CUR)) | ||
| 226 | printf("WARN: SEEK DID NOT WORK\n"); | ||
| 227 | char *threeletterword = (char *) malloc(sizeof(char) * 5); | ||
| 228 | afc_file_read(afc, my_file, threeletterword, 3, &bytes); | ||
| 229 | threeletterword[3] = '\0'; | ||
| 230 | if (bytes > 0) | ||
| 231 | printf("Result: %s\n", threeletterword); | ||
| 232 | else | ||
| 233 | printf("Couldn't read!\n"); | ||
| 234 | free(threeletterword); | ||
| 235 | afc_file_close(afc, my_file); | ||
| 236 | } | ||
| 237 | |||
| 238 | if (gnp && lockfile) { | ||
| 239 | printf("XXX sleeping\n"); | ||
| 240 | sleep(5); | ||
| 241 | |||
| 242 | printf("XXX unlocking file\n"); | ||
| 243 | afc_file_lock(afc, lockfile, AFC_LOCK_UN); | ||
| 244 | |||
| 245 | printf("XXX closing file\n"); | ||
| 246 | afc_file_close(afc, lockfile); | ||
| 247 | |||
| 248 | printf("XXX sleeping\n"); | ||
| 249 | sleep(5); | ||
| 250 | //perform_notification(phone, client, NP_SYNC_DID_FINISH); | ||
| 251 | } | ||
| 252 | |||
| 253 | if (gnp) { | ||
| 254 | np_client_free(gnp); | ||
| 255 | gnp = NULL; | ||
| 256 | } | ||
| 257 | |||
| 258 | afc_client_free(afc); | ||
| 259 | |||
| 260 | lockdownd_service_descriptor_free(service); | ||
| 261 | service = NULL; | ||
| 262 | } else { | ||
| 263 | printf("Start service failure.\n"); | ||
| 264 | } | ||
| 265 | |||
| 266 | printf("All done.\n"); | ||
| 267 | |||
| 268 | lockdownd_client_free(client); | ||
| 269 | idevice_free(phone); | ||
| 270 | |||
| 271 | return 0; | ||
| 272 | } | ||
diff --git a/dev/ideviceheartbeat.c b/dev/ideviceheartbeat.c deleted file mode 100644 index a140589..0000000 --- a/dev/ideviceheartbeat.c +++ /dev/null | |||
| @@ -1,157 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ideviceheartbeat.c | ||
| 3 | * Simple utility which keeps a "heartbeat service" connection alive | ||
| 4 | * | ||
| 5 | * Copyright (c) 2013 Martin Szulecki All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <stdio.h> | ||
| 23 | #include <string.h> | ||
| 24 | #include <inttypes.h> | ||
| 25 | #include <signal.h> | ||
| 26 | #include <stdlib.h> | ||
| 27 | |||
| 28 | #include <libimobiledevice/libimobiledevice.h> | ||
| 29 | #include <libimobiledevice/heartbeat.h> | ||
| 30 | |||
| 31 | static int quit_flag = 0; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * signal handler function for cleaning up properly | ||
| 35 | */ | ||
| 36 | static void clean_exit(int sig) | ||
| 37 | { | ||
| 38 | fprintf(stderr, "Exiting...\n"); | ||
| 39 | quit_flag++; | ||
| 40 | } | ||
| 41 | |||
| 42 | static void print_usage(int argc, char **argv) | ||
| 43 | { | ||
| 44 | char *name = NULL; | ||
| 45 | |||
| 46 | name = strrchr(argv[0], '/'); | ||
| 47 | printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0])); | ||
| 48 | printf("Runs in the foreground and keeps a \"heartbeat\" connection alive.\n\n"); | ||
| 49 | printf(" -d, --debug\t\tenable communication debugging\n"); | ||
| 50 | printf(" -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n"); | ||
| 51 | printf(" -h, --help\t\tprints usage information\n"); | ||
| 52 | printf("\n"); | ||
| 53 | } | ||
| 54 | |||
| 55 | int main(int argc, char *argv[]) | ||
| 56 | { | ||
| 57 | heartbeat_client_t heartbeat = NULL; | ||
| 58 | idevice_t device = NULL; | ||
| 59 | idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; | ||
| 60 | int i; | ||
| 61 | const char* udid = NULL; | ||
| 62 | |||
| 63 | signal(SIGINT, clean_exit); | ||
| 64 | signal(SIGTERM, clean_exit); | ||
| 65 | #ifndef WIN32 | ||
| 66 | signal(SIGQUIT, clean_exit); | ||
| 67 | signal(SIGPIPE, SIG_IGN); | ||
| 68 | #endif | ||
| 69 | /* parse cmdline args */ | ||
| 70 | for (i = 1; i < argc; i++) { | ||
| 71 | if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { | ||
| 72 | idevice_set_debug_level(1); | ||
| 73 | continue; | ||
| 74 | } | ||
| 75 | else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { | ||
| 76 | i++; | ||
| 77 | if (!argv[i] || (strlen(argv[i]) != 40)) { | ||
| 78 | print_usage(argc, argv); | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | udid = argv[i]; | ||
| 82 | continue; | ||
| 83 | } | ||
| 84 | else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { | ||
| 85 | print_usage(argc, argv); | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | else { | ||
| 89 | print_usage(argc, argv); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | ret = idevice_new(&device, udid); | ||
| 95 | if (ret != IDEVICE_E_SUCCESS) { | ||
| 96 | if (udid) { | ||
| 97 | printf("No device found with udid %s, is it plugged in?\n", udid); | ||
| 98 | } else { | ||
| 99 | printf("No device found, is it plugged in?\n"); | ||
| 100 | } | ||
| 101 | return -1; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* start heartbeat service on device */ | ||
| 105 | heartbeat_client_start_service(device, &heartbeat, "ideviceheartbeat"); | ||
| 106 | if (heartbeat) { | ||
| 107 | printf("< heartbeat started, listening...\n"); | ||
| 108 | } else { | ||
| 109 | printf("Failed to start heartbeat service\n"); | ||
| 110 | idevice_free(device); | ||
| 111 | return -1; | ||
| 112 | } | ||
| 113 | |||
| 114 | /* main loop */ | ||
| 115 | uint8_t b = 0; | ||
| 116 | uint64_t interval = 10000; | ||
| 117 | plist_t message = NULL; | ||
| 118 | plist_t node = NULL; | ||
| 119 | do { | ||
| 120 | /* await a "ping" message from the device every interval seconds */ | ||
| 121 | heartbeat_receive_with_timeout(heartbeat, &message, (uint32_t)interval); | ||
| 122 | if (message) { | ||
| 123 | /* report device beat settings */ | ||
| 124 | node = plist_dict_get_item(message, "SupportsSleepyTime"); | ||
| 125 | if (node && plist_get_node_type(node) == PLIST_BOOLEAN) { | ||
| 126 | plist_get_bool_val(node, &b); | ||
| 127 | } | ||
| 128 | node = plist_dict_get_item(message, "Interval"); | ||
| 129 | if (node && plist_get_node_type(node) == PLIST_UINT) { | ||
| 130 | plist_get_uint_val(node, &interval); | ||
| 131 | } | ||
| 132 | |||
| 133 | printf("> marco: supports_sleepy_time %d, interval %"PRIu64"\n", b, interval); | ||
| 134 | |||
| 135 | plist_free(message); | ||
| 136 | message = NULL; | ||
| 137 | |||
| 138 | /* answer with a "pong" message */ | ||
| 139 | message = plist_new_dict(); | ||
| 140 | plist_dict_set_item(message, "Command", plist_new_string("Polo")); | ||
| 141 | heartbeat_send(heartbeat, message); | ||
| 142 | |||
| 143 | printf("< polo\n"); | ||
| 144 | |||
| 145 | if (message) { | ||
| 146 | plist_free(message); | ||
| 147 | message = NULL; | ||
| 148 | } | ||
| 149 | } | ||
| 150 | } while(!quit_flag); | ||
| 151 | |||
| 152 | heartbeat_client_free(heartbeat); | ||
| 153 | |||
| 154 | idevice_free(device); | ||
| 155 | |||
| 156 | return 0; | ||
| 157 | } | ||
diff --git a/dev/lckdclient.c b/dev/lckdclient.c deleted file mode 100644 index 08d798f..0000000 --- a/dev/lckdclient.c +++ /dev/null | |||
| @@ -1,163 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * lckdclient.c | ||
| 3 | * Rudimentary command line interface to the Lockdown protocol | ||
| 4 | * | ||
| 5 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with this library; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <stdio.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <string.h> | ||
| 25 | #include <readline/readline.h> | ||
| 26 | #include <readline/history.h> | ||
| 27 | |||
| 28 | #include <libimobiledevice/libimobiledevice.h> | ||
| 29 | #include <libimobiledevice/lockdown.h> | ||
| 30 | |||
| 31 | static char** get_tokens(const char *str) | ||
| 32 | { | ||
| 33 | char *strcp = strdup(str); | ||
| 34 | char *p; | ||
| 35 | char res_max = 8; | ||
| 36 | char **result = NULL; | ||
| 37 | int cnt = 0; | ||
| 38 | |||
| 39 | p = strtok(strcp, " "); | ||
| 40 | if (!p) { | ||
| 41 | result = (char**)malloc(2 * sizeof(char*)); | ||
| 42 | result[0] = strdup(str); | ||
| 43 | result[1] = NULL; | ||
| 44 | return result; | ||
| 45 | } | ||
| 46 | |||
| 47 | result = (char**)malloc(res_max * sizeof(char*)); | ||
| 48 | memset(result, 0, res_max * sizeof(char*)); | ||
| 49 | |||
| 50 | while (p) { | ||
| 51 | if (cnt >= res_max) { | ||
| 52 | res_max += 8; | ||
| 53 | result = (char**)realloc(result, res_max * sizeof(char*)); | ||
| 54 | } | ||
| 55 | result[cnt] = strdup(p); | ||
| 56 | cnt++; | ||
| 57 | p = strtok(NULL, " "); | ||
| 58 | } | ||
| 59 | |||
| 60 | if (cnt >= res_max) { | ||
| 61 | res_max += 1; | ||
| 62 | result = (char**)realloc(result, res_max * sizeof(char*)); | ||
| 63 | result[cnt] = NULL; | ||
| 64 | } | ||
| 65 | |||
| 66 | return result; | ||
| 67 | } | ||
| 68 | |||
| 69 | static void strfreev(char **strs) | ||
| 70 | { | ||
| 71 | int i = 0; | ||
| 72 | while (strs && strs[i]) { | ||
| 73 | free(strs[i]); | ||
| 74 | i++; | ||
| 75 | } | ||
| 76 | free(strs); | ||
| 77 | } | ||
| 78 | |||
| 79 | int main(int argc, char *argv[]) | ||
| 80 | { | ||
| 81 | lockdownd_client_t client = NULL; | ||
| 82 | idevice_t phone = NULL; | ||
| 83 | |||
| 84 | idevice_set_debug_level(1); | ||
| 85 | |||
| 86 | if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { | ||
| 87 | printf("No device found, is it plugged in?\n"); | ||
| 88 | return -1; | ||
| 89 | } | ||
| 90 | |||
| 91 | char *udid = NULL; | ||
| 92 | if (IDEVICE_E_SUCCESS == idevice_get_udid(phone, &udid)) { | ||
| 93 | printf("DeviceUniqueID : %s\n", udid); | ||
| 94 | } | ||
| 95 | if (udid) | ||
| 96 | free(udid); | ||
| 97 | |||
| 98 | if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "lckdclient")) { | ||
| 99 | idevice_free(phone); | ||
| 100 | return -1; | ||
| 101 | } | ||
| 102 | |||
| 103 | using_history(); | ||
| 104 | int loop = 1; | ||
| 105 | while (loop) { | ||
| 106 | char *cmd = readline("> "); | ||
| 107 | if (cmd) { | ||
| 108 | |||
| 109 | char **args = get_tokens(cmd); | ||
| 110 | |||
| 111 | int len = 0; | ||
| 112 | while (args && args[len]) { | ||
| 113 | len++; | ||
| 114 | } | ||
| 115 | |||
| 116 | if (len > 0) { | ||
| 117 | add_history(cmd); | ||
| 118 | if (!strcmp(*args, "quit")) | ||
| 119 | loop = 0; | ||
| 120 | |||
| 121 | if (!strcmp(*args, "get") && len >= 2) { | ||
| 122 | plist_t value = NULL; | ||
| 123 | if (LOCKDOWN_E_SUCCESS == lockdownd_get_value(client, len == 3 ? *(args + 1):NULL, len == 3 ? *(args + 2):*(args + 1), &value)) | ||
| 124 | { | ||
| 125 | char *xml = NULL; | ||
| 126 | uint32_t length; | ||
| 127 | plist_to_xml(value, &xml, &length); | ||
| 128 | printf("Success : value = %s\n", xml); | ||
| 129 | free(xml); | ||
| 130 | } | ||
| 131 | else | ||
| 132 | printf("Error\n"); | ||
| 133 | |||
| 134 | if (value) | ||
| 135 | plist_free(value); | ||
| 136 | } | ||
| 137 | |||
| 138 | if (!strcmp(*args, "start") && len == 2) { | ||
| 139 | lockdownd_service_descriptor_t service = NULL; | ||
| 140 | if(LOCKDOWN_E_SUCCESS == lockdownd_start_service(client, *(args + 1), &service)) { | ||
| 141 | printf("started service %s on port %i\n", *(args + 1), service->port); | ||
| 142 | if (service) { | ||
| 143 | lockdownd_service_descriptor_free(service); | ||
| 144 | service = NULL; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | else | ||
| 148 | { | ||
| 149 | printf("failed to start service %s on device.\n", *(args + 1)); | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | strfreev(args); | ||
| 154 | } | ||
| 155 | free(cmd); | ||
| 156 | cmd = NULL; | ||
| 157 | } | ||
| 158 | clear_history(); | ||
| 159 | lockdownd_client_free(client); | ||
| 160 | idevice_free(phone); | ||
| 161 | |||
| 162 | return 0; | ||
| 163 | } | ||
