diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a5c1620..c9f28d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ on: jobs: build-docs: runs-on: ubuntu-latest - steps: + steps: - name: Checkout uses: actions/checkout@v3 @@ -39,6 +39,10 @@ jobs: mkdir ready cp docs/*.html docs/mandoc.css docs/palera1n.1 ready + - name: Get branch name + id: branch-name + uses: tj-actions/branch-names@v7 + - name: Upload artifact if: ${{ github.event_name != 'pull_request' }} uses: wangyucode/sftp-upload-action@v1.4.8 @@ -50,7 +54,7 @@ jobs: forceUpload: true dryRun: false localDir: 'ready/' - remoteDir: '/palera1n/artifacts/c-rewrite' + remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref_name }}/${{ github.run_number }}" build-darwin: strategy: @@ -70,7 +74,7 @@ jobs: minos: 7.0 runs-on: macos-12 env: - MBEDTLS_VERSION: 3.3.0 + MBEDTLS_VERSION: 3.4.0 READLINE_VERSION: 8.2 SLANG_VERSION: 2.3.3 NEWT_VERSION: 0.52.23 @@ -325,6 +329,10 @@ jobs: mkdir -p ready tar -zcf ready/dep_root-${{ matrix.os }}-${{ matrix.arch }}.tgz dep_root + - name: Get branch name + id: branch-name + uses: tj-actions/branch-names@v7 + - name: Upload artifact if: ${{ github.event_name != 'pull_request' }} uses: wangyucode/sftp-upload-action@v1.4.8 @@ -336,7 +344,7 @@ jobs: forceUpload: true dryRun: false localDir: 'ready/' - remoteDir: '/palera1n/artifacts/c-rewrite' + remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref }}/${{ github.run_number }}" - name: Upload ${{ matrix.os }} thin ${{ matrix.arch }} build if: ${{ github.event_name != 'pull_request' }} @@ -353,7 +361,7 @@ jobs: name: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM path: palera1n-${{ matrix.os }}-${{ matrix.arch }}.dSYM retention-days: 1 - + darwin-dist: if: ${{ github.event_name != 'pull_request' }} runs-on: macos-latest @@ -461,6 +469,19 @@ jobs: dpkg-deb -Zzstd -b stage palera1n_iphoneos-arm64.deb mv palera1n*.deb ready/ rm -rf stage + + - name: Save build tag + run: echo "$(git describe --dirty --tags --abbrev=7 | sed 's|-dirty||')" > build-tag.txt + + - name: Upload build tag + uses: actions/upload-artifact@v3 + with: + name: build-tag + path: build-tag.txt + + - name: Get branch name + id: branch-name + uses: tj-actions/branch-names@v7 - name: Upload artifact if: ${{ github.event_name != 'pull_request' }} @@ -473,7 +494,7 @@ jobs: forceUpload: true dryRun: false localDir: 'ready/' - remoteDir: '/palera1n/artifacts/c-rewrite' + remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref }}/${{ github.run_number }}" build-Linux: strategy: @@ -485,7 +506,7 @@ jobs: - aarch64-linux-musl runs-on: ubuntu-latest env: - MBEDTLS_VERSION: 3.3.0 + MBEDTLS_VERSION: 3.4.0 LIBUSB_VERSION: 1.0.26 READLINE_VERSION: 8.2 SLANG_VERSION: 2.3.3 @@ -771,6 +792,10 @@ jobs: mv palera1n*.deb ready/ rm -rf stage + - name: Get branch name + id: branch-name + uses: tj-actions/branch-names@v7 + - name: Upload artifact if: ${{ github.event_name != 'pull_request' }} uses: wangyucode/sftp-upload-action@v1.4.8 @@ -782,4 +807,27 @@ jobs: forceUpload: true dryRun: false localDir: 'ready/' - remoteDir: '/palera1n/artifacts/c-rewrite' + remoteDir: "/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch || github.ref }}/${{ github.run_number }}" + + finish-build: + runs-on: ubuntu-latest + if: ${{ github.event_name != 'pull_request' }} + needs: [build-docs, build-darwin, darwin-dist, build-Linux] + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Get branch name + id: branch-name + uses: tj-actions/branch-names@v7 + + - name: Download build tag + uses: actions/download-artifact@v3 + with: + name: build-tag + + - name: Send Discord build message + run: | + COMMITMESSAGE=`git log --pretty=format:'- \`%h\` %s' -1 --reverse` && + (curl "${{ secrets.DISCORD_WEBHOOK }}" -sS -H "Content-Type:application/json" -X POST -d "{\"content\":null,\"embeds\":[{\"title\":\"[palera1n:${{ steps.branch-name.outputs.ref_branch }}] Nightly Build ${{ github.run_number }}\",\"url\":\"https://github.com/palera1n/palera1n/actions/runs/${GITHUB_RUN_ID}\",\"color\":2829617,\"fields\":[{\"name\":\"Build tag\",\"value\":\"- \`$(cat build-tag.txt | sed 's|\n||')\`\"},{\"name\":\"Destination\",\"value\":\"- https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}\"},{\"name\":\"Documentation\",\"value\":\"- [palera1n.1.html](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n.1.html)\"},{\"name\":\"Main Artifacts\",\"value\":\"- [palera1n-ios](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-ios)\n- [palera1n-linux-arm64](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-linux-arm64)\n- [palera1n-linux-armel](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-linux-armel)\n- [palera1n-linux-x86](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/$${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-linux-x86)\n- [palera1n-linux-x86_64](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-linux-x86_64)\n- [palera1n-macos-universal](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/${{ steps.branch-name.outputs.ref_branch }}/${{ github.run_number }}/palera1n-macos-universal)\"}],\"footer\":{\"text\":\"${{ github.actor }}\", \"icon_url\": \"https://github.com/${{ github.actor }}.png\",\"timestamp\":\"$(date -u +"%FT%TZ")\"}}],\"username\":\"GitHub Actions\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png\"}") + diff --git a/Makefile b/Makefile index 1606004..838c98c 100644 --- a/Makefile +++ b/Makefile @@ -5,12 +5,12 @@ DEP = $(SRC)/dep_root STRIP = strip CC ?= cc CXX ?= c++ -CFLAGS += -I$(DEP)/include -I$(SRC)/include -I$(SRC) -CFLAGS += -Wall -Wextra -DPALERAIN_VERSION=\"2.0.0\" -Wall -Wextra -Wno-unused-parameter +CFLAGS += -I$(DEP)/include -I$(SRC)/include -I$(SRC) -D_XOPEN_SOURCE=500 +CFLAGS += -Wall -Wextra -Wno-unused-parameter -DPALERAIN_VERSION=\"2.0.0\" CFLAGS += -Wno-unused-variable -I$(SRC)/src -std=c99 -pedantic-errors -D_C99_SOURCE -D_POSIX_C_SOURCE=200112L CXXFLAGS += -I$(DEP)/include -I$(SRC)/include -I$(SRC) -std=c++11 LIBS += $(DEP)/lib/libimobiledevice-1.0.a $(DEP)/lib/libirecovery-1.0.a $(DEP)/lib/libusbmuxd-2.0.a -LIBS += $(DEP)/lib/libimobiledevice-glue-1.0.a $(DEP)/lib/libplist-2.0.a -pthread +LIBS += $(DEP)/lib/libimobiledevice-glue-1.0.a $(DEP)/lib/libplist-2.0.a -pthread -lm ifeq ($(TARGET_OS),) TARGET_OS = $(shell uname -s) endif diff --git a/README.md b/README.md index 63b5f50..93518ac 100644 --- a/README.md +++ b/README.md @@ -2,36 +2,20 @@ palera1n logo -

An iOS 15.0-16.4 work-in-progress,
semi-tethered checkm8 jailbreak

-

- Usage - • - Contributors - • - Discord - • - Twitter -

-
+
-## If you want a jailbreak, you should read the [guide](https://palera.in). - -### You can obtain v2.0.0 beta [here](https://github.com/palera1n/palera1n/releases). -If you need an older v2.0.0 beta, please get it [here](https://github.com/palera1n/palera1n-c/releases/tag/v2.0.0-beta.4). - -# Warnings -- This palera1n rewrite has noticeably different arguments compared to the shell version of palera1n. - - Highly recommended that you take a look at how to use palera1n-c [here](https://cdn.nickchan.lol/palera1n/c-rewrite/releases/v2.0.0-beta.1/palera1n.1.html). - -- This does **NOT** support tethered creation or booting. You must use the older [shell version of palera1n](https://github.com/palera1n/palera1n/tree/legacy) (clone with `-b legacy`). +## Information +- Guides to palera1n can be found [here](https://ios.cfw.guide/installing-palera1n). +- Full documentation can be also found [here](https://cdn.nickchan.lol/palera1n/artifacts/c-rewrite/palera1n.1.html). +## Warnings - We are **NOT** responsible for any data loss, or the result of a device being bricked. The user of this program accepts responsibility should something happen to their device. While nothing should happen, jailbreaking has risks in itself. - If your device is stuck in recovery, please run futurerestore `--exit-recovery`, or use `irecovery -n`. - palera1n will never work in VirtualBox, VMware or any virtual machine that doesn't support PCI passthrough. -# Requirements +## Requirements - A checkm8 vulnerable iOS device on iOS 15.x or 16.x (`A8` - `A11`) - If using rootful, you will need **5-10GB of space** for the fakefs. This means 16GB devices cannot use the full fakefs creation. However, you can change the arguments to `-Bf` to create a fakefs with bind mounts, so it uses a smaller size, at the expense having unwritable parts in rarely-written paths, and then boot it - On `A11`, **you must disable your passcode while in the jailbroken state** (on iOS 16, you need to **reset your device** before proceeding with palera1n). @@ -41,8 +25,12 @@ If you need an older v2.0.0 beta, please get it [here](https://github.com/palera - A Linux or macOS computer - AMD CPUs (not AMD Mobile) have an issue [with (likely) their USB controllers] that causes them to have a very low success rate with checkm8. It is not recommended that you use them with palera1n. - If your device does not successfully jailbreak, try a computer with an Intel or other CPU + +- Apple Silicon Macs with USB-C + - USB-C port on Apple Silicon Macs may require manual unplugging and replugging of the lightning cable after checkm8 exploit. + - This problem may be solved by connecting via USBHub. -# Need help? +## Need help? Make sure you provide full details on your device, such as: - iDevice @@ -50,19 +38,15 @@ Make sure you provide full details on your device, such as: - Passcode enabled? - Logs, if panicked then send latest `panic-full` log from your iDevice. -Using `-V` and `-v` would help with debugging. +Using `-VvL` would help with debugging. Join the [Support Discord](https://dsc.gg/palera1n), and create a thread in [#support](https://discord.com/channels/1028398973452570725/1028730487700738130) or ask in [#general](https://discord.com/channels/1028398973452570725/1028398976640229380). -# Credits -
palera1n-c Contributors and Credits +## Credits +
Credits

-- [Nick Chan](https://github.com/asdfugil) for the rewrite -- [Nebula](https://github.com/itsnebulalol) - palera1n owner and manager -- [Mineek](https://github.com/mineek) -- [Tom](https://github.com/plooshi) for updated ploosh kpf and universal loader -- [Lakhan Lothiyi](https://github.com/llsc12) for palera1n loader app +- [Lakhan Lothiyi](https://github.com/llsc12) for older palera1n loader app - [checkra1n](https://github.com/checkra1n) for the base of the kpf - [the Procursus Team](https://github.com/ProcursusTeam) for the amazing [bootstrap](https://github.com/ProcursusTeam/Procursus) - [Évelyne](https://github.com/evelyneee) for [ElleKit](https://github.com/evelyneee/ellekit), rootless tweak injection @@ -86,5 +70,6 @@ Thank you so much to our Patreons that make the future development possible! You - + +

diff --git a/docs/palera1n.1 b/docs/palera1n.1 index 173742d..91f1998 100644 --- a/docs/palera1n.1 +++ b/docs/palera1n.1 @@ -6,7 +6,7 @@ .Dt palera1n 1 .Sh NAME .Nm palera1n -.Nd iOS 15.0-16.4 arm64 iOS/iPadOS jailbreaking tool +.Nd iOS 15.0-16.5 arm64 iOS/iPadOS jailbreaking tool .Sh SYNOPSIS .Nm .Op Fl cCdDEfhIlLnpRsSvV @@ -20,7 +20,7 @@ .Op Fl -force-revert .Sh DESCRIPTION .Nm -jailbreaks any iOS/iPadOS device with an arm64 (arm64e excluded) on iOS 15.0-16.4, +jailbreaks any iOS/iPadOS device with an arm64 (arm64e excluded) on iOS 15.0-16.5, utilizing the .Em checkm8 bootROM exploit. @@ -52,7 +52,7 @@ In the remainder of this document, the term "iOS" and "iPadOS" will be used inte as the difference is negligible as far as the jailbreak is concerened. .Pp .Sh SUPPORTED DEVICES -As described above, arm64 iOS 15.0-16.4 devices are supported, here is an explicit +As described above, arm64 iOS 15.0-16.5 devices are supported, here is an explicit list of supported devicecs: .Bl -tag -compact @@ -113,6 +113,18 @@ This option currently does not work on iOS 16. When used with .Fl f , -fakefs , creates the new APFS volume required for rootful. Will fail if one already exists. +.It Fl C , -clean-fakefs +This reverts the fakefs to the +.Em orig-fs +snapshot that is created when the fakefs +is first created, then the device will continue to boot jailbroken. This option +allows resetting the rootful environment without deleting the entire fakefs. +Note that this option will not work if the fakefs is created in an older version +of palera1n that does not create the +.Em orig-fs +snapshot on the fakefs. This option will also remove some jailbreak files inside +of /var. The files in /var will not be deleted when a userspace reboot is done +with this flag set. .It Fl d , -demote Set the effective production fuse to 0, so as to enable hardware debugging features. .It Fl D , -dfuhelper @@ -143,7 +155,7 @@ Override the kernel patchfinder PongoOS module. The module is required to suppor root filesystem in paleinfo with .Em rootfs command. If in doubt, use -.Sy https://github.com/guacaplushy/PongoOS +.Sy https://github.com/palera1n/PongoOS iOS15 branch or your own fork of it. .It Fl l , -rootless Proceed in rootless mode, this is the default when neither @@ -311,8 +323,7 @@ may crash if the machine it is running on: .Pp The exploit may also work less reliably on some hosts, like AMD desktops, or some MediaTek devices. .Pp -.Fl B , -setup-fakefs-partial -does not work on iOS 16. +The device may randomly crash and reboot due to launchd exiting with code 7. .Sh NOTES .Nm injects a dylib into launchd to allow the diff --git a/include/kerninfo.h b/include/kerninfo.h index 2df1407..60c6f41 100644 --- a/include/kerninfo.h +++ b/include/kerninfo.h @@ -61,6 +61,11 @@ #define palerain_option_setup_partial_root (1 << 4) /* fakefs creating should be partial */ #define palerain_option_checkrain_is_clone (1 << 5) /* supplied checkra1n is checkra1n clone */ #define palerain_option_rootless_livefs (1 << 6) /* mount root livefs on rootless */ +/* reserved values */ +// #define palerain_option_no_ssv (1 << 7) /* no signed system volume */ +// #define palerain_option_force_fakefs (1 << 8) /* force fakefs, even without SSV */ +// #define palerain_option_rootless (1 << 9) /* rootless jailbreak */ +#define palerain_option_clean_fakefs (1 << 10) /* clean fakefs, but does not delete it */ #ifdef DEV_BUILD #define palerain_option_test1 (1 << 29) @@ -122,18 +127,8 @@ struct kpfinfo { options = (checkrain_option_t)(options & ~option); \ } while (0); -static inline bool checkrain_option_enabled(checkrain_option_t flags, checkrain_option_t opt) +static inline bool checkrain_options_enabled(checkrain_option_t flags, checkrain_option_t opt) { - if(flags == checkrain_option_failure) - { - switch(opt) - { - case checkrain_option_safemode: - return true; - default: - return false; - } - } return (flags & opt) != 0; } diff --git a/include/palerain.h b/include/palerain.h index 17527df..09b370c 100644 --- a/include/palerain.h +++ b/include/palerain.h @@ -100,6 +100,8 @@ struct mach_header_64 }; #endif +typedef void *(*pthread_start_t)(void *); + // Keep in sync with Pongo #define PONGO_USB_VENDOR 0x05ac #define PONGO_USB_PRODUCT 0x4141 @@ -203,7 +205,7 @@ boyermoore_horspool_memmem(const unsigned char* haystack, size_t hlen, const unsigned char* needle, size_t nlen); -extern void* pongo_usb_callback(void* arg); +extern void* pongo_usb_callback(stuff_t* arg); usb_ret_t USBControlTransfer(usb_device_handle_t handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t wLength, void *data, uint32_t *wLenDone); const char *usb_strerror(usb_ret_t err); int wait_for_pongo(void); diff --git a/include/tui.h b/include/tui.h index bc61094..b31d528 100644 --- a/include/tui.h +++ b/include/tui.h @@ -20,7 +20,7 @@ #define PI_STEP_CURRENT NEWT_COLORSET_CUSTOM(1) #define PI_STEP_OTHER NEWT_COLORSET_CUSTOM(2) -#define CHECKBOX_STATE(flags, opt) checkrain_option_enabled(flags, opt) ? '*' : ' ' +#define CHECKBOX_STATE(flags, opt) checkrain_options_enabled(flags, opt) ? '*' : ' ' typedef enum tui_screens { ERROR_SCREEN = -1, diff --git a/packaging/control b/packaging/control index 8bf87dc..970a7dc 100644 --- a/packaging/control +++ b/packaging/control @@ -8,8 +8,8 @@ Depends: usbmuxd Section: Utilities Priority: optional Homepage: https://palera.in -Description: iOS 15.0-16.4 semi-tethered checkm8 jailbreak - palera1n is an iOS/iPadOS 15.0-15.3.1 semi tethered jailbreak +Description: iOS 15.0-16.5 semi-tethered checkm8 jailbreak + palera1n is an iOS/iPadOS 15.0-16.5 semi tethered jailbreak based on the checkm8 exploit. . palera1n is able to jailbreak the device in fakefs-rootful mode, diff --git a/packaging/control.macosx b/packaging/control.macosx index 6687b8d..6dfdabc 100644 --- a/packaging/control.macosx +++ b/packaging/control.macosx @@ -7,8 +7,8 @@ Author: palera1n team Section: Utilities Priority: optional Homepage: https://palera.in -Description: iOS 15.0-16.4 semi-tethered checkm8 jailbreak - palera1n is an iOS/iPadOS 15.0-15.3.1 semi tethered jailbreak +Description: iOS 15.0-16.5 semi-tethered checkm8 jailbreak + palera1n is an iOS/iPadOS 15.0-16.5 semi tethered jailbreak based on the checkm8 exploit. . palera1n is able to jailbreak the device in fakefs-rootful mode, diff --git a/patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch b/patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch index 6696609..4212647 100644 --- a/patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch +++ b/patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch @@ -1,6 +1,6 @@ -From 632cdb6de3f1693fb90d60d81552b723e8dd5e84 Mon Sep 17 00:00:00 2001 +From a2d012f3ba459f6debe636b576ad9aeab7b3c2aa Mon Sep 17 00:00:00 2001 From: Nick Chan -Date: Wed, 25 Jan 2023 01:53:00 +0800 +Date: Sat, 27 May 2023 23:50:23 +0800 Subject: [PATCH] Allow empty x509 cert issuer --- @@ -8,25 +8,24 @@ Subject: [PATCH] Allow empty x509 cert issuer 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/x509_crt.c b/library/x509_crt.c -index 0eee97cb6..46702f683 100644 +index cf62532f2..ef25b3d77 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c -@@ -1185,14 +1185,14 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { -- mbedtls_x509_crt_free( crt ); -- return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) ); -+ // mbedtls_x509_crt_free( crt ); -+ // return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) ); +@@ -1061,13 +1061,13 @@ static int x509_crt_parse_der_core(mbedtls_x509_crt *crt, + + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { +- mbedtls_x509_crt_free(crt); +- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); ++ /*mbedtls_x509_crt_free(crt); ++ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);*/ } - if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) - { -- mbedtls_x509_crt_free( crt ); -- return( ret ); -+ // mbedtls_x509_crt_free( crt ); -+ // return( ret ); + if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) { +- mbedtls_x509_crt_free(crt); +- return ret; ++ /*mbedtls_x509_crt_free(crt); ++ return ret;*/ } crt->issuer_raw.len = p - crt->issuer_raw.p; diff --git a/src/Makefile b/src/Makefile index fa5d57f..3d6460c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -153,7 +153,7 @@ checkra1n-kpf-pongo: curl -LO https://cdn.nickchan.lol/palera1n/artifacts/kpf/checkra1n-kpf-pongo ramdisk.dmg: - curl -LO https://cdn.nickchan.lol/palera1n/artifacts/jbinit_rootless/ramdisk.dmg + curl -LO https://cdn.nickchan.lol/palera1n/c-rewrite/deps/ramdisk.dmg binpack.dmg: curl -LO https://cdn.nickchan.lol/palera1n/c-rewrite/deps/binpack.dmg diff --git a/src/credits.c b/src/credits.c index 17eed30..16eb606 100644 --- a/src/credits.c +++ b/src/credits.c @@ -1,7 +1,7 @@ #include #ifndef BAKERAIN_DEVELOPE_R -#define BAKERAIN_DEVELOPE_R "dora2ios" +#define BAKERAIN_DEVELOPE_R "kok3shidoll" #endif #define THE_PLUSH "Ploosh" @@ -12,8 +12,8 @@ #define B stderr #define L , #define E "# == palera1n-c == \n#\n" -#define M "# Made by: Nick Chan, " THE_PLUSH ", Mineek, Nebula, llsc12\n#\n" -#define A "# Thanks to: " BAKERAIN_DEVELOPE_R ", pythonplayer, tihmstar, nikias\n" +#define M "# Made by: Nick Chan, " THE_PLUSH ", Samara, Nebula, staturnz, " BAKERAIN_DEVELOPE_R " \n#\n" +#define A "# Thanks to: pythonplayer123, llsc12, Mineek, tihmstar, nikias\n" #define K "# (libimobiledevice), checkra1n team (Siguza, axi0mx, littlelailo\n" #define I "# et al.), Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)\n\n" #define N ) diff --git a/src/devhelper.c b/src/devhelper.c index d2e7174..e05075f 100644 --- a/src/devhelper.c +++ b/src/devhelper.c @@ -76,27 +76,27 @@ bool cpid_is_arm64(unsigned int cpid) { * ========== 0x8960 =========== * (ARM64) A7 */ - if ( - cpid == 0x8960 || cpid == 0x7000 || cpid == 0x7001 - || cpid == 0x8000 || cpid == 0x8001 || cpid == 0x8003 - || cpid == 0x8010 || cpid == 0x8011 || cpid == 0x8012 - || cpid == 0x8015 - - ) return true; - return false; + return ( + cpid == 0x8960 || cpid == 0x7000 || cpid == 0x7001 || + cpid == 0x8000 || cpid == 0x8001 || cpid == 0x8003 || + cpid == 0x8010 || cpid == 0x8011 || cpid == 0x8012 || + cpid == 0x8015 + ); } int subscribe_cmd(usbmuxd_event_cb_t device_event_cb, irecv_device_event_cb_t irecv_event_cb) { - usbmuxd_events_subscribe(&usbmuxdctx, device_event_cb, NULL); - irecv_device_event_subscribe(&irecvctx, irecv_event_cb, NULL); + int ret; + if ((ret = usbmuxd_events_subscribe(&usbmuxdctx, device_event_cb, NULL))) return ret; + if ((ret = irecv_device_event_subscribe(&irecvctx, irecv_event_cb, NULL))) return ret; return 0; } int unsubscribe_cmd(void) { - usbmuxd_events_unsubscribe(usbmuxdctx); - irecv_device_event_unsubscribe(irecvctx); + int ret; + if ((ret = usbmuxd_events_unsubscribe(usbmuxdctx))) return ret; + if ((ret = irecv_device_event_unsubscribe(irecvctx))) return ret; irecvctx = NULL; usbmuxdctx = NULL; return 0; @@ -119,15 +119,15 @@ int devinfo_cmd(devinfo_t *dev, const char *udid) } if (lockdownd_client_new(device, &lockdown, "palera1n") != LOCKDOWN_E_SUCCESS) { - idevice_free(device); + (void)idevice_free(device); LOG(LOG_ERROR, "Device is not in normal mode."); return -1; } plist_t node = NULL; if (lockdownd_get_value(lockdown, NULL, "UniqueChipID", &node) != LOCKDOWN_E_SUCCESS) { - lockdownd_client_free(lockdown); - idevice_free(device); + (void)lockdownd_client_free(lockdown); + (void)idevice_free(device); LOG(LOG_ERROR, "Error getting ECID"); return -1; } @@ -137,8 +137,8 @@ int devinfo_cmd(devinfo_t *dev, const char *udid) node = NULL; if (lockdownd_get_value(lockdown, NULL, "ProductType", &node) != LOCKDOWN_E_SUCCESS) { - lockdownd_client_free(lockdown); - idevice_free(device); + (void)lockdownd_client_free(lockdown); + (void)idevice_free(device); LOG(LOG_ERROR, "Error getting product type"); return -1; } @@ -148,8 +148,8 @@ int devinfo_cmd(devinfo_t *dev, const char *udid) node = NULL; if (lockdownd_get_value(lockdown, NULL, "CPUArchitecture", &node) != LOCKDOWN_E_SUCCESS) { - lockdownd_client_free(lockdown); - idevice_free(device); + (void)lockdownd_client_free(lockdown); + (void)idevice_free(device); LOG(LOG_ERROR, "Error getting CPU type"); return -1; } @@ -159,8 +159,8 @@ int devinfo_cmd(devinfo_t *dev, const char *udid) node = NULL; if (lockdownd_get_value(lockdown, NULL, "ProductVersion", &node) != LOCKDOWN_E_SUCCESS) { - lockdownd_client_free(lockdown); - idevice_free(device); + (void)lockdownd_client_free(lockdown); + (void)idevice_free(device); LOG(LOG_ERROR, "Error getting product version"); return -1; } @@ -170,21 +170,21 @@ int devinfo_cmd(devinfo_t *dev, const char *udid) node = NULL; if (lockdownd_get_value(lockdown, NULL, "BuildVersion", &node) != LOCKDOWN_E_SUCCESS) { - lockdownd_client_free(lockdown); - idevice_free(device); + (void)lockdownd_client_free(lockdown); + (void)idevice_free(device); LOG(LOG_ERROR, "Error getting build version"); return -1; } plist_get_string_val(node, &buildVersion); plist_free(node); - lockdownd_client_free(lockdown); - idevice_free(device); + (void)lockdownd_client_free(lockdown); + (void)idevice_free(device); + irecv_device_t rcvydev; if (irecv_devices_get_device_by_product_type(productType, &rcvydev) == IRECV_E_SUCCESS) { displayName = rcvydev->display_name; - } - else + } else { displayName = productType; } @@ -209,23 +209,22 @@ int enter_recovery_cmd(const char* udid) { LOG(LOG_ERROR, "Could not connect to lockdownd: %s", lockdownd_strerror(ldret)); return -1; } - do { - ldret = lockdownd_enter_recovery(lockdown); - if (ldret == LOCKDOWN_E_SESSION_INACTIVE) { - lockdownd_client_free(lockdown); - lockdown = NULL; - if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &lockdown, "palera1n"))) { - LOG(LOG_ERROR, "Could not connect to lockdownd: %s", lockdownd_strerror(ldret)); - return -1; - } - ldret = lockdownd_enter_recovery(lockdown); - } + ldret = lockdownd_enter_recovery(lockdown); + if (ldret == LOCKDOWN_E_SESSION_INACTIVE) { + lockdownd_client_free(lockdown); + lockdown = NULL; + ldret = lockdownd_client_new_with_handshake(device, &lockdown, "palera1n"); if (ldret != LOCKDOWN_E_SUCCESS) { - LOG(LOG_ERROR, "Could not trigger entering recovery mode: %s", lockdownd_strerror(ldret)); + LOG(LOG_ERROR, "Could not connect to lockdownd: %s", lockdownd_strerror(ldret)); return -1; } - lockdownd_client_free(lockdown); - } while (0); + ldret = lockdownd_enter_recovery(lockdown); + } + if (ldret != LOCKDOWN_E_SUCCESS) { + LOG(LOG_ERROR, "Could not trigger entering recovery mode: %s", lockdownd_strerror(ldret)); + return -1; + } + lockdownd_client_free(lockdown); idevice_free(device); return 0; } @@ -242,8 +241,8 @@ int reboot_cmd(const char* udid) { if (diagnostics_relay_restart(diag, DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT) != DIAGNOSTICS_RELAY_E_SUCCESS) { LOG(LOG_ERROR, "Could not reboot device."); } - diagnostics_relay_goodbye(diag); - diagnostics_relay_client_free(diag); + (void)diagnostics_relay_goodbye(diag); + (void)diagnostics_relay_client_free(diag); } else { LOG(LOG_ERROR, "Could not connect to device."); return -1; @@ -302,9 +301,9 @@ int passstat_cmd(unsigned char* status, const char* udid) { derr = diagnostics_relay_query_mobilegestalt(diagnostics_client, keys, &node); plist_free(keys); - diagnostics_relay_client_free(diagnostics_client); - lockdownd_service_descriptor_free(service); - idevice_free(dev); + (void)diagnostics_relay_client_free(diagnostics_client); + (void)lockdownd_service_descriptor_free(service); + (void)idevice_free(dev); if (derr != DIAGNOSTICS_RELAY_E_SUCCESS || !node) { @@ -322,7 +321,7 @@ int passstat_cmd(unsigned char* status, const char* udid) { plist_get_string_val(status_node, &passstat_status); if (!status || strncmp(passstat_status, "Succ", 4)) { - if (passstat_status) + if (passstat_status) free(passstat_status); passstat_status = NULL; plist_free(node); @@ -349,20 +348,16 @@ int passstat_cmd(unsigned char* status, const char* udid) { int recvinfo_cmd(recvinfo_t* info, const uint64_t ecid) { irecv_client_t client = NULL; irecv_error_t err = irecv_open_with_ecid(&client, ecid); - if (err != IRECV_E_SUCCESS) { - LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err)); - return -1; - } + if (err != IRECV_E_SUCCESS) goto err; int mode = 0; - irecv_get_mode(client, &mode); + err = irecv_get_mode(client, &mode); + if (err != IRECV_E_SUCCESS) goto err; char *ibootver = NULL; - irecv_getenv(client, "build-version", &ibootver); + err = irecv_getenv(client, "build-version", &ibootver); + if (err != IRECV_E_SUCCESS) goto err; irecv_device_t device; err = irecv_devices_get_device_by_client(client, &device); - if (err != IRECV_E_SUCCESS) { - LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err)); - return -1; - } + if (err != IRECV_E_SUCCESS) goto err; info->mode = mode; info->cpid = device->chip_id; snprintf(info->product_type, 0x20, "%s", device->product_type); @@ -371,33 +366,41 @@ int recvinfo_cmd(recvinfo_t* info, const uint64_t ecid) { free(ibootver); irecv_close(client); return 0; +err: + LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err)); + return -1; } int autoboot_cmd(const uint64_t ecid) { irecv_client_t client = NULL; irecv_error_t err = irecv_open_with_ecid(&client, ecid); - if (err == IRECV_E_SUCCESS) { - irecv_setenv(client, "auto-boot", "true"); - irecv_saveenv(client); - irecv_close(client); - return 0; - } else { - LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err)); + if (err != IRECV_E_SUCCESS) goto err; + err = irecv_setenv(client, "auto-boot", "true"); + if (err != IRECV_E_SUCCESS) goto err; + err = irecv_saveenv(client); + if (err != IRECV_E_SUCCESS) goto err; + err = irecv_close(client); + if (err != IRECV_E_SUCCESS) goto err; + return 0; +err: + LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err)); return -1; - } } int exitrecv_cmd(const uint64_t ecid) { irecv_client_t client = NULL; irecv_error_t err = irecv_open_with_ecid(&client, ecid); - if (err == IRECV_E_SUCCESS) { - irecv_setenv(client, "auto-boot", "true"); - irecv_saveenv(client); - irecv_reboot(client); - irecv_close(client); - return 0; - } else { - LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err)); - return -1; - } + if (err != IRECV_E_SUCCESS) goto err; + err = irecv_setenv(client, "auto-boot", "true"); + if (err != IRECV_E_SUCCESS) goto err; + err = irecv_saveenv(client); + if (err != IRECV_E_SUCCESS) goto err; + err = irecv_reboot(client); + if (err != IRECV_E_SUCCESS) goto err; + err = irecv_close(client); + if (err != IRECV_E_SUCCESS) goto err; + return 0; +err: + LOG(LOG_ERROR, "libirecovery error: %d (%s)", err, irecv_strerror(err)); + return -1; } diff --git a/src/dfuhelper.c b/src/dfuhelper.c index d9b27d6..8eed57f 100644 --- a/src/dfuhelper.c +++ b/src/dfuhelper.c @@ -36,12 +36,20 @@ int dfuhelper_thr_running = false; void step(int time, int time2, char *text, bool (*cond)(uint64_t), uint64_t cond_arg) { for (int i = time2; i < time; i++) { - printf(checkrain_option_enabled(host_flags, host_option_no_colors) ? "\r\033[K%s (%d)" : BCYN "\r\033[K%s (%d)" CRESET, text, time - i + time2); + printf( + checkrain_options_enabled(host_flags, host_option_no_colors) + ? "\r\033[K%s (%d)" + : BCYN "\r\033[K%s (%d)" CRESET, text, time - i + time2 + ); fflush(stdout); sleep(1); if (cond != NULL && cond(cond_arg)) pthread_exit(NULL); } - printf(checkrain_option_enabled(host_flags, host_option_no_colors) ? "\r%s (%d)" : CYN "\r%s (%d)" CRESET, text, time2); + printf( + checkrain_options_enabled(host_flags, host_option_no_colors) + ? "\r%s (%d)" + : CYN "\r%s (%d)" CRESET, text, time2 + ); if (time2 == 0) puts(""); } @@ -53,13 +61,14 @@ int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) { LOG(LOG_ERROR, "Unable to get device information"); return 0; } - if (strcmp(dev.CPUArchitecture, "arm64")) { + if (strncmp(dev.CPUArchitecture, "arm64", strlen("arm64"))) { devinfo_free(&dev); LOG(LOG_WARNING, "Ignoring non-arm64 device..."); + LOG(LOG_WARNING, "palera1n doesn't and never will work on A12+ (arm64e)"); return -1; } if (!strncmp(dev.productType, "iPhone10,", strlen("iPhone10,"))) { - if (!checkrain_option_enabled(host_flags, host_option_device_info)) + if (!checkrain_options_enabled(host_flags, host_option_device_info)) LOG(LOG_VERBOSE2, "Product %s requires passcode to be disabled", dev.productType); unsigned char passcode_state = 0; ret = passstat_cmd(&passcode_state, usbmuxd_device->udid); @@ -70,14 +79,14 @@ int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) { } if (passcode_state) { LOG(LOG_ERROR, "Passcode must be disabled on this device"); - if (!checkrain_option_enabled(host_flags, host_option_device_info)) - LOG(LOG_ERROR, "Additionally, passcode must never be set since restore on iOS 16+"); + if (!checkrain_options_enabled(host_flags, host_option_device_info)) + LOG(LOG_ERROR, "Additionally, passcode must never be set since a restore on iOS 16+"); devinfo_free(&dev); return -1; } } - if (checkrain_option_enabled(host_flags, host_option_device_info)) { + if (checkrain_options_enabled(host_flags, host_option_device_info)) { printf("Mode: normal\n"); printf("ProductType: %s\n", dev.productType); printf("Architecture: %s\n", dev.CPUArchitecture); @@ -92,7 +101,7 @@ int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) { LOG(LOG_INFO, "Telling device with udid %s to enter recovery mode immediately", usbmuxd_device->udid); enter_recovery_cmd(usbmuxd_device->udid); devinfo_free(&dev); - if (checkrain_option_enabled(host_flags, host_option_enter_recovery)) { + if (checkrain_options_enabled(host_flags, host_option_enter_recovery)) { device_has_booted = true; set_spin(0); unsubscribe_cmd(); @@ -137,17 +146,14 @@ void* connected_recovery_mode(struct irecv_device_info* info) { return NULL; } printf("\r\033[K"); - bool nohome = NOHOME; - if (nohome) + if (NOHOME) { step(2, 0, "Hold volume down + side button", NULL, 0); - else - step(2, 0, "Hold home + power button", NULL, 0); - if (nohome) step(10, 0, "Hold volume down button", conditional, ecid); - else - step(10, 0, "Hold home button", conditional, ecid); - if (get_ecid_wait_for_dfu() != ecid) { } else { + step(2, 0, "Hold home + power button", NULL, 0); + step(10, 0, "Hold home button", conditional, ecid); + } + if (get_ecid_wait_for_dfu() == ecid) { LOG(LOG_WARNING, "Whoops, device did not enter DFU mode"); LOG(LOG_INFO, "Waiting for device to reconnect..."); set_ecid_wait_for_dfu(0); @@ -175,13 +181,15 @@ void device_event_cb(const usbmuxd_event_t *event, void* userdata) { switch (event->event) { case UE_DEVICE_ADD: LOG(LOG_VERBOSE, "Normal mode device connected"); - if (checkrain_option_enabled(host_flags, host_option_exit_recovery)) { + if (checkrain_options_enabled(host_flags, host_option_exit_recovery)) { break; - } else if (checkrain_option_enabled(host_flags, host_option_reboot_device)) { - reboot_cmd(event->device.udid); - LOG(LOG_INFO, "Restarted device"); - set_spin(0); - unsubscribe_cmd(); + } else if (checkrain_options_enabled(host_flags, host_option_reboot_device)) { + int ret = reboot_cmd(event->device.udid); + if (!ret) { + LOG(LOG_INFO, "Restarted device"); + set_spin(0); + unsubscribe_cmd(); + } pthread_exit(NULL); break; } @@ -195,69 +203,85 @@ void device_event_cb(const usbmuxd_event_t *event, void* userdata) { void irecv_device_event_cb(const irecv_device_event_t *event, void* userdata) { pthread_t recovery_thread, dfu_thread; + int ret; switch(event->type) { case IRECV_DEVICE_ADD: - if (event->mode == IRECV_K_RECOVERY_MODE_1 || event->mode == IRECV_K_RECOVERY_MODE_2 || event->mode == IRECV_K_RECOVERY_MODE_3 || event->mode == IRECV_K_RECOVERY_MODE_4) { - if (!checkrain_option_enabled(host_flags, host_option_device_info)) - LOG(LOG_VERBOSE, "Recovery mode device %ld connected", event->device_info->ecid); - if (checkrain_option_enabled(host_flags, host_option_exit_recovery)) { - exitrecv_cmd(event->device_info->ecid); - LOG(LOG_INFO, "Exited recovery mode"); - device_has_booted = true; - set_spin(0); - unsubscribe_cmd(); - if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread); - pthread_exit(NULL); - break; - } - - if (checkrain_option_enabled(host_flags, host_option_device_info)) { - recvinfo_t info; - recvinfo_cmd(&info, event->device_info->ecid); - printf("Mode: recovery\n"); - printf("ProductType: %s\n", info.product_type); - printf("DisplayName: %s\n", info.display_name); - - device_has_booted = true; - set_spin(0); - unsubscribe_cmd(); - if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread); - pthread_exit(NULL); - break; - } - - if (checkrain_option_enabled(host_flags, host_option_enter_recovery) || - checkrain_option_enabled(host_flags, host_option_reboot_device)) return; - pthread_create(&recovery_thread, NULL, (void* (*)(void*))connected_recovery_mode, event->device_info); - } else if (event->mode == IRECV_K_DFU_MODE) { - if (!checkrain_option_enabled(host_flags, host_option_device_info)) - LOG(LOG_VERBOSE, "DFU mode device %ld connected", event->device_info->ecid); - - if (checkrain_option_enabled(host_flags, host_option_device_info)) { - recvinfo_t info; - recvinfo_cmd(&info, event->device_info->ecid); - printf("Mode: dfu\n"); - printf("ProductType: %s\n", info.product_type); - printf("DisplayName: %s\n", info.display_name); - - device_has_booted = true; - set_spin(0); - unsubscribe_cmd(); - if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread); - pthread_exit(NULL); - break; - } - - if ( - checkrain_option_enabled(host_flags, host_option_exit_recovery) || - checkrain_option_enabled(host_flags, host_option_enter_recovery) || - checkrain_option_enabled(host_flags, host_option_reboot_device)) { + if (event->mode == IRECV_K_RECOVERY_MODE_1 || + event->mode == IRECV_K_RECOVERY_MODE_2 || + event->mode == IRECV_K_RECOVERY_MODE_3 || + event->mode == IRECV_K_RECOVERY_MODE_4) { + if (!checkrain_options_enabled(host_flags, host_option_device_info)) + LOG(LOG_VERBOSE, "Recovery mode device %ld connected", event->device_info->ecid); + if (checkrain_options_enabled(host_flags, host_option_exit_recovery)) { + ret = exitrecv_cmd(event->device_info->ecid); + if (!ret) { + LOG(LOG_INFO, "Exited recovery mode"); + device_has_booted = true; + set_spin(0); + unsubscribe_cmd(); + } else { + LOG(LOG_WARNING, "Could not exit recovery mode"); + } + if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread); + pthread_exit(NULL); break; + } + + if (checkrain_options_enabled(host_flags, host_option_device_info)) { + recvinfo_t info; + ret = recvinfo_cmd(&info, event->device_info->ecid); + if (ret) { + LOG(LOG_WARNING, "Could not get info from device"); + } else { + printf("Mode: Recovery\n"); + printf("ProductType: %s\n", info.product_type); + printf("DisplayName: %s\n", info.display_name); + + device_has_booted = true; + set_spin(0); + unsubscribe_cmd(); + } + if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread); + pthread_exit(NULL); + break; + } + + if (checkrain_options_enabled(host_flags, host_option_enter_recovery) || + checkrain_options_enabled(host_flags, host_option_reboot_device)) return; + pthread_create(&recovery_thread, NULL, (pthread_start_t)connected_recovery_mode, event->device_info); + } else if (event->mode == IRECV_K_DFU_MODE) { + if (!checkrain_options_enabled(host_flags, host_option_device_info)) + LOG(LOG_VERBOSE, "DFU mode device %ld connected", event->device_info->ecid); + + if (checkrain_options_enabled(host_flags, host_option_device_info)) { + recvinfo_t info; + ret = recvinfo_cmd(&info, event->device_info->ecid); + if (ret) { + LOG(LOG_WARNING, "Could not get info from device"); + } else { + printf("Mode: DFU\n"); + printf("ProductType: %s\n", info.product_type); + printf("DisplayName: %s\n", info.display_name); + + device_has_booted = true; + set_spin(0); + unsubscribe_cmd(); + } + if (dfuhelper_thr_running) pthread_cancel(dfuhelper_thread); + pthread_exit(NULL); + break; + } + + if ( + checkrain_options_enabled(host_flags, host_option_exit_recovery) || + checkrain_options_enabled(host_flags, host_option_enter_recovery) || + checkrain_options_enabled(host_flags, host_option_reboot_device)) { + break; + } + pthread_create(&dfu_thread, NULL, (pthread_start_t)connected_dfu_mode, event->device_info); } - pthread_create(&dfu_thread, NULL, (void* (*)(void*))connected_dfu_mode, event->device_info); - } - break; + break; case IRECV_DEVICE_REMOVE: LOG(LOG_VERBOSE, "Recovery mode device disconnected"); break; diff --git a/src/exec_checkra1n.c b/src/exec_checkra1n.c index 60686bd..64962a6 100644 --- a/src/exec_checkra1n.c +++ b/src/exec_checkra1n.c @@ -126,11 +126,11 @@ int exec_checkra1n(void) { #endif checkra1n_exec: {}; char args[0x10] = "-E"; - if (checkrain_option_enabled(host_flags, host_option_demote)) strncat(args, "d", 0xf); - if (!checkrain_option_enabled(host_flags, palerain_option_checkrain_is_clone)) { + if (checkrain_options_enabled(host_flags, host_option_demote)) strncat(args, "d", 0xf); + if (!checkrain_options_enabled(host_flags, palerain_option_checkrain_is_clone)) { strncat(args, "p", 0xf); if (verbose >= 2) strncat(args, "v", 0xf); - if (checkrain_option_enabled(host_flags, host_option_no_colors)) strncat(args, "n", 0xf); + if (checkrain_options_enabled(host_flags, host_option_no_colors)) strncat(args, "n", 0xf); } else { strncat(args, "R", 0xf); } diff --git a/src/lockdown_helper.c b/src/lockdown_helper.c index 5e7f0cc..b7b941c 100644 --- a/src/lockdown_helper.c +++ b/src/lockdown_helper.c @@ -11,22 +11,19 @@ #ifdef DEBUG #define log_debug(...) fprintf(stderr, __VA_ARGS__); fputc('\n', stderr) #else -#define log_debug(...) +#define log_debug(...) do {} while (0) #endif #define log_error(...) fprintf(stderr, __VA_ARGS__); fputc('\n', stderr) -int lockdown_connect_handle(uint32_t handle) -{ +int lockdown_connect_handle(uint32_t handle) { int fd = usbmuxd_connect(handle, 62078); if (fd < 0) { log_debug("Can't connect to lockownd on device #%u", handle); - return fd; } return fd; } -int lockdown_connect_udid(const char* udid) -{ +int lockdown_connect_udid(const char* udid) { usbmuxd_device_info_t device; if (usbmuxd_get_device_by_udid(udid, &device) < 0) { log_debug("Can't find device %s", udid); @@ -35,8 +32,7 @@ int lockdown_connect_udid(const char* udid) return lockdown_connect_handle(device.handle); } -void lockdown_disconnect(int fd) -{ +void lockdown_disconnect(int fd) { usbmuxd_disconnect(fd); } @@ -56,8 +52,7 @@ static const int INTEGER_NODE_SIZE = sizeof(INTEGER_NODE)-1; static const int STRING_NODE_SIZE = sizeof(STRING_NODE)-1; static const int ERROR_KEY_NODE_SIZE = sizeof(ERROR_KEY_NODE)-1; -static void skip_ws(char** cur, char* end) -{ +static void skip_ws(char** cur, char* end) { char* p = *cur; while (p < end && ((*p == ' ') || (*p == '\t') || (*p == '\r') || (*p == '\n'))) { p++; @@ -65,8 +60,7 @@ static void skip_ws(char** cur, char* end) *cur = p; } -static char* _send_request_and_get_reply(int fd, const char* request, uint32_t len, uint32_t* received) -{ +static char* _send_request_and_get_reply(int fd, const char* request, uint32_t len, uint32_t* received) { uint32_t sent_bytes = 0; usbmuxd_send(fd, request, len, &sent_bytes); if (sent_bytes != len) { @@ -100,8 +94,7 @@ static char* _send_request_and_get_reply(int fd, const char* request, uint32_t l return resp; } -int lockdown_check_type(int fd, const char* type_match) -{ +int lockdown_check_type(int fd, const char* type_match) { unsigned char tmp[512]; uint32_t len = (uint32_t)snprintf((char*)tmp, 512, QUERY_TYPE_REQUEST); uint32_t belen = htonl(len-4); @@ -119,8 +112,7 @@ int lockdown_check_type(int fd, const char* type_match) return result; } -int lockdown_get_uint_value(int fd, const char* domain, const char* key, uint64_t* value) -{ +int lockdown_get_uint_value(int fd, const char* domain, const char* key, uint64_t* value) { char tmp[1024]; uint32_t len; if (domain) { @@ -159,8 +151,7 @@ int lockdown_get_uint_value(int fd, const char* domain, const char* key, uint64_ return 0; } -int lockdown_get_string_value(int fd, const char* domain, const char* key, char** value) -{ +int lockdown_get_string_value(int fd, const char* domain, const char* key, char** value) { char tmp[1024]; uint32_t len; if (domain) { @@ -212,8 +203,7 @@ int lockdown_get_string_value(int fd, const char* domain, const char* key, char* return 0; } -int lockdown_enter_recovery(int fd) -{ +int lockdown_enter_recovery(int fd) { char tmp[512]; uint32_t len = (uint32_t)snprintf(tmp, 512, ENTER_RECOVERY_REQUEST); *(uint32_t*)&tmp = htonl(len-4); diff --git a/src/log.c b/src/log.c index 5c286f8..4d5a8e6 100644 --- a/src/log.c +++ b/src/log.c @@ -12,7 +12,7 @@ int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxna { if (verbose >= 5 #ifdef TUI - && !checkrain_option_enabled(host_flags, host_option_tui) + && !checkrain_options_enabled(host_flags, host_option_tui) #endif ) fprintf(stderr, "p1_log: loglevel %d from %s:%d:%s()\n", loglevel, fname, lineno, fxname); int ret = 0; @@ -57,12 +57,12 @@ int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxna snprintf(colour_bold, 0x10, "%s", BWHT); break; } - if (checkrain_option_enabled(host_flags, host_option_no_colors)) { + if (checkrain_options_enabled(host_flags, host_option_no_colors)) { colour[0] = '\0'; colour_bold[0] = '\0'; } #ifdef TUI - if (checkrain_option_enabled(host_flags, host_option_tui) && tui_started) { + if (checkrain_options_enabled(host_flags, host_option_tui) && tui_started) { newtComponent co = get_tui_log(); if (co == NULL) { return 0; /* 0 bytes printed */ @@ -79,26 +79,26 @@ int p1_log(log_level_t loglevel, const char *fname, int lineno, const char *fxna time_t curtime; time(&curtime); struct tm* timeinfo = localtime(&curtime); - if (!checkrain_option_enabled(host_flags, host_option_no_colors)) + if (!checkrain_options_enabled(host_flags, host_option_no_colors)) snprintf(timestring, 0x80, "%s[%s%02d/%02d/%d %02d:%02d:%02d%s]", CRESET, HBLK, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_year - 100, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, CRESET); else snprintf(timestring, 0x80, "[%02d/%02d/%d %02d:%02d:%02d]", timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_year - 100, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); - if (verbose >= 2 && !checkrain_option_enabled(host_flags, host_option_no_colors)) { + if (verbose >= 2 && !checkrain_options_enabled(host_flags, host_option_no_colors)) { printf("%s| - %s%s <%s> " CRESET "%s" HBLU "%s" CRESET ":" BLU "%d" CRESET ":" BMAG "%s()" CRESET ": \n%s| ----> ", colour_bold, timestring, colour_bold, type, WHT, fname, lineno, fxname, colour_bold); - } else if (!checkrain_option_enabled(host_flags, host_option_no_colors)) { + } else if (!checkrain_options_enabled(host_flags, host_option_no_colors)) { printf(" - %s %s<%s>%s: ", timestring, colour_bold, type, CRESET); - } else if (verbose >= 2 && checkrain_option_enabled(host_flags, host_option_no_colors)) { + } else if (verbose >= 2 && checkrain_options_enabled(host_flags, host_option_no_colors)) { printf("%s| - %s%s <%s> %s:%d:%s(): \n%s| ----> ", colour_bold, timestring, colour_bold, type, fname, lineno, fxname, colour_bold); - } else if (checkrain_option_enabled(host_flags, host_option_no_colors)) { + } else if (checkrain_options_enabled(host_flags, host_option_no_colors)) { printf(" - %s %s<%s>: ", timestring, colour_bold, type); } printf("%s", colour); ret = vprintf(format, args); va_end(args); - if (verbose < 2 && !checkrain_option_enabled(host_flags, host_option_no_colors)) + if (verbose < 2 && !checkrain_options_enabled(host_flags, host_option_no_colors)) printf(CRESET "\n"); - else if (!checkrain_option_enabled(host_flags, host_option_no_colors)) + else if (!checkrain_options_enabled(host_flags, host_option_no_colors)) printf("\n%s-%s\n", colour, CRESET); else if (verbose < 2) printf("\n"); diff --git a/src/main.c b/src/main.c index 8e4de2f..18056d2 100644 --- a/src/main.c +++ b/src/main.c @@ -73,7 +73,7 @@ int build_checks(void) { if (checkra1n_len <= (UCHAR_MAX + 1)) { LOG(LOG_FATAL, "checkra1n too small"); } - if (boyermoore_horspool_memmem(&checkra1n[0], checkra1n_len, (const unsigned char*)"[ra1npoc15-part] thanks to", strlen("[ra1npoc15-part] thanks to")) != NULL) { + if (boyermoore_horspool_memmem(&checkra1n[0], checkra1n_len, (const unsigned char *)"[ra1npoc15-part] thanks to", strlen("[ra1npoc15-part] thanks to")) != NULL) { host_flags |= palerain_option_checkrain_is_clone; } #endif @@ -82,8 +82,7 @@ int build_checks(void) { if (kpf_hdr->magic != MH_MAGIC_64 && kpf_hdr->magic != MH_CIGAM_64) { LOG(LOG_FATAL, "Broken build: Invalid kernel patchfinder: Not thin 64-bit Mach-O"); return -1; - } else - if (kpf_hdr->filetype != MH_KEXT_BUNDLE) { + } else if (kpf_hdr->filetype != MH_KEXT_BUNDLE) { LOG(LOG_FATAL, "Broken build: Invalid kernel patchfinder: Not a kext bundle"); return -1; } else if (kpf_hdr->cputype != CPU_TYPE_ARM64) { @@ -113,10 +112,9 @@ int palera1n(int argc, char *argv[]) { pthread_mutex_init(&ecid_dfu_wait_mutex, NULL); if ((ret = build_checks())) return ret; if ((ret = optparse(argc, argv))) goto cleanup; - if (!checkrain_option_enabled(host_flags, host_option_device_info)) - if (checkrain_option_enabled(host_flags, host_option_palerain_version)) goto normal_exit; + if (!checkrain_options_enabled(host_flags, host_option_device_info) && checkrain_options_enabled(host_flags, host_option_palerain_version)) goto normal_exit; #ifdef TUI - if (checkrain_option_enabled(host_flags, host_option_tui)) { + if (checkrain_options_enabled(host_flags, host_option_tui)) { ret = tui(); if (ret) goto cleanup; else goto normal_exit; @@ -136,7 +134,7 @@ int palera1n(int argc, char *argv[]) { } #endif - if (!checkrain_option_enabled(host_flags, host_option_device_info)) + if (!checkrain_options_enabled(host_flags, host_option_device_info)) LOG(LOG_INFO, "Waiting for devices"); if (access("/var/run/usbmuxd", F_OK) != 0) @@ -146,16 +144,16 @@ int palera1n(int argc, char *argv[]) { pthread_create(&dfuhelper_thread, NULL, dfuhelper, NULL); pthread_join(dfuhelper_thread, NULL); set_spin(0); - if (checkrain_option_enabled(host_flags, host_option_dfuhelper_only) || - checkrain_option_enabled(host_flags, host_option_reboot_device) || - checkrain_option_enabled(host_flags, host_option_exit_recovery) || - checkrain_option_enabled(host_flags, host_option_enter_recovery) || - checkrain_option_enabled(host_flags, host_option_device_info) || - device_has_booted) + if (checkrain_options_enabled(host_flags, host_option_dfuhelper_only | + host_option_reboot_device | + host_option_exit_recovery | + host_option_enter_recovery | + host_option_device_info + ) || device_has_booted) goto normal_exit; if (exec_checkra1n()) goto cleanup; - if (checkrain_option_enabled(host_flags, host_option_pongo_exit) || checkrain_option_enabled(host_flags, host_option_demote)) + if (checkrain_options_enabled(host_flags, host_option_pongo_exit | host_option_demote)) goto normal_exit; set_spin(1); sleep(2); diff --git a/src/optparse.c b/src/optparse.c index ce0c333..e85168c 100644 --- a/src/optparse.c +++ b/src/optparse.c @@ -19,10 +19,9 @@ checkrain_option_p host_flags_p = &host_flags; static bool force_use_verbose_boot = false; static struct option longopts[] = { -#ifdef ROOTFUL {"setup-partial-fakefs", no_argument, NULL, 'B'}, {"setup-fakefs", no_argument, NULL, 'c'}, -#endif + {"clean-fakefs", no_argument, NULL, 'c'}, {"dfuhelper", no_argument, NULL, 'D'}, {"help", no_argument, NULL, 'h'}, {"pongo-shell", no_argument, NULL, 'p'}, @@ -30,9 +29,7 @@ static struct option longopts[] = { {"debug-logging", no_argument, NULL, 'v'}, {"verbose-boot", no_argument, NULL, 'V'}, {"boot-args", required_argument, NULL, 'e'}, -#ifdef ROOTFUL {"fakefs", no_argument, NULL, 'f'}, -#endif {"rootless", no_argument, NULL, 'l'}, {"jbinit-log-to-file", no_argument, NULL, 'L'}, {"demote", no_argument, NULL, 'd'}, @@ -68,14 +65,14 @@ static int usage(int e, char* prog_name) "12" #endif #ifdef ROOTFUL - "cfB" + "cCfB" #endif #ifdef TUI "t" #endif "] [-e boot arguments] [-k Pongo image] [-o overlay file] [-r ramdisk file] [-K KPF file] [-i checkra1n file]\n" "Copyright (C) 2023, palera1n team, All Rights Reserved.\n\n" - "iOS/iPadOS 15.0-16.4 arm64 jailbreaking tool\n\n" + "iOS/iPadOS 15.0-16.5 arm64 jailbreaking tool\n\n" "\t--version\t\t\t\tPrint version\n" "\t--force-revert\t\t\t\tRemove jailbreak\n" #ifdef DEV_BUILD @@ -85,6 +82,7 @@ static int usage(int e, char* prog_name) #ifdef ROOTFUL "\t-B, --setup-partial-fakefs\t\tSetup partial fakefs\n" "\t-c, --setup-fakefs\t\t\tSetup fakefs\n" + "\t-C, --clean-fakefs\t\t\tClean fakefs\n" #endif "\t-d, --demote\t\t\t\tDemote\n" "\t-D, --dfuhelper\t\t\t\tExit after entering DFU\n" @@ -130,13 +128,10 @@ int optparse(int argc, char* argv[]) { #ifdef DEV_BUILD "12" #endif -#ifdef ROOTFUL - "fcB" -#endif + "fCcB" ,longopts, NULL)) != -1) { switch (opt) { -#ifdef ROOTFUL case 'B': palerain_flags |= palerain_option_setup_partial_root; palerain_flags |= palerain_option_setup_rootful; @@ -146,7 +141,9 @@ int optparse(int argc, char* argv[]) { palerain_flags |= palerain_option_setup_rootful; kpf_flags |= checkrain_option_verbose_boot; break; -#endif + case 'C': + palerain_flags |= palerain_option_clean_fakefs; + break; case 'p': host_flags |= host_option_pongo_exit; break; @@ -176,17 +173,13 @@ int optparse(int argc, char* argv[]) { } snprintf(xargs_cmd, sizeof(xargs_cmd), "xargs %s", optarg); break; -#ifdef ROOTFUL case 'f': snprintf(rootfs_cmd, sizeof(rootfs_cmd), "rootfs %s", optarg); snprintf(dtpatch_cmd, 0x20, "dtpatch %s", optarg); palerain_flags |= palerain_option_rootful; break; -#endif case 'l': -#ifdef ROOTFUL palerain_flags &= ~palerain_option_rootful; -#endif break; case 'L': palerain_flags |= palerain_option_jbinit_log_to_file; @@ -308,7 +301,7 @@ int optparse(int argc, char* argv[]) { break; } } - if (checkrain_option_enabled(host_flags, host_option_palerain_version)) { + if (checkrain_options_enabled(host_flags, host_option_palerain_version)) { printf( "palera1n " PALERAIN_VERSION "\n" BUILD_COMMIT " " BUILD_NUMBER " (" BUILD_BRANCH ")\n\n" @@ -326,7 +319,7 @@ int optparse(int argc, char* argv[]) { return 0; } - if ((strstr(xargs_cmd, "serial=") != NULL) && !force_use_verbose_boot && checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful)) { + if ((strstr(xargs_cmd, "serial=") != NULL) && !force_use_verbose_boot && checkrain_options_enabled(palerain_flags, palerain_option_setup_rootful)) { kpf_flags &= ~checkrain_option_verbose_boot; } @@ -350,17 +343,17 @@ int optparse(int argc, char* argv[]) { LOG(LOG_VERBOSE4, "overlay override ptr %p -> %p", override_overlay.orig_ptr, **overlay_to_upload); } - if (!checkrain_option_enabled(palerain_flags, palerain_option_rootful)) { - if (checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful) || checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful_forced)) { + if (!checkrain_options_enabled(palerain_flags, palerain_option_rootful)) { + if (checkrain_options_enabled(palerain_flags, palerain_option_setup_rootful) || checkrain_options_enabled(palerain_flags, palerain_option_setup_rootful_forced)) { LOG(LOG_FATAL, "Cannot setup rootful when rootless is requested. Use -f to enable rootful mode."); return -1; } } if (!( - checkrain_option_enabled(host_flags, host_option_dfuhelper_only) || - checkrain_option_enabled(host_flags, host_option_enter_recovery) || - checkrain_option_enabled(host_flags, host_option_exit_recovery) || - checkrain_option_enabled(host_flags, host_option_reboot_device))) + checkrain_options_enabled(host_flags, host_option_dfuhelper_only) || + checkrain_options_enabled(host_flags, host_option_enter_recovery) || + checkrain_options_enabled(host_flags, host_option_exit_recovery) || + checkrain_options_enabled(host_flags, host_option_reboot_device))) { #ifdef NO_CHECKRAIN if (checkra1n_len == 0 && ext_checkra1n == NULL) @@ -368,7 +361,7 @@ int optparse(int argc, char* argv[]) { LOG(LOG_FATAL, "checkra1n omitted in build but no override specified"); return -1; } - if (!(checkrain_option_enabled(host_flags, host_option_pongo_exit) || checkrain_option_enabled(host_flags, host_option_pongo_exit))) + if (!(checkrain_options_enabled(host_flags, host_option_pongo_exit) || checkrain_options_enabled(host_flags, host_option_pongo_exit))) { #ifdef NO_KPF if (checkra1n_kpf_pongo_len == 0) diff --git a/src/pongo_helper.c b/src/pongo_helper.c index 727e15d..4ae9269 100644 --- a/src/pongo_helper.c +++ b/src/pongo_helper.c @@ -29,15 +29,15 @@ void* pongo_helper(void* ptr) { return NULL; } -void *pongo_usb_callback(void *arg) { +void *pongo_usb_callback(stuff_t *arg) { if (get_found_pongo()) return NULL; set_found_pongo(1); - if (checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful)) { + if (checkrain_options_enabled(palerain_flags, palerain_option_setup_rootful)) { strncat(xargs_cmd, " wdt=-1", 0x270 - strlen(xargs_cmd) - 1); } LOG(LOG_INFO, "Found PongoOS USB Device"); - usb_device_handle_t handle = (((stuff_t *)arg)->handle); + usb_device_handle_t handle = arg->handle; issue_pongo_command(handle, NULL); issue_pongo_command(handle, "fuse lock"); issue_pongo_command(handle, "sep auto"); @@ -46,7 +46,7 @@ void *pongo_usb_callback(void *arg) { issue_pongo_command(handle, kpf_flags_cmd); issue_pongo_command(handle, checkrain_flags_cmd); issue_pongo_command(handle, palerain_flags_cmd); - if (checkrain_option_enabled(palerain_flags, palerain_option_rootful)) + if (checkrain_options_enabled(palerain_flags, palerain_option_rootful)) { issue_pongo_command(handle, "rootfs"); } @@ -66,13 +66,13 @@ void *pongo_usb_callback(void *arg) { issue_pongo_command(handle, "overlay"); } issue_pongo_command(handle, xargs_cmd); - if (checkrain_option_enabled(host_flags, host_option_pongo_full)) goto done; + if (checkrain_options_enabled(host_flags, host_option_pongo_full)) goto done; issue_pongo_command(handle, "bootx"); LOG(LOG_INFO, "Booting Kernel..."); - if (checkrain_option_enabled(palerain_flags, palerain_option_setup_partial_root)) { + if (checkrain_options_enabled(palerain_flags, palerain_option_setup_partial_root)) { LOG(LOG_INFO, "Please wait up to 5 minutes for the bindfs to be created."); LOG(LOG_INFO, "Once the device boots up to iOS, run again without the -B (Create BindFS) option to jailbreak."); - } else if (checkrain_option_enabled(palerain_flags, palerain_option_setup_rootful)) { + } else if (checkrain_options_enabled(palerain_flags, palerain_option_setup_rootful)) { LOG(LOG_INFO, "Please wait up to 10 minutes for the fakefs to be created."); LOG(LOG_INFO, "Once the device boots up to iOS, run again without the -c (Create FakeFS) option to jailbreak."); } @@ -83,7 +83,7 @@ void *pongo_usb_callback(void *arg) { done: device_has_booted = true; #ifdef USE_LIBUSB - libusb_unref_device(((stuff_t *)arg)->dev); + libusb_unref_device(arg->dev); #endif set_spin(0); return NULL; @@ -163,7 +163,7 @@ int upload_pongo_file(usb_device_handle_t handle, unsigned char *buf, unsigned i if (verbose < 3 || verbose > 4) { LOG(LOG_VERBOSE, "Uploaded %llu bytes to PongoOS", (unsigned long long)buf_len); } else { - if (checkrain_option_enabled(host_flags, host_option_no_colors)) + if (checkrain_options_enabled(host_flags, host_option_no_colors)) printf("/send mem:%p:%p\nUploaded %llu bytes]\n", (void*)buf, (void*)(buf + buf_len), (unsigned long long)buf_len); else printf("/send mem:%p:%p\n" BCYN "[Uploaded %llu bytes]\n" CRESET, (void*)buf, (void*)(buf + buf_len), (unsigned long long)buf_len); @@ -176,7 +176,7 @@ int upload_pongo_file(usb_device_handle_t handle, unsigned char *buf, unsigned i void io_start(stuff_t *stuff) { - int r = pthread_create(&stuff->th, NULL, &pongo_usb_callback, stuff); + int r = pthread_create(&stuff->th, NULL, (pthread_start_t)pongo_usb_callback, stuff); if(r != 0) { ERR("pthread_create: %s", strerror(r)); diff --git a/src/usb_libusb.c b/src/usb_libusb.c index 7653878..3685379 100644 --- a/src/usb_libusb.c +++ b/src/usb_libusb.c @@ -114,12 +114,12 @@ usb_ret_t USBBulkUpload(usb_device_handle_t handle, void *data, int len) static int FoundDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *arg) { - LOG(LOG_VERBOSE, "PongoOS USB Device connected"); stuff_t *stuff = arg; if(stuff->handle) { return LIBUSB_SUCCESS; } + LOG(LOG_VERBOSE, "PongoOS USB Device connected"); libusb_device_handle *handle; int r = libusb_open(dev, &handle); @@ -162,12 +162,12 @@ static int FoundDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_e static int LostDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *arg) { - LOG(LOG_VERBOSE, "PongoOS USB Device disconnected"); stuff_t *stuff = arg; if(stuff->dev != dev) { return LIBUSB_SUCCESS; } + LOG(LOG_VERBOSE, "PongoOS USB Device disconnected"); io_stop(stuff); libusb_close(stuff->handle); @@ -181,6 +181,7 @@ static int LostDevice(libusb_context *ctx, libusb_device *dev, libusb_hotplug_ev int wait_for_pongo(void) { stuff_t stuff; + stuff.handle = NULL; libusb_hotplug_callback_handle hp[2]; libusb_context* ctx = NULL; @@ -198,14 +199,6 @@ int wait_for_pongo(void) return -1; } - r = libusb_hotplug_register_callback(ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, PONGO_USB_VENDOR, PONGO_USB_PRODUCT, LIBUSB_HOTPLUG_MATCH_ANY, FoundDevice, &stuff, &hp[0]); - if(r != LIBUSB_SUCCESS) - { - ERR("libusb_hotplug: %s", libusb_error_name(r)); - libusb_exit(ctx); - return -1; - } - r = libusb_hotplug_register_callback(ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, PONGO_USB_VENDOR, PONGO_USB_PRODUCT, LIBUSB_HOTPLUG_MATCH_ANY, LostDevice, &stuff, &hp[1]); if(r != LIBUSB_SUCCESS) { @@ -214,55 +207,61 @@ int wait_for_pongo(void) return -1; } - libusb_device **list; - ssize_t sz = libusb_get_device_list(ctx, &list); - if(sz < 0) - { - ERR("libusb_get_device_list: %s", libusb_error_name((int)sz)); - libusb_exit(ctx); - return -1; - } - - for(ssize_t i = 0; i < sz; ++i) - { - struct libusb_device_descriptor desc; - r = libusb_get_device_descriptor(list[i], &desc); - if(r != LIBUSB_SUCCESS) - { - ERR("libusb_get_device_descriptor: %s", libusb_error_name(r)); - // continue anyway - } - if(desc.idVendor != PONGO_USB_VENDOR || desc.idProduct != PONGO_USB_PRODUCT) - { - libusb_unref_device(list[i]); - continue; - } - r = FoundDevice(ctx, list[i], LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, &stuff); - for(ssize_t j = i + 1; j < sz; ++j) - { - libusb_unref_device(list[j]); - } - if(r != LIBUSB_SUCCESS) - { - libusb_free_device_list(list, 0); - libusb_exit(ctx); - return -1; - } - break; - } - libusb_free_device_list(list, 0); - - while(get_spin()) - { + while (1) { r = libusb_handle_events(ctx); if(r != LIBUSB_SUCCESS) { ERR("libusb_handle_events: %s", libusb_error_name(r)); break; } + + libusb_device **list; + ssize_t sz = libusb_get_device_list(ctx, &list); + bool done = false; + if(sz < 0) + { + ERR("libusb_get_device_list: %s", libusb_error_name((int)sz)); + libusb_exit(ctx); + return -1; + } + + for(ssize_t i = 0; i < sz; ++i) + { + struct libusb_device_descriptor desc; + r = libusb_get_device_descriptor(list[i], &desc); + if(r != LIBUSB_SUCCESS) + { + ERR("libusb_get_device_descriptor: %s", libusb_error_name(r)); + // continue anyway + } + if(desc.idVendor != PONGO_USB_VENDOR || desc.idProduct != PONGO_USB_PRODUCT) + { + libusb_unref_device(list[i]); + continue; + } + r = FoundDevice(ctx, list[i], LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, &stuff); + for (ssize_t j = i; j < sz; ++j) { + libusb_unref_device(list[j]); + } + + if(r != LIBUSB_SUCCESS) + { + libusb_free_device_list(list, 0); + libusb_exit(ctx); + return -1; + } else { + done = true; + } + break; + } + + libusb_free_device_list(list, 0); + + if (done) goto end; } - libusb_exit(ctx); - return 0; + end: + libusb_exit(ctx); + return 0; } #endif