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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 916bc5da742977785158bc9d6be72695583bf002
4
- data.tar.gz: a8ce8ccf69f2c827d04db34b81a0db10e4aefe00
3
+ metadata.gz: 7b5ec94211e6d7114d1d410d5a28c6c84166c0a1
4
+ data.tar.gz: cba491c806f2be5def28a0faef8e345241f745ca
5
5
  SHA512:
6
- metadata.gz: 8ac70880d34b4851037d2170d90e3be2cafa633222dcd726ff4f6a0ff4d3d4210279c02f428c42aa7dd9a334973b9bfd465ce6ab491263750bf9e9184067d2e9
7
- data.tar.gz: 4bb37d2324ecf6c410d8638d90a6aef0548910cd56c484b74738a453fedbe0e016c5d2563235d1f9d551565d80cd2b0505e9b40ec981fcd97fa472b9c56bef72
6
+ metadata.gz: 7d3f8e2da8061fd529ab56da1fd02bad472fe9471de29b3d8e5a7bda3e0c441ac198c789bb056bff676ae27729371ae4e40bc9e61e28e2cdc913adf9c5af93ec
7
+ data.tar.gz: 464a4efb981763195d1aa73a075415209c09ddcd71885b9868d03d0b286b104a790d20f309cb38c4d68e4f9c0e67a8e2cdca842003827f2a978cad2eb27205cc
@@ -1,3 +1,3 @@
1
1
  module IosDeploy
2
- VERSION = "1.3.2"
2
+ VERSION = "1.5.0"
3
3
  end
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.
@@ -16,7 +16,7 @@
16
16
  #include <netinet/tcp.h>
17
17
  #include "MobileDevice.h"
18
18
 
19
- #define APP_VERSION "1.3.2"
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
- sys.exit(254)\n\
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 = process.GetStateFromEvent(event)\n\
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 = lldb.eStateInvalid\n\
113
- process.Detach()\n\
114
- sys.exit(0)\n\
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 = process.GetStateFromEvent(event)\n\
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 = lldb.eStateInvalid\n\
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 = 12345;
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
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("M68AP"), kCFCompareNonliteral))
319
- return CFSTR("iPhone");
320
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N45AP"), kCFCompareNonliteral))
321
- return CFSTR("iPod touch");
322
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N82AP"), kCFCompareNonliteral))
323
- return CFSTR("iPhone 3G");
324
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N72AP"), kCFCompareNonliteral))
325
- return CFSTR("iPod touch 2G");
326
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N88AP"), kCFCompareNonliteral))
327
- return CFSTR("iPhone 3GS");
328
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N18AP"), kCFCompareNonliteral))
329
- return CFSTR("iPod touch 3G");
330
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K48AP"), kCFCompareNonliteral))
331
- return CFSTR("iPad");
332
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N90AP"), kCFCompareNonliteral))
333
- return CFSTR("iPhone 4 (GSM)");
334
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N81AP"), kCFCompareNonliteral))
335
- return CFSTR("iPod touch 4G");
336
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K66AP"), kCFCompareNonliteral))
337
- return CFSTR("Apple TV 2G");
338
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N92AP"), kCFCompareNonliteral))
339
- return CFSTR("iPhone 4 (CDMA)");
340
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N90BAP"), kCFCompareNonliteral))
341
- return CFSTR("iPhone 4 (GSM, revision A)");
342
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K93AP"), kCFCompareNonliteral))
343
- return CFSTR("iPad 2");
344
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K94AP"), kCFCompareNonliteral))
345
- return CFSTR("iPad 2 (GSM)");
346
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K95AP"), kCFCompareNonliteral))
347
- return CFSTR("iPad 2 (CDMA)");
348
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K93AAP"), kCFCompareNonliteral))
349
- return CFSTR("iPad 2 (Wi-Fi, revision A)");
350
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P105AP"), kCFCompareNonliteral))
351
- return CFSTR("iPad mini");
352
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P106AP"), kCFCompareNonliteral))
353
- return CFSTR("iPad mini (GSM)");
354
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P107AP"), kCFCompareNonliteral))
355
- return CFSTR("iPad mini (CDMA)");
356
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N94AP"), kCFCompareNonliteral))
357
- return CFSTR("iPhone 4S");
358
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N41AP"), kCFCompareNonliteral))
359
- return CFSTR("iPhone 5 (GSM)");
360
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N42AP"), kCFCompareNonliteral))
361
- return CFSTR("iPhone 5 (Global/CDMA)");
362
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N48AP"), kCFCompareNonliteral))
363
- return CFSTR("iPhone 5c (GSM)");
364
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N49AP"), kCFCompareNonliteral))
365
- return CFSTR("iPhone 5c (Global/CDMA)");
366
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N51AP"), kCFCompareNonliteral))
367
- return CFSTR("iPhone 5s (GSM)");
368
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N53AP"), kCFCompareNonliteral))
369
- return CFSTR("iPhone 5s (Global/CDMA)");
370
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N61AP"), kCFCompareNonliteral))
371
- return CFSTR("iPhone 6 (GSM)");
372
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J1AP"), kCFCompareNonliteral))
373
- return CFSTR("iPad 3");
374
- if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J2AP"), kCFCompareNonliteral))
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
- // FIXME: Close the socket
842
- //shutdown (CFSocketGetNative (lldb_socket), SHUT_RDWR);
843
- //close (CFSocketGetNative (lldb_socket));
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
- char buf [256];
883
- int res, err, i;
884
- char msg [256];
885
- int chsum, len;
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(INADDR_ANY);
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
- int yes = 1;
911
- setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
912
- int flag = 1;
913
- res = setsockopt(CFSocketGetNative(fdvendor), IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
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: 12345 \n"
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, "VmcdvunrILi:b:a:t:g:x:p:1:2:o:l::w::", longopts, NULL)) != -1)
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 exitcode_error;
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, &notify);
1799
1823
  CFRunLoopRun();
1800
1824
  }
1801
-
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ios-deploy",
3
- "version": "1.3.2",
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": "33f6a83e1d94df5cf5041e9e16394409c4f63656",
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.3.2",
30
- "_shasum": "6ffbbe287cec383198fc977ac6336e150ef2f5bc",
31
- "_from": "ios-deploy@>=1.3.2 <2.0.0",
32
- "_npmVersion": "1.4.14",
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": "6ffbbe287cec383198fc977ac6336e150ef2f5bc",
45
- "tarball": "http://registry.npmjs.org/ios-deploy/-/ios-deploy-1.3.2.tgz"
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.3.2.tgz",
49
- "readme": "ERROR: No README data found!"
57
+ "_resolved": "https://registry.npmjs.org/ios-deploy/-/ios-deploy-1.5.0.tgz"
50
58
  }
@@ -4,7 +4,7 @@
4
4
  "description": "TODO: Write a gem description",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
- "ios-deploy": "^1.3.2"
7
+ "ios-deploy": "^1.5.0"
8
8
  },
9
9
  "devDependencies": {},
10
10
  "scripts": {
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.3.2
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-02-24 00:00:00.000000000 Z
11
+ date: 2015-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler