summaryrefslogtreecommitdiffstats
path: root/tools/idevicescreenshot.c
diff options
context:
space:
mode:
authorGravatar Greg Dennis2020-12-10 01:37:01 +0100
committerGravatar Nikias Bassen2020-12-10 01:37:01 +0100
commitbe72ca64cd9e853588ec65047d16a0a22f4ef291 (patch)
treeabf5fc83e9f297c431bd3c18c82ba2e8e84f7efe /tools/idevicescreenshot.c
parentfad6a83086d39d4f6ee6cab8276238a71cd165ff (diff)
downloadlibimobiledevice-be72ca64cd9e853588ec65047d16a0a22f4ef291.tar.gz
libimobiledevice-be72ca64cd9e853588ec65047d16a0a22f4ef291.tar.bz2
idevicescreenshot: Choose a better filename, prevent overwriting existing files
Diffstat (limited to 'tools/idevicescreenshot.c')
-rw-r--r--tools/idevicescreenshot.c75
1 files changed, 57 insertions, 18 deletions
diff --git a/tools/idevicescreenshot.c b/tools/idevicescreenshot.c
index 75a69ce..f33e83e 100644
--- a/tools/idevicescreenshot.c
+++ b/tools/idevicescreenshot.c
@@ -29,7 +29,9 @@
29#include <string.h> 29#include <string.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <errno.h> 31#include <errno.h>
32#include <math.h>
32#include <time.h> 33#include <time.h>
34#include <unistd.h>
33#ifndef WIN32 35#ifndef WIN32
34#include <signal.h> 36#include <signal.h>
35#endif 37#endif
@@ -38,6 +40,7 @@
38#include <libimobiledevice/lockdown.h> 40#include <libimobiledevice/lockdown.h>
39#include <libimobiledevice/screenshotr.h> 41#include <libimobiledevice/screenshotr.h>
40 42
43void get_image_filename(char *imgdata, char **filename);
41void print_usage(int argc, char **argv); 44void print_usage(int argc, char **argv);
42 45
43int main(int argc, char **argv) 46int main(int argc, char **argv)
@@ -117,21 +120,7 @@ int main(int argc, char **argv)
117 char *imgdata = NULL; 120 char *imgdata = NULL;
118 uint64_t imgsize = 0; 121 uint64_t imgsize = 0;
119 if (screenshotr_take_screenshot(shotr, &imgdata, &imgsize) == SCREENSHOTR_E_SUCCESS) { 122 if (screenshotr_take_screenshot(shotr, &imgdata, &imgsize) == SCREENSHOTR_E_SUCCESS) {
120 if (!filename) { 123 get_image_filename(imgdata, &filename);
121 const char *fileext = NULL;
122 if (memcmp(imgdata, "\x89PNG", 4) == 0) {
123 fileext = ".png";
124 } else if (memcmp(imgdata, "MM\x00*", 4) == 0) {
125 fileext = ".tiff";
126 } else {
127 printf("WARNING: screenshot data has unexpected image format.\n");
128 fileext = ".dat";
129 }
130 time_t now = time(NULL);
131 filename = (char*)malloc(36);
132 size_t pos = strftime(filename, 36, "screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now));
133 sprintf(filename+pos, "%s", fileext);
134 }
135 FILE *f = fopen(filename, "wb"); 124 FILE *f = fopen(filename, "wb");
136 if (f) { 125 if (f) {
137 if (fwrite(imgdata, 1, (size_t)imgsize, f) == (size_t)imgsize) { 126 if (fwrite(imgdata, 1, (size_t)imgsize, f) == (size_t)imgsize) {
@@ -162,6 +151,53 @@ int main(int argc, char **argv)
162 return result; 151 return result;
163} 152}
164 153
154void get_image_filename(char *imgdata, char **filename)
155{
156 // If the provided filename already has an extension, use it as is.
157 if (*filename) {
158 char *last_dot = strrchr(*filename, '.');
159 if (last_dot && !strchr(last_dot, '/')) {
160 return;
161 }
162 }
163
164 // Find the appropriate file extension for the filename.
165 const char *fileext = NULL;
166 if (memcmp(imgdata, "\x89PNG", 4) == 0) {
167 fileext = ".png";
168 } else if (memcmp(imgdata, "MM\x00*", 4) == 0) {
169 fileext = ".tiff";
170 } else {
171 printf("WARNING: screenshot data has unexpected image format.\n");
172 fileext = ".dat";
173 }
174
175 // If a filename without an extension is provided, append the extension.
176 // Otherwise, generate a filename based on the current time.
177 char *basename = NULL;
178 if (*filename) {
179 basename = (char*)malloc(strlen(*filename) + 1);
180 strcpy(basename, *filename);
181 free(*filename);
182 } else {
183 time_t now = time(NULL);
184 basename = (char*)malloc(32);
185 strftime(basename, 31, "screenshot-%Y-%m-%d-%H-%M-%S", gmtime(&now));
186 }
187
188 // Ensure the filename is unique on disk.
189 char *unique_filename = (char*)malloc(strlen(basename) + strlen(fileext) + 1);
190 sprintf(unique_filename, "%s%s", basename, fileext);
191 int i;
192 for (i = 2; access(unique_filename, F_OK) != -1; i++) {
193 free(unique_filename);
194 unique_filename = (char*)malloc(strlen(basename) + strlen(fileext) + floor(log10(i)) + 3);
195 sprintf(unique_filename, "%s-%d%s", basename, i, fileext);
196 }
197 *filename = unique_filename;
198 free(basename);
199}
200
165void print_usage(int argc, char **argv) 201void print_usage(int argc, char **argv)
166{ 202{
167 char *name = NULL; 203 char *name = NULL;
@@ -169,10 +205,13 @@ void print_usage(int argc, char **argv)
169 name = strrchr(argv[0], '/'); 205 name = strrchr(argv[0], '/');
170 printf("Usage: %s [OPTIONS] [FILE]\n", (name ? name + 1: argv[0])); 206 printf("Usage: %s [OPTIONS] [FILE]\n", (name ? name + 1: argv[0]));
171 printf("\n"); 207 printf("\n");
172 printf("Gets a screenshot from a device.\n"); 208 printf("Gets a screenshot from a connected device.\n");
173 printf("\n"); 209 printf("\n");
174 printf("The screenshot is saved as a TIFF image with the given FILE name,\n"); 210 printf("The image is in PNG format for iOS 9+ and otherwise in TIFF format.\n");
175 printf("where the default name is \"screenshot-DATE.tiff\", e.g.:\n"); 211 printf("The screenshot is saved as an image with the given FILE name.\n");
212 printf("If FILE has no extension, FILE will be a prefix of the saved filename.\n");
213 printf("If FILE is not specified, \"screenshot-DATE\", will be used as a prefix\n");
214 printf("of the filename, e.g.:\n");
176 printf(" ./screenshot-2013-12-31-23-59-59.tiff\n"); 215 printf(" ./screenshot-2013-12-31-23-59-59.tiff\n");
177 printf("\n"); 216 printf("\n");
178 printf("NOTE: A mounted developer disk image is required on the device, otherwise\n"); 217 printf("NOTE: A mounted developer disk image is required on the device, otherwise\n");