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 @@
24#include <errno.h> 24#include <errno.h>
25#include <signal.h> 25#include <signal.h>
26#include <stdlib.h> 26#include <stdlib.h>
27#include <unistd.h>
28
29#ifdef WIN32
30#include <windows.h>
31#define sleep(x) Sleep(x*1000)
32#else
33#include <pthread.h>
34#endif
27 35
28#include <libimobiledevice/libimobiledevice.h> 36#include <libimobiledevice/libimobiledevice.h>
29#include <libimobiledevice/lockdown.h> 37#include <libimobiledevice/lockdown.h>
@@ -34,21 +42,137 @@ static int quit_flag = 0;
34 42
35void print_usage(int argc, char **argv); 43void print_usage(int argc, char **argv);
36 44
45static char* udid = NULL;
46
47static idevice_t device = NULL;
48static service_client_t syslog = NULL;
49
50#ifdef WIN32
51HANDLE worker = NULL;
52#else
53pthread_t worker;
54#endif
55
56static int logging = 0;
57
58static void *syslog_worker(void *arg)
59{
60 service_error_t ret = SERVICE_E_UNKNOWN_ERROR;
61
62 fprintf(stdout, "[connected]\n");
63 fflush(stdout);
64
65 logging = 1;
66
67 while (logging) {
68 char c;
69 uint32_t bytes = 0;
70 ret = service_receive_with_timeout(syslog, &c, 1, &bytes, 0);
71 if (ret < 0 || (bytes != 1)) {
72 printf("\n[connection interrupted]\n");
73 fflush(stdout);
74 break;
75 }
76 if(c != 0) {
77 putchar(c);
78 }
79 }
80
81 return NULL;
82}
83
84static int start_logging()
85{
86 idevice_error_t ret = idevice_new(&device, udid);
87 if (ret != IDEVICE_E_SUCCESS) {
88 fprintf(stderr, "Device with udid %s not found!?\n", udid);
89 return -1;
90 }
91
92 /* start and connect to syslog_relay service */
93 service_error_t serr = SERVICE_E_UNKNOWN_ERROR;
94 service_client_factory_start_service(device, "com.apple.syslog_relay", (void**)&syslog, "idevicesyslog", NULL, &serr);
95 if (serr != SERVICE_E_SUCCESS) {
96 fprintf(stderr, "ERROR: Could not start service com.apple.syslog_relay.\n");
97 idevice_free(device);
98 device = NULL;
99 return -1;
100 }
101
102 /* start worker thread */
103 logging = 1;
104#ifdef WIN32
105 worker = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)syslog_worker, NULL, 0, NULL);
106 if (worker == INVALID_HANDLE_VALUE) {
107 logging = 0;
108 return -1;
109 }
110#else
111 if (pthread_create(&worker, NULL, syslog_worker, NULL) != 0) {
112 logging = 0;
113 return -1;
114 }
115#endif
116
117 return 0;
118}
119
120static void stop_logging()
121{
122 if (logging) {
123 /* notify thread to finish */
124 logging = 0;
125 if (syslog) {
126 service_client_free(syslog);
127 syslog = NULL;
128 }
129
130 /* wait for thread to complete */
131#ifdef WIN32
132 WaitForSingleObject(worker, INFINITE);
133#else
134 pthread_join(worker, NULL);
135#endif
136 }
137
138 if (device) {
139 idevice_free(device);
140 device = NULL;
141 }
142}
143
144static void device_event_cb(const idevice_event_t* event, void* userdata)
145{
146 if (event->event == IDEVICE_DEVICE_ADD) {
147 if (!logging) {
148 if (!udid) {
149 udid = strdup(event->udid);
150 }
151 if (strcmp(udid, event->udid) == 0) {
152 if (start_logging() != 0) {
153 fprintf(stderr, "Could not start logger for udid %s\n", udid);
154 }
155 }
156 }
157 } else if (event->event == IDEVICE_DEVICE_REMOVE) {
158 if (logging && (strcmp(udid, event->udid) == 0)) {
159 stop_logging();
160 }
161 }
162}
163
37/** 164/**
38 * signal handler function for cleaning up properly 165 * signal handler function for cleaning up properly
39 */ 166 */
40static void clean_exit(int sig) 167static void clean_exit(int sig)
41{ 168{
42 fprintf(stderr, "Exiting...\n"); 169 fprintf(stderr, "\nExiting...\n");
43 quit_flag++; 170 quit_flag++;
44} 171}
45 172
46int main(int argc, char *argv[]) 173int main(int argc, char *argv[])
47{ 174{
48 idevice_t device = NULL;
49 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
50 int i; 175 int i;
51 const char* udid = NULL;
52 176
53 signal(SIGINT, clean_exit); 177 signal(SIGINT, clean_exit);
54 signal(SIGTERM, clean_exit); 178 signal(SIGTERM, clean_exit);
@@ -69,7 +193,7 @@ int main(int argc, char *argv[])
69 print_usage(argc, argv); 193 print_usage(argc, argv);
70 return 0; 194 return 0;
71 } 195 }
72 udid = argv[i]; 196 udid = strdup(argv[i]);
73 continue; 197 continue;
74 } 198 }
75 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { 199 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
@@ -82,38 +206,30 @@ int main(int argc, char *argv[])
82 } 206 }
83 } 207 }
84 208
85 ret = idevice_new(&device, udid); 209 int num = 0;
86 if (ret != IDEVICE_E_SUCCESS) { 210 char **devices = NULL;
87 if (udid) { 211 idevice_get_device_list(&devices, &num);
88 printf("No device found with udid %s, is it plugged in?\n", udid); 212 idevice_device_list_free(devices);
213 if (num == 0) {
214 if (!udid) {
215 fprintf(stderr, "No device found. Plug in a device or pass UDID with -u to wait for device to be available.\n");
216 return -1;
89 } else { 217 } else {
90 printf("No device found, is it plugged in?\n"); 218 fprintf(stderr, "Waiting for device with UDID %s to become available...\n", udid);
91 } 219 }
92 return -1;
93 } 220 }
94 221
95 service_error_t serr = SERVICE_E_UNKNOWN_ERROR; 222 idevice_event_subscribe(device_event_cb, NULL);
96 service_client_t syslog = NULL;
97 223
98 service_client_factory_start_service(device, "com.apple.syslog_relay", (void**)&syslog, "idevicesyslog", NULL, &serr); 224 while (!quit_flag) {
99 if (serr == SERVICE_E_SUCCESS) { 225 sleep(1);
100 while (!quit_flag) { 226 }
101 char c; 227 idevice_event_unsubscribe();
102 uint32_t bytes = 0; 228 stop_logging();
103 if (service_receive(syslog, &c, 1, &bytes) != SERVICE_E_SUCCESS) { 229
104 fprintf(stderr, "Error receiving data. Exiting...\n"); 230 if (udid) {
105 break; 231 free(udid);
106 }
107 if (c != 0) {
108 putchar(c);
109 fflush(stdout);
110 }
111 }
112 service_client_free(syslog);
113 } else {
114 printf("ERROR: Could not start service com.apple.syslog_relay.\n");
115 } 232 }
116 idevice_free(device);
117 233
118 return 0; 234 return 0;
119} 235}