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 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