ios-deploy 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|