idevicescreenshot.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * idevicescreenshot.c
  3. * Gets a screenshot from a device
  4. *
  5. * Copyright (C) 2010 Nikias Bassen <nikias@gmx.li>
  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. #include <stdio.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <errno.h>
  25. #include <time.h>
  26. #include <libimobiledevice/libimobiledevice.h>
  27. #include <libimobiledevice/lockdown.h>
  28. #include <libimobiledevice/screenshotr.h>
  29. void print_usage(int argc, char **argv);
  30. int main(int argc, char **argv)
  31. {
  32. idevice_t device = NULL;
  33. lockdownd_client_t lckd = NULL;
  34. lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
  35. screenshotr_client_t shotr = NULL;
  36. lockdownd_service_descriptor_t service = NULL;
  37. int result = -1;
  38. int i;
  39. const char *udid = NULL;
  40. char *filename = NULL;
  41. /* parse cmdline args */
  42. for (i = 1; i < argc; i++) {
  43. if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
  44. idevice_set_debug_level(1);
  45. continue;
  46. }
  47. else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
  48. i++;
  49. if (!argv[i] || (strlen(argv[i]) != 40)) {
  50. print_usage(argc, argv);
  51. return 0;
  52. }
  53. udid = argv[i];
  54. continue;
  55. }
  56. else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
  57. print_usage(argc, argv);
  58. return 0;
  59. }
  60. else if (argv[i][0] != '-' && !filename) {
  61. filename = strdup(argv[i]);
  62. continue;
  63. }
  64. else {
  65. print_usage(argc, argv);
  66. return 0;
  67. }
  68. }
  69. if (IDEVICE_E_SUCCESS != idevice_new(&device, udid)) {
  70. if (udid) {
  71. printf("No device found with udid %s, is it plugged in?\n", udid);
  72. } else {
  73. printf("No device found, is it plugged in?\n");
  74. }
  75. return -1;
  76. }
  77. if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &lckd, NULL))) {
  78. idevice_free(device);
  79. printf("ERROR: Could not connect to lockdownd, error code %d\n", ldret);
  80. return -1;
  81. }
  82. lockdownd_start_service(lckd, "com.apple.mobile.screenshotr", &service);
  83. lockdownd_client_free(lckd);
  84. if (service && service->port > 0) {
  85. if (screenshotr_client_new(device, service, &shotr) != SCREENSHOTR_E_SUCCESS) {
  86. printf("Could not connect to screenshotr!\n");
  87. } else {
  88. char *imgdata = NULL;
  89. uint64_t imgsize = 0;
  90. if (!filename) {
  91. time_t now = time(NULL);
  92. filename = (char*)malloc(36);
  93. strftime(filename, 36, "screenshot-%Y-%m-%d-%H-%M-%S.tiff", gmtime(&now));
  94. }
  95. if (screenshotr_take_screenshot(shotr, &imgdata, &imgsize) == SCREENSHOTR_E_SUCCESS) {
  96. FILE *f = fopen(filename, "wb");
  97. if (f) {
  98. if (fwrite(imgdata, 1, (size_t)imgsize, f) == (size_t)imgsize) {
  99. printf("Screenshot saved to %s\n", filename);
  100. result = 0;
  101. } else {
  102. printf("Could not save screenshot to file %s!\n", filename);
  103. }
  104. fclose(f);
  105. } else {
  106. printf("Could not open %s for writing: %s\n", filename, strerror(errno));
  107. }
  108. } else {
  109. printf("Could not get screenshot!\n");
  110. }
  111. screenshotr_client_free(shotr);
  112. }
  113. } else {
  114. printf("Could not start screenshotr service! Remember that you have to mount the Developer disk image on your device if you want to use the screenshotr service.\n");
  115. }
  116. if (service)
  117. lockdownd_service_descriptor_free(service);
  118. idevice_free(device);
  119. free(filename);
  120. return result;
  121. }
  122. void print_usage(int argc, char **argv)
  123. {
  124. char *name = NULL;
  125. name = strrchr(argv[0], '/');
  126. printf("Usage: %s [OPTIONS] [FILE]\n", (name ? name + 1: argv[0]));
  127. printf("Gets a screenshot from a device.\n");
  128. printf("The screenshot is saved as a TIFF image with the given FILE name,\n");
  129. printf("where the default name is \"screenshot-DATE.tiff\", e.g.:\n");
  130. printf(" ./screenshot-2013-12-31-23-59-59.tiff\n\n");
  131. printf("NOTE: A mounted developer disk image is required on the device, otherwise\n");
  132. printf("the screenshotr service is not available.\n\n");
  133. printf(" -d, --debug\t\tenable communication debugging\n");
  134. printf(" -u, --udid UDID\ttarget specific device by its 40-digit device UDID\n");
  135. printf(" -h, --help\t\tprints usage information\n");
  136. printf("\n");
  137. printf("Homepage: <http://libimobiledevice.org>\n");
  138. }