blob: 0cc993663ba1e0af8dfee4607fd06311c81fc9fe [file] [log] [blame]
Martin Szulecki5844d662009-08-01 18:54:59 +02001/*
Nikias Bassen96101a12010-01-28 22:18:41 +01002 * ideviceenterrecovery.c
Martin Szulecki5844d662009-08-01 18:54:59 +02003 * Simple utility to make a device in normal mode enter recovery mode.
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.
Martin Szulecki24ce2e22015-01-28 01:27:59 +010011 *
Martin Szulecki5844d662009-08-01 18:54:59 +020012 * 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.
Martin Szulecki24ce2e22015-01-28 01:27:59 +010016 *
Martin Szulecki5844d662009-08-01 18:54:59 +020017 * 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
Martin Szulecki24ce2e22015-01-28 01:27:59 +010019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Martin Szulecki5844d662009-08-01 18:54:59 +020020 */
21
Martin Szuleckid93043e2015-10-06 22:10:56 +020022#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
Nikias Bassen3aa4e242020-06-05 18:42:20 +020026#define TOOL_NAME "ideviceenterrecovery"
27
Martin Szulecki5844d662009-08-01 18:54:59 +020028#include <stdio.h>
29#include <string.h>
30#include <errno.h>
31#include <stdlib.h>
Nikias Bassen8c7321b2019-09-28 12:08:12 +020032#ifndef WIN32
33#include <signal.h>
34#endif
Martin Szulecki5844d662009-08-01 18:54:59 +020035
Nikias Bassen96101a12010-01-28 22:18:41 +010036#include <libimobiledevice/libimobiledevice.h>
37#include <libimobiledevice/lockdown.h>
Martin Szulecki5844d662009-08-01 18:54:59 +020038
39static void print_usage(int argc, char **argv)
40{
41 char *name = NULL;
Martin Szulecki24ce2e22015-01-28 01:27:59 +010042
Martin Szulecki5844d662009-08-01 18:54:59 +020043 name = strrchr(argv[0], '/');
Martin Szulecki74573462012-03-22 16:07:07 +010044 printf("Usage: %s [OPTIONS] UDID\n", (name ? name + 1: argv[0]));
Martin Szuleckibc2a1552020-06-04 02:46:09 +020045 printf("\n");
46 printf("Makes a device with the supplied UDID enter recovery mode immediately.\n");
47 printf("\n");
48 printf("OPTIONS:\n");
Martin Szulecki5844d662009-08-01 18:54:59 +020049 printf(" -d, --debug\t\tenable communication debugging\n");
50 printf(" -h, --help\t\tprints usage information\n");
Nikias Bassen3aa4e242020-06-05 18:42:20 +020051 printf(" -v, --version\t\tprints version information\n");
Martin Szulecki5844d662009-08-01 18:54:59 +020052 printf("\n");
Martin Szuleckibc2a1552020-06-04 02:46:09 +020053 printf("Homepage: <" PACKAGE_URL ">\n");
54 printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n");
Martin Szulecki5844d662009-08-01 18:54:59 +020055}
56
57int main(int argc, char *argv[])
58{
59 lockdownd_client_t client = NULL;
Nikias Bassenfd435442014-10-11 22:12:04 +020060 lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
Nikias Bassen14bacd92012-11-29 04:02:18 +010061 idevice_t device = NULL;
Nikias Bassen96101a12010-01-28 22:18:41 +010062 idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
Martin Szulecki5844d662009-08-01 18:54:59 +020063 int i;
Nikias Bassen36c01922012-11-29 03:42:06 +010064 const char* udid = NULL;
Martin Szulecki5844d662009-08-01 18:54:59 +020065
Nikias Bassen8c7321b2019-09-28 12:08:12 +020066#ifndef WIN32
67 signal(SIGPIPE, SIG_IGN);
68#endif
Martin Szulecki5844d662009-08-01 18:54:59 +020069 /* parse cmdline args */
70 for (i = 1; i < argc; i++) {
71 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
Nikias Bassen96101a12010-01-28 22:18:41 +010072 idevice_set_debug_level(1);
Martin Szulecki5844d662009-08-01 18:54:59 +020073 continue;
74 }
75 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
76 print_usage(argc, argv);
77 return 0;
78 }
Nikias Bassen3aa4e242020-06-05 18:42:20 +020079 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
80 printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
81 return 0;
82 }
Martin Szulecki5844d662009-08-01 18:54:59 +020083 }
84
85 i--;
Nikias Bassenb34e3432018-10-01 02:32:51 +020086 if (argc < 2 || !argv[i] || !*argv[i]) {
Martin Szulecki5844d662009-08-01 18:54:59 +020087 print_usage(argc, argv);
88 return 0;
89 }
Nikias Bassen36c01922012-11-29 03:42:06 +010090 udid = argv[i];
Martin Szulecki5844d662009-08-01 18:54:59 +020091
Nikias Bassen14bacd92012-11-29 04:02:18 +010092 ret = idevice_new(&device, udid);
Nikias Bassen96101a12010-01-28 22:18:41 +010093 if (ret != IDEVICE_E_SUCCESS) {
Nikias Bassen489a6732020-06-05 20:50:34 +020094 printf("No device found with udid %s.\n", udid);
Nikias Bassen25059d42021-02-09 02:45:06 +010095 return 1;
Martin Szulecki5844d662009-08-01 18:54:59 +020096 }
97
Nikias Bassen3aa4e242020-06-05 18:42:20 +020098 if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new(device, &client, TOOL_NAME))) {
Nikias Bassen25059d42021-02-09 02:45:06 +010099 printf("ERROR: Could not connect to lockdownd: %s (%d)\n", lockdownd_strerror(ldret), ldret);
Nikias Bassen14bacd92012-11-29 04:02:18 +0100100 idevice_free(device);
Nikias Bassen25059d42021-02-09 02:45:06 +0100101 return 1;
Martin Szulecki5844d662009-08-01 18:54:59 +0200102 }
103
Nikias Bassen25059d42021-02-09 02:45:06 +0100104 int res = 0;
Martin Szulecki74573462012-03-22 16:07:07 +0100105 printf("Telling device with udid %s to enter recovery mode.\n", udid);
Nikias Bassen25059d42021-02-09 02:45:06 +0100106 ldret = lockdownd_enter_recovery(client);
107 if (ldret == LOCKDOWN_E_SESSION_INACTIVE) {
108 lockdownd_client_free(client);
109 client = NULL;
110 if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, TOOL_NAME))) {
111 printf("ERROR: Could not connect to lockdownd: %s (%d)\n", lockdownd_strerror(ldret), ldret);
112 idevice_free(device);
113 return 1;
114 }
115 ldret = lockdownd_enter_recovery(client);
Martin Szulecki5844d662009-08-01 18:54:59 +0200116 }
Nikias Bassen25059d42021-02-09 02:45:06 +0100117 if (ldret != LOCKDOWN_E_SUCCESS) {
118 printf("Failed to enter recovery mode.\n");
119 res = 1;
120 } else {
121 printf("Device is successfully switching to recovery mode.\n");
122 }
Martin Szulecki5844d662009-08-01 18:54:59 +0200123
124 lockdownd_client_free(client);
Nikias Bassen14bacd92012-11-29 04:02:18 +0100125 idevice_free(device);
Martin Szulecki5844d662009-08-01 18:54:59 +0200126
Nikias Bassen25059d42021-02-09 02:45:06 +0100127 return res;
Martin Szulecki5844d662009-08-01 18:54:59 +0200128}