43 Commits
1.0.9 ... 1.3.2

Author SHA1 Message Date
Shazron Abdullah
33f6a83e1d Fixes phonegap/ios-deploy#80 (re-fix) --detect not showing non-zero exit code when no devices are detected.
When --detect is turned on, --debug is turned on implicitly so you won't get a segmentation fault.
2014-11-16 20:49:33 -08:00
Shazron Abdullah
7c9af71d86 Updated version to 1.3.1 2014-11-14 13:09:11 -08:00
Shazron Abdullah
767c386ba9 Fixes phonegap/ios-deploy#80 --detect not showing non-zero exit code when no devices are detected. 2014-11-14 13:07:19 -08:00
Shazron Abdullah
7a447b480f Fixes phonegap/ios-deploy#79 - Update README.md for sample usage of ios-deploy flags and options 2014-11-13 23:47:50 -08:00
Shazron Abdullah
021c222a55 Update README. Removed gdbargs, gdbexec. Added download. 2014-11-13 23:24:51 -08:00
Shazron Abdullah
63303ea4b0 Removed unused gdbargs and gdbexec options. 2014-11-13 23:24:27 -08:00
Shazron Abdullah
5bfc25376a Update package.json version to 1.3.0 2014-11-13 22:58:18 -08:00
Shazron Abdullah
7075657015 Fixes phonegap/ios-deploy#74 - SIGSEGV-ed while listing the sandbox of an application on iOS8 2014-11-13 22:57:58 -08:00
Shazron Abdullah
6f662ae450 Fixes phonegap/ios-deploy#37 - AMDeviceValidatePairing fails when uninstalling 2014-11-13 17:33:44 -08:00
Shazron Abdullah
4617a7df59 Merge pull request #72 from CSOscarTanner/master
Fixed problem with the parser of the value of the parameter -i.
2014-11-12 16:22:33 -08:00
Shazron Abdullah
7ca72695b6 Merge pull request #68 from senthilmanick/master
Fixed the hang when the device is locked.

When the device is locked, we get empty packets in the server.
Now fixed by closing both the lldb and server sockets.
Also after safequit, we need to detach to make the "justlaunch" option to be less error prone.

Multiple bug fixes: 
1. When multiple devices are connected, the detect was not listing all the devices ios-deploy -c -t 1
2. Fixes for issue #75 - non-interactive mode broken lldb and ios-deploy may still be running ios-deploy -b ... -d -I -L
3. Fixes for issue #60 - -L option not working properly ios-deploy will not quit or sometimes hang
4. When multiple devices are connected, cannot use -i option to specify the device ios-deploy -b ... -i -d -I -L
5. Allow timeout when downloading
2014-11-12 16:11:52 -08:00
senthil
dbe381112a Removed the wrong comment 2014-11-12 16:23:20 -05:00
senthil
72caad4526 Allow timeout for download and run 2014-11-12 16:15:53 -05:00
senthil
06187e348a updated the version to 1.3.0 2014-11-12 12:04:47 -05:00
senthil
b4f91912ee fixed the lauch using python 2014-11-11 20:15:39 -05:00
senthil
b796b70e29 updated the version 2014-11-07 18:43:02 -05:00
senthil
1a309dcebf Merge branch 'disk-image-fix' of https://github.com/eddieh/ios-deploy
Conflicts:
	ios-deploy.c
2014-11-07 18:40:28 -05:00
Eddie Hillenbrand
049a89e873 Fix for mismatched build numbers. 2014-11-04 12:35:14 -08:00
Eddie Hillenbrand
4aa233d147 Allow the symbols and the disk images to be in different DeviceSupport directories. 2014-11-03 16:09:36 -08:00
CSOscarTanner
d51bb22f23 Fixed problem with the parser of the value of the parameter -i. 2014-10-21 14:33:33 -02:00
senthil
54600a9eaf Fixed two issues:
1. When the device is locked, the python source prints and exists. The
server sees this as an empty packet. We are using this to exit out of
the connection
2. When we use just launch, we need to do safequit and detach. Otherwise
we hang for ever
2014-10-13 17:20:52 -04:00
senthil
d86b0cad0d Merged with phone-gap and fixed the hang 2014-10-13 16:59:19 -04:00
senthil
029d22ecef added iPhone 6 2014-10-09 14:29:15 -04:00
Shazron Abdullah
63917d796b Added scripts for buildbox. 2014-10-07 14:35:45 -07:00
Shazron Abdullah
0b89be65bd Merge pull request #67 from dot-asm/master
Add download option.
2014-10-07 11:04:10 -07:00
Andy Polyakov
7742c5d532 Allow --list and --download to pick specific subdirectories.
Note that in a way it introduces inconsistency with help message.
This is because arguments to --list and --download are optional
and has to be passed with '=', e.g. --list=/Documents.
2014-10-07 11:23:33 +02:00
Andy Polyakov
9f0c8a85c6 Add download option.
Unlike upload option, download pulls down whole tree. For this reason
--to is expected to be directory path.
2014-10-07 09:23:34 +02:00
Shazron Abdullah
c57f208422 Update version to 1.2.0 2014-10-06 22:09:39 -07:00
Shazron Abdullah
0467b69fd8 Merge pull request #66 from dot-asm/master
Fix AFCFileRef[Read|Write] prototypes
2014-10-06 21:56:59 -07:00
Shazron Abdullah
77116e3f7c Merge pull request #65 from alexmipego/lldb-python-connect-fix
Fix lldb status checking
2014-10-06 21:55:19 -07:00
Andy Polyakov
4589cd5d05 arrange callback in read_dir for future use
Custom callback is called for every file or directory listed on device. This will be used for file download.
2014-10-06 23:16:40 +02:00
Andy Polyakov
9a2da6f642 Fix usage semantic and pair of resource leaks
AFCConnectionOpen and AFCFIleInfoOpen don't require initialized pointer to pointer to result, but do require corresponding Close calls.
2014-10-06 23:02:06 +02:00
Andy Polyakov
23afce0d37 handle no --args
When no --args are passed application was started with {args} as argument instead of no argument.
2014-10-06 22:40:43 +02:00
Andy Polyakov
4869a343e8 fix AFCFileRef[Read|Write] prototypes
Incorrect AFCFileRefRead prototype was causing crashes in 64-bit build when reading large files.
2014-10-06 22:32:36 +02:00
Alexandre Gomes
bf5a1e065e fix lldb status checking 2014-10-06 13:36:31 +01:00
senthil
6bd90a5133 a minor debugging version 2014-09-02 16:18:33 -04:00
Shazron Abdullah
e2f436ad52 Merge pull request #57 from hinesmr/patch-1
Include iPods for device search in the README "Listing Device IDs" section.
2014-08-29 16:36:51 -07:00
Michael R. Hines
35097bd5a0 Don't forget about iPods too =)
Update the readme to include iPods in the device identifier search.
2014-08-19 19:51:20 +08:00
senthilmanick
c85248c88a Merge pull request #1 from phonegap/master
Merge with main
2014-08-05 19:12:45 -04:00
Shazron Abdullah
0f1ef6f4ef Fixes #54 - Publish 1.1.0 version 2014-08-04 19:07:31 -07:00
Shazron Abdullah
6801052024 Merge pull request #53 from senthilmanick/master
Fixes #51 - When the device is locked, ios-deploy hangs.
Fixes #52 - Enhancement: Add "Just launch" option
2014-08-04 18:56:51 -07:00
senthil
616b6ab1ff updated to version 1.0.10 2014-08-03 13:43:38 -04:00
senthil
55a12cb02e Fix for issues 51 and 52
51: Updated the python:run_command to look for : Locked.
52: Added option -L that is a variation of non-interactive
Added the constant with safequit and implemented the equivalent python
2014-08-03 12:56:17 -04:00
5 changed files with 473 additions and 124 deletions

View File

@@ -396,11 +396,11 @@ afc_error_t AFCFileRefOpen(afc_connection *conn, const char *path,
afc_error_t AFCFileRefSeek(afc_connection *conn, afc_file_ref ref,
unsigned long long offset1, unsigned long long offset2);
afc_error_t AFCFileRefRead(afc_connection *conn, afc_file_ref ref,
void *buf, unsigned int *len);
void *buf, size_t *len);
afc_error_t AFCFileRefSetFileSize(afc_connection *conn, afc_file_ref ref,
unsigned long long offset);
afc_error_t AFCFileRefWrite(afc_connection *conn, afc_file_ref ref,
const void *buf, unsigned int len);
const void *buf, size_t len);
afc_error_t AFCFileRefClose(afc_connection *conn, afc_file_ref ref);
afc_error_t AFCFileInfoOpen(afc_connection *conn, const char *path, struct
@@ -493,4 +493,4 @@ typedef unsigned int (*t_performOperation)(struct am_restore_device *rdev,
}
#endif
#endif
#endif

View File

@@ -1,16 +1,16 @@
ios-deploy
==========
Install and debug iPhone apps without using Xcode. Designed to work on unjailbroken devices.
Install and debug iOS apps without using Xcode. Designed to work on un-jailbroken devices.
## Requirements
* Mac OS X. Tested on Snow Leopard only.
* You need to have a valid iPhone development certificate installed.
* Xcode must be installed, along with the SDK for your iOS version.
* Mac OS X. Tested on 10.10 Yosemite and iOS 8.1
* You need to have a valid iOS development certificate installed.
* Xcode 6.1 should be installed
## Usage
Usage: ./ios-deploy [OPTION]...
Usage: ios-deploy [OPTION]...
-d, --debug launch the app in GDB after installation
-i, --id <device_id> the id of the device to connect to
-c, --detect only detect if the device is connected
@@ -18,10 +18,9 @@ Install and debug iPhone apps without using Xcode. Designed to work on unjailbro
-a, --args <args> command line arguments to pass to the app when launching it
-t, --timeout <timeout> number of seconds to wait for a device to be connected
-u, --unbuffered don't buffer stdout
-g, --gdbargs <args> extra arguments to pass to GDB when starting the debugger
-x, --gdbexec <file> GDB commands script file
-n, --nostart do not start the app when debugging
-I, --noninteractive start in non interactive mode (quit when app crashes or exits)
-L, --justlaunch just launch the app and exit lldb
-v, --verbose enable verbose output
-m, --noinstall directly start debugging without app install (-d not required)
-p, --port <number> port used for device, default: 12345
@@ -29,9 +28,35 @@ Install and debug iPhone apps without using Xcode. Designed to work on unjailbro
-1, --bundle_id <bundle id> specify bundle id for list and upload
-l, --list list files
-o, --upload <file> upload file
-2, --to <target pathname> use together with upload file. specify target for upload
-w, --download download app tree
-2, --to <target pathname> use together with up/download file/tree. specify target
-V, --version print the executable version
## Examples
The commands below assume that you have an app called `my.app` with bundle id `bundle.id`. Substitute where necessary.
// deploy and debug your app to a connected device
ios-deploy --debug --bundle my.app
// deploy and launch your app to a connected device, but quit the debugger after
ios-deploy --justlaunch --debug --bundle my.app
// deploy and launch your app to a connected device, quit when app crashes or exits
ios-deploy --noninteractive --debug --bundle my.app
// Upload a file to your app's Documents folder
ios-deploy --bundle_id 'bundle.id' --upload test.txt --to Documents/test.txt
// Download your app's Documents, Library and tmp folders
ios-deploy --bundle_id 'bundle.id' --download --to MyDestinationFolder
// List the contents of your app's Documents, Library and tmp folders
ios-deploy --bundle_id 'bundle.id' --list
// deploy and debug your app to a connected device, uninstall the app first
ios-deploy --uninstall --debug --bundle my.app
## Demo
* The included demo.app represents the minimum required to get code running on iOS.
@@ -40,11 +65,11 @@ Install and debug iPhone apps without using Xcode. Designed to work on unjailbro
## Notes
* With some modifications, it may be possible to use this without Xcode installed; however, you would need a copy of the relevant DeveloperDiskImage.dmg (included with Xcode). GDB would also run slower as symbols would be downloaded from the device on-the-fly.
* With some modifications, it may be possible to use this without Xcode installed; however, you would need a copy of the relevant DeveloperDiskImage.dmg (included with Xcode). lldb would also run slower as symbols would be downloaded from the device on-the-fly.
## Listing Device Ids
Device Ids are the UDIDs of the iOS devices. From the command line, you can list device ids [this way](http://javierhz.blogspot.com/2012/06/how-to-get-udid-of-iphone-using-shell.html):
system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p' -e '/iPhone/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}'
system_profiler SPUSBDataType | sed -n -e '/iPod/,/Serial/p' | sed -n -e '/iPad/,/Serial/p' -e '/iPhone/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}'

View File

@@ -16,10 +16,9 @@
#include <netinet/tcp.h>
#include "MobileDevice.h"
#define APP_VERSION "1.0.9"
#define APP_VERSION "1.3.2"
#define PREP_CMDS_PATH "/tmp/fruitstrap-lldb-prep-cmds-"
#define LLDB_SHELL "lldb -s " PREP_CMDS_PATH
/*
* Startup script passed to lldb.
* To see how xcode interacts with lldb, put this into .lldbinit:
@@ -35,6 +34,7 @@
command script add -f {python_command}.connect_command connect\n\
command script add -s asynchronous -f {python_command}.run_command run\n\
command script add -s asynchronous -f {python_command}.autoexit_command autoexit\n\
command script add -s asynchronous -f {python_command}.safequit_command safequit\n\
connect\n\
")
@@ -44,6 +44,11 @@ const char* lldb_prep_interactive_cmds = "\
run\n\
";
const char* lldb_prep_noninteractive_justlaunch_cmds = "\
run\n\
safequit\n\
";
const char* lldb_prep_noninteractive_cmds = "\
run\n\
autoexit\n\
@@ -70,7 +75,7 @@ def connect_command(debugger, command, result, internal_dict):\n\
listener = lldb.target.GetDebugger().GetListener()\n\
listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n\
events = []\n\
state = lldb.eStateInvalid\n\
state = (process.GetState() or lldb.eStateInvalid)\n\
while state != lldb.eStateConnected:\n\
event = lldb.SBEvent()\n\
if listener.WaitForEvent(1, event):\n\
@@ -88,7 +93,25 @@ def run_command(debugger, command, result, internal_dict):\n\
error = lldb.SBError()\n\
lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n\
lldb.target.Launch(lldb.SBLaunchInfo(shlex.split('{args}')), error)\n\
print str(error)\n\
lockedstr = ': Locked'\n\
if lockedstr in str(error):\n\
print('\\nDevice Locked\\n')\n\
sys.exit(254)\n\
else:\n\
print(str(error))\n\
\n\
def safequit_command(debugger, command, result, internal_dict):\n\
process = lldb.target.process\n\
listener = debugger.GetListener()\n\
listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n\
event = lldb.SBEvent()\n\
while True:\n\
if listener.WaitForEvent(1, event):\n\
state = process.GetStateFromEvent(event)\n\
else:\n\
state = lldb.eStateInvalid\n\
process.Detach()\n\
sys.exit(0)\n\
\n\
def autoexit_command(debugger, command, result, internal_dict):\n\
process = lldb.target.process\n\
@@ -135,9 +158,11 @@ char *target_filename = NULL;
char *upload_pathname = NULL;
char *bundle_id = NULL;
bool interactive = true;
bool justlaunch = false;
char *app_path = NULL;
char *device_id = NULL;
char *args = NULL;
char *list_root = NULL;
int timeout = 0;
int port = 12345;
CFStringRef last_path = NULL;
@@ -170,10 +195,20 @@ Boolean path_exists(CFTypeRef path) {
CFStringRef find_path(CFStringRef rootPath, CFStringRef namePattern, CFStringRef expression) {
FILE *fpipe = NULL;
CFStringRef quotedRootPath = rootPath;
CFStringRef cf_command;
CFRange slashLocation;
if (CFStringGetCharacterAtIndex(rootPath, 0) != '`') {
quotedRootPath = CFStringCreateWithFormat(NULL, NULL, CFSTR("'%@'"), rootPath);
}
CFStringRef cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -name '%@' %@ 2>/dev/null | sort | tail -n 1"), quotedRootPath, namePattern, expression);
slashLocation = CFStringFind(namePattern, CFSTR("/"), 0);
if (slashLocation.location == kCFNotFound) {
cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -name '%@' %@ 2>/dev/null | sort | tail -n 1"), quotedRootPath, namePattern, expression);
} else {
cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -path '%@' %@ 2>/dev/null | sort | tail -n 1"), quotedRootPath, namePattern, expression);
}
if (quotedRootPath != rootPath) {
CFRelease(quotedRootPath);
}
@@ -238,6 +273,7 @@ CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) {
CFStringRef path;
bool found = false;
const char* home = get_home();
CFRange slashLocation;
// Try using xcode-select --print-path
@@ -247,7 +283,12 @@ CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) {
}
// Try find `xcode-select --print-path` with search as a name pattern
if (!found) {
slashLocation = CFStringFind(search, CFSTR("/"), 0);
if (slashLocation.location == kCFNotFound) {
path = find_path(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), xcodeDevPath, subPath), search, CFSTR("-maxdepth 1"));
} else {
path = find_path(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), xcodeDevPath, subPath), search, CFSTR(""));
}
found = CFStringGetLength(path) > 0 && path_exists(path);
}
// If not look in the default xcode location (xcode-select is sometimes wrong)
@@ -274,80 +315,101 @@ CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) {
// Please ensure that device is connected or the name will be unknown
const CFStringRef get_device_hardware_name(const AMDeviceRef device) {
CFStringRef model = AMDeviceCopyValue(device, 0, CFSTR("HardwareModel"));
const char *hwmodel = CFStringGetCStringPtr(model, CFStringGetSystemEncoding());
if (hwmodel && !strcmp("M68AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("M68AP"), kCFCompareNonliteral))
return CFSTR("iPhone");
if (hwmodel && !strcmp("N45AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N45AP"), kCFCompareNonliteral))
return CFSTR("iPod touch");
if (hwmodel && !strcmp("N82AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N82AP"), kCFCompareNonliteral))
return CFSTR("iPhone 3G");
if (hwmodel && !strcmp("N72AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N72AP"), kCFCompareNonliteral))
return CFSTR("iPod touch 2G");
if (hwmodel && !strcmp("N88AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N88AP"), kCFCompareNonliteral))
return CFSTR("iPhone 3GS");
if (hwmodel && !strcmp("N18AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N18AP"), kCFCompareNonliteral))
return CFSTR("iPod touch 3G");
if (hwmodel && !strcmp("K48AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K48AP"), kCFCompareNonliteral))
return CFSTR("iPad");
if (hwmodel && !strcmp("N90AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N90AP"), kCFCompareNonliteral))
return CFSTR("iPhone 4 (GSM)");
if (hwmodel && !strcmp("N81AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N81AP"), kCFCompareNonliteral))
return CFSTR("iPod touch 4G");
if (hwmodel && !strcmp("K66AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K66AP"), kCFCompareNonliteral))
return CFSTR("Apple TV 2G");
if (hwmodel && !strcmp("N92AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N92AP"), kCFCompareNonliteral))
return CFSTR("iPhone 4 (CDMA)");
if (hwmodel && !strcmp("N90BAP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N90BAP"), kCFCompareNonliteral))
return CFSTR("iPhone 4 (GSM, revision A)");
if (hwmodel && !strcmp("K93AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K93AP"), kCFCompareNonliteral))
return CFSTR("iPad 2");
if (hwmodel && !strcmp("K94AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K94AP"), kCFCompareNonliteral))
return CFSTR("iPad 2 (GSM)");
if (hwmodel && !strcmp("K95AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K95AP"), kCFCompareNonliteral))
return CFSTR("iPad 2 (CDMA)");
if (hwmodel && !strcmp("K93AAP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("K93AAP"), kCFCompareNonliteral))
return CFSTR("iPad 2 (Wi-Fi, revision A)");
if (hwmodel && !strcmp("P105AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P105AP"), kCFCompareNonliteral))
return CFSTR("iPad mini");
if (hwmodel && !strcmp("P106AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P106AP"), kCFCompareNonliteral))
return CFSTR("iPad mini (GSM)");
if (hwmodel && !strcmp("P107AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P107AP"), kCFCompareNonliteral))
return CFSTR("iPad mini (CDMA)");
if (hwmodel && !strcmp("N94AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N94AP"), kCFCompareNonliteral))
return CFSTR("iPhone 4S");
if (hwmodel && !strcmp("N41AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N41AP"), kCFCompareNonliteral))
return CFSTR("iPhone 5 (GSM)");
if (hwmodel && !strcmp("N42AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N42AP"), kCFCompareNonliteral))
return CFSTR("iPhone 5 (Global/CDMA)");
if (hwmodel && !strcmp("N48AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N48AP"), kCFCompareNonliteral))
return CFSTR("iPhone 5c (GSM)");
if (hwmodel && !strcmp("N49AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N49AP"), kCFCompareNonliteral))
return CFSTR("iPhone 5c (Global/CDMA)");
if (hwmodel && !strcmp("N51AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N51AP"), kCFCompareNonliteral))
return CFSTR("iPhone 5s (GSM)");
if (hwmodel && !strcmp("N53AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N53AP"), kCFCompareNonliteral))
return CFSTR("iPhone 5s (Global/CDMA)");
if (hwmodel && !strcmp("J1AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N61AP"), kCFCompareNonliteral))
return CFSTR("iPhone 6 (GSM)");
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J1AP"), kCFCompareNonliteral))
return CFSTR("iPad 3");
if (hwmodel && !strcmp("J2AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J2AP"), kCFCompareNonliteral))
return CFSTR("iPad 3 (GSM)");
if (hwmodel && !strcmp("J2AAP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J2AAP"), kCFCompareNonliteral))
return CFSTR("iPad 3 (CDMA)");
if (hwmodel && !strcmp("P101AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P101AP"), kCFCompareNonliteral))
return CFSTR("iPad 4");
if (hwmodel && !strcmp("P102AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P102AP"), kCFCompareNonliteral))
return CFSTR("iPad 4 (GSM)");
if (hwmodel && !strcmp("P103AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("P103AP"), kCFCompareNonliteral))
return CFSTR("iPad 4 (CDMA)");
if (hwmodel && !strcmp("N78AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("N78AP"), kCFCompareNonliteral))
return CFSTR("iPod touch 5G");
if (hwmodel && !strcmp("J33AP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("A1509"), kCFCompareNonliteral))
return CFSTR("iPod touch 5G");
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J33AP"), kCFCompareNonliteral))
return CFSTR("Apple TV 3G");
if (hwmodel && !strcmp("J33IAP", hwmodel))
if (kCFCompareEqualTo == CFStringCompare(model,CFSTR("J33IAP"), kCFCompareNonliteral))
return CFSTR("Apple TV 3.1G");
return CFSTR("Unknown Device");
return model;
//return CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), hwmodel);
//return CFSTR("Unknown Device");
}
char * MYCFStringCopyUTF8String(CFStringRef aString) {
if (aString == NULL) {
return NULL;
}
CFIndex length = CFStringGetLength(aString);
CFIndex maxSize =
CFStringGetMaximumSizeForEncoding(length,
kCFStringEncodingUTF8);
char *buffer = (char *)malloc(maxSize);
if (CFStringGetCString(aString, buffer, maxSize,
kCFStringEncodingUTF8)) {
return buffer;
}
return NULL;
}
CFStringRef get_device_full_name(const AMDeviceRef device) {
@@ -361,10 +423,30 @@ CFStringRef get_device_full_name(const AMDeviceRef device) {
device_name = AMDeviceCopyValue(device, 0, CFSTR("DeviceName")),
model_name = get_device_hardware_name(device);
if (verbose)
{
char *devName = MYCFStringCopyUTF8String(device_name);
printf("Device Name:[%s]\n",devName);
CFShow(device_name);
printf("\n");
free(devName);
char *mdlName = MYCFStringCopyUTF8String(model_name);
printf("Model Name:[%s]\n",mdlName);
printf("MM: [%s]\n",CFStringGetCStringPtr(model_name, kCFStringEncodingUTF8));
CFShow(model_name);
printf("\n");
free(mdlName);
}
if(device_name != NULL && model_name != NULL)
{
full_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ '%@' (%@)"), model_name, device_name, device_udid);
}
else
full_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("(%@)"), device_udid);
{
full_name = CFStringCreateWithFormat(NULL, NULL, CFSTR("(%@ss)"), device_udid);
}
AMDeviceDisconnect(device);
@@ -441,22 +523,38 @@ CFStringRef copy_device_support_path(AMDeviceRef device) {
return path;
}
CFStringRef copy_developer_disk_image_path(CFStringRef deviceSupportPath) {
CFStringRef path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), deviceSupportPath, CFSTR("DeveloperDiskImage.dmg"));
if (!path_exists(path)) {
CFRelease(path);
path = NULL;
}
CFStringRef copy_developer_disk_image_path(AMDeviceRef device) {
CFStringRef version = NULL;
CFStringRef build = AMDeviceCopyValue(device, 0, CFSTR("BuildVersion"));
CFStringRef path = NULL;
CFMutableArrayRef version_parts = get_device_product_version_parts(device);
while (CFArrayGetCount(version_parts) > 0) {
version = CFStringCreateByCombiningStrings(NULL, version_parts, CFSTR("."));
if (path == NULL) {
// Sometimes Latest seems to be missing in Xcode, in that case use find and hope for the best
path = copy_long_shot_disk_image_path();
if (CFStringGetLength(path) < 5) {
CFRelease(path);
path = NULL;
path = copy_xcode_path_for(CFSTR("iOS DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)/DeveloperDiskImage.dmg"), version, build));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)/DeveloperDiskImage.dmg"), version, build));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("*/%@ (*)/DeveloperDiskImage.dmg"), version));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/DeveloperDiskImage.dmg"), version));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport/Latest"), CFSTR("DeveloperDiskImage.dmg"));
}
CFRelease(version);
if (path != NULL) {
break;
}
CFArrayRemoveValueAtIndex(version_parts, CFArrayGetCount(version_parts) - 1);
}
CFRelease(version_parts);
CFRelease(build);
if (path == NULL)
{
printf("[ !! ] Unable to locate DeveloperDiskImage.dmg.\n[ !! ] This probably means you don't have Xcode installed, you will need to launch the app manually and logging output will not be shown!\n");
@@ -480,7 +578,7 @@ void mount_callback(CFDictionaryRef dict, int arg) {
void mount_developer_image(AMDeviceRef device) {
CFStringRef ds_path = copy_device_support_path(device);
CFStringRef image_path = copy_developer_disk_image_path(ds_path);
CFStringRef image_path = copy_developer_disk_image_path(device);
CFStringRef sig_path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.signature"), image_path);
if (verbose) {
@@ -631,9 +729,14 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
rangeLLDB.length = CFStringGetLength(pmodule);
CFStringFindAndReplace(pmodule, CFSTR("{args}"), cf_args, rangeLLDB, 0);
//printf("write_lldb_prep_cmds:args: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
// CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
CFRelease(cf_args);
} else {
CFStringFindAndReplace(cmds, CFSTR(" {args}"), CFSTR(""), range, 0);
CFStringFindAndReplace(cmds, CFSTR("{args}"), CFSTR(""), range, 0);
CFStringFindAndReplace(pmodule, CFSTR("{args}"), CFSTR(""), rangeLLDB, 0);
//printf("write_lldb_prep_cmds: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
// CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
}
range.length = CFStringGetLength(cmds);
@@ -688,7 +791,12 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
// Write additional commands based on mode we're running in
const char* extra_cmds;
if (!interactive)
extra_cmds = lldb_prep_noninteractive_cmds;
{
if (justlaunch)
extra_cmds = lldb_prep_noninteractive_justlaunch_cmds;
else
extra_cmds = lldb_prep_noninteractive_cmds;
}
else if (nostart)
extra_cmds = lldb_prep_no_cmds;
else
@@ -723,17 +831,29 @@ CFSocketRef lldb_socket;
CFWriteStreamRef serverWriteStream = NULL;
CFWriteStreamRef lldbWriteStream = NULL;
int kill_ptree(pid_t root, int signum);
void
server_callback (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
{
int res;
//PRINT ("server: %s\n", CFDataGetBytePtr (data));
if (CFDataGetLength (data) == 0) {
// FIXME: Close the socket
//shutdown (CFSocketGetNative (lldb_socket), SHUT_RDWR);
//close (CFSocketGetNative (lldb_socket));
CFSocketInvalidate(lldb_socket);
CFSocketInvalidate(server_socket);
int mypid = getpid();
assert((child != 0) && (child != mypid)); //child should not be here
if ((parent != 0) && (parent == mypid) && (child != 0))
{
if (verbose)
{
printf("Got an empty packet hence killing child (%d) tree\n", child);
}
kill_ptree(child, SIGHUP);
}
exit(exitcode_error);
return;
}
res = write (CFSocketGetNative (lldb_socket), CFDataGetBytePtr (data), CFDataGetLength (data));
@@ -741,7 +861,7 @@ server_callback (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef add
void lldb_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
{
//PRINT ("lldb: %s\n", CFDataGetBytePtr (data));
//printf ("lldb: %s\n", CFDataGetBytePtr (data));
if (CFDataGetLength (data) == 0)
return;
@@ -869,42 +989,46 @@ void setup_dummy_pipe_on_stdin(int pfd[2]) {
perror("dup2 failed");
}
void launch_debugger(AMDeviceRef device, CFURLRef url) {
void setup_lldb(AMDeviceRef device, CFURLRef url) {
CFStringRef device_full_name = get_device_full_name(device),
device_interface_name = get_device_interface_name(device);
device_interface_name = get_device_interface_name(device);
AMDeviceConnect(device);
assert(AMDeviceIsPaired(device));
assert(AMDeviceValidatePairing(device) == 0);
assert(AMDeviceStartSession(device) == 0);
printf("------ Debug phase ------\n");
if(AMDeviceGetInterfaceType(device) == 2)
{
printf("Cannot debug %s over %s.\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(device_interface_name, CFStringGetSystemEncoding()));
exit(0);
}
printf("Starting debug of %s connected through %s...\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(device_interface_name, CFStringGetSystemEncoding()));
mount_developer_image(device); // put debugserver on the device
start_remote_debug_server(device); // start debugserver
write_lldb_prep_cmds(device, url); // dump the necessary lldb commands into a file
CFRelease(url);
printf("[100%%] Connecting to remote debug server\n");
printf("-------------------------\n");
setpgid(getpid(), 0);
signal(SIGHUP, killed);
signal(SIGINT, killed);
signal(SIGTERM, killed);
// Need this before fork to avoid race conditions. For child process we remove this right after fork.
signal(SIGLLDB, lldb_finished_handler);
parent = getpid();
}
void launch_debugger(AMDeviceRef device, CFURLRef url) {
setup_lldb(device, url);
int pid = fork();
if (pid == 0) {
signal(SIGHUP, SIG_DFL);
@@ -932,7 +1056,8 @@ void launch_debugger(AMDeviceRef device, CFURLRef url) {
perror("failed launching lldb");
close(pfd[0]);
close(pfd[1]);
close(pfd[1]);
// Notify parent we're exiting
kill(parent, SIGLLDB);
// Pass lldb exit code
@@ -945,6 +1070,45 @@ void launch_debugger(AMDeviceRef device, CFURLRef url) {
}
}
void launch_debugger_and_exit(AMDeviceRef device, CFURLRef url) {
setup_lldb(device,url);
int pfd[2] = {-1, -1};
if (pipe(pfd) == -1)
perror("Pipe failed");
int pid = fork();
if (pid == 0) {
signal(SIGHUP, SIG_DFL);
signal(SIGLLDB, SIG_DFL);
child = getpid();
if (dup2(pfd[0],STDIN_FILENO) == -1)
perror("dup2 failed");
char lldb_shell[400];
sprintf(lldb_shell, LLDB_SHELL);
if(device_id != NULL)
strcat(lldb_shell, device_id);
int status = system(lldb_shell); // launch lldb
if (status == -1)
perror("failed launching lldb");
close(pfd[0]);
// Notify parent we're exiting
kill(parent, SIGLLDB);
// Pass lldb exit code
_exit(WEXITSTATUS(status));
} else if (pid > 0) {
child = pid;
if (verbose)
printf("Waiting for child [Child: %d][Parent: %d]\n", child, parent);
} else {
perror("fork failed");
exit(exitcode_error);
}
}
CFStringRef get_bundle_id(CFURLRef app_url)
{
if (app_url == NULL)
@@ -981,7 +1145,9 @@ CFStringRef get_bundle_id(CFURLRef app_url)
return bundle_id;
}
void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir)
void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir,
void(*callback)(afc_connection *conn,const char *dir,int file))
{
char *dir_ent;
@@ -993,24 +1159,43 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir)
printf("%s\n", dir);
afc_dictionary afc_dict;
afc_dictionary* afc_dict_p = &afc_dict;
AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p);
afc_dictionary* afc_dict_p;
char *key, *val;
int not_dir = 0;
unsigned int code = AFCFileInfoOpen(afc_conn_p, dir, &afc_dict_p);
if (code != 0) {
// there was a problem reading or opening the file to get info on it, abort
return;
}
afc_directory afc_dir;
afc_directory* afc_dir_p = &afc_dir;
while((AFCKeyValueRead(afc_dict_p,&key,&val) == 0) && key && val) {
if (strcmp(key,"st_ifmt")==0) {
not_dir = strcmp(val,"S_IFDIR");
break;
}
}
AFCKeyValueClose(afc_dict_p);
if (not_dir) {
if (callback) (*callback)(afc_conn_p, dir, not_dir);
return;
}
afc_directory* afc_dir_p;
afc_error_t err = AFCDirectoryOpen(afc_conn_p, dir, &afc_dir_p);
if (err != 0)
{
if (err != 0) {
// Couldn't open dir - was probably a file
return;
} else {
if (callback) (*callback)(afc_conn_p, dir, not_dir);
}
while(true) {
err = AFCDirectoryRead(afc_conn_p, afc_dir_p, &dir_ent);
if (!dir_ent)
if (err != 0 || !dir_ent)
break;
if (strcmp(dir_ent, ".") == 0 || strcmp(dir_ent, "..") == 0)
@@ -1021,7 +1206,7 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir)
if (dir_joined[strlen(dir)-1] != '/')
strcat(dir_joined, "/");
strcat(dir_joined, dir_ent);
read_dir(afcFd, afc_conn_p, dir_joined);
read_dir(afcFd, afc_conn_p, dir_joined, callback);
free(dir_joined);
}
@@ -1098,11 +1283,102 @@ void list_files(AMDeviceRef device)
{
service_conn_t houseFd = start_house_arrest_service(device);
afc_connection afc_conn;
afc_connection* afc_conn_p = &afc_conn;
AFCConnectionOpen(houseFd, 0, &afc_conn_p);
read_dir(houseFd, afc_conn_p, "/");
afc_connection* afc_conn_p;
if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) {
read_dir(houseFd, afc_conn_p, list_root?list_root:"/", NULL);
AFCConnectionClose(afc_conn_p);
}
}
void copy_file_callback(afc_connection* afc_conn_p, const char *name,int file)
{
const char *local_name=name;
if (*local_name=='/') local_name++;
if (*local_name=='\0') return;
if (file) {
afc_file_ref fref;
int err = AFCFileRefOpen(afc_conn_p,name,1,&fref);
if (err) {
fprintf(stderr,"AFCFileRefOpen(\"%s\") failed: %d\n",name,err);
return;
}
FILE *fp = fopen(local_name,"w");
if (fp==NULL) {
fprintf(stderr,"fopen(\"%s\",\"w\") failer: %s\n",local_name,strerror(errno));
AFCFileRefClose(afc_conn_p,fref);
return;
}
char buf[4096];
size_t sz=sizeof(buf);
while (AFCFileRefRead(afc_conn_p,fref,buf,&sz)==0 && sz) {
fwrite(buf,sz,1,fp);
sz = sizeof(buf);
}
AFCFileRefClose(afc_conn_p,fref);
fclose(fp);
} else {
if (mkdir(local_name,0777) && errno!=EEXIST)
fprintf(stderr,"mkdir(\"%s\") failed: %s\n",local_name,strerror(errno));
}
}
void mkdirhier(char *path)
{
char *slash;
struct stat buf;
if (path[0]=='.' && path[1]=='/') path+=2;
if ((slash = strrchr(path,'/'))) {
*slash = '\0';
if (stat(path,&buf)==0) {
*slash = '/';
return;
}
mkdirhier(path);
mkdir (path,0777);
*slash = '/';
}
return;
}
void download_tree(AMDeviceRef device)
{
service_conn_t houseFd = start_house_arrest_service(device);
afc_connection* afc_conn_p = NULL;
char *dirname = NULL;
if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) do {
if (target_filename) {
dirname = strdup(target_filename);
mkdirhier(dirname);
if (mkdir(dirname,0777) && errno!=EEXIST) {
fprintf(stderr,"mkdir(\"%s\") failed: %s\n",dirname,strerror(errno));
break;
}
if (chdir(dirname)) {
fprintf(stderr,"chdir(\"%s\") failed: %s\n",dirname,strerror(errno));
break;
}
}
read_dir(houseFd, afc_conn_p, list_root?list_root:"/", copy_file_callback);
} while(0);
if (dirname) free(dirname);
if (afc_conn_p) AFCConnectionClose(afc_conn_p);
}
void upload_file(AMDeviceRef device) {
@@ -1114,7 +1390,7 @@ void upload_file(AMDeviceRef device) {
afc_connection* afc_conn_p = &afc_conn;
AFCConnectionOpen(houseFd, 0, &afc_conn_p);
// read_dir(houseFd, NULL, "/");
// read_dir(houseFd, NULL, "/", NULL);
if (!target_filename)
{
@@ -1163,33 +1439,39 @@ void upload_file(AMDeviceRef device) {
}
void handle_device(AMDeviceRef device) {
if (found_device)
return; // handle one device only
//if (found_device)
// return; // handle one device only
CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device),
device_full_name = get_device_full_name(device),
device_interface_name = get_device_interface_name(device);
if (detect_only) {
printf("[....] Found %s connected through %s.\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(device_interface_name, CFStringGetSystemEncoding()));
found_device = true;
return;
}
if (device_id != NULL) {
if(strcmp(device_id, CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding())) == 0) {
found_device = true;
} else {
printf("Skipping %s.\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()));
return;
}
} else {
device_id = MYCFStringCopyUTF8String(found_device_id);
found_device = true;
}
if (detect_only) {
printf("[....] Found %s connected through %s.\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(device_interface_name, CFStringGetSystemEncoding()));
exit(0);
}
printf("[....] Using %s (%s).\n", CFStringGetCStringPtr(device_full_name, CFStringGetSystemEncoding()), CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));
if (command_only) {
if (strcmp("list", command) == 0) {
list_files(device);
} else if (strcmp("upload", command) == 0) {
upload_file(device);
} else if (strcmp("download", command) == 0) {
download_tree(device);
}
exit(0);
}
@@ -1214,13 +1496,15 @@ void handle_device(AMDeviceRef device) {
assert(AMDeviceIsPaired(device));
assert(AMDeviceValidatePairing(device) == 0);
assert(AMDeviceStartSession(device) == 0);
assert(AMDeviceSecureUninstallApplication(0, device, bundle_id, 0, NULL, 0) == 0);
int code = AMDeviceSecureUninstallApplication(0, device, bundle_id, 0, NULL, 0);
if (code == 0) {
printf("[ OK ] Uninstalled package with bundle id %s\n", CFStringGetCStringPtr(bundle_id, CFStringGetSystemEncoding()));
} else {
printf("[ ERROR ] Could not uninstall package with bundle id %s\n", CFStringGetCStringPtr(bundle_id, CFStringGetSystemEncoding()));
}
assert(AMDeviceStopSession(device) == 0);
assert(AMDeviceDisconnect(device) == 0);
printf("[ OK ] Uninstalled package with bundle id %s\n", CFStringGetCStringPtr(bundle_id, CFStringGetSystemEncoding()));
}
}
@@ -1288,7 +1572,10 @@ void handle_device(AMDeviceRef device) {
if (!debug)
exit(0); // no debug phase
launch_debugger(device, url);
if (justlaunch)
launch_debugger_and_exit(device, url);
else
launch_debugger(device, url);
}
void device_callback(struct am_device_notification_callback_info *info, void *arg) {
@@ -1306,7 +1593,7 @@ void device_callback(struct am_device_notification_callback_info *info, void *ar
}
void timeout_callback(CFRunLoopTimerRef timer, void *info) {
if (!found_device) {
if ((!found_device) && (!detect_only)) {
if(best_device_match != NULL) {
handle_device(best_device_match);
@@ -1319,22 +1606,43 @@ void timeout_callback(CFRunLoopTimerRef timer, void *info) {
exit(exitcode_error);
}
}
else
{
if (!debug) {
printf("[....] No more devices found.\n");
}
if (detect_only && !found_device) {
exit(exitcode_error);
return;
} else {
int mypid = getpid();
if ((parent != 0) && (parent == mypid) && (child != 0))
{
if (verbose)
{
printf("Timeout. Killing child (%d) tree\n", child);
}
kill_ptree(child, SIGHUP);
}
}
exit(0);
}
}
void usage(const char* app) {
printf(
"Usage: %s [OPTION]...\n"
" -d, --debug launch the app in GDB after installation\n"
" -d, --debug launch the app in lldb after installation\n"
" -i, --id <device_id> the id of the device to connect to\n"
" -c, --detect only detect if the device is connected\n"
" -b, --bundle <bundle.app> the path to the app bundle to be installed\n"
" -a, --args <args> command line arguments to pass to the app when launching it\n"
" -t, --timeout <timeout> number of seconds to wait for a device to be connected\n"
" -u, --unbuffered don't buffer stdout\n"
" -g, --gdbargs <args> extra arguments to pass to GDB when starting the debugger\n"
" -x, --gdbexec <file> GDB commands script file\n"
" -n, --nostart do not start the app when debugging\n"
" -I, --noninteractive start in non interactive mode (quit when app crashes or exits)\n"
" -L, --justlaunch just launch the app and exit lldb\n"
" -v, --verbose enable verbose output\n"
" -m, --noinstall directly start debugging without app install (-d not required)\n"
" -p, --port <number> port used for device, default: 12345 \n"
@@ -1342,7 +1650,8 @@ void usage(const char* app) {
" -1, --bundle_id <bundle id> specify bundle id for list and upload\n"
" -l, --list list files\n"
" -o, --upload <file> upload file\n"
" -2, --to <target pathname> use together with upload file. specify target for upload\n"
" -w, --download download app tree\n"
" -2, --to <target pathname> use together with up/download file/tree. specify target\n"
" -V, --version print the executable version \n",
app);
}
@@ -1359,24 +1668,25 @@ int main(int argc, char *argv[]) {
{ "args", required_argument, NULL, 'a' },
{ "verbose", no_argument, NULL, 'v' },
{ "timeout", required_argument, NULL, 't' },
{ "gdbexec", no_argument, NULL, 'x' },
{ "unbuffered", no_argument, NULL, 'u' },
{ "nostart", no_argument, NULL, 'n' },
{ "noninteractive", no_argument, NULL, 'I' },
{ "justlaunch", no_argument, NULL, 'L' },
{ "detect", no_argument, NULL, 'c' },
{ "version", no_argument, NULL, 'V' },
{ "noinstall", no_argument, NULL, 'm' },
{ "port", required_argument, NULL, 'p' },
{ "uninstall", no_argument, NULL, 'r' },
{ "list", no_argument, NULL, 'l' },
{ "list", optional_argument, NULL, 'l' },
{ "bundle_id", required_argument, NULL, '1'},
{ "upload", required_argument, NULL, 'o'},
{ "download", optional_argument, NULL, 'w'},
{ "to", required_argument, NULL, '2'},
{ NULL, 0, NULL, 0 },
};
char ch;
while ((ch = getopt_long(argc, argv, "VmcdvunlrIi:b:a:t:g:x:p:1:2:o:", longopts, NULL)) != -1)
while ((ch = getopt_long(argc, argv, "VmcdvunrILi:b:a:t:g:x:p:1:2:o:l::w::", longopts, NULL)) != -1)
{
switch (ch) {
case 'm':
@@ -1410,8 +1720,13 @@ int main(int argc, char *argv[]) {
case 'I':
interactive = false;
break;
case 'L':
interactive = false;
justlaunch = true;
break;
case 'c':
detect_only = true;
debug = 1;
break;
case 'V':
show_version();
@@ -1436,6 +1751,12 @@ int main(int argc, char *argv[]) {
case 'l':
command_only = true;
command = "list";
list_root = optarg;
break;
case 'w':
command_only = true;
command = "download";
list_root = optarg;
break;
default:
usage(argv[0]);

View File

@@ -1,7 +1,7 @@
{
"name": "ios-deploy",
"version": "1.0.9",
"description": "launch iOS apps iOS devices from the command line (Xcode 5)",
"version": "1.3.2",
"description": "launch iOS apps iOS devices from the command line (Xcode 6)",
"main": "ios-deploy",
"scripts": {
"preinstall": "make ios-deploy"

3
resources/buildbox/build.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env bash
echo "$ make"
make