blob: 683619155285845eff87978324586e2627bef545 [file] [log] [blame]
Martin Szuleckif104eb42009-04-16 17:12:45 +02001/*
Nikias Bassen96101a12010-01-28 22:18:41 +01002 * idevicesyslog.c
Martin Szuleckif104eb42009-04-16 17:12:45 +02003 * Relay the syslog of a device to stdout
4 *
5 * Copyright (c) 2009 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 <errno.h>
Martin Szuleckif104eb42009-04-16 17:12:45 +020025#include <signal.h>
Martin Szulecki0727ae72009-06-21 23:02:22 +020026#include <stdlib.h>
Nikias Bassenb5a74342013-02-28 11:04:17 +010027#include <unistd.h>
28
29#ifdef WIN32
30#include <windows.h>
31#define sleep(x) Sleep(x*1000)
Nikias Bassenb5a74342013-02-28 11:04:17 +010032#endif
Martin Szuleckif104eb42009-04-16 17:12:45 +020033
Nikias Bassen96101a12010-01-28 22:18:41 +010034#include <libimobiledevice/libimobiledevice.h>
35#include <libimobiledevice/lockdown.h>
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020036#include <libimobiledevice/syslog_relay.h>
Martin Szuleckif104eb42009-04-16 17:12:45 +020037
38static int quit_flag = 0;
39
40void print_usage(int argc, char **argv);
41
Nikias Bassenb5a74342013-02-28 11:04:17 +010042static char* udid = NULL;
43
44static idevice_t device = NULL;
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020045static syslog_relay_client_t syslog = NULL;
Nikias Bassenb5a74342013-02-28 11:04:17 +010046
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020047static void syslog_callback(char c, void *user_data)
Nikias Bassenb5a74342013-02-28 11:04:17 +010048{
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020049 putchar(c);
Nikias Bassenb5a74342013-02-28 11:04:17 +010050}
51
52static int start_logging()
53{
54 idevice_error_t ret = idevice_new(&device, udid);
55 if (ret != IDEVICE_E_SUCCESS) {
56 fprintf(stderr, "Device with udid %s not found!?\n", udid);
57 return -1;
58 }
59
60 /* start and connect to syslog_relay service */
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020061 syslog_relay_error_t serr = SYSLOG_RELAY_E_UNKNOWN_ERROR;
62 serr = syslog_relay_client_start_service(device, &syslog, "idevicesyslog");
63 if (serr != SYSLOG_RELAY_E_SUCCESS) {
Nikias Bassenb5a74342013-02-28 11:04:17 +010064 fprintf(stderr, "ERROR: Could not start service com.apple.syslog_relay.\n");
65 idevice_free(device);
66 device = NULL;
67 return -1;
68 }
69
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020070 /* start capturing syslog */
71 serr = syslog_relay_start_capture(syslog, syslog_callback, NULL);
72 if (serr != SYSLOG_RELAY_E_SUCCESS) {
73 fprintf(stderr, "ERROR: Unable tot start capturing syslog.\n");
74 syslog_relay_client_free(syslog);
75 syslog = NULL;
76 idevice_free(device);
77 device = NULL;
Nikias Bassenb5a74342013-02-28 11:04:17 +010078 return -1;
79 }
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020080
81 fprintf(stdout, "[connected]\n");
82 fflush(stdout);
83
Nikias Bassenb5a74342013-02-28 11:04:17 +010084 return 0;
85}
86
87static void stop_logging()
88{
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020089 fflush(stdout);
Nikias Bassenb5a74342013-02-28 11:04:17 +010090
Martin Szuleckiabad8cb2013-05-23 14:15:40 +020091 if (syslog) {
92 syslog_relay_client_free(syslog);
93 syslog = NULL;
Nikias Bassenb5a74342013-02-28 11:04:17 +010094 }
95
96 if (device) {
97 idevice_free(device);
98 device = NULL;
99 }
100}
101
102static void device_event_cb(const idevice_event_t* event, void* userdata)
103{
104 if (event->event == IDEVICE_DEVICE_ADD) {
Martin Szuleckiabad8cb2013-05-23 14:15:40 +0200105 if (!syslog) {
Nikias Bassenb5a74342013-02-28 11:04:17 +0100106 if (!udid) {
107 udid = strdup(event->udid);
108 }
109 if (strcmp(udid, event->udid) == 0) {
110 if (start_logging() != 0) {
111 fprintf(stderr, "Could not start logger for udid %s\n", udid);
112 }
113 }
114 }
115 } else if (event->event == IDEVICE_DEVICE_REMOVE) {
Martin Szuleckiabad8cb2013-05-23 14:15:40 +0200116 if (syslog && (strcmp(udid, event->udid) == 0)) {
Nikias Bassenb5a74342013-02-28 11:04:17 +0100117 stop_logging();
118 }
119 }
120}
121
Martin Szuleckif104eb42009-04-16 17:12:45 +0200122/**
123 * signal handler function for cleaning up properly
124 */
125static void clean_exit(int sig)
126{
Nikias Bassenb5a74342013-02-28 11:04:17 +0100127 fprintf(stderr, "\nExiting...\n");
Martin Szuleckif104eb42009-04-16 17:12:45 +0200128 quit_flag++;
129}
130
131int main(int argc, char *argv[])
132{
Martin Szuleckif104eb42009-04-16 17:12:45 +0200133 int i;
Martin Szuleckif104eb42009-04-16 17:12:45 +0200134
135 signal(SIGINT, clean_exit);
Martin Szuleckif104eb42009-04-16 17:12:45 +0200136 signal(SIGTERM, clean_exit);
Nikias Bassen7acb8ec2011-09-15 00:44:51 +0200137#ifndef WIN32
138 signal(SIGQUIT, clean_exit);
Martin Szuleckif104eb42009-04-16 17:12:45 +0200139 signal(SIGPIPE, SIG_IGN);
Nikias Bassen7acb8ec2011-09-15 00:44:51 +0200140#endif
Martin Szuleckif104eb42009-04-16 17:12:45 +0200141
142 /* parse cmdline args */
143 for (i = 1; i < argc; i++) {
144 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
Nikias Bassen96101a12010-01-28 22:18:41 +0100145 idevice_set_debug_level(1);
Martin Szuleckif104eb42009-04-16 17:12:45 +0200146 continue;
147 }
Martin Szulecki74573462012-03-22 16:07:07 +0100148 else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
Nikias Bassenb61667e2009-05-19 13:15:11 +0200149 i++;
150 if (!argv[i] || (strlen(argv[i]) != 40)) {
Martin Szuleckif104eb42009-04-16 17:12:45 +0200151 print_usage(argc, argv);
152 return 0;
153 }
Nikias Bassenb5a74342013-02-28 11:04:17 +0100154 udid = strdup(argv[i]);
Martin Szuleckif104eb42009-04-16 17:12:45 +0200155 continue;
156 }
157 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
158 print_usage(argc, argv);
159 return 0;
160 }
161 else {
162 print_usage(argc, argv);
163 return 0;
164 }
165 }
166
Nikias Bassenb5a74342013-02-28 11:04:17 +0100167 int num = 0;
168 char **devices = NULL;
169 idevice_get_device_list(&devices, &num);
170 idevice_device_list_free(devices);
171 if (num == 0) {
172 if (!udid) {
173 fprintf(stderr, "No device found. Plug in a device or pass UDID with -u to wait for device to be available.\n");
174 return -1;
Nikias Bassen36c01922012-11-29 03:42:06 +0100175 } else {
Nikias Bassenb5a74342013-02-28 11:04:17 +0100176 fprintf(stderr, "Waiting for device with UDID %s to become available...\n", udid);
Martin Szuleckif104eb42009-04-16 17:12:45 +0200177 }
Nikias Bassenb61667e2009-05-19 13:15:11 +0200178 }
Martin Szuleckif104eb42009-04-16 17:12:45 +0200179
Nikias Bassenb5a74342013-02-28 11:04:17 +0100180 idevice_event_subscribe(device_event_cb, NULL);
Martin Szuleckif104eb42009-04-16 17:12:45 +0200181
Nikias Bassenb5a74342013-02-28 11:04:17 +0100182 while (!quit_flag) {
183 sleep(1);
Martin Szuleckif104eb42009-04-16 17:12:45 +0200184 }
Nikias Bassenb5a74342013-02-28 11:04:17 +0100185 idevice_event_unsubscribe();
186 stop_logging();
187
188 if (udid) {
189 free(udid);
190 }
Martin Szuleckif104eb42009-04-16 17:12:45 +0200191
192 return 0;
193}
194
195void print_usage(int argc, char **argv)
196{
Martin Szulecki92233962009-07-01 18:17:16 +0200197 char *name = NULL;
198
199 name = strrchr(argv[0], '/');
200 printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0]));
Martin Szulecki1379f422012-04-07 15:50:04 +0200201 printf("Relay syslog of a connected device.\n\n");
Martin Szuleckif104eb42009-04-16 17:12:45 +0200202 printf(" -d, --debug\t\tenable communication debugging\n");
Martin Szulecki74573462012-03-22 16:07:07 +0100203 printf(" -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n");
Martin Szuleckif104eb42009-04-16 17:12:45 +0200204 printf(" -h, --help\t\tprints usage information\n");
205 printf("\n");
206}
207