ios-deploy 1.3.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ios-deploy/version.rb +1 -1
- data/node_modules/.bin/ios-deploy +0 -0
- data/node_modules/ios-deploy/README.md +21 -5
- data/node_modules/ios-deploy/ios-deploy +0 -0
- data/node_modules/ios-deploy/ios-deploy.c +212 -189
- data/node_modules/ios-deploy/ios-deploy.dSYM/Contents/Resources/DWARF/ios-deploy +0 -0
- data/node_modules/ios-deploy/package.json +18 -10
- data/package.json +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b5ec94211e6d7114d1d410d5a28c6c84166c0a1
|
4
|
+
data.tar.gz: cba491c806f2be5def28a0faef8e345241f745ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d3f8e2da8061fd529ab56da1fd02bad472fe9471de29b3d8e5a7bda3e0c441ac198c789bb056bff676ae27729371ae4e40bc9e61e28e2cdc913adf9c5af93ec
|
7
|
+
data.tar.gz: 464a4efb981763195d1aa73a075415209c09ddcd71885b9868d03d0b286b104a790d20f309cb38c4d68e4f9c0e67a8e2cdca842003827f2a978cad2eb27205cc
|
data/lib/ios-deploy/version.rb
CHANGED
Binary file
|
@@ -8,6 +8,17 @@ Install and debug iOS apps without using Xcode. Designed to work on un-jailbroke
|
|
8
8
|
* You need to have a valid iOS development certificate installed.
|
9
9
|
* Xcode 6.1 should be installed
|
10
10
|
|
11
|
+
## Installation
|
12
|
+
ios-deploy installation is made simple using the node.js package manager. If you use [Homebrew](http://brew.sh/), install node.js:
|
13
|
+
```bash
|
14
|
+
brew install node
|
15
|
+
```
|
16
|
+
|
17
|
+
Now install ios-deploy with the node.js package manager:
|
18
|
+
```bash
|
19
|
+
$ npm install -g ios-deploy
|
20
|
+
```
|
21
|
+
|
11
22
|
## Usage
|
12
23
|
|
13
24
|
Usage: ios-deploy [OPTION]...
|
@@ -23,14 +34,16 @@ Install and debug iOS apps without using Xcode. Designed to work on un-jailbroke
|
|
23
34
|
-L, --justlaunch just launch the app and exit lldb
|
24
35
|
-v, --verbose enable verbose output
|
25
36
|
-m, --noinstall directly start debugging without app install (-d not required)
|
26
|
-
-p, --port <number> port used for device, default: 12345
|
27
|
-
-r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared)
|
37
|
+
-p, --port <number> port used for device, default: 12345
|
38
|
+
-r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared)
|
28
39
|
-1, --bundle_id <bundle id> specify bundle id for list and upload
|
29
40
|
-l, --list list files
|
30
41
|
-o, --upload <file> upload file
|
31
42
|
-w, --download download app tree
|
32
43
|
-2, --to <target pathname> use together with up/download file/tree. specify target
|
33
|
-
-V, --version print the executable version
|
44
|
+
-V, --version print the executable version
|
45
|
+
-e, --exists check if the app with given bundle_id is installed or not
|
46
|
+
|
34
47
|
|
35
48
|
## Examples
|
36
49
|
|
@@ -47,7 +60,7 @@ The commands below assume that you have an app called `my.app` with bundle id `b
|
|
47
60
|
|
48
61
|
// Upload a file to your app's Documents folder
|
49
62
|
ios-deploy --bundle_id 'bundle.id' --upload test.txt --to Documents/test.txt
|
50
|
-
|
63
|
+
|
51
64
|
// Download your app's Documents, Library and tmp folders
|
52
65
|
ios-deploy --bundle_id 'bundle.id' --download --to MyDestinationFolder
|
53
66
|
|
@@ -56,7 +69,10 @@ The commands below assume that you have an app called `my.app` with bundle id `b
|
|
56
69
|
|
57
70
|
// deploy and debug your app to a connected device, uninstall the app first
|
58
71
|
ios-deploy --uninstall --debug --bundle my.app
|
59
|
-
|
72
|
+
|
73
|
+
// check whether an app by bundle id exists on the device (check return code `echo $?`)
|
74
|
+
ios-deploy --exists --bundle_id com.apple.mobilemail
|
75
|
+
|
60
76
|
## Demo
|
61
77
|
|
62
78
|
* The included demo.app represents the minimum required to get code running on iOS.
|
Binary file
|
@@ -16,7 +16,7 @@
|
|
16
16
|
#include <netinet/tcp.h>
|
17
17
|
#include "MobileDevice.h"
|
18
18
|
|
19
|
-
#define APP_VERSION "1.
|
19
|
+
#define APP_VERSION "1.5.0"
|
20
20
|
#define PREP_CMDS_PATH "/tmp/fruitstrap-lldb-prep-cmds-"
|
21
21
|
#define LLDB_SHELL "lldb -s " PREP_CMDS_PATH
|
22
22
|
/*
|
@@ -61,6 +61,7 @@ const char* lldb_prep_noninteractive_cmds = "\
|
|
61
61
|
*/
|
62
62
|
#define LLDB_FRUITSTRAP_MODULE CFSTR("\
|
63
63
|
import lldb\n\
|
64
|
+
import os\n\
|
64
65
|
import sys\n\
|
65
66
|
import shlex\n\
|
66
67
|
\n\
|
@@ -90,13 +91,14 @@ def connect_command(debugger, command, result, internal_dict):\n\
|
|
90
91
|
\n\
|
91
92
|
def run_command(debugger, command, result, internal_dict):\n\
|
92
93
|
device_app = internal_dict['fruitstrap_device_app']\n\
|
94
|
+
args = command.split('--',1)\n\
|
93
95
|
error = lldb.SBError()\n\
|
94
96
|
lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n\
|
95
|
-
lldb.target.Launch(lldb.SBLaunchInfo(shlex.split('{args}')), error)\n\
|
97
|
+
lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)\n\
|
96
98
|
lockedstr = ': Locked'\n\
|
97
99
|
if lockedstr in str(error):\n\
|
98
100
|
print('\\nDevice Locked\\n')\n\
|
99
|
-
|
101
|
+
os._exit(254)\n\
|
100
102
|
else:\n\
|
101
103
|
print(str(error))\n\
|
102
104
|
\n\
|
@@ -106,12 +108,16 @@ def safequit_command(debugger, command, result, internal_dict):\n\
|
|
106
108
|
listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n\
|
107
109
|
event = lldb.SBEvent()\n\
|
108
110
|
while True:\n\
|
109
|
-
if listener.WaitForEvent(1, event):\n\
|
110
|
-
state =
|
111
|
+
if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n\
|
112
|
+
state = lldb.SBProcess.GetStateFromEvent(event)\n\
|
111
113
|
else:\n\
|
112
|
-
state =
|
113
|
-
|
114
|
-
|
114
|
+
state = process.GetState()\n\
|
115
|
+
\n\
|
116
|
+
if state == lldb.eStateRunning:\n\
|
117
|
+
process.Detach()\n\
|
118
|
+
os._exit(0)\n\
|
119
|
+
elif state > lldb.eStateRunning:\n\
|
120
|
+
os._exit(state)\n\
|
115
121
|
\n\
|
116
122
|
def autoexit_command(debugger, command, result, internal_dict):\n\
|
117
123
|
process = lldb.target.process\n\
|
@@ -119,10 +125,16 @@ def autoexit_command(debugger, command, result, internal_dict):\n\
|
|
119
125
|
listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n\
|
120
126
|
event = lldb.SBEvent()\n\
|
121
127
|
while True:\n\
|
122
|
-
if listener.WaitForEvent(1, event):\n\
|
123
|
-
state =
|
128
|
+
if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n\
|
129
|
+
state = lldb.SBProcess.GetStateFromEvent(event)\n\
|
124
130
|
else:\n\
|
125
|
-
state =
|
131
|
+
state = process.GetState()\n\
|
132
|
+
\n\
|
133
|
+
if state == lldb.eStateExited:\n\
|
134
|
+
os._exit(process.GetExitStatus())\n\
|
135
|
+
elif state == lldb.eStateStopped:\n\
|
136
|
+
debugger.HandleCommand('bt')\n\
|
137
|
+
os._exit({exitcode_app_crash})\n\
|
126
138
|
\n\
|
127
139
|
stdout = process.GetSTDOUT(1024)\n\
|
128
140
|
while stdout:\n\
|
@@ -133,14 +145,6 @@ def autoexit_command(debugger, command, result, internal_dict):\n\
|
|
133
145
|
while stderr:\n\
|
134
146
|
sys.stdout.write(stderr)\n\
|
135
147
|
stderr = process.GetSTDERR(1024)\n\
|
136
|
-
\n\
|
137
|
-
if lldb.SBProcess.EventIsProcessEvent(event):\n\
|
138
|
-
if state == lldb.eStateExited:\n\
|
139
|
-
sys.exit(process.GetExitStatus())\n\
|
140
|
-
if state == lldb.eStateStopped:\n\
|
141
|
-
debugger.HandleCommand('frame select')\n\
|
142
|
-
debugger.HandleCommand('bt')\n\
|
143
|
-
sys.exit({exitcode_app_crash})\n\
|
144
148
|
")
|
145
149
|
|
146
150
|
typedef struct am_device * AMDeviceRef;
|
@@ -164,7 +168,7 @@ char *device_id = NULL;
|
|
164
168
|
char *args = NULL;
|
165
169
|
char *list_root = NULL;
|
166
170
|
int timeout = 0;
|
167
|
-
int port =
|
171
|
+
int port = 0; // 0 means "dynamically assigned"
|
168
172
|
CFStringRef last_path = NULL;
|
169
173
|
service_conn_t gdbfd;
|
170
174
|
pid_t parent = 0;
|
@@ -312,87 +316,71 @@ CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) {
|
|
312
316
|
}
|
313
317
|
}
|
314
318
|
|
319
|
+
#define GET_FRIENDLY_MODEL_NAME(VALUE, INTERNAL_NAME, FRIENDLY_NAME) if (kCFCompareEqualTo == CFStringCompare(VALUE, CFSTR(INTERNAL_NAME), kCFCompareNonliteral)) { return CFSTR( FRIENDLY_NAME); };
|
320
|
+
|
321
|
+
|
315
322
|
// Please ensure that device is connected or the name will be unknown
|
316
323
|
const CFStringRef get_device_hardware_name(const AMDeviceRef device) {
|
317
324
|
CFStringRef model = AMDeviceCopyValue(device, 0, CFSTR("HardwareModel"));
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
return CFSTR("iPad 3 (GSM)");
|
376
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J2AAP"), kCFCompareNonliteral))
|
377
|
-
return CFSTR("iPad 3 (CDMA)");
|
378
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P101AP"), kCFCompareNonliteral))
|
379
|
-
return CFSTR("iPad 4");
|
380
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P102AP"), kCFCompareNonliteral))
|
381
|
-
return CFSTR("iPad 4 (GSM)");
|
382
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P103AP"), kCFCompareNonliteral))
|
383
|
-
return CFSTR("iPad 4 (CDMA)");
|
384
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N78AP"), kCFCompareNonliteral))
|
385
|
-
return CFSTR("iPod touch 5G");
|
386
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("A1509"), kCFCompareNonliteral))
|
387
|
-
return CFSTR("iPod touch 5G");
|
388
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J33AP"), kCFCompareNonliteral))
|
389
|
-
return CFSTR("Apple TV 3G");
|
390
|
-
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J33IAP"), kCFCompareNonliteral))
|
391
|
-
return CFSTR("Apple TV 3.1G");
|
325
|
+
|
326
|
+
if (model == NULL) {
|
327
|
+
return CFSTR("Unknown Device");
|
328
|
+
}
|
329
|
+
|
330
|
+
// iPod Touch
|
331
|
+
|
332
|
+
GET_FRIENDLY_MODEL_NAME(model, "N45AP", "iPod Touch")
|
333
|
+
GET_FRIENDLY_MODEL_NAME(model, "N72AP", "iPod Touch 2G")
|
334
|
+
GET_FRIENDLY_MODEL_NAME(model, "N18AP", "iPod Touch 3G")
|
335
|
+
GET_FRIENDLY_MODEL_NAME(model, "N81AP", "iPod Touch 4G")
|
336
|
+
GET_FRIENDLY_MODEL_NAME(model, "N78AP", "iPod Touch 5G")
|
337
|
+
GET_FRIENDLY_MODEL_NAME(model, "N78AAP", "iPod Touch 5G")
|
338
|
+
|
339
|
+
// iPad
|
340
|
+
|
341
|
+
GET_FRIENDLY_MODEL_NAME(model, "K48AP", "iPad")
|
342
|
+
GET_FRIENDLY_MODEL_NAME(model, "K93AP", "iPad 2")
|
343
|
+
GET_FRIENDLY_MODEL_NAME(model, "K94AP", "iPad 2 (GSM)")
|
344
|
+
GET_FRIENDLY_MODEL_NAME(model, "K95AP", "iPad 2 (CDMA)")
|
345
|
+
GET_FRIENDLY_MODEL_NAME(model, "K93AAP", "iPad 2 (Wi-Fi, revision A)")
|
346
|
+
GET_FRIENDLY_MODEL_NAME(model, "J1AP", "iPad 3")
|
347
|
+
GET_FRIENDLY_MODEL_NAME(model, "J2AP", "iPad 3 (GSM)")
|
348
|
+
GET_FRIENDLY_MODEL_NAME(model, "J2AAP", "iPad 3 (CDMA)")
|
349
|
+
GET_FRIENDLY_MODEL_NAME(model, "P101AP", "iPad 4")
|
350
|
+
GET_FRIENDLY_MODEL_NAME(model, "P102AP", "iPad 4 (GSM)")
|
351
|
+
GET_FRIENDLY_MODEL_NAME(model, "P103AP", "iPad 4 (CDMA)")
|
352
|
+
|
353
|
+
// iPad Mini
|
354
|
+
|
355
|
+
GET_FRIENDLY_MODEL_NAME(model, "P105AP", "iPad mini")
|
356
|
+
GET_FRIENDLY_MODEL_NAME(model, "P106AP", "iPad mini (GSM)")
|
357
|
+
GET_FRIENDLY_MODEL_NAME(model, "P107AP", "iPad mini (CDMA)")
|
358
|
+
|
359
|
+
// Apple TV
|
360
|
+
|
361
|
+
GET_FRIENDLY_MODEL_NAME(model, "K66AP", "Apple TV 2G")
|
362
|
+
GET_FRIENDLY_MODEL_NAME(model, "J33AP", "Apple TV 3G")
|
363
|
+
GET_FRIENDLY_MODEL_NAME(model, "J33IAP", "Apple TV 3.1G")
|
364
|
+
|
365
|
+
// iPhone
|
366
|
+
|
367
|
+
GET_FRIENDLY_MODEL_NAME(model, "M68AP", "iPhone")
|
368
|
+
GET_FRIENDLY_MODEL_NAME(model, "N82AP", "iPhone 3G")
|
369
|
+
GET_FRIENDLY_MODEL_NAME(model, "N88AP", "iPhone 3GS")
|
370
|
+
GET_FRIENDLY_MODEL_NAME(model, "N90AP", "iPhone 4 (GSM)")
|
371
|
+
GET_FRIENDLY_MODEL_NAME(model, "N92AP", "iPhone 4 (CDMA)")
|
372
|
+
GET_FRIENDLY_MODEL_NAME(model, "N90BAP", "iPhone 4 (GSM, revision A)")
|
373
|
+
GET_FRIENDLY_MODEL_NAME(model, "N94AP", "iPhone 4S")
|
374
|
+
GET_FRIENDLY_MODEL_NAME(model, "N41AP", "iPhone 5 (GSM)")
|
375
|
+
GET_FRIENDLY_MODEL_NAME(model, "N42AP", "iPhone 5 (Global/CDMA)")
|
376
|
+
GET_FRIENDLY_MODEL_NAME(model, "N48AP", "iPhone 5c (GSM)")
|
377
|
+
GET_FRIENDLY_MODEL_NAME(model, "N49AP", "iPhone 5c (Global/CDMA)")
|
378
|
+
GET_FRIENDLY_MODEL_NAME(model, "N51AP", "iPhone 5s (GSM)")
|
379
|
+
GET_FRIENDLY_MODEL_NAME(model, "N53AP", "iPhone 5s (Global/CDMA)")
|
380
|
+
GET_FRIENDLY_MODEL_NAME(model, "N61AP", "iPhone 6 (GSM)")
|
381
|
+
GET_FRIENDLY_MODEL_NAME(model, "N56AP", "iPhone 6 Plus")
|
392
382
|
|
393
383
|
return model;
|
394
|
-
//return CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), hwmodel);
|
395
|
-
//return CFSTR("Unknown Device");
|
396
384
|
}
|
397
385
|
|
398
386
|
char * MYCFStringCopyUTF8String(CFStringRef aString) {
|
@@ -419,7 +407,7 @@ CFStringRef get_device_full_name(const AMDeviceRef device) {
|
|
419
407
|
model_name = NULL;
|
420
408
|
|
421
409
|
AMDeviceConnect(device);
|
422
|
-
|
410
|
+
|
423
411
|
device_name = AMDeviceCopyValue(device, 0, CFSTR("DeviceName")),
|
424
412
|
model_name = get_device_hardware_name(device);
|
425
413
|
|
@@ -430,7 +418,7 @@ CFStringRef get_device_full_name(const AMDeviceRef device) {
|
|
430
418
|
CFShow(device_name);
|
431
419
|
printf("\n");
|
432
420
|
free(devName);
|
433
|
-
|
421
|
+
|
434
422
|
char *mdlName = MYCFStringCopyUTF8String(model_name);
|
435
423
|
printf("Model Name:[%s]\n",mdlName);
|
436
424
|
printf("MM: [%s]\n",CFStringGetCStringPtr(model_name, kCFStringEncodingUTF8));
|
@@ -670,10 +658,10 @@ CFURLRef copy_device_app_url(AMDeviceRef device, CFStringRef identifier) {
|
|
670
658
|
@"UIStatusBarHidden",
|
671
659
|
@"UISupportedInterfaceOrientations",
|
672
660
|
nil];
|
673
|
-
|
661
|
+
|
674
662
|
NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:a forKey:@"ReturnAttributes"];
|
675
663
|
CFDictionaryRef options = (CFDictionaryRef)optionsDict;
|
676
|
-
|
664
|
+
|
677
665
|
afc_error_t resultStatus = AMDeviceLookupApplications(device, options, &result);
|
678
666
|
assert(resultStatus == 0);
|
679
667
|
|
@@ -729,13 +717,13 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
|
|
729
717
|
rangeLLDB.length = CFStringGetLength(pmodule);
|
730
718
|
CFStringFindAndReplace(pmodule, CFSTR("{args}"), cf_args, rangeLLDB, 0);
|
731
719
|
|
732
|
-
//printf("write_lldb_prep_cmds:args: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
|
720
|
+
//printf("write_lldb_prep_cmds:args: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
|
733
721
|
// CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
|
734
722
|
CFRelease(cf_args);
|
735
723
|
} else {
|
736
724
|
CFStringFindAndReplace(cmds, CFSTR("{args}"), CFSTR(""), range, 0);
|
737
725
|
CFStringFindAndReplace(pmodule, CFSTR("{args}"), CFSTR(""), rangeLLDB, 0);
|
738
|
-
//printf("write_lldb_prep_cmds: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
|
726
|
+
//printf("write_lldb_prep_cmds: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
|
739
727
|
// CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
|
740
728
|
}
|
741
729
|
range.length = CFStringGetLength(cmds);
|
@@ -838,22 +826,9 @@ server_callback (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef add
|
|
838
826
|
int res;
|
839
827
|
|
840
828
|
if (CFDataGetLength (data) == 0) {
|
841
|
-
//
|
842
|
-
|
843
|
-
|
844
|
-
CFSocketInvalidate(lldb_socket);
|
845
|
-
CFSocketInvalidate(server_socket);
|
846
|
-
int mypid = getpid();
|
847
|
-
assert((child != 0) && (child != mypid)); //child should not be here
|
848
|
-
if ((parent != 0) && (parent == mypid) && (child != 0))
|
849
|
-
{
|
850
|
-
if (verbose)
|
851
|
-
{
|
852
|
-
printf("Got an empty packet hence killing child (%d) tree\n", child);
|
853
|
-
}
|
854
|
-
kill_ptree(child, SIGHUP);
|
855
|
-
}
|
856
|
-
exit(exitcode_error);
|
829
|
+
// close the socket on which we've got end-of-file, the server_socket.
|
830
|
+
CFSocketInvalidate(s);
|
831
|
+
CFRelease(s);
|
857
832
|
return;
|
858
833
|
}
|
859
834
|
res = write (CFSocketGetNative (lldb_socket), CFDataGetBytePtr (data), CFDataGetLength (data));
|
@@ -863,8 +838,12 @@ void lldb_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef a
|
|
863
838
|
{
|
864
839
|
//printf ("lldb: %s\n", CFDataGetBytePtr (data));
|
865
840
|
|
866
|
-
if (CFDataGetLength (data) == 0)
|
841
|
+
if (CFDataGetLength (data) == 0) {
|
842
|
+
// close the socket on which we've got end-of-file, the lldb_socket.
|
843
|
+
CFSocketInvalidate(s);
|
844
|
+
CFRelease(s);
|
867
845
|
return;
|
846
|
+
}
|
868
847
|
write (gdbfd, CFDataGetBytePtr (data), CFDataGetLength (data));
|
869
848
|
}
|
870
849
|
|
@@ -875,21 +854,20 @@ void fdvendor_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataR
|
|
875
854
|
//PRINT ("callback!\n");
|
876
855
|
|
877
856
|
lldb_socket = CFSocketCreateWithNative(NULL, socket, kCFSocketDataCallBack, &lldb_callback, NULL);
|
857
|
+
int flag = 1;
|
858
|
+
int res = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
|
859
|
+
assert(res == 0);
|
878
860
|
CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, lldb_socket, 0), kCFRunLoopCommonModes);
|
861
|
+
|
862
|
+
CFSocketInvalidate(s);
|
863
|
+
CFRelease(s);
|
879
864
|
}
|
880
865
|
|
881
866
|
void start_remote_debug_server(AMDeviceRef device) {
|
882
|
-
|
883
|
-
int res,
|
884
|
-
|
885
|
-
|
886
|
-
struct stat s;
|
887
|
-
socklen_t buflen;
|
888
|
-
struct sockaddr name;
|
889
|
-
int namelen;
|
890
|
-
|
891
|
-
assert(AMDeviceStartService(device, CFSTR("com.apple.debugserver"), &gdbfd, NULL) == 0);
|
892
|
-
assert (gdbfd);
|
867
|
+
|
868
|
+
int res = AMDeviceStartService(device, CFSTR("com.apple.debugserver"), &gdbfd, NULL);
|
869
|
+
assert(res == 0);
|
870
|
+
assert(gdbfd > 0);
|
893
871
|
|
894
872
|
/*
|
895
873
|
* The debugserver connection is through a fd handle, while lldb requires a host/port to connect, so create an intermediate
|
@@ -903,20 +881,24 @@ void start_remote_debug_server(AMDeviceRef device) {
|
|
903
881
|
addr4.sin_len = sizeof(addr4);
|
904
882
|
addr4.sin_family = AF_INET;
|
905
883
|
addr4.sin_port = htons(port);
|
906
|
-
addr4.sin_addr.s_addr = htonl(
|
884
|
+
addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
907
885
|
|
908
886
|
CFSocketRef fdvendor = CFSocketCreate(NULL, PF_INET, 0, 0, kCFSocketAcceptCallBack, &fdvendor_callback, NULL);
|
909
887
|
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
assert (res == 0);
|
888
|
+
if (port) {
|
889
|
+
int yes = 1;
|
890
|
+
setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
|
891
|
+
}
|
915
892
|
|
916
893
|
CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&addr4, sizeof(addr4));
|
917
894
|
|
918
895
|
CFSocketSetAddress(fdvendor, address_data);
|
919
896
|
CFRelease(address_data);
|
897
|
+
socklen_t addrlen = sizeof(addr4);
|
898
|
+
res = getsockname(CFSocketGetNative(fdvendor),(struct sockaddr *)&addr4,&addrlen);
|
899
|
+
assert(res == 0);
|
900
|
+
port = ntohs(addr4.sin_port);
|
901
|
+
|
920
902
|
CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, fdvendor, 0), kCFRunLoopCommonModes);
|
921
903
|
}
|
922
904
|
|
@@ -992,38 +974,38 @@ void setup_dummy_pipe_on_stdin(int pfd[2]) {
|
|
992
974
|
void setup_lldb(AMDeviceRef device, CFURLRef url) {
|
993
975
|
CFStringRef device_full_name = get_device_full_name(device),
|
994
976
|
device_interface_name = get_device_interface_name(device);
|
995
|
-
|
977
|
+
|
996
978
|
AMDeviceConnect(device);
|
997
979
|
assert(AMDeviceIsPaired(device));
|
998
980
|
assert(AMDeviceValidatePairing(device) == 0);
|
999
981
|
assert(AMDeviceStartSession(device) == 0);
|
1000
|
-
|
982
|
+
|
1001
983
|
printf("------ Debug phase ------\n");
|
1002
|
-
|
984
|
+
|
1003
985
|
if(AMDeviceGetInterfaceType(device) == 2)
|
1004
986
|
{
|
1005
987
|
printf("Cannot debug %s over %s.\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(device_interface_name, CFStringGetSystemEncoding()));
|
1006
988
|
exit(0);
|
1007
989
|
}
|
1008
|
-
|
990
|
+
|
1009
991
|
printf("Starting debug of %s connected through %s...\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(device_interface_name, CFStringGetSystemEncoding()));
|
1010
|
-
|
992
|
+
|
1011
993
|
mount_developer_image(device); // put debugserver on the device
|
1012
994
|
start_remote_debug_server(device); // start debugserver
|
1013
995
|
write_lldb_prep_cmds(device, url); // dump the necessary lldb commands into a file
|
1014
|
-
|
996
|
+
|
1015
997
|
CFRelease(url);
|
1016
|
-
|
998
|
+
|
1017
999
|
printf("[100%%] Connecting to remote debug server\n");
|
1018
1000
|
printf("-------------------------\n");
|
1019
|
-
|
1001
|
+
|
1020
1002
|
setpgid(getpid(), 0);
|
1021
1003
|
signal(SIGHUP, killed);
|
1022
1004
|
signal(SIGINT, killed);
|
1023
1005
|
signal(SIGTERM, killed);
|
1024
1006
|
// Need this before fork to avoid race conditions. For child process we remove this right after fork.
|
1025
1007
|
signal(SIGLLDB, lldb_finished_handler);
|
1026
|
-
|
1008
|
+
|
1027
1009
|
parent = getpid();
|
1028
1010
|
}
|
1029
1011
|
|
@@ -1057,7 +1039,7 @@ void launch_debugger(AMDeviceRef device, CFURLRef url) {
|
|
1057
1039
|
|
1058
1040
|
close(pfd[0]);
|
1059
1041
|
close(pfd[1]);
|
1060
|
-
|
1042
|
+
|
1061
1043
|
// Notify parent we're exiting
|
1062
1044
|
kill(parent, SIGLLDB);
|
1063
1045
|
// Pass lldb exit code
|
@@ -1080,21 +1062,21 @@ void launch_debugger_and_exit(AMDeviceRef device, CFURLRef url) {
|
|
1080
1062
|
signal(SIGHUP, SIG_DFL);
|
1081
1063
|
signal(SIGLLDB, SIG_DFL);
|
1082
1064
|
child = getpid();
|
1083
|
-
|
1065
|
+
|
1084
1066
|
if (dup2(pfd[0],STDIN_FILENO) == -1)
|
1085
1067
|
perror("dup2 failed");
|
1086
|
-
|
1068
|
+
|
1087
1069
|
char lldb_shell[400];
|
1088
1070
|
sprintf(lldb_shell, LLDB_SHELL);
|
1089
1071
|
if(device_id != NULL)
|
1090
1072
|
strcat(lldb_shell, device_id);
|
1091
|
-
|
1073
|
+
|
1092
1074
|
int status = system(lldb_shell); // launch lldb
|
1093
1075
|
if (status == -1)
|
1094
1076
|
perror("failed launching lldb");
|
1095
|
-
|
1077
|
+
|
1096
1078
|
close(pfd[0]);
|
1097
|
-
|
1079
|
+
|
1098
1080
|
// Notify parent we're exiting
|
1099
1081
|
kill(parent, SIGLLDB);
|
1100
1082
|
// Pass lldb exit code
|
@@ -1145,20 +1127,20 @@ CFStringRef get_bundle_id(CFURLRef app_url)
|
|
1145
1127
|
return bundle_id;
|
1146
1128
|
}
|
1147
1129
|
|
1148
|
-
|
1130
|
+
|
1149
1131
|
void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir,
|
1150
1132
|
void(*callback)(afc_connection *conn,const char *dir,int file))
|
1151
1133
|
{
|
1152
1134
|
char *dir_ent;
|
1153
|
-
|
1135
|
+
|
1154
1136
|
afc_connection afc_conn;
|
1155
1137
|
if (!afc_conn_p) {
|
1156
1138
|
afc_conn_p = &afc_conn;
|
1157
1139
|
AFCConnectionOpen(afcFd, 0, &afc_conn_p);
|
1158
1140
|
}
|
1159
|
-
|
1141
|
+
|
1160
1142
|
printf("%s\n", dir);
|
1161
|
-
|
1143
|
+
|
1162
1144
|
afc_dictionary* afc_dict_p;
|
1163
1145
|
char *key, *val;
|
1164
1146
|
int not_dir = 0;
|
@@ -1168,7 +1150,7 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir,
|
|
1168
1150
|
// there was a problem reading or opening the file to get info on it, abort
|
1169
1151
|
return;
|
1170
1152
|
}
|
1171
|
-
|
1153
|
+
|
1172
1154
|
while((AFCKeyValueRead(afc_dict_p,&key,&val) == 0) && key && val) {
|
1173
1155
|
if (strcmp(key,"st_ifmt")==0) {
|
1174
1156
|
not_dir = strcmp(val,"S_IFDIR");
|
@@ -1184,23 +1166,23 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir,
|
|
1184
1166
|
|
1185
1167
|
afc_directory* afc_dir_p;
|
1186
1168
|
afc_error_t err = AFCDirectoryOpen(afc_conn_p, dir, &afc_dir_p);
|
1187
|
-
|
1169
|
+
|
1188
1170
|
if (err != 0) {
|
1189
1171
|
// Couldn't open dir - was probably a file
|
1190
1172
|
return;
|
1191
1173
|
} else {
|
1192
1174
|
if (callback) (*callback)(afc_conn_p, dir, not_dir);
|
1193
1175
|
}
|
1194
|
-
|
1176
|
+
|
1195
1177
|
while(true) {
|
1196
1178
|
err = AFCDirectoryRead(afc_conn_p, afc_dir_p, &dir_ent);
|
1197
|
-
|
1179
|
+
|
1198
1180
|
if (err != 0 || !dir_ent)
|
1199
1181
|
break;
|
1200
|
-
|
1182
|
+
|
1201
1183
|
if (strcmp(dir_ent, ".") == 0 || strcmp(dir_ent, "..") == 0)
|
1202
1184
|
continue;
|
1203
|
-
|
1185
|
+
|
1204
1186
|
char* dir_joined = malloc(strlen(dir) + strlen(dir_ent) + 2);
|
1205
1187
|
strcpy(dir_joined, dir);
|
1206
1188
|
if (dir_joined[strlen(dir)-1] != '/')
|
@@ -1209,7 +1191,7 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir,
|
|
1209
1191
|
read_dir(afcFd, afc_conn_p, dir_joined, callback);
|
1210
1192
|
free(dir_joined);
|
1211
1193
|
}
|
1212
|
-
|
1194
|
+
|
1213
1195
|
AFCDirectoryClose(afc_conn_p, afc_dir_p);
|
1214
1196
|
}
|
1215
1197
|
|
@@ -1220,25 +1202,25 @@ service_conn_t start_house_arrest_service(AMDeviceRef device) {
|
|
1220
1202
|
assert(AMDeviceIsPaired(device));
|
1221
1203
|
assert(AMDeviceValidatePairing(device) == 0);
|
1222
1204
|
assert(AMDeviceStartSession(device) == 0);
|
1223
|
-
|
1205
|
+
|
1224
1206
|
service_conn_t houseFd;
|
1225
|
-
|
1207
|
+
|
1226
1208
|
if (bundle_id == NULL) {
|
1227
1209
|
printf("Bundle id is not specified\n");
|
1228
1210
|
exit(1);
|
1229
1211
|
}
|
1230
|
-
|
1212
|
+
|
1231
1213
|
CFStringRef cf_bundle_id = CFStringCreateWithCString(NULL, bundle_id, kCFStringEncodingASCII);
|
1232
1214
|
if (AMDeviceStartHouseArrestService(device, cf_bundle_id, 0, &houseFd, 0) != 0)
|
1233
1215
|
{
|
1234
1216
|
printf("Unable to find bundle with id: %s\n", bundle_id);
|
1235
1217
|
exit(1);
|
1236
1218
|
}
|
1237
|
-
|
1219
|
+
|
1238
1220
|
assert(AMDeviceStopSession(device) == 0);
|
1239
1221
|
assert(AMDeviceDisconnect(device) == 0);
|
1240
1222
|
CFRelease(cf_bundle_id);
|
1241
|
-
|
1223
|
+
|
1242
1224
|
return houseFd;
|
1243
1225
|
}
|
1244
1226
|
|
@@ -1266,7 +1248,7 @@ void* read_file_to_memory(char * path, size_t* file_size)
|
|
1266
1248
|
{
|
1267
1249
|
return NULL;
|
1268
1250
|
}
|
1269
|
-
|
1251
|
+
|
1270
1252
|
*file_size = buf.st_size;
|
1271
1253
|
FILE* fd = fopen(path, "r");
|
1272
1254
|
char* content = malloc(*file_size);
|
@@ -1282,7 +1264,7 @@ void* read_file_to_memory(char * path, size_t* file_size)
|
|
1282
1264
|
void list_files(AMDeviceRef device)
|
1283
1265
|
{
|
1284
1266
|
service_conn_t houseFd = start_house_arrest_service(device);
|
1285
|
-
|
1267
|
+
|
1286
1268
|
afc_connection* afc_conn_p;
|
1287
1269
|
if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) {
|
1288
1270
|
read_dir(houseFd, afc_conn_p, list_root?list_root:"/", NULL);
|
@@ -1290,6 +1272,40 @@ void list_files(AMDeviceRef device)
|
|
1290
1272
|
}
|
1291
1273
|
}
|
1292
1274
|
|
1275
|
+
int app_exists(AMDeviceRef device)
|
1276
|
+
{
|
1277
|
+
if (bundle_id == NULL) {
|
1278
|
+
printf("Bundle id is not specified\n");
|
1279
|
+
return false;
|
1280
|
+
}
|
1281
|
+
|
1282
|
+
AMDeviceConnect(device);
|
1283
|
+
assert(AMDeviceIsPaired(device));
|
1284
|
+
assert(AMDeviceValidatePairing(device) == 0);
|
1285
|
+
assert(AMDeviceStartSession(device) == 0);
|
1286
|
+
|
1287
|
+
CFStringRef cf_bundle_id = CFStringCreateWithCString(NULL, bundle_id, kCFStringEncodingASCII);
|
1288
|
+
|
1289
|
+
NSArray *a = [NSArray arrayWithObjects:@"CFBundleIdentifier", nil];
|
1290
|
+
NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:a forKey:@"ReturnAttributes"];
|
1291
|
+
CFDictionaryRef options = (CFDictionaryRef)optionsDict;
|
1292
|
+
|
1293
|
+
CFDictionaryRef result = nil;
|
1294
|
+
afc_error_t resultStatus = AMDeviceLookupApplications(device, options, &result);
|
1295
|
+
assert(resultStatus == 0);
|
1296
|
+
|
1297
|
+
CFDictionaryRef app_dict = CFDictionaryGetValue(result, cf_bundle_id);
|
1298
|
+
|
1299
|
+
int appExists = (app_dict == NULL) ? -1 : 0;
|
1300
|
+
|
1301
|
+
CFRelease(cf_bundle_id);
|
1302
|
+
|
1303
|
+
assert(AMDeviceStopSession(device) == 0);
|
1304
|
+
assert(AMDeviceDisconnect(device) == 0);
|
1305
|
+
|
1306
|
+
return appExists;
|
1307
|
+
}
|
1308
|
+
|
1293
1309
|
void copy_file_callback(afc_connection* afc_conn_p, const char *name,int file)
|
1294
1310
|
{
|
1295
1311
|
const char *local_name=name;
|
@@ -1383,15 +1399,15 @@ void download_tree(AMDeviceRef device)
|
|
1383
1399
|
|
1384
1400
|
void upload_file(AMDeviceRef device) {
|
1385
1401
|
service_conn_t houseFd = start_house_arrest_service(device);
|
1386
|
-
|
1402
|
+
|
1387
1403
|
afc_file_ref file_ref;
|
1388
|
-
|
1404
|
+
|
1389
1405
|
afc_connection afc_conn;
|
1390
1406
|
afc_connection* afc_conn_p = &afc_conn;
|
1391
1407
|
AFCConnectionOpen(houseFd, 0, &afc_conn_p);
|
1392
|
-
|
1408
|
+
|
1393
1409
|
// read_dir(houseFd, NULL, "/", NULL);
|
1394
|
-
|
1410
|
+
|
1395
1411
|
if (!target_filename)
|
1396
1412
|
{
|
1397
1413
|
target_filename = get_filename_from_path(upload_pathname);
|
@@ -1399,7 +1415,7 @@ void upload_file(AMDeviceRef device) {
|
|
1399
1415
|
|
1400
1416
|
size_t file_size;
|
1401
1417
|
void* file_content = read_file_to_memory(upload_pathname, &file_size);
|
1402
|
-
|
1418
|
+
|
1403
1419
|
if (!file_content)
|
1404
1420
|
{
|
1405
1421
|
printf("Could not open file: %s\n", upload_pathname);
|
@@ -1419,7 +1435,7 @@ void upload_file(AMDeviceRef device) {
|
|
1419
1435
|
*lastSlash = '\0';
|
1420
1436
|
assert(AFCDirectoryCreate(afc_conn_p, dirpath) == 0);
|
1421
1437
|
}
|
1422
|
-
|
1438
|
+
|
1423
1439
|
|
1424
1440
|
int ret = AFCFileRefOpen(afc_conn_p, target_filename, 3, &file_ref);
|
1425
1441
|
if (ret == 0x000a) {
|
@@ -1434,12 +1450,12 @@ void upload_file(AMDeviceRef device) {
|
|
1434
1450
|
assert(AFCFileRefWrite(afc_conn_p, file_ref, file_content, file_size) == 0);
|
1435
1451
|
assert(AFCFileRefClose(afc_conn_p, file_ref) == 0);
|
1436
1452
|
assert(AFCConnectionClose(afc_conn_p) == 0);
|
1437
|
-
|
1453
|
+
|
1438
1454
|
free(file_content);
|
1439
1455
|
}
|
1440
1456
|
|
1441
1457
|
void handle_device(AMDeviceRef device) {
|
1442
|
-
//if (found_device)
|
1458
|
+
//if (found_device)
|
1443
1459
|
// return; // handle one device only
|
1444
1460
|
|
1445
1461
|
CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device),
|
@@ -1464,7 +1480,7 @@ void handle_device(AMDeviceRef device) {
|
|
1464
1480
|
}
|
1465
1481
|
|
1466
1482
|
printf("[....] Using %s (%s).\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));
|
1467
|
-
|
1483
|
+
|
1468
1484
|
if (command_only) {
|
1469
1485
|
if (strcmp("list", command) == 0) {
|
1470
1486
|
list_files(device);
|
@@ -1472,6 +1488,8 @@ void handle_device(AMDeviceRef device) {
|
|
1472
1488
|
upload_file(device);
|
1473
1489
|
} else if (strcmp("download", command) == 0) {
|
1474
1490
|
download_tree(device);
|
1491
|
+
} else if (strcmp("exists", command) == 0) {
|
1492
|
+
exit(app_exists(device));
|
1475
1493
|
}
|
1476
1494
|
exit(0);
|
1477
1495
|
}
|
@@ -1496,7 +1514,7 @@ void handle_device(AMDeviceRef device) {
|
|
1496
1514
|
assert(AMDeviceIsPaired(device));
|
1497
1515
|
assert(AMDeviceValidatePairing(device) == 0);
|
1498
1516
|
assert(AMDeviceStartSession(device) == 0);
|
1499
|
-
|
1517
|
+
|
1500
1518
|
int code = AMDeviceSecureUninstallApplication(0, device, bundle_id, 0, NULL, 0);
|
1501
1519
|
if (code == 0) {
|
1502
1520
|
printf("[ OK ] Uninstalled package with bundle id %s\n", CFStringGetCStringPtr(bundle_id, CFStringGetSystemEncoding()));
|
@@ -1533,7 +1551,7 @@ void handle_device(AMDeviceRef device) {
|
|
1533
1551
|
|
1534
1552
|
close(afcFd);
|
1535
1553
|
|
1536
|
-
|
1554
|
+
|
1537
1555
|
|
1538
1556
|
AMDeviceConnect(device);
|
1539
1557
|
assert(AMDeviceIsPaired(device));
|
@@ -1569,9 +1587,9 @@ void handle_device(AMDeviceRef device) {
|
|
1569
1587
|
printf("[100%%] Installed package %s\n", app_path);
|
1570
1588
|
}
|
1571
1589
|
|
1572
|
-
if (!debug)
|
1590
|
+
if (!debug)
|
1573
1591
|
exit(0); // no debug phase
|
1574
|
-
|
1592
|
+
|
1575
1593
|
if (justlaunch)
|
1576
1594
|
launch_debugger_and_exit(device, url);
|
1577
1595
|
else
|
@@ -1584,7 +1602,7 @@ void device_callback(struct am_device_notification_callback_info *info, void *ar
|
|
1584
1602
|
if(device_id != NULL || !debug || AMDeviceGetInterfaceType(info->dev) != 2) {
|
1585
1603
|
handle_device(info->dev);
|
1586
1604
|
} else if(best_device_match == NULL) {
|
1587
|
-
best_device_match = info->dev;
|
1605
|
+
best_device_match = info->dev;
|
1588
1606
|
CFRetain(best_device_match);
|
1589
1607
|
}
|
1590
1608
|
default:
|
@@ -1611,7 +1629,7 @@ void timeout_callback(CFRunLoopTimerRef timer, void *info) {
|
|
1611
1629
|
if (!debug) {
|
1612
1630
|
printf("[....] No more devices found.\n");
|
1613
1631
|
}
|
1614
|
-
|
1632
|
+
|
1615
1633
|
if (detect_only && !found_device) {
|
1616
1634
|
exit(exitcode_error);
|
1617
1635
|
return;
|
@@ -1645,14 +1663,15 @@ void usage(const char* app) {
|
|
1645
1663
|
" -L, --justlaunch just launch the app and exit lldb\n"
|
1646
1664
|
" -v, --verbose enable verbose output\n"
|
1647
1665
|
" -m, --noinstall directly start debugging without app install (-d not required)\n"
|
1648
|
-
" -p, --port <number> port used for device, default:
|
1666
|
+
" -p, --port <number> port used for device, default: dynamic\n"
|
1649
1667
|
" -r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared) \n"
|
1650
1668
|
" -1, --bundle_id <bundle id> specify bundle id for list and upload\n"
|
1651
1669
|
" -l, --list list files\n"
|
1652
1670
|
" -o, --upload <file> upload file\n"
|
1653
1671
|
" -w, --download download app tree\n"
|
1654
1672
|
" -2, --to <target pathname> use together with up/download file/tree. specify target\n"
|
1655
|
-
" -V, --version print the executable version \n"
|
1673
|
+
" -V, --version print the executable version \n"
|
1674
|
+
" -e, --exists check if the app with given bundle_id is installed or not \n",
|
1656
1675
|
app);
|
1657
1676
|
}
|
1658
1677
|
|
@@ -1682,11 +1701,12 @@ int main(int argc, char *argv[]) {
|
|
1682
1701
|
{ "upload", required_argument, NULL, 'o'},
|
1683
1702
|
{ "download", optional_argument, NULL, 'w'},
|
1684
1703
|
{ "to", required_argument, NULL, '2'},
|
1704
|
+
{ "exists", no_argument, NULL, 'e'},
|
1685
1705
|
{ NULL, 0, NULL, 0 },
|
1686
1706
|
};
|
1687
1707
|
char ch;
|
1688
1708
|
|
1689
|
-
while ((ch = getopt_long(argc, argv, "
|
1709
|
+
while ((ch = getopt_long(argc, argv, "VmcdvunrILei:b:a:t:g:x:p:1:2:o:l::w::", longopts, NULL)) != -1)
|
1690
1710
|
{
|
1691
1711
|
switch (ch) {
|
1692
1712
|
case 'm':
|
@@ -1730,7 +1750,7 @@ int main(int argc, char *argv[]) {
|
|
1730
1750
|
break;
|
1731
1751
|
case 'V':
|
1732
1752
|
show_version();
|
1733
|
-
return
|
1753
|
+
return 0;
|
1734
1754
|
case 'p':
|
1735
1755
|
port = atoi(optarg);
|
1736
1756
|
break;
|
@@ -1758,6 +1778,10 @@ int main(int argc, char *argv[]) {
|
|
1758
1778
|
command = "download";
|
1759
1779
|
list_root = optarg;
|
1760
1780
|
break;
|
1781
|
+
case 'e':
|
1782
|
+
command_only = true;
|
1783
|
+
command = "exists";
|
1784
|
+
break;
|
1761
1785
|
default:
|
1762
1786
|
usage(argv[0]);
|
1763
1787
|
return exitcode_error;
|
@@ -1798,4 +1822,3 @@ int main(int argc, char *argv[]) {
|
|
1798
1822
|
AMDeviceNotificationSubscribe(&device_callback, 0, 0, NULL, ¬ify);
|
1799
1823
|
CFRunLoopRun();
|
1800
1824
|
}
|
1801
|
-
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ios-deploy",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.5.0",
|
4
4
|
"description": "launch iOS apps iOS devices from the command line (Xcode 6)",
|
5
5
|
"main": "ios-deploy",
|
6
6
|
"scripts": {
|
@@ -21,15 +21,16 @@
|
|
21
21
|
"name": "Greg Hughes"
|
22
22
|
},
|
23
23
|
"license": "GPLv3",
|
24
|
-
"gitHead": "
|
24
|
+
"gitHead": "5efdcae8cec80f6fd15dc31f1b319585ac14b8aa",
|
25
25
|
"bugs": {
|
26
26
|
"url": "https://github.com/phonegap/ios-deploy/issues"
|
27
27
|
},
|
28
28
|
"homepage": "https://github.com/phonegap/ios-deploy",
|
29
|
-
"_id": "ios-deploy@1.
|
30
|
-
"_shasum": "
|
31
|
-
"_from": "ios-deploy@>=1.
|
32
|
-
"_npmVersion": "
|
29
|
+
"_id": "ios-deploy@1.5.0",
|
30
|
+
"_shasum": "bd4d45266027afebe49e1755370e6d14296179a3",
|
31
|
+
"_from": "ios-deploy@>=1.5.0 <2.0.0",
|
32
|
+
"_npmVersion": "2.5.1",
|
33
|
+
"_nodeVersion": "0.12.0",
|
33
34
|
"_npmUser": {
|
34
35
|
"name": "shazron",
|
35
36
|
"email": "shazron@gmail.com"
|
@@ -38,13 +39,20 @@
|
|
38
39
|
{
|
39
40
|
"name": "shazron",
|
40
41
|
"email": "shazron@gmail.com"
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"name": "purplecabbage",
|
45
|
+
"email": "purplecabbage@gmail.com"
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"name": "stevegill",
|
49
|
+
"email": "stevengill97@gmail.com"
|
41
50
|
}
|
42
51
|
],
|
43
52
|
"dist": {
|
44
|
-
"shasum": "
|
45
|
-
"tarball": "http://registry.npmjs.org/ios-deploy/-/ios-deploy-1.
|
53
|
+
"shasum": "bd4d45266027afebe49e1755370e6d14296179a3",
|
54
|
+
"tarball": "http://registry.npmjs.org/ios-deploy/-/ios-deploy-1.5.0.tgz"
|
46
55
|
},
|
47
56
|
"directories": {},
|
48
|
-
"_resolved": "https://registry.npmjs.org/ios-deploy/-/ios-deploy-1.
|
49
|
-
"readme": "ERROR: No README data found!"
|
57
|
+
"_resolved": "https://registry.npmjs.org/ios-deploy/-/ios-deploy-1.5.0.tgz"
|
50
58
|
}
|
data/package.json
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ios-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Giovanni Lodi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|