diff options
| -rw-r--r-- | tools/idevicesyslog.c | 178 |
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 | ||
| 35 | void print_usage(int argc, char **argv); | 43 | void print_usage(int argc, char **argv); |
| 36 | 44 | ||
| 45 | static char* udid = NULL; | ||
| 46 | |||
| 47 | static idevice_t device = NULL; | ||
| 48 | static service_client_t syslog = NULL; | ||
| 49 | |||
| 50 | #ifdef WIN32 | ||
| 51 | HANDLE worker = NULL; | ||
| 52 | #else | ||
| 53 | pthread_t worker; | ||
| 54 | #endif | ||
| 55 | |||
| 56 | static int logging = 0; | ||
| 57 | |||
| 58 | static 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 | |||
| 84 | static 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 | |||
| 120 | static 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 | |||
| 144 | static 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 | */ |
| 40 | static void clean_exit(int sig) | 167 | static 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 | ||
| 46 | int main(int argc, char *argv[]) | 173 | int 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 | } |
