summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2013-02-28 11:04:17 +0100
committerGravatar Nikias Bassen2013-02-28 11:04:17 +0100
commitb5a7434997c4668cc66b3e6a9527bd3922cf6f0d (patch)
tree07f3cc8cc7df8489a64df35bd5b2d05d7a2894f1 /tools
parent76ce1e8910a56c456e49d12fa980adc3488e1883 (diff)
downloadlibimobiledevice-b5a7434997c4668cc66b3e6a9527bd3922cf6f0d.tar.gz
libimobiledevice-b5a7434997c4668cc66b3e6a9527bd3922cf6f0d.tar.bz2
idevicesyslog: use events to allow automatic reconnect to device
Diffstat (limited to 'tools')
-rw-r--r--tools/idevicesyslog.c178
1 files changed, 147 insertions, 31 deletions
diff --git a/tools/idevicesyslog.c b/tools/idevicesyslog.c
index 44c8246..d7e7463 100644
--- a/tools/idevicesyslog.c
+++ b/tools/idevicesyslog.c
@@ -24,6 +24,14 @@
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef WIN32
+#include <windows.h>
+#define sleep(x) Sleep(x*1000)
+#else
+#include <pthread.h>
+#endif
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
@@ -34,21 +42,137 @@ static int quit_flag = 0;
void print_usage(int argc, char **argv);
+static char* udid = NULL;
+
+static idevice_t device = NULL;
+static service_client_t syslog = NULL;
+
+#ifdef WIN32
+HANDLE worker = NULL;
+#else
+pthread_t worker;
+#endif
+
+static int logging = 0;
+
+static void *syslog_worker(void *arg)
+{
+ service_error_t ret = SERVICE_E_UNKNOWN_ERROR;
+
+ fprintf(stdout, "[connected]\n");
+ fflush(stdout);
+
+ logging = 1;
+
+ while (logging) {
+ char c;
+ uint32_t bytes = 0;
+ ret = service_receive_with_timeout(syslog, &c, 1, &bytes, 0);
+ if (ret < 0 || (bytes != 1)) {
+ printf("\n[connection interrupted]\n");
+ fflush(stdout);
+ break;
+ }
+ if(c != 0) {
+ putchar(c);
+ }
+ }
+
+ return NULL;
+}
+
+static int start_logging()
+{
+ idevice_error_t ret = idevice_new(&device, udid);
+ if (ret != IDEVICE_E_SUCCESS) {
+ fprintf(stderr, "Device with udid %s not found!?\n", udid);
+ return -1;
+ }
+
+ /* start and connect to syslog_relay service */
+ service_error_t serr = SERVICE_E_UNKNOWN_ERROR;
+ service_client_factory_start_service(device, "com.apple.syslog_relay", (void**)&syslog, "idevicesyslog", NULL, &serr);
+ if (serr != SERVICE_E_SUCCESS) {
+ fprintf(stderr, "ERROR: Could not start service com.apple.syslog_relay.\n");
+ idevice_free(device);
+ device = NULL;
+ return -1;
+ }
+
+ /* start worker thread */
+ logging = 1;
+#ifdef WIN32
+ worker = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)syslog_worker, NULL, 0, NULL);
+ if (worker == INVALID_HANDLE_VALUE) {
+ logging = 0;
+ return -1;
+ }
+#else
+ if (pthread_create(&worker, NULL, syslog_worker, NULL) != 0) {
+ logging = 0;
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+static void stop_logging()
+{
+ if (logging) {
+ /* notify thread to finish */
+ logging = 0;
+ if (syslog) {
+ service_client_free(syslog);
+ syslog = NULL;
+ }
+
+ /* wait for thread to complete */
+#ifdef WIN32
+ WaitForSingleObject(worker, INFINITE);
+#else
+ pthread_join(worker, NULL);
+#endif
+ }
+
+ if (device) {
+ idevice_free(device);
+ device = NULL;
+ }
+}
+
+static void device_event_cb(const idevice_event_t* event, void* userdata)
+{
+ if (event->event == IDEVICE_DEVICE_ADD) {
+ if (!logging) {
+ if (!udid) {
+ udid = strdup(event->udid);
+ }
+ if (strcmp(udid, event->udid) == 0) {
+ if (start_logging() != 0) {
+ fprintf(stderr, "Could not start logger for udid %s\n", udid);
+ }
+ }
+ }
+ } else if (event->event == IDEVICE_DEVICE_REMOVE) {
+ if (logging && (strcmp(udid, event->udid) == 0)) {
+ stop_logging();
+ }
+ }
+}
+
/**
* signal handler function for cleaning up properly
*/
static void clean_exit(int sig)
{
- fprintf(stderr, "Exiting...\n");
+ fprintf(stderr, "\nExiting...\n");
quit_flag++;
}
int main(int argc, char *argv[])
{
- idevice_t device = NULL;
- idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
int i;
- const char* udid = NULL;
signal(SIGINT, clean_exit);
signal(SIGTERM, clean_exit);
@@ -69,7 +193,7 @@ int main(int argc, char *argv[])
print_usage(argc, argv);
return 0;
}
- udid = argv[i];
+ udid = strdup(argv[i]);
continue;
}
else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
@@ -82,38 +206,30 @@ int main(int argc, char *argv[])
}
}
- ret = idevice_new(&device, udid);
- if (ret != IDEVICE_E_SUCCESS) {
- if (udid) {
- printf("No device found with udid %s, is it plugged in?\n", udid);
+ int num = 0;
+ char **devices = NULL;
+ idevice_get_device_list(&devices, &num);
+ idevice_device_list_free(devices);
+ if (num == 0) {
+ if (!udid) {
+ fprintf(stderr, "No device found. Plug in a device or pass UDID with -u to wait for device to be available.\n");
+ return -1;
} else {
- printf("No device found, is it plugged in?\n");
+ fprintf(stderr, "Waiting for device with UDID %s to become available...\n", udid);
}
- return -1;
}
- service_error_t serr = SERVICE_E_UNKNOWN_ERROR;
- service_client_t syslog = NULL;
+ idevice_event_subscribe(device_event_cb, NULL);
- service_client_factory_start_service(device, "com.apple.syslog_relay", (void**)&syslog, "idevicesyslog", NULL, &serr);
- if (serr == SERVICE_E_SUCCESS) {
- while (!quit_flag) {
- char c;
- uint32_t bytes = 0;
- if (service_receive(syslog, &c, 1, &bytes) != SERVICE_E_SUCCESS) {
- fprintf(stderr, "Error receiving data. Exiting...\n");
- break;
- }
- if (c != 0) {
- putchar(c);
- fflush(stdout);
- }
- }
- service_client_free(syslog);
- } else {
- printf("ERROR: Could not start service com.apple.syslog_relay.\n");
+ while (!quit_flag) {
+ sleep(1);
+ }
+ idevice_event_unsubscribe();
+ stop_logging();
+
+ if (udid) {
+ free(udid);
}
- idevice_free(device);
return 0;
}