Compare commits

...

29 Commits
1.x ... main

Author SHA1 Message Date
Shazron Abdullah
79a2a3bf95 Fixes #250 - Can't pass in command line args to the iOS application
Thanks to https://github.com/dot-asm
2016-09-16 02:52:18 -07:00
Shazron Abdullah
8741d74623 Add iPad Pro friendly names
This closes #252
2016-09-16 02:46:35 -07:00
Shazron Abdullah
009089254c Added iPhone 7 and 7 Plus friendly names
This closes #251
2016-09-16 02:40:01 -07:00
Shazron Abdullah
e72626a832 Added new iPhone SE friendly name 2016-09-16 02:36:08 -07:00
Shazron Abdullah
100c8a3cbc Added tvOS Apple TV 4G friendly name
This closes #248

Thanks to https://github.com/gusc
2016-09-16 02:34:33 -07:00
Shazron Abdullah
71e14bed95 Merge pull request #228 from Vrixyz/master
Added support for AppleTV OS
2016-09-16 02:20:07 -07:00
Shazron Abdullah
022fd2865a Fixes #240 - IndexError: list index out of range
Thanks to https://github.com/gusc (Gusts Kaksis) for the patch.
2016-09-14 02:11:59 -07:00
Shazron Abdullah
7a808cb6b4 Merge pull request #243 from trigger-corp/master
Add missing iPad Air and iPad Mini models, and fixes #244 - ios-deploy will exit when the detection timeout ends even if the device has been detected
2016-08-08 19:52:55 -07:00
Antoine van Gelder
25588767f2 Fixed: ios-deploy will exit when the detection timeout ends even if the device has been detected 2016-08-02 15:32:37 +02:00
Antoine van Gelder
babe79f391 Add missing iPad Air and iPad Mini models 2016-08-02 15:27:48 +02:00
Shazron Abdullah
26f981e51c Merge pull request #232 from jakepetroules/codes
Bring list of error messages up-to-date.
2016-05-26 14:39:10 -07:00
Jake Petroules
07de7505cc Bring list of error messages up-to-date.
Automatically generated using MobileDevice.framework private APIs.
Xcode 7.3.1 and OS X 10.11.5.
2016-05-26 14:25:52 -07:00
Thierry Berger
978b1bb139 added support for AppleTV OS ; simplified find_path() to avoid quoting root_path (some paths weren't working) 2016-05-13 20:46:09 +02:00
Alexis Kofman
76e8d08e43 Fixes #219 - iOS 9.3 app hangs on splash screen
Fixes cases where process is not yet running.

Signed-off-by: Shazron Abdullah <shazron@apache.org>
2016-04-11 14:06:07 -07:00
Shazron Abdullah
3ef9dfefcf Merge pull request #222 from akofman/tweaks
Tweaks
2016-04-08 11:06:41 -07:00
Alexis Kofman
888323b76e rm autogenerated files from the repo 2016-04-08 19:48:36 +02:00
Alexis Kofman
908a2d56ab replace remaining tabs by spaces 2016-04-08 19:47:48 +02:00
Shazron Abdullah
77654faabd Added travis ci badge 2016-03-23 12:21:54 -07:00
Shazron Abdullah
81b52cd69d Added travis ci config 2016-03-23 12:20:43 -07:00
Shazron Abdullah
d30f6bd379 Merge pull request #217 from stevemoser/patch-1
Update for iPhone SE
2016-03-22 13:16:15 -07:00
Steve Moser
17d0841ab8 Update for iPhone SE
https://twitter.com/panzer/status/712330579291668480
2016-03-22 13:50:13 -04:00
Shazron Abdullah
2461665ea4 Updated Github issue template. 2016-02-25 16:04:11 -08:00
Shazron Abdullah
e8f90b0d2c Added Github issue template. 2016-02-25 16:02:58 -08:00
Shazron Abdullah
1f1725a33b Fixed npm run test 2016-02-04 10:13:39 -08:00
Shazron Abdullah
8757ca562f Added warning text to the check_reqs.js log when running under OS X 10.11 El Capitan 2016-02-04 09:32:07 -08:00
Shazron Abdullah
411f054b0c Merge pull request #205 from stevenkramer/recursive_uploads
Added support for recursive directory uploads
2016-01-19 17:04:53 -08:00
Steven Kramer
4dd9d740aa Added support for recursive directory uploads 2016-01-19 10:08:38 +01:00
Shazron Abdullah
9a9c648cdc Updated version to 2.0.0 2016-01-16 10:35:03 -08:00
Shazron Abdullah
2fceef2c75 Updated README to reflect 1.x branch and master (dev) branch expectations. 2016-01-16 10:33:11 -08:00
13 changed files with 499 additions and 273 deletions

28
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,28 @@
## MUST READ BEFORE YOU FILE (DELETE THIS SECTION BEFORE FILING)
Include the **command line arguments** you used for ios-deploy.
Don't forget to check out the [El Capitan](https://github.com/phonegap/ios-deploy/blob/master/README.md#os-x-1011-el-capitan) section of the [README](https://github.com/phonegap/ios-deploy/blob/master/README.md) before filing this issue.
# Expected behavior
# Actual behavior.
# Steps to reproduce the problem
# System Specs
Please run the commands below in your Terminal.app and include it in the issue. Check when done and include results below.
- [ ] 1. sw_vers -productVersion
- [ ] 2. ios-deploy -V
- [ ] 3. xcodebuild -version
- [ ] 4. xcode-select --print-path
- [ ] 5. gcc --version
- [ ] 6. lldb --version

2
.gitignore vendored
View File

@ -2,3 +2,5 @@ build/*
node_modules/*
/.DS_Store
*~
src/scripts/lldb.pyc
src/ios-deploy/lldb.py.h

11
.travis.yml Normal file
View File

@ -0,0 +1,11 @@
language: objective-c
sudo: false
node_js:
- "0.10"
- "0.12"
- "4.2"
install:
- npm install
script:
- "npm test"

View File

@ -1,3 +1,5 @@
[![Build Status](https://travis-ci.org/phonegap/ios-deploy.svg?branch=master)](https://travis-ci.org/phonegap/ios-deploy)
ios-deploy
==========
Install and debug iOS apps without using Xcode. Designed to work on un-jailbroken devices.
@ -14,8 +16,13 @@ See our [milestones](https://github.com/phonegap/ios-deploy/milestones).
Significant changes:
1.8.0 will use an Xcode project instead of a Makefile (to prepare for 2.0.0)
2.0.0 will break out the commands into their own files, and create ios-deploy-lib for node.js use
1.8.0 will use an Xcode project instead of a Makefile (to prepare for 2.0.0) (1.x branch)
2.0.0 will break out the commands into their own files, and create ios-deploy-lib for node.js use (master branch)
## Development
The legacy `1.x` version is under the `1.x` branch. Bug fixes for the `1.x` series will occur under there.
The 'master' branch now contains the `2.x` series, and is the development branch.
## Installation
=======

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7E8E3A821C45D4CE0017F6C1"
BuildableName = "ios-deploy-tests.xctest"
BlueprintName = "ios-deploy-tests"
ReferencedContainer = "container:ios-deploy.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1,6 +1,6 @@
{
"name": "ios-deploy",
"version": "1.8.4",
"version": "2.0.0",
"os": [
"darwin"
],
@ -18,7 +18,7 @@
},
"scripts": {
"preinstall": "./src/scripts/check_reqs.js && xcodebuild",
"test": "npm run pycompile && npm run jshint && xcodebuild -scheme ios-deploy-lib && xcodebuild test -scheme ios-deploy-tests",
"test": "npm run pycompile && npm run jshint && xcodebuild -target ios-deploy-lib && xcodebuild test -scheme ios-deploy-tests",
"jshint": "node node_modules/jshint/bin/jshint src/scripts/*.js",
"pycompile": "python -m py_compile src/scripts/*.py"
},

View File

@ -33,6 +33,7 @@ typedef struct error_id_to_message {
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static errorcode_to_id_t errorcode_to_id[] = {
{ 0x00000000, "kAMDSuccess" },
{ 0xe8000001, "kAMDUndefinedError" },
{ 0xe8000002, "kAMDBadHeaderError" },
{ 0xe8000003, "kAMDNoResourcesError" },
@ -189,23 +190,111 @@ static errorcode_to_id_t errorcode_to_id[] = {
{ 0xe800009a, "kAMDMCProtected" },
{ 0xe800009b, "kAMDMCChallengeRequired" },
{ 0xe800009c, "kAMDMissingBundleVersionError" },
{ 0xe800009d, "kAMDAppBlacklistedError" },
{ 0xe800009e, "This app contains an app extension with an illegal bundle identifier. App extension bundle identifiers must have a prefix consisting of their containing application's bundle identifier followed by a '.'." },
{ 0xe800009f, "If an app extension defines the XPCService key in its Info.plist, it must have a dictionary value." },
{ 0xe80000a0, "App extensions must define the NSExtension key with a dictionary value in their Info.plist." },
{ 0xe80000a1, "If an app extension defines the CFBundlePackageType key in its Info.plist, it must have the value \"XPC!\"." },
{ 0xe80000a2, "App extensions must define either NSExtensionMainStoryboard or NSExtensionPrincipalClass keys in the NSExtension dictionary in their Info.plist." },
{ 0xe80000a3, "If an app extension defines the NSExtensionContextClass key in the NSExtension dictionary in its Info.plist, it must have a string value containing one or more characters." },
{ 0xe80000a4, "If an app extension defines the NSExtensionContextHostClass key in the NSExtension dictionary in its Info.plist, it must have a string value containing one or more characters." },
{ 0xe80000a5, "If an app extension defines the NSExtensionViewControllerHostClass key in the NSExtension dictionary in its Info.plist, it must have a string value containing one or more characters." },
{ 0xe80000a6, "This app contains an app extension that does not define the NSExtensionPointIdentifier key in its Info.plist. This key must have a reverse-DNS format string value." },
{ 0xe80000a7, "This app contains an app extension that does not define the NSExtensionPointIdentifier key in its Info.plist with a valid reverse-DNS format string value." },
{ 0xe80000a8, "If an app extension defines the NSExtensionAttributes key in the NSExtension dictionary in its Info.plist, it must have a dictionary value." },
{ 0xe80000a9, "If an app extension defines the NSExtensionPointName key in the NSExtensionAttributes dictionary in the NSExtension dictionary in its Info.plist, it must have a string value containing one or more characters." },
{ 0xe80000aa, "If an app extension defines the NSExtensionPointVersion key in the NSExtensionAttributes dictionary in the NSExtension dictionary in its Info.plist, it must have a string value containing one or more characters." },
{ 0xe80000ab, "This app or a bundle it contains does not define the CFBundleName key in its Info.plist with a string value containing one or more characters." },
{ 0xe80000ac, "This app or a bundle it contains does not define the CFBundleDisplayName key in its Info.plist with a string value containing one or more characters." },
{ 0xe80000ad, "This app or a bundle it contains defines the CFBundleShortVersionStringKey key in its Info.plist with a non-string value or a zero-length string value." },
{ 0xe80000ae, "This app or a bundle it contains defines the RunLoopType key in the XPCService dictionary in its Info.plist with a non-string value or a zero-length string value." },
{ 0xe80000af, "This app or a bundle it contains defines the ServiceType key in the XPCService dictionary in its Info.plist with a non-string value or a zero-length string value." },
{ 0xe80000b0, "This application or a bundle it contains has the same bundle identifier as this application or another bundle that it contains. Bundle identifiers must be unique." },
{ 0xe80000b1, "This app contains an app extension that specifies an extension point identifier that is not supported on this version of iOS for the value of the NSExtensionPointIdentifier key in its Info.plist." },
{ 0xe80000b2, "This app contains multiple app extensions that are file providers. Apps are only allowed to contain at most a single file provider app extension." },
{ 0xe80000b3, "kMobileHouseArrestMissingCommand" },
{ 0xe80000b4, "kMobileHouseArrestUnknownCommand" },
{ 0xe80000b5, "kMobileHouseArrestMissingIdentifier" },
{ 0xe80000b6, "kMobileHouseArrestDictionaryFailed" },
{ 0xe80000b7, "kMobileHouseArrestInstallationLookupFailed" },
{ 0xe80000b8, "kMobileHouseArrestApplicationLookupFailed" },
{ 0xe80000b9, "kMobileHouseArrestMissingContainer" },
// 0xe80000ba does not exist
{ 0xe80000bb, "kMobileHouseArrestPathConversionFailed" },
{ 0xe80000bc, "kMobileHouseArrestPathMissing" },
{ 0xe80000bd, "kMobileHouseArrestInvalidPath" },
{ 0xe80000be, "kAMDMismatchedApplicationIdentifierEntitlementError" },
{ 0xe80000bf, "kAMDInvalidSymlinkError" },
{ 0xe80000c0, "kAMDNoSpaceError" },
{ 0xe80000c1, "The WatchKit app extension must have, in its Info.plist's NSExtension dictionary's NSExtensionAttributes dictionary, the key WKAppBundleIdentifier with a value equal to the associated WatchKit app's bundle identifier." },
{ 0xe80000c2, "This app is not a valid AppleTV Stub App" },
{ 0xe80000c3, "kAMDBundleiTunesMetadataVersionMismatchError" },
{ 0xe80000c4, "kAMDInvalidiTunesMetadataPlistError" },
{ 0xe80000c5, "kAMDMismatchedBundleIDSigningIdentifierError" },
{ 0xe80000c6, "This app contains multiple WatchKit app extensions. Only a single WatchKit extension is allowed." },
{ 0xe80000c7, "A WatchKit app within this app is not a valid bundle." },
{ 0xe80000c8, "kAMDDeviceNotSupportedByThinningError" },
{ 0xe80000c9, "The UISupportedDevices key in this app's Info.plist does not specify a valid set of supported devices." },
{ 0xe80000ca, "This app contains an app extension with an illegal bundle identifier. App extension bundle identifiers must have a prefix consisting of their containing application's bundle identifier followed by a '.', with no further '.' characters after the prefix." },
{ 0xe80000cb, "kAMDAppexBundleIDConflictWithOtherIdentifierError" },
{ 0xe80000cc, "kAMDBundleIDConflictWithOtherIdentifierError" },
{ 0xe80000cd, "This app contains multiple WatchKit 1.0 apps. Only a single WatchKit 1.0 app is allowed." },
{ 0xe80000ce, "This app contains multiple WatchKit 2.0 apps. Only a single WatchKit 2.0 app is allowed." },
{ 0xe80000cf, "The WatchKit app has an invalid stub executable." },
{ 0xe80000d0, "The WatchKit app has multiple app extensions. Only a single WatchKit extension is allowed in a WatchKit app, and only if this is a WatchKit 2.0 app." },
{ 0xe80000d1, "The WatchKit 2.0 app contains non-WatchKit app extensions. Only WatchKit app extensions are allowed in WatchKit apps." },
{ 0xe80000d2, "The WatchKit app has one or more embedded frameworks. Frameworks are only allowed in WatchKit app extensions in WatchKit 2.0 apps." },
{ 0xe80000d3, "This app contains a WatchKit 1.0 app with app extensions. This is not allowed." },
{ 0xe80000d4, "This app contains a WatchKit 2.0 app without an app extension. WatchKit 2.0 apps must contain a WatchKit app extension." },
{ 0xe80000d5, "The WatchKit app's Info.plist must have a WKCompanionAppBundleIdentifier key set to the bundle identifier of the companion app." },
{ 0xe80000d6, "The WatchKit app's Info.plist contains a non-string key." },
{ 0xe80000d7, "The WatchKit app's Info.plist contains a key that is not in the whitelist of allowed keys for a WatchKit app." },
{ 0xe80000d8, "The WatchKit 1.0 and a WatchKit 2.0 apps within this app must have have the same bundle identifier." },
{ 0xe80000d9, "This app contains a WatchKit app with an invalid bundle identifier. The bundle identifier of a WatchKit app must have a prefix consisting of the companion app's bundle identifier, followed by a '.'." },
{ 0xe80000da, "This app contains a WatchKit app where the UIDeviceFamily key in its Info.plist does not specify the value 4 to indicate that it's compatible with the Apple Watch device type." },
{ 0xe80000db, "The device is out of storage for apps. Please remove some apps from the device and try again." },
// Errors without id->string mapping.
{ 0xe8008001, "An unknown error has occurred." },
{ 0xe8008002, "Attempted to modify an immutable provisioning profile." },
{ 0xe8008003, "This provisioning profile is malformed." },
{ 0xe8008004, "This provisioning profile does not have a valid signature (or it has a valid, but untrusted signature)." },
{ 0xe8008005, "This provisioning profile is malformed." },
{ 0xe8008006, "This provisioning profile is malformed." },
{ 0xe8008007, "This provisioning profile is malformed." },
{ 0xe8008008, "This provisioning profile is malformed." },
{ 0xe8008009, "The signature was not valid." },
{ 0xe800800a, "Unable to allocate memory." },
{ 0xe800800b, "A file operation failed." },
{ 0xe800800c, "There was an error communicating with your device." },
{ 0xe800800d, "There was an error communicating with your device." },
{ 0xe800800e, "This provisioning profile does not have a valid signature (or it has a valid, but untrusted signature)." },
{ 0xe800800f, "The application's signature is valid but it does not match the expected hash." },
{ 0xe8008010, "This provisioning profile is unsupported." },
{ 0xe8008011, "This provisioning profile has expired." },
{ 0xe8008012, "This provisioning profile cannot be installed on this device." },
{ 0xe8008013, "This provisioning profile does not have a valid signature (or it has a valid, but untrusted signature)." },
{ 0xe8008014, "The executable contains an invalid signature." },
{ 0xe8008015, "A valid provisioning profile for this executable was not found." },
{ 0xe8008016, "The entitlements specified in your applications Code Signing Entitlements file do not match those specified in your provisioning profile." },
{ 0xe8008016, "The executable was signed with invalid entitlements." },
{ 0xe8008017, "A signed resource has been added, modified, or deleted." },
{ 0xe8008018, "The identity used to sign the executable is no longer valid. Please verify that your devices clock is properly set, and that your signing certificate is not expired." },
{ 0xe8008018, "The identity used to sign the executable is no longer valid." },
{ 0xe8008019, "The application does not have a valid signature." },
{ 0xe800801a, "This provisioning profile does not have a valid signature (or it has a valid, but untrusted signature)." },
{ 0xe800801b, "There was an error communicating with your device." },
{ 0xe800801c, "No code signature found." },
{ 0xe800801d, "Rejected by policy." },
{ 0xe800801e, "The requested profile does not exist (it may have been removed)." },
};
const int errorcode_to_id_count = sizeof(errorcode_to_id) / sizeof(errorcode_to_id_t);
// Taken from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/Resources/en_GB.lproj/Localizable.strings
// Taken from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/Resources/English.lproj/Localizable.strings
error_id_to_message_t error_id_to_message[] = {
{ "kAMDAPIInternalError", "There was an internal API error." },
{ "kAMDAlreadyArchivedError", "The application is already archived." },
{ "kAMDAppBlacklistedError", "This app is not allowed to be installed on this device." },
{ "kAMDAppexBundleIDConflictWithOtherIdentifierError", "This application contains an app extension with a bundle identifier that conflicts with the bundle identifier of another app or app extension already installed." },
{ "kAMDApplicationAlreadyInstalledError", "A system application with the given bundle identifier is already installed on the device and cannot be replaced." },
{ "kAMDApplicationMoveFailedError", "The application could not be moved into place on the device." },
{ "kAMDApplicationSandboxFailedError", "The application could not be sandboxed." },
@ -214,7 +303,9 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDBadHeaderError", "Could not transfer file." },
{ "kAMDBreadcrumbFailedError", "Could not write installation breadcrumb." },
{ "kAMDBreadcrumbUnlockError", "Could not update installation breadcrumb." },
{ "kAMDBundleIDConflictWithOtherIdentifierError", "This application's bundle identifier conflicts with the identifier of another app or app extension already installed." },
{ "kAMDBundleVerificationFailedError", "The carrier bundle could not be verified." },
{ "kAMDBundleiTunesMetadataVersionMismatchError", "This application's iTunesMetadata.plist specifies versions that do not match the versions listed for the app in its Info.plist" },
{ "kAMDBusyError", "The device is busy." },
{ "kAMDCannotTranslateError", "Could not translate messages from device" },
{ "kAMDCarrierBundleCopyFailedError", "Could not install the carrier bundle." },
@ -234,6 +325,7 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDCryptoError", "Could not establish a secure connection to the device." },
{ "kAMDDeviceDisconnectedError", "This device is no longer connected." },
{ "kAMDDeviceFamilyNotSupported", "This application does not support this kind of device." },
{ "kAMDDeviceNotSupportedByThinningError", "This application is not built for this device." },
{ "kAMDDeviceOSVersionTooLow", "The device OS version is too low." },
{ "kAMDDeviceRefNoGood", "This device is no longer connected." },
{ "kAMDDeviceTooNewError", "This application needs to be updated." },
@ -248,7 +340,7 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDFMiPProtectedError", "The device is in lost mode." },
{ "kAMDFileExistsError", "The file already exists." },
{ "kAMDGeoJSONCaptureFailedError", "Could not save the GeoJSON data." },
{ "kAMDGetProhibitedError", "Cannot retrieve value from the passcode-locked device." },
{ "kAMDGetProhibitedError", "Cannot retrieve value from the passcode locked device." },
{ "kAMDImmutableValueError", "This value cannot be changed." },
{ "kAMDIncorrectArchitectureError", "This application does not support this device's CPU type." },
{ "kAMDInstallMapUpdateFailedError", "Could not update the installed applications list." },
@ -257,17 +349,21 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDInvalidArgumentError", "The argument is invalid." },
{ "kAMDInvalidCheckinError", "Could not start service on device" },
{ "kAMDInvalidDiskImageError", "The disk image is invalid." },
{ "kAMDInvalidHostIDError", "The device does not recognise this host." },
{ "kAMDInvalidHostIDError", "The device does not recognize this host." },
{ "kAMDInvalidPairRecordError", "The host is no longer paired with the device." },
{ "kAMDInvalidResponseError", "Received an unexpected response from the device." },
{ "kAMDInvalidServiceError", "The service is invalid." },
{ "kAMDInvalidSessionIDError", "The session ID is invalid." },
{ "kAMDInvalidSymlinkError", "The bundle contained an invalid symlink." },
{ "kAMDInvalidiTunesMetadataPlistError", "This application's iTunesMetadata.plist is not valid." },
{ "kAMDIsDirectoryError", "The path is a directory." },
{ "kAMDLookupFailedError", "Could not list installed applications." },
{ "kAMDMCChallengeRequired", "A policy on the device requires secure pairing." },
{ "kAMDMCProtected", "Pairing is prohibited by a policy on the device." },
{ "kAMDManifestCaptureFailedError", "Could not save the application manifest." },
{ "kAMDMapGenerationFailedError", "Could not generate the map." },
{ "kAMDMismatchedApplicationIdentifierEntitlementError", "This application's application-identifier entitlement does not match that of the installed application. These values must match for an upgrade to be allowed." },
{ "kAMDMismatchedBundleIDSigningIdentifierError", "This application's bundle identifier does not match its code signing identifier." },
{ "kAMDMissingActivationRecordError", "The activation record could not be found." },
{ "kAMDMissingApplicationIdentifierError", "Request was missing the application identifier." },
{ "kAMDMissingAttributeValueError", "Request was missing a required value." },
@ -279,7 +375,7 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDMissingContainerError", "Could not find the container for the installed application." },
{ "kAMDMissingContainerPathError", "Request was missing the container path." },
{ "kAMDMissingDigestError", "The digest is missing." },
{ "kAMDMissingHostIDError", "The device does not recognise this host." },
{ "kAMDMissingHostIDError", "The device does not recognize this host." },
{ "kAMDMissingImageTypeError", "The image is missing." },
{ "kAMDMissingKeyError", "The key is missing." },
{ "kAMDMissingOptionsError", "The options are missing." },
@ -310,6 +406,7 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDMuxGetListenerError", "Could not get the USB listener." },
{ "kAMDNewsstandArtworkCaptureFailedError", "Could not save the Newsstand artwork." },
{ "kAMDNoResourcesError", "Could not allocate a resource." },
{ "kAMDNoSpaceError", "No space is available on the device." },
{ "kAMDNoWifiSyncSupportError", "Device doesn't support wireless sync." },
{ "kAMDNotConnectedError", "Not connected to the device." },
{ "kAMDNotEntitledError", "The requesting application is not allowed to make this request." },
@ -325,7 +422,7 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDPasswordProtectedError", "The device is passcode protected." },
{ "kAMDPathConversionFailedError", "Could not convert the path." },
{ "kAMDPermissionError", "You do not have permission." },
{ "kAMDPluginCopyFailedError", "Could not copy VPN Plug-in into app container." },
{ "kAMDPluginCopyFailedError", "Could not copy VPN Plugin into app container." },
{ "kAMDProhibitedBySupervision", "Operation prohibited on supervised devices." },
{ "kAMDProvisioningProfileNotValid", "The provisioning profile is not valid." },
{ "kAMDReadError", "Could not read from the device." },
@ -351,7 +448,7 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDTooBigError", "The message is too big." },
{ "kAMDUndefinedError", "An unknown error occurred." },
{ "kAMDUninstallProhibitedError", "Uninstallation of apps is prohibited by a policy on the device." },
{ "kAMDUnknownCommandError", "The device does not recognise the command." },
{ "kAMDUnknownCommandError", "The device does not recognize the command." },
{ "kAMDUnknownPacketError", "The packet is unknown." },
{ "kAMDUnsupportedError", "This operation is unsupported." },
{ "kAMDUserDeniedPairingError", "The device rejected the pairing attempt." },
@ -359,6 +456,16 @@ error_id_to_message_t error_id_to_message[] = {
{ "kAMDWrongDroidError", "The device is in recovery mode." },
{ "kAMDiTunesArtworkCaptureFailedError", "Could not save the iTunes artwork." },
{ "kAMDiTunesMetadataCaptureFailedError", "Could not save the iTunes metadata." },
{ "kMobileHouseArrestApplicationLookupFailed", "The requested application is not a user application." },
{ "kMobileHouseArrestDictionaryFailed", "The request contained an invalid request dictionary." },
{ "kMobileHouseArrestInstallationLookupFailed", "Could not find the requested application." },
{ "kMobileHouseArrestInvalidPath", "The requested application contained an invalid data container path." },
{ "kMobileHouseArrestMissingCommand", "The request was missing a command." },
{ "kMobileHouseArrestMissingContainer", "The requested application does not contain a valid data container." },
{ "kMobileHouseArrestMissingIdentifier", "The request was missing an application identifier." },
{ "kMobileHouseArrestPathConversionFailed", "Could not convert the requested application's data container path." },
{ "kMobileHouseArrestPathMissing", "The requested application's data container path does not exist." },
{ "kMobileHouseArrestUnknownCommand", "The request contained an invalid command." },
};
const int error_id_to_message_count = sizeof(error_id_to_message) / sizeof(error_id_to_message_t);

View File

@ -76,8 +76,8 @@ int AMDeviceGetInterfaceType(struct am_device *device);
bool found_device = false, debug = false, verbose = false, unbuffered = false, nostart = false, detect_only = false, install = true, uninstall = false, no_wifi = false;
bool command_only = false;
char *command = NULL;
char *target_filename = NULL;
char *upload_pathname = NULL;
char const*target_filename = NULL;
char const*upload_pathname = NULL;
char *bundle_id = NULL;
bool interactive = true;
bool justlaunch = false;
@ -86,7 +86,7 @@ char *device_id = NULL;
char *args = NULL;
char *list_root = NULL;
int _timeout = 0;
int port = 0; // 0 means "dynamically assigned"
int port = 0; // 0 means "dynamically assigned"
CFStringRef last_path = NULL;
service_conn_t gdbfd;
pid_t parent = 0;
@ -122,8 +122,8 @@ void on_error(NSString* format, ...)
NSString* str = [[[NSString alloc] initWithFormat:format arguments:valist] autorelease];
va_end(valist);
NSLog(@"[ !! ] %@", str);
NSLog(@"[ !! ] %@", str);
exit(exitcode_error);
}
@ -135,7 +135,7 @@ void on_sys_error(NSString* format, ...) {
va_start(valist, format);
NSString* str = [[[NSString alloc] initWithFormat:format arguments:valist] autorelease];
va_end(valist);
on_error(@"%@ : %@", str, [NSString stringWithUTF8String:errstr]);
}
@ -147,25 +147,25 @@ void __NSLogOut(NSString* format, va_list valist) {
void NSLogOut(NSString* format, ...) {
va_list valist;
va_start(valist, format);
__NSLogOut(format, valist);
__NSLogOut(format, valist);
va_end(valist);
}
void NSLogVerbose(NSString* format, ...) {
if (verbose) {
va_list valist;
va_start(valist, format);
__NSLogOut(format, valist);
va_end(valist);
}
if (verbose) {
va_list valist;
va_start(valist, format);
__NSLogOut(format, valist);
va_end(valist);
}
}
BOOL mkdirp(NSString* path) {
NSError* error = nil;
BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:path
withIntermediateDirectories:YES
attributes:nil
BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:path
withIntermediateDirectories:YES
attributes:nil
error:&error];
return success;
}
@ -185,23 +185,14 @@ 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);
}
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);
cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -name '%@' %@ 2>/dev/null | sort | tail -n 1"), rootPath, 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);
cf_command = CFStringCreateWithFormat(NULL, NULL, CFSTR("find %@ -path '%@' %@ 2>/dev/null | sort | tail -n 1"), rootPath, namePattern, expression);
}
char command[1024] = { '\0' };
@ -330,18 +321,38 @@ const CFStringRef get_device_hardware_name(const AMDeviceRef device) {
GET_FRIENDLY_MODEL_NAME(model, "P101AP", "iPad 4")
GET_FRIENDLY_MODEL_NAME(model, "P102AP", "iPad 4 (GSM)")
GET_FRIENDLY_MODEL_NAME(model, "P103AP", "iPad 4 (CDMA)")
GET_FRIENDLY_MODEL_NAME(model, "J71AP", "iPad Air")
GET_FRIENDLY_MODEL_NAME(model, "J72AP", "iPad Air (GSM)")
GET_FRIENDLY_MODEL_NAME(model, "J73AP", "iPad Air (CDMA)")
GET_FRIENDLY_MODEL_NAME(model, "J81AP", "iPad Air 2")
GET_FRIENDLY_MODEL_NAME(model, "J82AP", "iPad Air 2 (GSM)")
GET_FRIENDLY_MODEL_NAME(model, "J83AP", "iPad Air 2 (CDMA)")
// iPad Pro
GET_FRIENDLY_MODEL_NAME(model, "J98aAP", "iPad Pro (12.9\")")
GET_FRIENDLY_MODEL_NAME(model, "J98aAP", "iPad Pro (12.9\")")
GET_FRIENDLY_MODEL_NAME(model, "J127AP", "iPad Pro (9.7\")")
GET_FRIENDLY_MODEL_NAME(model, "J128AP", "iPad Pro (9.7\")")
// iPad Mini
GET_FRIENDLY_MODEL_NAME(model, "P105AP", "iPad mini")
GET_FRIENDLY_MODEL_NAME(model, "P106AP", "iPad mini (GSM)")
GET_FRIENDLY_MODEL_NAME(model, "P107AP", "iPad mini (CDMA)")
GET_FRIENDLY_MODEL_NAME(model, "J85AP", "iPad mini 2")
GET_FRIENDLY_MODEL_NAME(model, "J86AP", "iPad mini 2 (GSM)")
GET_FRIENDLY_MODEL_NAME(model, "J87AP", "iPad mini 2 (CDMA)")
GET_FRIENDLY_MODEL_NAME(model, "J85MAP", "iPad mini 3")
GET_FRIENDLY_MODEL_NAME(model, "J86MAP", "iPad mini 3 (GSM)")
GET_FRIENDLY_MODEL_NAME(model, "J87MAP", "iPad mini 3 (CDMA)")
// Apple TV
GET_FRIENDLY_MODEL_NAME(model, "K66AP", "Apple TV 2G")
GET_FRIENDLY_MODEL_NAME(model, "J33AP", "Apple TV 3G")
GET_FRIENDLY_MODEL_NAME(model, "J33IAP", "Apple TV 3.1G")
GET_FRIENDLY_MODEL_NAME(model, "J42dAP", "Apple TV 4G")
// iPhone
@ -360,11 +371,18 @@ const CFStringRef get_device_hardware_name(const AMDeviceRef device) {
GET_FRIENDLY_MODEL_NAME(model, "N53AP", "iPhone 5s (Global/CDMA)")
GET_FRIENDLY_MODEL_NAME(model, "N61AP", "iPhone 6 (GSM)")
GET_FRIENDLY_MODEL_NAME(model, "N56AP", "iPhone 6 Plus")
GET_FRIENDLY_MODEL_NAME(model, "N71mAP", "iPhone 6s")
GET_FRIENDLY_MODEL_NAME(model, "N71AP", "iPhone 6s")
GET_FRIENDLY_MODEL_NAME(model, "N66AP", "iPhone 6s Plus")
GET_FRIENDLY_MODEL_NAME(model, "N66mAP", "iPhone 6s Plus")
GET_FRIENDLY_MODEL_NAME(model, "N69AP", "iPhone SE")
GET_FRIENDLY_MODEL_NAME(model, "N69uAP", "iPhone SE")
GET_FRIENDLY_MODEL_NAME(model, "N71mAP", "iPhone 6s")
GET_FRIENDLY_MODEL_NAME(model, "N71AP", "iPhone 6s")
GET_FRIENDLY_MODEL_NAME(model, "N66AP", "iPhone 6s Plus")
GET_FRIENDLY_MODEL_NAME(model, "N66mAP", "iPhone 6s Plus")
GET_FRIENDLY_MODEL_NAME(model, "D10AP", "iPhone 7")
GET_FRIENDLY_MODEL_NAME(model, "D101AP", "iPhone 7")
GET_FRIENDLY_MODEL_NAME(model, "D11AP", "iPhone 7 Plus")
GET_FRIENDLY_MODEL_NAME(model, "D111AP", "iPhone 7 Plus")
return model;
}
@ -397,8 +415,8 @@ CFStringRef get_device_full_name(const AMDeviceRef device) {
device_name = AMDeviceCopyValue(device, 0, CFSTR("DeviceName")),
model_name = get_device_hardware_name(device);
NSLogVerbose(@"Device Name: %@", device_name);
NSLogVerbose(@"Model Name: %@", model_name);
NSLogVerbose(@"Device Name: %@", device_name);
NSLogVerbose(@"Model Name: %@", model_name);
if(device_name != NULL && model_name != NULL)
{
@ -445,25 +463,39 @@ CFMutableArrayRef get_device_product_version_parts(AMDeviceRef device) {
CFStringRef copy_device_support_path(AMDeviceRef device) {
CFStringRef version = NULL;
CFStringRef build = AMDeviceCopyValue(device, 0, CFSTR("BuildVersion"));
CFStringRef deviceClass = AMDeviceCopyValue(device, 0, CFSTR("DeviceClass"));
CFStringRef path = NULL;
CFMutableArrayRef version_parts = get_device_product_version_parts(device);
NSLogVerbose(@"Device Class: %@", deviceClass);
NSLogVerbose(@"build: %@", build);
CFStringRef deviceClassPath_platform;
CFStringRef deviceClassPath_alt;
if (CFStringCompare(CFSTR("AppleTV"), deviceClass, 0) == kCFCompareEqualTo) {
deviceClassPath_platform = CFSTR("Platforms/AppleTVOS.platform/DeviceSupport");
deviceClassPath_alt = CFSTR("tvOS\\ DeviceSupport");
} else {
deviceClassPath_platform = CFSTR("Platforms/iPhoneOS.platform/DeviceSupport");
deviceClassPath_alt = CFSTR("iOS\\ DeviceSupport");
}
while (CFArrayGetCount(version_parts) > 0) {
version = CFStringCreateByCombiningStrings(NULL, version_parts, CFSTR("."));
NSLogVerbose(@"version: %@", version);
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("iOS DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)"), version, build));
path = copy_xcode_path_for(deviceClassPath_alt, CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\\ \\(%@\\)"), version, build));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)"), version, build));
path = copy_xcode_path_for(deviceClassPath_platform, CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\\ \\(%@\\)"), version, build));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (*)"), version));
path = copy_xcode_path_for(deviceClassPath_platform, CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\\ \\(*\\)"), version));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport"), version);
path = copy_xcode_path_for(deviceClassPath_platform, version);
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport/Latest"), CFSTR(""));
path = copy_xcode_path_for(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), deviceClassPath_platform, CFSTR("/Latest")), CFSTR(""));
}
CFRelease(version);
if (path != NULL) {
@ -474,7 +506,7 @@ CFStringRef copy_device_support_path(AMDeviceRef device) {
CFRelease(version_parts);
CFRelease(build);
CFRelease(deviceClass);
if (path == NULL)
on_error(@"Unable to locate DeviceSupport directory. This probably means you don't have Xcode installed, you will need to launch the app manually and logging output will not be shown!");
@ -484,25 +516,40 @@ CFStringRef copy_device_support_path(AMDeviceRef device) {
CFStringRef copy_developer_disk_image_path(AMDeviceRef device) {
CFStringRef version = NULL;
CFStringRef build = AMDeviceCopyValue(device, 0, CFSTR("BuildVersion"));
CFStringRef deviceClass = AMDeviceCopyValue(device, 0, CFSTR("DeviceClass"));
CFStringRef path = NULL;
CFMutableArrayRef version_parts = get_device_product_version_parts(device);
NSLogVerbose(@"Device Class: %@", deviceClass);
NSLogVerbose(@"build: %@", build);
CFStringRef deviceClassPath_platform;
CFStringRef deviceClassPath_alt;
if (CFStringCompare(CFSTR("AppleTV"), deviceClass, 0) == kCFCompareEqualTo) {
deviceClassPath_platform = CFSTR("Platforms/AppleTVOS.platform/DeviceSupport");
deviceClassPath_alt = CFSTR("tvOS\\ DeviceSupport");
} else {
deviceClassPath_platform = CFSTR("Platforms/iPhoneOS.platform/DeviceSupport");
deviceClassPath_alt = CFSTR("iOS\\ DeviceSupport");
}
// path = getPathForTVOS(device);
while (CFArrayGetCount(version_parts) > 0) {
version = CFStringCreateByCombiningStrings(NULL, version_parts, CFSTR("."));
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("iOS DeviceSupport"), CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ (%@)/DeveloperDiskImage.dmg"), version, build));
NSLogVerbose(@"version: %@", version);
if (path == NULL) {
path = copy_xcode_path_for(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@\\ \\(%@\\)"), deviceClassPath_alt, version, build), CFSTR("DeveloperDiskImage.dmg"));
}
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));
path = copy_xcode_path_for(deviceClassPath_platform, 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));
path = copy_xcode_path_for(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@\\ \\(*\\)"), deviceClassPath_platform, version), CFSTR("DeveloperDiskImage.dmg"));
}
if (path == NULL) {
path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/DeviceSupport/Latest"), CFSTR("DeveloperDiskImage.dmg"));
path = copy_xcode_path_for(deviceClassPath_platform, CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/DeveloperDiskImage.dmg"), version));
}
if (path == NULL) {
path = copy_xcode_path_for(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/Latest"), deviceClassPath_platform), CFSTR("/DeveloperDiskImage.dmg"));
}
CFRelease(version);
if (path != NULL) {
@ -513,6 +560,7 @@ CFStringRef copy_developer_disk_image_path(AMDeviceRef device) {
CFRelease(version_parts);
CFRelease(build);
CFRelease(deviceClass);
if (path == NULL)
on_error(@"Unable to locate DeveloperDiskImage.dmg. This probably means you don't have Xcode installed, you will need to launch the app manually and logging output will not be shown!");
@ -536,9 +584,9 @@ void mount_developer_image(AMDeviceRef device) {
CFStringRef image_path = copy_developer_disk_image_path(device);
CFStringRef sig_path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.signature"), image_path);
NSLogVerbose(@"Device support path: %@", ds_path);
NSLogVerbose(@"Developer disk image: %@", image_path);
CFRelease(ds_path);
NSLogVerbose(@"Device support path: %@", ds_path);
NSLogVerbose(@"Developer disk image: %@", image_path);
CFRelease(ds_path);
FILE* sig = fopen(CFStringGetCStringPtr(sig_path, kCFStringEncodingMacRoman), "rb");
void *sig_buf = malloc(128);
@ -599,7 +647,7 @@ CFURLRef copy_device_app_url(AMDeviceRef device, CFStringRef identifier) {
CFDictionaryRef result = nil;
NSArray *a = [NSArray arrayWithObjects:
@"CFBundleIdentifier", // absolute must
@"CFBundleIdentifier", // absolute must
@"ApplicationDSID",
@"ApplicationType",
@"CFBundleExecutable",
@ -624,7 +672,7 @@ CFURLRef copy_device_app_url(AMDeviceRef device, CFStringRef identifier) {
nil];
NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:a forKey:@"ReturnAttributes"];
CFDictionaryRef options = (CFDictionaryRef)optionsDict;
CFDictionaryRef options = (CFDictionaryRef)optionsDict;
check_error(AMDeviceLookupApplications(device, options, &result));
@ -643,9 +691,9 @@ CFStringRef copy_disk_app_identifier(CFURLRef disk_app_url) {
CFURLRef plist_url = CFURLCreateCopyAppendingPathComponent(NULL, disk_app_url, CFSTR("Info.plist"), false);
CFReadStreamRef plist_stream = CFReadStreamCreateWithFile(NULL, plist_url);
if (!CFReadStreamOpen(plist_stream)) {
on_error(@"Cannot read Info.plist file: %@", plist_url);
on_error(@"Cannot read Info.plist file: %@", plist_url);
}
CFPropertyListRef plist = CFPropertyListCreateWithStream(NULL, plist_stream, 0, kCFPropertyListImmutable, NULL, NULL);
CFStringRef bundle_identifier = CFRetain(CFDictionaryGetValue(plist, CFSTR("CFBundleIdentifier")));
CFReadStreamClose(plist_stream);
@ -722,14 +770,14 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
CFStringFindAndReplace(cmds, CFSTR("{disk_container}"), disk_container_path, range, 0);
NSString* python_file_path = [NSString stringWithFormat:@"/tmp/%@/fruitstrap_", tmpUUID];
mkdirp(python_file_path);
mkdirp(python_file_path);
NSString* python_command = @"fruitstrap_";
if(device_id != NULL) {
python_file_path = [python_file_path stringByAppendingString:[NSString stringWithUTF8String:device_id]];
python_command = [python_command stringByAppendingString:[NSString stringWithUTF8String:device_id]];
python_file_path = [python_file_path stringByAppendingString:[NSString stringWithUTF8String:device_id]];
python_command = [python_command stringByAppendingString:[NSString stringWithUTF8String:device_id]];
}
python_file_path = [python_file_path stringByAppendingString:@".py"];
python_file_path = [python_file_path stringByAppendingString:@".py"];
CFStringFindAndReplace(cmds, CFSTR("{python_command}"), (CFStringRef)python_command, range, 0);
range.length = CFStringGetLength(cmds);
@ -740,7 +788,7 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) {
NSString* prep_cmds_path = [NSString stringWithFormat:PREP_CMDS_PATH, tmpUUID];
if(device_id != NULL) {
prep_cmds_path = [prep_cmds_path stringByAppendingString:[NSString stringWithUTF8String:device_id]];
}
}
FILE *out = fopen([prep_cmds_path UTF8String], "w");
fwrite(CFDataGetBytePtr(cmds_data), CFDataGetLength(cmds_data), 1, out);
// Write additional commands based on mode we're running in
@ -993,12 +1041,12 @@ void launch_debugger(AMDeviceRef device, CFURLRef url) {
setup_dummy_pipe_on_stdin(pfd);
NSString* lldb_shell;
NSString* prep_cmds = [NSString stringWithFormat:PREP_CMDS_PATH, tmpUUID];
lldb_shell = [NSString stringWithFormat:LLDB_SHELL, prep_cmds];
NSString* prep_cmds = [NSString stringWithFormat:PREP_CMDS_PATH, tmpUUID];
lldb_shell = [NSString stringWithFormat:LLDB_SHELL, prep_cmds];
if(device_id != NULL) {
lldb_shell = [lldb_shell stringByAppendingString: [NSString stringWithUTF8String:device_id]];
}
lldb_shell = [lldb_shell stringByAppendingString: [NSString stringWithUTF8String:device_id]];
}
int status = system([lldb_shell UTF8String]); // launch lldb
if (status == -1)
@ -1034,10 +1082,10 @@ void launch_debugger_and_exit(AMDeviceRef device, CFURLRef url) {
NSString* prep_cmds = [NSString stringWithFormat:PREP_CMDS_PATH, tmpUUID];
NSString* lldb_shell = [NSString stringWithFormat:LLDB_SHELL, prep_cmds];
NSString* lldb_shell = [NSString stringWithFormat:LLDB_SHELL, prep_cmds];
if(device_id != NULL) {
lldb_shell = [lldb_shell stringByAppendingString:[NSString stringWithUTF8String:device_id]];
}
lldb_shell = [lldb_shell stringByAppendingString:[NSString stringWithUTF8String:device_id]];
}
int status = system([lldb_shell UTF8String]); // launch lldb
if (status == -1)
@ -1122,15 +1170,15 @@ void read_dir(service_conn_t afcFd, afc_connection* afc_conn_p, const char* dir,
}
}
AFCKeyValueClose(afc_dict_p);
if (not_dir) {
NSLogOut(@"%@", [NSString stringWithUTF8String:dir]);
} else {
NSLogOut(@"%@/", [NSString stringWithUTF8String:dir]);
}
if (not_dir) {
if (callback) (*callback)(afc_conn_p, dir, not_dir);
NSLogOut(@"%@", [NSString stringWithUTF8String:dir]);
} else {
NSLogOut(@"%@/", [NSString stringWithUTF8String:dir]);
}
if (not_dir) {
if (callback) (*callback)(afc_conn_p, dir, not_dir);
return;
}
@ -1192,9 +1240,9 @@ service_conn_t start_house_arrest_service(AMDeviceRef device) {
return houseFd;
}
char* get_filename_from_path(char* path)
char const* get_filename_from_path(char const* path)
{
char *ptr = path + strlen(path);
char const*ptr = path + strlen(path);
while (ptr > path)
{
if (*ptr == '/')
@ -1208,7 +1256,7 @@ char* get_filename_from_path(char* path)
return ptr+1;
}
void* read_file_to_memory(char * path, size_t* file_size)
void* read_file_to_memory(char const * path, size_t* file_size)
{
struct stat buf;
int err = stat(path, &buf);
@ -1266,7 +1314,7 @@ int app_exists(AMDeviceRef device)
check_error(AMDeviceStopSession(device));
check_error(AMDeviceDisconnect(device));
if (appExists)
return 0;
return 0;
return -1;
}
@ -1276,13 +1324,13 @@ void list_bundle_id(AMDeviceRef device)
assert(AMDeviceIsPaired(device));
check_error(AMDeviceValidatePairing(device));
check_error(AMDeviceStartSession(device));
NSArray *a = [NSArray arrayWithObjects:@"CFBundleIdentifier", nil];
NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:a forKey:@"ReturnAttributes"];
CFDictionaryRef options = (CFDictionaryRef)optionsDict;
CFDictionaryRef result = nil;
check_error(AMDeviceLookupApplications(device, options, &result));
CFIndex count;
count = CFDictionaryGetCount(result);
const void *keys[count];
@ -1290,7 +1338,7 @@ void list_bundle_id(AMDeviceRef device)
for(int i = 0; i < count; ++i) {
NSLogOut(@"%@", (CFStringRef)keys[i]);
}
check_error(AMDeviceStopSession(device));
check_error(AMDeviceDisconnect(device));
}
@ -1304,35 +1352,35 @@ void copy_file_callback(afc_connection* afc_conn_p, const char *name,int file)
if (*local_name=='\0') return;
if (file) {
afc_file_ref fref;
int err = AFCFileRefOpen(afc_conn_p,name,1,&fref);
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;
}
if (err) {
fprintf(stderr,"AFCFileRefOpen(\"%s\") failed: %d\n",name,err);
return;
}
FILE *fp = fopen(local_name,"w");
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;
}
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);
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);
}
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);
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));
if (mkdir(local_name,0777) && errno!=EEXIST)
fprintf(stderr,"mkdir(\"%s\") failed: %s\n",local_name,strerror(errno));
}
}
@ -1341,29 +1389,29 @@ void download_tree(AMDeviceRef device)
service_conn_t houseFd = start_house_arrest_service(device);
afc_connection* afc_conn_p = NULL;
char *dirname = NULL;
list_root = list_root? list_root : "/";
target_filename = target_filename? target_filename : ".";
list_root = list_root? list_root : "/";
target_filename = target_filename? target_filename : ".";
NSString* targetPath = [NSString pathWithComponents:@[ @(target_filename), @(list_root)] ];
mkdirp([targetPath stringByDeletingLastPathComponent]);
if (AFCConnectionOpen(houseFd, 0, &afc_conn_p) == 0) do {
if (target_filename) {
dirname = strdup(target_filename);
mkdirp(@(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;
}
}
if (target_filename) {
dirname = strdup(target_filename);
mkdirp(@(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, copy_file_callback);
read_dir(houseFd, afc_conn_p, list_root, copy_file_callback);
} while(0);
@ -1371,10 +1419,12 @@ void download_tree(AMDeviceRef device)
if (afc_conn_p) AFCConnectionClose(afc_conn_p);
}
void upload_file(AMDeviceRef device) {
service_conn_t houseFd = start_house_arrest_service(device);
void upload_dir(AMDeviceRef device, afc_connection* afc_conn_p, NSString* source, NSString* destination);
void upload_single_file(AMDeviceRef device, afc_connection* afc_conn_p, NSString* sourcePath, NSString* destinationPath);
afc_file_ref file_ref;
void upload_file(AMDeviceRef device)
{
service_conn_t houseFd = start_house_arrest_service(device);
afc_connection afc_conn;
afc_connection* afc_conn_p = &afc_conn;
@ -1387,44 +1437,82 @@ void upload_file(AMDeviceRef device) {
target_filename = get_filename_from_path(upload_pathname);
}
NSString* sourcePath = [NSString stringWithUTF8String: upload_pathname];
NSString* destinationPath = [NSString stringWithUTF8String: target_filename];
BOOL isDir;
bool exists = [[NSFileManager defaultManager] fileExistsAtPath: sourcePath isDirectory: &isDir];
if (!exists)
{
on_error(@"Could not find file: %s", upload_pathname);
}
else if (isDir)
{
upload_dir(device, afc_conn_p, sourcePath, destinationPath);
}
else
{
upload_single_file(device, afc_conn_p, sourcePath, destinationPath);
}
assert(AFCConnectionClose(afc_conn_p) == 0);
}
void upload_single_file(AMDeviceRef device, afc_connection* afc_conn_p, NSString* sourcePath, NSString* destinationPath) {
afc_file_ref file_ref;
// read_dir(houseFd, NULL, "/", NULL);
size_t file_size;
void* file_content = read_file_to_memory(upload_pathname, &file_size);
void* file_content = read_file_to_memory([sourcePath fileSystemRepresentation], &file_size);
if (!file_content)
{
on_error(@"Could not open file: %@", [NSString stringWithUTF8String:upload_pathname]);
on_error(@"Could not open file: %@", sourcePath);
}
// Make sure the directory was created
{
char *dirpath = strdup(target_filename);
char *c = dirpath, *lastSlash = dirpath;
while(*c) {
if(*c == '/') {
lastSlash = c;
}
c++;
}
*lastSlash = '\0';
check_error(AFCDirectoryCreate(afc_conn_p, dirpath));
NSString *dirpath = [destinationPath stringByDeletingLastPathComponent];
check_error(AFCDirectoryCreate(afc_conn_p, [dirpath fileSystemRepresentation]));
}
int ret = AFCFileRefOpen(afc_conn_p, target_filename, 3, &file_ref);
int ret = AFCFileRefOpen(afc_conn_p, [destinationPath fileSystemRepresentation], 3, &file_ref);
if (ret == 0x000a) {
on_error(@"Cannot write to %@. Permission error.", [NSString stringWithUTF8String:target_filename]);
on_error(@"Cannot write to %@. Permission error.", destinationPath);
}
if (ret == 0x0009) {
on_error(@"Target %@ is a directory.", [NSString stringWithUTF8String:target_filename]);
on_error(@"Target %@ is a directory.", destinationPath);
}
assert(ret == 0);
assert(AFCFileRefWrite(afc_conn_p, file_ref, file_content, file_size) == 0);
assert(AFCFileRefClose(afc_conn_p, file_ref) == 0);
assert(AFCConnectionClose(afc_conn_p) == 0);
free(file_content);
}
void upload_dir(AMDeviceRef device, afc_connection* afc_conn_p, NSString* source, NSString* destination)
{
check_error(AFCDirectoryCreate(afc_conn_p, [destination fileSystemRepresentation]));
destination = [destination copy];
for (NSString* item in [[NSFileManager defaultManager] contentsOfDirectoryAtPath: source error: nil])
{
NSString* sourcePath = [source stringByAppendingPathComponent: item];
NSString* destinationPath = [destination stringByAppendingPathComponent: item];
BOOL isDir;
[[NSFileManager defaultManager] fileExistsAtPath: sourcePath isDirectory: &isDir];
if (isDir)
{
upload_dir(device, afc_conn_p, sourcePath, destinationPath);
}
else
{
upload_single_file(device, afc_conn_p, sourcePath, destinationPath);
}
}
}
void make_directory(AMDeviceRef device) {
service_conn_t houseFd = start_house_arrest_service(device);
@ -1482,12 +1570,12 @@ void uninstall_app(AMDeviceRef device) {
}
void handle_device(AMDeviceRef device) {
NSLogVerbose(@"Already found device? %d", found_device);
NSLogVerbose(@"Already found device? %d", found_device);
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) {
NSLogOut(@"[....] Found %@ connected through %@.", device_full_name, device_interface_name);
found_device = true;
@ -1515,7 +1603,7 @@ void handle_device(AMDeviceRef device) {
} else if (strcmp("upload", command) == 0) {
upload_file(device);
} else if (strcmp("download", command) == 0) {
download_tree(device);
download_tree(device);
} else if (strcmp("mkdir", command) == 0) {
make_directory(device);
} else if (strcmp("rm", command) == 0) {
@ -1636,17 +1724,17 @@ void device_callback(struct am_device_notification_callback_info *info, void *ar
switch (info->msg) {
case ADNCI_MSG_CONNECTED:
if(device_id != NULL || !debug || AMDeviceGetInterfaceType(info->dev) != 2) {
if (no_wifi && AMDeviceGetInterfaceType(info->dev) == 2)
{
NSLogVerbose(@"Skipping wifi device (type: %d)", AMDeviceGetInterfaceType(info->dev));
}
else
{
NSLogVerbose(@"Handling device type: %d", AMDeviceGetInterfaceType(info->dev));
handle_device(info->dev);
}
if (no_wifi && AMDeviceGetInterfaceType(info->dev) == 2)
{
NSLogVerbose(@"Skipping wifi device (type: %d)", AMDeviceGetInterfaceType(info->dev));
}
else
{
NSLogVerbose(@"Handling device type: %d", AMDeviceGetInterfaceType(info->dev));
handle_device(info->dev);
}
} else if(best_device_match == NULL) {
NSLogVerbose(@"Best device match: %d", AMDeviceGetInterfaceType(info->dev));
NSLogVerbose(@"Best device match: %d", AMDeviceGetInterfaceType(info->dev));
best_device_match = info->dev;
CFRetain(best_device_match);
}
@ -1656,9 +1744,11 @@ void device_callback(struct am_device_notification_callback_info *info, void *ar
}
void timeout_callback(CFRunLoopTimerRef timer, void *info) {
if ((!found_device) && (!detect_only)) {
if (found_device && (!detect_only)) {
return;
} else if ((!found_device) && (!detect_only)) {
if(best_device_match != NULL) {
NSLogVerbose(@"Handling best device match.");
NSLogVerbose(@"Handling best device match.");
handle_device(best_device_match);
CFRelease(best_device_match);
@ -1681,8 +1771,8 @@ void timeout_callback(CFRunLoopTimerRef timer, void *info) {
int mypid = getpid();
if ((parent != 0) && (parent == mypid) && (child != 0))
{
NSLogVerbose(@"Timeout. Killing child (%d) tree.", child);
kill_ptree(child, SIGHUP);
NSLogVerbose(@"Timeout. Killing child (%d) tree.", child);
kill_ptree(child, SIGHUP);
}
}
exit(0);
@ -1729,12 +1819,12 @@ void show_version() {
int main(int argc, char *argv[]) {
// create a UUID for tmp purposes
// create a UUID for tmp purposes
CFUUIDRef uuid = CFUUIDCreate(NULL);
CFStringRef str = CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
tmpUUID = [(NSString*)str autorelease];
static struct option longopts[] = {
{ "debug", no_argument, NULL, 'd' },
{ "id", required_argument, NULL, 'i' },

View File

@ -1,86 +0,0 @@
"# AUTO-GENERATED - DO NOT MODIFY\n"
"import lldb\n"
"import os\n"
"import sys\n"
"import shlex\n"
"\n"
"def connect_command(debugger, command, result, internal_dict):\n"
" # These two are passed in by the script which loads us\n"
" connect_url = internal_dict['fruitstrap_connect_url']\n"
" error = lldb.SBError()\n"
"\n"
" process = lldb.target.ConnectRemote(lldb.target.GetDebugger().GetListener(), connect_url, None, error)\n"
"\n"
" # Wait for connection to succeed\n"
" listener = lldb.target.GetDebugger().GetListener()\n"
" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n"
" events = []\n"
" state = (process.GetState() or lldb.eStateInvalid)\n"
" while state != lldb.eStateConnected:\n"
" event = lldb.SBEvent()\n"
" if listener.WaitForEvent(1, event):\n"
" state = process.GetStateFromEvent(event)\n"
" events.append(event)\n"
" else:\n"
" state = lldb.eStateInvalid\n"
"\n"
" # Add events back to queue, otherwise lldb freezes\n"
" for event in events:\n"
" listener.AddEvent(event)\n"
"\n"
"def run_command(debugger, command, result, internal_dict):\n"
" device_app = internal_dict['fruitstrap_device_app']\n"
" args = command.split('--',1)\n"
" error = lldb.SBError()\n"
" lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n"
" lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)\n"
" lockedstr = ': Locked'\n"
" if lockedstr in str(error):\n"
" print('\\nDevice Locked\\n')\n"
" os._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) and lldb.SBProcess.EventIsProcessEvent(event):\n"
" state = lldb.SBProcess.GetStateFromEvent(event)\n"
" else:\n"
" state = process.GetState()\n"
"\n"
" if state == lldb.eStateRunning:\n"
" process.Detach()\n"
" os._exit(0)\n"
" elif state > lldb.eStateRunning:\n"
" os._exit(state)\n"
"\n"
"def autoexit_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) and lldb.SBProcess.EventIsProcessEvent(event):\n"
" state = lldb.SBProcess.GetStateFromEvent(event)\n"
" else:\n"
" state = process.GetState()\n"
"\n"
" if state == lldb.eStateExited:\n"
" os._exit(process.GetExitStatus())\n"
" elif state == lldb.eStateStopped:\n"
" debugger.HandleCommand('bt')\n"
" os._exit({exitcode_app_crash})\n"
"\n"
" stdout = process.GetSTDOUT(1024)\n"
" while stdout:\n"
" sys.stdout.write(stdout)\n"
" stdout = process.GetSTDOUT(1024)\n"
"\n"
" stderr = process.GetSTDERR(1024)\n"
" while stderr:\n"
" sys.stdout.write(stderr)\n"
" stderr = process.GetSTDERR(1024)\n"

View File

@ -1 +1 @@
"1.8.4"
"2.0.0"

View File

@ -36,6 +36,17 @@ xcode_version.on('close', function (code) {
if (ver < XCODEBUILD_MIN_VERSION) {
console.log(util.format('%s : %s. (you have version %s)', TOOL, XCODEBUILD_NOT_FOUND_MESSAGE, ver));
}
if (os.release() >= '15.0.0') { // print the El Capitan warning
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
console.log('!!!! WARNING: You are on OS X 10.11 El Capitan, you may need to add the');
console.log('!!!! WARNING: `--unsafe-perm=true` flag when running `npm install`');
console.log('!!!! WARNING: or else it will fail.');
console.log('!!!! WARNING: link:');
console.log('!!!! WARNING: https://github.com/phonegap/ios-deploy#os-x-1011-el-capitan');
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
}
}
process.exit(code);
});

View File

@ -32,7 +32,12 @@ def run_command(debugger, command, result, internal_dict):
args = command.split('--',1)
error = lldb.SBError()
lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))
lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)
args_arr = []
if len(args) > 1:
args_arr = shlex.split(args[1])
else:
args_arr = shlex.split('{args}')
lldb.target.Launch(lldb.SBLaunchInfo(args_arr), error)
lockedstr = ': Locked'
if lockedstr in str(error):
print('\\nDevice Locked\\n')
@ -42,20 +47,15 @@ def run_command(debugger, command, result, internal_dict):
def safequit_command(debugger, command, result, internal_dict):
process = lldb.target.process
listener = debugger.GetListener()
listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)
event = lldb.SBEvent()
while True:
if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):
state = lldb.SBProcess.GetStateFromEvent(event)
else:
state = process.GetState()
if state == lldb.eStateRunning:
process.Detach()
os._exit(0)
elif state > lldb.eStateRunning:
os._exit(state)
state = process.GetState()
if state == lldb.eStateRunning:
process.Detach()
os._exit(0)
elif state > lldb.eStateRunning:
os._exit(state)
else:
print('\\nApplication has not been launched\\n')
os._exit(1)
def autoexit_command(debugger, command, result, internal_dict):
process = lldb.target.process