├── utils ├── kindletool └── fbink_patch │ ├── meson_options.txt │ └── meson.build ├── src ├── kmc │ ├── armel │ │ └── bin │ │ │ └── gandalf │ ├── armhf │ │ └── bin │ │ │ └── gandalf │ ├── hotfix │ │ ├── jobs │ │ │ ├── setup_fbink.sh │ │ │ ├── install_mntus_exec.sh │ │ │ ├── install_kmc_upstart.sh │ │ │ ├── install_gm_debugging.sh │ │ │ ├── install_dispatch.sh │ │ │ ├── install_mkk_kindlet_jb.sh │ │ │ ├── install_debug_commands_kpp_app.sh │ │ │ ├── install_debug_commands_kpp_sys.sh │ │ │ ├── install_debug_commands_pillow.sh │ │ │ ├── install_mkk_dev_keystore.sh │ │ │ ├── 00_setup_kmc_binaries.sh │ │ │ ├── setup_gandalf.sh │ │ │ └── install_update_keys.sh │ │ ├── run_hotfix.sh │ │ ├── hotfix.sh │ │ ├── appreg_register_hotfix_runner.sql │ │ ├── appreg_register_sh_integration.sql │ │ ├── kmc.conf │ │ └── libhotfixutils │ └── KMCLog.sh ├── mkk │ ├── developer.keystore │ ├── json_simple-1.1.jar │ └── dispatch.sh ├── libotautils6 └── install.sh ├── CREDITS ├── .gitmodules ├── .gitignore ├── serialConverter.py ├── .github ├── FUNDING.yml └── workflows │ └── main.yml └── README.md /utils/kindletool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KindleModding/Hotfix/HEAD/utils/kindletool -------------------------------------------------------------------------------- /src/kmc/armel/bin/gandalf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KindleModding/Hotfix/HEAD/src/kmc/armel/bin/gandalf -------------------------------------------------------------------------------- /src/kmc/armhf/bin/gandalf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KindleModding/Hotfix/HEAD/src/kmc/armhf/bin/gandalf -------------------------------------------------------------------------------- /src/mkk/developer.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KindleModding/Hotfix/HEAD/src/mkk/developer.keystore -------------------------------------------------------------------------------- /src/mkk/json_simple-1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KindleModding/Hotfix/HEAD/src/mkk/json_simple-1.1.jar -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | CREDITS 2 | 3 | gandalf: BusyBox, licensed under the GNU General Public License version 2. 4 | (http://www.busybox.net/license.html) 5 | 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sh_integration"] 2 | path = sh_integration 3 | url = https://github.com/KindleModding/sh_integration.git 4 | [submodule "FBInk"] 5 | path = FBInk 6 | url = https://github.com/KindleModding/FBInk.git 7 | -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/setup_fbink.sh: -------------------------------------------------------------------------------- 1 | logmsg "I" "install" "" "Installing fbink" 2 | mkdir -p "/mnt/us/libkh/bin" 3 | rm -f /mnt/us/libkh/bin/fbink 4 | cp -f "${KMC_PERSISTENT_STORAGE}/bin/fbink" "/mnt/us/libkh/bin/fbink" 5 | chmod a+rx "/mnt/us/libkh/bin/fbink" -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_mntus_exec.sh: -------------------------------------------------------------------------------- 1 | if [ ! -f "/MNTUS_EXEC" ] ; then 2 | logmsg "I" "install_mntus_exec_flag" "" "Creating the mntus exec flag file" 3 | make_mutable "/MNTUS_EXEC" 4 | rm -rf "/MNTUS_EXEC" 5 | touch "/MNTUS_EXEC" 6 | make_immutable "/MNTUS_EXEC" 7 | fi -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /build_cache 3 | /build_tmp 4 | /tmp_build_cache 5 | /src/kmc/*/bin/* 6 | /src/kmc/*/lib/* 7 | /src/kmrp/armel 8 | /src/kmrp/armhf 9 | 10 | # We don't build gandalf ourselves at this time 11 | !/src/kmc/*/bin/gandalf 12 | !/src/kmc/*/bin/su 13 | # I know the above (copied su binary) is a bit hacky - BUT IT WORKS -------------------------------------------------------------------------------- /src/kmc/hotfix/run_hotfix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This script is needed if someone performs a cross-architecture downgrade/upgrade 3 | # It selects the correct version of gandalf to run 4 | 5 | ARCH="armel" 6 | # Check if the Kindle is ARMHF or ARMEL 7 | if [ -f /lib/ld-linux-armhf.so.3 ]; then 8 | ARCH="armhf" 9 | fi 10 | 11 | /var/local/kmc/${ARCH}/bin/su -c "sh /var/local/kmc/hotfix/hotfix.sh" -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_kmc_upstart.sh: -------------------------------------------------------------------------------- 1 | # Check if we need to do something with the KMC job 2 | if [ -f "${KMC_PERSISTENT_STORAGE}/hotfix/kmc.conf" ] ; then 3 | if [ ! -f "/etc/upstart/kmc.conf" ] ; then 4 | make_mutable "/etc/upstart/kmc.conf" 5 | rm -rf "/etc/upstart/kmc.conf" 6 | cp -f "${KMC_PERSISTENT_STORAGE}/hotfix/kmc.conf" "/etc/upstart/kmc.conf" 7 | chmod 0664 "/etc/upstart/kmc.conf" 8 | make_immutable "/etc/upstart/kmc.conf" 9 | fi 10 | fi -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_gm_debugging.sh: -------------------------------------------------------------------------------- 1 | if [ ! -f "/PRE_GM_DEBUGGING_FEATURES_ENABLED__REMOVE_AT_GMC" ] ; then 2 | logmsg "I" "install_debugging_flag" "" "Creating the debugging flag file" 3 | make_mutable "/PRE_GM_DEBUGGING_FEATURES_ENABLED__REMOVE_AT_GMC" 4 | rm -rf "/PRE_GM_DEBUGGING_FEATURES_ENABLED__REMOVE_AT_GMC" 5 | touch "/PRE_GM_DEBUGGING_FEATURES_ENABLED__REMOVE_AT_GMC" 6 | make_immutable "/PRE_GM_DEBUGGING_FEATURES_ENABLED__REMOVE_AT_GMC" 7 | fi -------------------------------------------------------------------------------- /serialConverter.py: -------------------------------------------------------------------------------- 1 | # NOTE: Pilfered from https://github.com/NiLuJe/KindleTool/blob/master/tools/kindle_model_sort.py#L26 2 | # NOTE: Pilfered from https://stackoverflow.com/questions/1119722/ 3 | BASE_LIST = tuple("0123456789ABCDEFGHJKLMNPQRSTUVWX") 4 | BASE_DICT = dict((c, v) for v, c in enumerate(BASE_LIST)) 5 | BASE_LEN = len(BASE_LIST) 6 | 7 | def devCode(string): 8 | num = 0 9 | for char in string: 10 | num = num * BASE_LEN + BASE_DICT[char] 11 | return num 12 | 13 | # BionicGecko's ColorSoft 14 | print(hex(devCode("3H7"))) -------------------------------------------------------------------------------- /utils/fbink_patch/meson_options.txt: -------------------------------------------------------------------------------- 1 | option('target', type: 'combo', choices: ['Kindle', 'Kobo', 'Linux', 'reMarkable'], value: 'Linux') 2 | 3 | # Features. 4 | option('bitmap' , type: 'feature') 5 | option('button-scan', type: 'feature') 6 | option('draw' , type: 'feature') 7 | option('fonts' , type: 'feature') 8 | option('image' , type: 'feature') 9 | option('inputlib' , type: 'feature') 10 | option('opentype' , type: 'feature') 11 | 12 | # Programs. 13 | option('input_scan', type: 'feature') 14 | option('fbdepth', type: 'feature') 15 | option('fbink' , type: 'feature') -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_dispatch.sh: -------------------------------------------------------------------------------- 1 | # Ensure we have a dispatch script 2 | if [ -f "${MKK_PERSISTENT_STORAGE}/dispatch.sh" ] ; then 3 | # If logThis.sh isn't installed OR It isn't our Dispatch script 4 | if [ ! -f "/usr/bin/logThis.sh" ] || ! grep -q "Dispatch" "/usr/bin/logThis.sh" ; then 5 | logmsg "I" "install_dispatch" "" "Copying the dispatch script" 6 | make_mutable "/usr/bin/logThis.sh" 7 | rm -rf "/usr/bin/logThis.sh" 8 | cp -f "${MKK_PERSISTENT_STORAGE}/dispatch.sh" "/usr/bin/logThis.sh" 9 | chmod 0755 "/usr/bin/logThis.sh" 10 | make_immutable "/usr/bin/logThis.sh" 11 | fi 12 | fi -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_mkk_kindlet_jb.sh: -------------------------------------------------------------------------------- 1 | # Check if we need to do something with the Kindlet JB 2 | if [ -f "${MKK_PERSISTENT_STORAGE}/json_simple-1.1.jar" ] ; then 3 | # Kindlet JB doesn't match, install it 4 | if [ "$(md5sum "/opt/amazon/ebook/lib/json_simple-1.1.jar" | cut -d' ' -f1)" != "$(md5sum "${MKK_PERSISTENT_STORAGE}/json_simple-1.1.jar" | cut -d' ' -f1)" ] ; then 5 | logmsg "I" "install_mkk_kindlet_jb" "" "Copying the kindlet jailbreak" 6 | cp -f "${MKK_PERSISTENT_STORAGE}/json_simple-1.1.jar" "/opt/amazon/ebook/lib/json_simple-1.1.jar" 7 | chmod 0664 "/opt/amazon/ebook/lib/json_simple-1.1.jar" 8 | fi 9 | fi 10 | -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_debug_commands_kpp_app.sh: -------------------------------------------------------------------------------- 1 | if [ -f "/app/kpp_app_cmds.json" ] ; then 2 | if ! grep -q "logThis.sh" "/app/kpp_app_cmds.json" ; then 3 | logmsg "I" "install_log_kpp" "" "Patching in the dispatch command for kpp" 4 | # KPP (React, new UI) (app) 5 | sed -e '/^{/a\' -e ' ";log" : "/usr/bin/logThis.sh",' -i "/app/kpp_app_cmds.json" 6 | fi 7 | 8 | if ! grep -q "KMCLog.sh" "/app/kpp_app_cmds.json" ; then 9 | logmsg "I" "install_log_kpp" "" "Patching in the KMC log command for kpp" 10 | sed -e '/^{/a\' -e ' ";kmclog" : "/var/local/kmc/KMCLog.sh",' -i "/app/kpp_app_cmds.json" 11 | fi 12 | fi -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_debug_commands_kpp_sys.sh: -------------------------------------------------------------------------------- 1 | if [ -f "/usr/share/app/kpp_sys_cmds.json" ] ; then 2 | if ! grep -q "logThis.sh" "/usr/share/app/kpp_sys_cmds.json" ; then 3 | logmsg "I" "install_log_kpp" "" "Patching in the dispatch command for kpp" 4 | # KPP (React, new UI) (sys) 5 | sed -e '/^{/a\' -e ' ";log" : "/usr/bin/logThis.sh",' -i "/usr/share/app/kpp_sys_cmds.json" 6 | fi 7 | 8 | if ! grep -q "KMCLog.sh" "/usr/share/app/kpp_sys_cmds.json" ; then 9 | logmsg "I" "install_log_kpp" "" "Patching in the KMC log command for kpp" 10 | sed -e '/^{/a\' -e ' ";kmclog" : "/var/local/kmc/KMCLog.sh",' -i "/usr/share/app/kpp_sys_cmds.json" 11 | fi 12 | fi -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_debug_commands_pillow.sh: -------------------------------------------------------------------------------- 1 | if [ -f "/usr/share/webkit-1.0/pillow/debug_cmds.json" ] ; then 2 | if ! grep -q "logThis.sh" "/usr/share/webkit-1.0/pillow/debug_cmds.json" ; then 3 | logmsg "I" "install_log_pillow" "" "Patching in the dispatch command for pillow" 4 | # Pillow (old UI) 5 | sed -e '/^{/a\' -e ' ";log" : "/usr/bin/logThis.sh",' -i "/usr/share/webkit-1.0/pillow/debug_cmds.json" 6 | fi 7 | 8 | if ! grep -q "KMCLog.sh" "/usr/share/webkit-1.0/pillow/debug_cmds.json" ; then 9 | logmsg "I" "install_log_kpp" "" "Patching in the KMC log command for kpp" 10 | sed -e '/^{/a\' -e ' ";kmclog" : "/var/local/kmc/KMCLog.sh",' -i "/usr/share/webkit-1.0/pillow/debug_cmds.json" 11 | fi 12 | fi -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: hackerdude 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 15 | -------------------------------------------------------------------------------- /src/kmc/hotfix/hotfix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | # Pull some helper functions and the such 5 | source /etc/upstart/functions 6 | source /var/local/kmc/hotfix/libhotfixutils 7 | LOG_DOMAIN="jb_hotfix" 8 | 9 | #if [ ! -f "/tmp/run_hotfix" ] || [ $(date +%s) -gt $(($(cat /tmp/run_hotfix) + 30)) ]; then 10 | # date +%s > /tmp/run_hotfix 11 | # ${FBINK_BIN} -y 1 -S 3 "CONFIRM?" 12 | # exit 0 13 | #fi 14 | 15 | # Here we go... 16 | logmsg "I" "hotfix" "" "Running Universal Hotfix (${HOTFIX_VERSION})" 17 | 18 | logmsg "I" "hotfix" "" "Mounting root as RW" 19 | mntroot rw 20 | 21 | for JOB in ${KMC_PERSISTENT_STORAGE}/hotfix/jobs/*.sh ; do 22 | logmsg "I" "jobrunner" "" "Running job: $(basename $JOB)" 23 | source "$(realpath $JOB)" 24 | done 25 | 26 | logmsg "I" "hotfix" "" "Mounting root as RO" 27 | mntroot ro 28 | 29 | logmsg "I" "hotfix" "" "Hotfix Complete! Restarting GUI." 30 | sleep 3 # So they can read what's about to happen 31 | restart lab126_gui & 32 | sleep 3 # Wait for it to stop 33 | /var/local/kmc/bin/fbink -y 3 -m -S 7 "Restarting GUI" 34 | /var/local/kmc/bin/fbink -y 4 -m -S 7 "Please Wait..." 35 | /var/local/kmc/bin/fbink -y 16 -p -S 3 "(Kindles are slow lol) " 36 | /var/local/kmc/bin/fbink -y -6 -m -S 4 "(Error dialog is fine)" 37 | /var/local/kmc/bin/fbink -y -5 -m -S 4 "(Just press close and keep waiting!)" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HAKT 2 | Buy Me a Coffee at ko-fi.com 3 | 4 | HAckerdude's
5 | Kindle
6 | Toolkit
7 | 8 | A collection of utilities including a revamped hotfix all as a single update file to be installed after jailbreaking 9 | - Universal Hotfix 10 | - sh_integration 11 | - KPM 12 | 13 | ## Universal Hotfix 14 | - This is a hotfix based on NiLuJe's K5 Hotfix modified to support both `armel` and `armhf` Kindles 15 | - We target every Kindle the original hotfix did* (*testing needed to validate this to be honest) 16 | - Targets all Kindle architectures and persists cross-architecture upgrades/downgrades 17 | - Designed to install more than just the hotfix/bridge script 18 | - Hotfix Script now uses FBInk natively so eink deprecation issues are ignored 19 | 20 | ## sh_integration 21 | - Allows any .sh file put into a Kindle's documents folder to show up in the library as if it were a book 22 | - .sh files can be run simply by clicking on them 23 | - Stdout and stderr are both redirected to the display via fbink 24 | 25 | ## KPM 26 | - The Kindle Package Manager 27 | - It's like APT, if APT was built in a week and made for Kindles 28 | - Use it via the search bar `;kpm` -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_mkk_dev_keystore.sh: -------------------------------------------------------------------------------- 1 | # Check if we need to do something with the Kindlet developer keystore 2 | if [ -f "${MKK_PERSISTENT_STORAGE}/developer.keystore" ] ; then 3 | # No developer keystore, install it OR The developer keystore doesn't match - NOTE: This *will* mess with real, official developer keystores. Not that we really care about it, but it should be noted ;). 4 | if [ ! -f "/var/local/java/keystore/developer.keystore" ] || \ 5 | [ "$(md5sum "/var/local/java/keystore/developer.keystore" | cut -d' ' -f1)" != "$(md5sum "${MKK_PERSISTENT_STORAGE}/developer.keystore" | cut -d' ' -f1)" ] ; then 6 | 7 | # Install the kindlet keystore 8 | logmsg "I" "install_mkk_dev_keystore" "" "Copying the kindlet keystore" 9 | # We shouldn't need to do anything specific to read/write /var/local 10 | if [ "$(df -k /var/local | tail -n 1 | tr -s ' ' | cut -d' ' -f4)" -lt "512" ] ; then 11 | # Hu ho... Keep track of this... 12 | VARLOCAL_OOS="true" 13 | logmsg "W" "install_mkk_dev_keystore" "" "Failed to copy the kindlet keystore: not enough space left on device" 14 | else 15 | # NOTE: This might have gone poof on newer devices without Kindlet support, so, create it as needed 16 | mkdir -p "/var/local/java/keystore" 17 | cp -f "${MKK_PERSISTENT_STORAGE}/developer.keystore" "/var/local/java/keystore/developer.keystore" 18 | fi 19 | 20 | # Show some feedback 21 | print_mkk_dev_keystore_feedback 22 | fi 23 | fi 24 | -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/00_setup_kmc_binaries.sh: -------------------------------------------------------------------------------- 1 | ### 2 | # Fix permissions for KMC (MKK doesn't need this) 3 | ### 4 | logmsg "I" "install" "" "Fixing KMC permissions" 5 | make_mutable "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 6 | make_mutable "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 7 | chmod -R a+rx "${KMC_PERSISTENT_STORAGE}"/armel/* 8 | chmod -R a+rx "${KMC_PERSISTENT_STORAGE}"/armhf/* 9 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/hotfix.sh" 10 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/run_hotfix.sh" 11 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/libhotfixutils" 12 | chmod a+rx "${KMC_PERSISTENT_STORAGE}"/hotfix/jobs/* 13 | chmod 0664 "${KMC_PERSISTENT_STORAGE}/hotfix/kmc.conf" 14 | 15 | # Fix Gandalf permissions 16 | logmsg "I" "install" "" "Fixing KMC gandalf permissions" 17 | chown root:root "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 18 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 19 | chmod +s "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 20 | chown root:root "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 21 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 22 | chmod +s "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 23 | make_immutable "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 24 | make_immutable "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 25 | 26 | logmsg "I" "install" "" "Installing KMC binaries for ${ARCH}" 27 | rm -rf "${KMC_PERSISTENT_STORAGE}/lib" 28 | rm -rf "${KMC_PERSISTENT_STORAGE}/bin" 29 | ln -sf "${KMC_PERSISTENT_STORAGE}/${ARCH}/lib" "${KMC_PERSISTENT_STORAGE}/lib" 30 | ln -sf "${KMC_PERSISTENT_STORAGE}/${ARCH}/bin" "${KMC_PERSISTENT_STORAGE}/bin" 31 | # Since the links to these binaries are SOFT links, no additional copying/linking is required 32 | -------------------------------------------------------------------------------- /src/kmc/KMCLog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ### 4 | # I'm tired of useless logs 5 | ### 6 | 7 | rm -rf /mnt/us/documents/kmc_log 8 | mkdir /mnt/us/documents/kmc_log 9 | cp -r /var/local/log /mnt/us/documents/kmc_log 10 | LOG_PATH="/mnt/us/documents/kmc_log/kmc_log.txt" 11 | 12 | echo "====================" > "$LOG_PATH" 13 | echo "= START KMC LOG =" >> "$LOG_PATH" 14 | echo "====================" >> "$LOG_PATH" 15 | echo "Running Hotfix v2.3.2" >> "$LOG_PATH" 16 | 17 | # Dump the file list 18 | echo >> "$LOG_PATH" 19 | echo >> "$LOG_PATH" 20 | echo >> "$LOG_PATH" 21 | echo "===> /mnt/us contents" >> "$LOG_PATH" 22 | find /mnt/us -exec md5sum {} \; >> "$LOG_PATH" 23 | 24 | echo >> "$LOG_PATH" 25 | echo >> "$LOG_PATH" 26 | echo >> "$LOG_PATH" 27 | echo "===> /var/local/kmc contents" >> "$LOG_PATH" 28 | find /var/local/kmc -exec md5sum {} \; >> "$LOG_PATH" 29 | 30 | echo >> "$LOG_PATH" 31 | echo >> "$LOG_PATH" 32 | echo >> "$LOG_PATH" 33 | echo "===> /var/local/mkk contents" >> "$LOG_PATH" 34 | find /var/local/mkk -exec md5sum {} \; >> "$LOG_PATH" 35 | 36 | echo "====================" >> "$LOG_PATH" 37 | echo "= THANK YOU. =" >> "$LOG_PATH" 38 | echo "= END KMC LOG =" >> "$LOG_PATH" 39 | echo "====================" >> "$LOG_PATH" 40 | 41 | cp /etc/version.txt /mnt/us/documents/kmc_log/ 42 | cp /etc/prettyversion.txt /mnt/us/documents/kmc_log/ 43 | 44 | cp /var/log/messages /mnt/us/documents/kmc_log/var_log_messages 45 | dmesg >> /mnt/us/documents/kmc_log/dmesg 46 | 47 | cp /var/local/appreg.db /mnt/us/documents/kmc_log/ 48 | cp /var/local/cc.db /mnt/us/documents/kmc_log/ 49 | cp /var/local/deviceType.txt /mnt/us/documents/kmc_log/ 50 | 51 | tar czf /mnt/us/documents/kmc_log.tar.gz /mnt/us/documents/kmc_log 52 | rm -rf /mnt/us/documents/kmc_log -------------------------------------------------------------------------------- /src/kmc/hotfix/appreg_register_hotfix_runner.sql: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | DELETE FROM properties WHERE handlerId='org.kindlemodding.hotfix_launcher'; 3 | DELETE FROM mimetypes WHERE ext='run_hotfix'; 4 | DELETE FROM extenstions WHERE ext='run_hotfix'; 5 | DELETE FROM handlerIds WHERE handlerId='org.kindlemodding.hotfix_launcher'; 6 | DELETE FROM associations WHERE handlerId='org.kindlemodding.hotfix_launcher'; 7 | 8 | INSERT INTO mimetypes (ext, mimetype) VALUES ('run_hotfix', 'MT:kindlemodding/run_hotfix'); 9 | INSERT INTO extenstions (ext, mimetype) VALUES ('run_hotfix', 'MT:kindlemodding/run_hotfix'); 10 | 11 | INSERT INTO associations (interface, handlerId, contentId, defaultAssoc) VALUES ('extractor', 'com.lab126.generic.extractor', 'GL:*.run_hotfix', 'true'); 12 | 13 | INSERT INTO handlerIds (handlerId) VALUES ('org.kindlemodding.hotfix_launcher'); 14 | INSERT INTO properties (handlerId, name, value) VALUES ('org.kindlemodding.hotfix_launcher', 'extend-start', 'Y'); 15 | INSERT INTO properties (handlerId, name, value) VALUES ('org.kindlemodding.hotfix_launcher', 'unloadPolicy', 'unloadOnPause'); 16 | INSERT INTO properties (handlerId, name, value) VALUES ('org.kindlemodding.hotfix_launcher', 'maxGoTime', '600'); 17 | INSERT INTO properties (handlerId, name, value) VALUES ('org.kindlemodding.hotfix_launcher', 'maxPauseTime', '600'); 18 | INSERT INTO properties (handlerId, name, value) VALUES ('org.kindlemodding.hotfix_launcher', 'maxUnloadTime', '600'); 19 | INSERT INTO properties (handlerId, name, value) VALUES ('org.kindlemodding.hotfix_launcher', 'maxLoadTime', '600'); 20 | INSERT INTO properties (handlerId, name, value) VALUES ('org.kindlemodding.hotfix_launcher', 'command', '/bin/sh /var/local/kmc/hotfix/run_hotfix.sh'); 21 | 22 | INSERT INTO associations (interface, handlerId, contentId, defaultAssoc) VALUES ('application', 'org.kindlemodding.hotfix_launcher', 'MT:kindlemodding/run_hotfix', 'true'); 23 | 24 | 25 | COMMIT; -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/setup_gandalf.sh: -------------------------------------------------------------------------------- 1 | setup_gandalf() 2 | { 3 | # Fix Gandalf permissions 4 | logmsg "I" "install" "" "Fixing KMC Gandalf permissions" 5 | for gandalf_arch in armel armhf; do 6 | make_mutable "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 7 | chown root:root "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 8 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 9 | chmod +s "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 10 | make_immutable "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 11 | done 12 | 13 | make_mutable "${KMC_PERSISTENT_STORAGE}" 14 | logmsg "I" "setup_gandalf" "" "Setting up gandalf... you shall not pass!" 15 | logmsg "I" "install" "" "Linking gandalf to MKK" 16 | 17 | make_mutable "${MKK_PERSISTENT_STORAGE}" 18 | rm -f "${MKK_PERSISTENT_STORAGE}/gandalf" 19 | ln -sf "${KMC_PERSISTENT_STORAGE}/bin/gandalf" "${MKK_PERSISTENT_STORAGE}/gandalf" 20 | ln -sf "${MKK_PERSISTENT_STORAGE}/gandalf" "${MKK_PERSISTENT_STORAGE}/su" 21 | make_immutable "${MKK_PERSISTENT_STORAGE}" 22 | 23 | # Show some feedback 24 | print_gandalf_feedback 25 | } 26 | 27 | # Check if we need to do something with Gandalf 28 | if [ -f "${MKK_PERSISTENT_STORAGE}/gandalf" ] ; then 29 | # NOTE: The bridge job already does this, too. 30 | if [ ! -O "${MKK_PERSISTENT_STORAGE}/gandalf" ] || [ ! -G "${MKK_PERSISTENT_STORAGE}/gandalf" ] ; then 31 | setup_gandalf 32 | fi 33 | if [ ! -x "${MKK_PERSISTENT_STORAGE}/gandalf" ] ; then 34 | setup_gandalf 35 | fi 36 | if [ ! -u "${MKK_PERSISTENT_STORAGE}/gandalf" ] ; then 37 | setup_gandalf 38 | fi 39 | if [ ! -h "${MKK_PERSISTENT_STORAGE}/su" ] ; then 40 | setup_gandalf 41 | fi 42 | if [ ! -x "${MKK_PERSISTENT_STORAGE}/su" ] ; then 43 | setup_gandalf 44 | fi 45 | # NOTE: This will actually end up a NOOP, because -O & -G tests don't behave all that well with symlinks... 46 | if [ ! -O "${MKK_PERSISTENT_STORAGE}/su" ] || [ ! -G "${MKK_PERSISTENT_STORAGE}/su" ] ; then 47 | setup_gandalf 48 | fi 49 | fi -------------------------------------------------------------------------------- /src/mkk/dispatch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Kindle Oasis Dispatch 4 | # 5 | # $Id: dispatch.sh 16928 2020-03-08 18:29:45Z NiLuJe $ 6 | # 7 | ## 8 | 9 | ## NOTE: We always bridge this, even though it's no longer accessible on stock FW >= 5.12.2, 10 | ## because the ;log debug command is gone. Emphasis on "stock", though ;). 11 | 12 | ## Check our args... 13 | if [ "$#" -ne 1 ] ; then 14 | /var/local/kmc/bin/fbink -x 1 -y 0 -S 3 "No arg passed. Select from mrpi or runme" 15 | return 0 16 | fi 17 | 18 | case "${1}" in 19 | # Launch MRPI! 20 | "mrpi" | "MRPI" | m* ) 21 | if [ -f "/mnt/us/extensions/MRInstaller/bin/mrinstaller.sh" ] ; then 22 | if [ "$(id -u)" -ne 0 ] ; then 23 | if [ -x "/var/local/mkk/gandalf" ] ; then 24 | exec /var/local/mkk/su -s /bin/sh -c "/mnt/us/extensions/MRInstaller/bin/mrinstaller.sh launch_installer" 25 | else 26 | /var/local/kmc/bin/fbink -x 1 -y 0 -S 3 "No wizard to help you out. " 27 | # Run it anyway, who knows. 28 | exec /bin/sh "/mnt/us/extensions/MRInstaller/bin/mrinstaller.sh" launch_installer 29 | fi 30 | else 31 | exec /bin/sh "/mnt/us/extensions/MRInstaller/bin/mrinstaller.sh" launch_installer 32 | fi 33 | else 34 | /var/local/kmc/bin/fbink -x 1 -y 0 -S 3 "MRPI is not installed. " 35 | fi 36 | ;; 37 | # Launch user script! 38 | "custom" | "CUSTOM" | "runme" | "RUNME" | r* ) 39 | if [ -f "/mnt/us/RUNME.sh" ] ; then 40 | if [ "$(id -u)" -ne 0 ] ; then 41 | if [ -x "/var/local/mkk/gandalf" ] ; then 42 | exec /var/local/mkk/su -s /bin/sh -c "/mnt/us/RUNME.sh" 43 | else 44 | /var/local/kmc/bin/fbink -x 1 -y 0 -S 3 "No wizard to help you out. " 45 | # Run it anyway, who knows. 46 | exec /bin/sh "/mnt/us/RUNME.sh" 47 | fi 48 | else 49 | exec /bin/sh "/mnt/us/RUNME.sh" 50 | fi 51 | else 52 | /var/local/kmc/bin/fbink -x 1 -y 0 -S 3 "No user script found. " 53 | fi 54 | ;; 55 | * ) 56 | /var/local/kmc/bin/fbink -x 1 -y 0 -S 3 "Wrong arg. Select from mrpi or runme " 57 | ;; 58 | esac 59 | 60 | return 0 61 | -------------------------------------------------------------------------------- /src/kmc/hotfix/appreg_register_sh_integration.sql: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | DELETE FROM properties WHERE handlerId='com.notmarek.shell_integration.launcher'; 3 | DELETE FROM properties WHERE handlerId='com.notmarek.shell_integration.extractor'; 4 | DELETE FROM mimetypes WHERE ext='sh'; 5 | DELETE FROM extenstions WHERE ext='sh'; 6 | DELETE FROM handlerIds WHERE handlerId='com.notmarek.shell_integration.launcher'; 7 | DELETE FROM handlerIds WHERE handlerId='com.notmarek.shell_integration.extractor'; 8 | DELETE FROM associations WHERE handlerId='com.notmarek.shell_integration.launcher'; 9 | 10 | INSERT INTO mimetypes (ext, mimetype) VALUES ('sh', 'MT:text/x-shellscript'); 11 | INSERT INTO extenstions (ext, mimetype) VALUES ('sh', 'MT:text/x-shellscript'); 12 | 13 | INSERT INTO handlerIds (handlerId) VALUES ('com.notmarek.shell_integration.launcher'); 14 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.launcher', 'extend-start', 'Y'); 15 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.launcher', 'unloadPolicy', 'unloadOnPause'); 16 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.launcher', 'maxGoTime', '60'); 17 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.launcher', 'maxPauseTime', '60'); 18 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.launcher', 'maxUnloadTime', '60'); 19 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.launcher', 'maxLoadTime', '60'); 20 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.launcher', 'command', '/var/local/kmc/bin/sh_integration_launcher'); 21 | INSERT INTO associations (interface, handlerId, contentId, defaultAssoc) VALUES ('application', 'com.notmarek.shell_integration.launcher', 'MT:text/x-shellscript', 'true'); 22 | 23 | 24 | INSERT INTO handlerIds (handlerId) VALUES ('com.notmarek.shell_integration.extractor'); 25 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.extractor', 'lib', '/var/local/kmc/lib/sh_integration_extractor.so'); 26 | INSERT INTO properties (handlerId, name, value) VALUES ('com.notmarek.shell_integration.extractor', 'entry', 'load_extractor'); 27 | INSERT INTO associations (interface, handlerId, contentId, defaultAssoc) VALUES ('extractor', 'com.notmarek.shell_integration.extractor', 'GL:*.sh', 'true'); 28 | COMMIT; -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | kindletool: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | if: steps.cache-kindletool.outputs.cache-hit != 'true' 15 | with: 16 | repository: KindleModding/KindleTool 17 | - name: Cache Kindletool 18 | id: cache-kindletool 19 | uses: actions/cache@v4 20 | with: 21 | path: KindleTool 22 | key: ${{ runner.os }}-kindletool-${{ hashFiles('KindleTool/**') }} 23 | - name: Compile KindleTool 24 | if: steps.cache-kindletool.outputs.cache-hit != 'true' 25 | run: | 26 | sudo apt-get install -y zlib1g-dev libarchive-dev nettle-dev 27 | make 28 | - uses: actions/upload-artifact@v4 29 | with: 30 | name: kindletool 31 | path: KindleTool/Release/kindletool 32 | 33 | build: 34 | runs-on: ubuntu-latest 35 | needs: kindletool 36 | 37 | steps: 38 | - name: Setup 39 | run: sudo apt-get install meson 40 | - name: Download toolchain 41 | run: | 42 | wget -q https://github.com/KindleModding/koxtoolchain/releases/latest/download/kindlepw2.tar.gz -O - | tar -xzf - -C ~ 43 | wget -q https://github.com/KindleModding/koxtoolchain/releases/latest/download/kindlehf.tar.gz -O - | tar -xzf - -C ~ 44 | - uses: actions/checkout@v4 45 | with: 46 | submodules: recursive 47 | - name: Remove old Kindletool 48 | run: rm -f ./utils/kindletool 49 | - uses: actions/download-artifact@v4 50 | with: 51 | name: kindletool 52 | path: ./utils/ 53 | - uses: actions/checkout@v4 54 | with: 55 | repository: KindleModding/kindle-sdk 56 | submodules: recursive 57 | path: kindle-sdk 58 | - name: "Setup kindle-sdk" 59 | run: | 60 | sudo apt-get install -y zlib1g-dev libarchive-dev nettle-dev curl 61 | bash ./kindle-sdk/gen-sdk.sh kindlepw2 62 | bash ./kindle-sdk/gen-sdk.sh kindlehf 63 | - name: Cache Kindle firmware 64 | id: build-cache 65 | uses: actions/cache@v4 66 | with: 67 | path: ./build_cache 68 | key: ${{ runner.os }}-build-cache 69 | - name: build 70 | run: | 71 | chmod 755 ./utils/kindletool 72 | chown -R $USER: ./utils/ 73 | sh ./build.sh 74 | - uses: actions/upload-artifact@v4 75 | with: 76 | name: HAKT_BUILD_DEV 77 | path: build/ 78 | -------------------------------------------------------------------------------- /src/kmc/hotfix/jobs/install_update_keys.sh: -------------------------------------------------------------------------------- 1 | install_touch_update_key() 2 | { 3 | logmsg "I" "install_touch_update_key" "" "Copying the jailbreak updater key" 4 | make_mutable "/etc/uks/pubdevkey01.pem" 5 | rm -rf "/etc/uks/pubdevkey01.pem" 6 | cat > "/etc/uks/pubdevkey01.pem" << EOF 7 | -----BEGIN PUBLIC KEY----- 8 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJn1jWU+xxVv/eRKfCPR9e47lP 9 | WN2rH33z9QbfnqmCxBRLP6mMjGy6APyycQXg3nPi5fcb75alZo+Oh012HpMe9Lnp 10 | eEgloIdm1E4LOsyrz4kttQtGRlzCErmBGt6+cAVEV86y2phOJ3mLk0Ek9UQXbIUf 11 | rvyJnS2MKLG2cczjlQIDAQAB 12 | -----END PUBLIC KEY----- 13 | EOF 14 | # Harmonize permissions 15 | chown root:root "/etc/uks/pubdevkey01.pem" 16 | chmod 0644 "/etc/uks/pubdevkey01.pem" 17 | make_immutable "/etc/uks/pubdevkey01.pem" 18 | 19 | # Show some feedback 20 | print_jb_install_feedback 21 | } 22 | 23 | install_touch_update_key_squash() 24 | { 25 | logmsg "I" "install_touch_update_key_squash" "" "Copying the jailbreak updater keystore" 26 | make_mutable "/etc/uks.sqsh" 27 | local my_loop="$(grep ' /etc/uks ' /proc/mounts | cut -f1 -d' ')" 28 | umount "${my_loop}" 29 | losetup -d "${my_loop}" 30 | cp -f "${MKK_PERSISTENT_STORAGE}/updater_keys.sqsh" "/etc/uks.sqsh" 31 | mount -o loop="${my_loop}",nodiratime,noatime -t squashfs "/etc/uks.sqsh" "/etc/uks" 32 | #make_immutable "/etc/uks.sqsh" # Breaks 12th gen 33 | 34 | # Show some feedback 35 | print_jb_squash_install_feedback 36 | } 37 | 38 | # Check if we need to do something with the OTA pubkey 39 | if [ ! -f "/etc/uks.sqsh" ] ; then 40 | if [ ! -f "/etc/uks/pubdevkey01.pem" ] ; then 41 | # No jailbreak key, install it 42 | install_touch_update_key 43 | else 44 | # Jailbreak key found... Check it. 45 | if [ "$(md5sum "/etc/uks/pubdevkey01.pem" | cut -d' ' -f1)" != "7130ce39bb3596c5067cabb377c7a9ed" ] ; then 46 | # Unknown (?!) jailbreak key, install it 47 | install_touch_update_key 48 | fi 49 | if [ ! -O "/etc/uks/pubdevkey01.pem" ] || [ ! -G "/etc/uks/pubdevkey01.pem" ] ; then 50 | # Not our own? Make it so! 51 | install_touch_update_key 52 | fi 53 | fi 54 | fi 55 | 56 | # Check if we need to do something with the OTA keystore 57 | if [ -f "/etc/uks.sqsh" ] && [ -f "${MKK_PERSISTENT_STORAGE}/updater_keys.sqsh" ] ; then 58 | # Check it. 59 | if [ "$(md5sum "/etc/uks.sqsh" | cut -d' ' -f1)" != "17b5ca595e70ffeee1424ed5e7f09c47" ] ; then 60 | # Unknown (?!) jailbreak keystore, install it 61 | install_touch_update_key_squash 62 | fi 63 | if [ ! -O "/etc/uks.sqsh" ] || [ ! -G "/etc/uks.sqsh" ] ; then 64 | # Not our own? Make it so! 65 | install_touch_update_key_squash 66 | fi 67 | fi 68 | -------------------------------------------------------------------------------- /src/kmc/hotfix/kmc.conf: -------------------------------------------------------------------------------- 1 | #kate: syntax bash; 2 | description "Bridge companion" 3 | version "$Id: bridge.conf 17398 2020-05-24 03:39:18Z NiLuJe $" 4 | 5 | 6 | # The updated framework job is the root of our problems, so start well after it ;). 7 | start on framework_ready 8 | stop on stopping framework 9 | 10 | export LANG LC_ALL 11 | 12 | pre-start script 13 | [ -f "/etc/upstart/functions" ] && source /etc/upstart/functions 14 | 15 | BRJOB_REV="$( echo '$Revision: 17398 $' | cut -d ' ' -f 2 )" 16 | f_log I bridge start "" "hello there! (r${BRJOB_REV})" 17 | 18 | BRIDGE_EMERGENCY="/mnt/us/emergency.sh" 19 | 20 | # First things first, check for an emergency script 21 | if [ -f "${BRIDGE_EMERGENCY}" ] ; then 22 | # We got one, make it executable and use it 23 | [ -x "${BRIDGE_EMERGENCY}" ] || chmod +x "${BRIDGE_EMERGENCY}" 24 | # Run it... 25 | f_log I bridge start "" "starting bridge emergency script" 26 | /bin/sh "${BRIDGE_EMERGENCY}" 27 | # And GET OUT! NOW! 28 | return 0 29 | fi 30 | 31 | # Find which chattr to use 32 | OLD_CHATTR="/bin/chattr" 33 | NEW_CHATTR="/bin/chattr.e2fsprogs" # KT6 5.18.1.5+ and PW6, KS, & KS2 5.18.5+ 34 | if [ -f "${OLD_CHATTR}" ]; then 35 | CHATTR="${OLD_CHATTR}" 36 | elif [ -f "${NEW_CHATTR}" ]; then 37 | CHATTR="${NEW_CHATTR}" 38 | else 39 | # We couldn't find one, show an error, and pretend it's the old one I guess 40 | f_log E bridge find_chattr "" "Could not find chattr command!" 41 | CHATTR="${OLD_CHATTR}" # won't be found, but better than nothing? 42 | fi 43 | 44 | make_mutable() { 45 | local my_path="${1}" 46 | # NOTE: Can't do that on symlinks, hence the hoop-jumping... 47 | if [ -d "${my_path}" ] ; then 48 | find "${my_path}" -type d -exec ${CHATTR} -i '{}' \; 49 | find "${my_path}" -type f -exec ${CHATTR} -i '{}' \; 50 | elif [ -f "${my_path}" ] ; then 51 | ${CHATTR} -i "${my_path}" 52 | fi 53 | } 54 | 55 | make_immutable() { 56 | local my_path="${1}" 57 | if [ -d "${my_path}" ] ; then 58 | find "${my_path}" -type d -exec ${CHATTR} +i '{}' \; 59 | find "${my_path}" -type f -exec ${CHATTR} +i '{}' \; 60 | elif [ -f "${my_path}" ] ; then 61 | ${CHATTR} +i "${my_path}" 62 | fi 63 | } 64 | 65 | # Barring that, let's fix our stuff up... 66 | MKK_PERSISTENT_STORAGE="/var/local/mkk" 67 | KMC_PERSISTENT_STORAGE="/var/local/kmc" 68 | 69 | # Get the Kindle's architecture 70 | ARCH="armel" 71 | # Check if the Kindle is ARMHF or ARMEL 72 | if [ -f /lib/ld-linux-armhf.so.3 ]; then 73 | ARCH="armhf" 74 | fi 75 | 76 | # Permissions fixups... 77 | make_mutable "${MKK_PERSISTENT_STORAGE}" 78 | for my_path in "${MKK_PERSISTENT_STORAGE}" ; do 79 | if [ -d "${my_path}" ] ; then 80 | # Not ours? Fix it! 81 | if [ ! -O "${my_path}" ] || [ ! -G "${my_path}" ] ; then 82 | chown -R root:root "${my_path}" 83 | fi 84 | # Has a crappy setgid bit set? Kill it! 85 | if [ -g "${my_path}" ] ; then 86 | chmod g-s "${my_path}" 87 | fi 88 | fi 89 | done 90 | 91 | ### 92 | # Fix permissions for KMC (MKK doesn't need this) 93 | ### 94 | make_mutable "${MKK_PERSISTENT_STORAGE}" 95 | f_log "I" "install" "" "Fixing KMC permissions" 96 | chmod 0664 "${KMC_PERSISTENT_STORAGE}/kmc.conf" 97 | chmod -R a+rx "${KMC_PERSISTENT_STORAGE}/armel/*" 98 | chmod -R a+rx "${KMC_PERSISTENT_STORAGE}/armhf/*" 99 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/hotfix.sh" 100 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/run_hotfix.sh" 101 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/libhotfixutils" 102 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/jobs/*" 103 | 104 | # Fix Gandalf permissions 105 | f_log "I" "install" "" "Fixing KMC gandalf permissions" 106 | chown root:root "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 107 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 108 | chmod +s "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" 109 | chown root:root "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 110 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 111 | chmod +s "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" 112 | 113 | f_log "I" "install" "" "Installing KMC binaries for ${ARCH}" 114 | make_mutable "${KMC_PERSISTENT_STORAGE}/bin" 115 | make_mutable "${KMC_PERSISTENT_STORAGE}/lib" 116 | rm -rf "${KMC_PERSISTENT_STORAGE}/lib" 117 | rm -rf "${KMC_PERSISTENT_STORAGE}/bin" 118 | ln -sf "${KMC_PERSISTENT_STORAGE}/${ARCH}/lib" "${KMC_PERSISTENT_STORAGE}/lib" 119 | ln -sf "${KMC_PERSISTENT_STORAGE}/${ARCH}/bin" "${KMC_PERSISTENT_STORAGE}/bin" 120 | # Since the links to these binaries are SOFT links, no additional copying/linking is required 121 | make_immutable "${MKK_PERSISTENT_STORAGE}/bin" 122 | make_immutable "${MKK_PERSISTENT_STORAGE}/lib" 123 | make_immutable "${MKK_PERSISTENT_STORAGE}" 124 | 125 | f_log I bridge start "" "so uncivilized" 126 | 127 | return 0 128 | end script 129 | -------------------------------------------------------------------------------- /utils/fbink_patch/meson.build: -------------------------------------------------------------------------------- 1 | project('fbink', 'c', version: '1.25.0') 2 | 3 | cc = meson.get_compiler('c') 4 | 5 | m_dep = cc.find_library('m', required: false) 6 | 7 | target = get_option('target') 8 | if target == '' 9 | target = host_machine.system() 10 | endif 11 | 12 | c_args = [ 13 | '-D_REENTRANT=1', 14 | '-D_GNU_SOURCE', 15 | '-DFBINK_MINIMAL', 16 | '-DFBINK_FOR_' + target.to_upper(), 17 | '-DFBINK_VERSION="' + meson.project_version() + ' for ' + get_option('target') + 18 | '"', 19 | ] 20 | 21 | src = [ 22 | 'cutef8/dfa.c', 23 | 'cutef8/utf8.c', 24 | 'fbink.c', 25 | ] 26 | 27 | draw_opt = get_option('draw') 28 | if draw_opt.allowed() 29 | c_args += '-DFBINK_WITH_DRAW' 30 | endif 31 | 32 | bitmap_opt = get_option( 33 | 'bitmap', 34 | ).require( 35 | draw_opt.allowed(), 36 | error_message: 'needs the draw feature', 37 | ) 38 | if bitmap_opt.allowed() 39 | c_args += '-DFBINK_WITH_BITMAP' 40 | endif 41 | 42 | button_scan_opt = get_option( 43 | 'button-scan', 44 | ).require( 45 | target in ['Cervantes', 'Kobo'], 46 | error_message: 'is only supported for the Cervantes and Kobo targets', 47 | ).require( 48 | draw_opt.allowed(), 49 | error_message: 'needs the draw feature', 50 | ) 51 | if button_scan_opt.allowed() 52 | c_args += '-DFBINK_WITH_BUTTON_SCAN' 53 | endif 54 | 55 | fonts_opt = get_option( 56 | 'fonts', 57 | ).require( 58 | bitmap_opt.allowed(), 59 | error_message: 'needs the bitmap feature', 60 | ) 61 | if fonts_opt.allowed() 62 | c_args += '-DFBINK_WITH_FONTS' 63 | endif 64 | 65 | image_opt = get_option( 66 | 'image', 67 | ).require( 68 | draw_opt.allowed(), 69 | error_message: 'needs the draw feature', 70 | ) 71 | if image_opt.allowed() 72 | c_args += '-DFBINK_WITH_IMAGE' 73 | src += 'qimagescale/qimagescale.c' 74 | endif 75 | 76 | inputlib_opt = get_option('inputlib') 77 | if inputlib_opt.allowed() 78 | c_args += '-DFBINK_WITH_INPUT' 79 | endif 80 | 81 | opentype_opt = get_option( 82 | 'opentype', 83 | ).require( 84 | draw_opt.allowed(), 85 | error_message: 'needs the draw feature', 86 | ) 87 | if opentype_opt.allowed() 88 | c_args += '-DFBINK_WITH_OPENTYPE' 89 | src += [ 90 | 'libunibreak/src/eastasianwidthdef.c', 91 | 'libunibreak/src/linebreak.c', 92 | 'libunibreak/src/linebreakdata.c', 93 | 'libunibreak/src/linebreakdef.c', 94 | 'libunibreak/src/unibreakdef.c', 95 | ] 96 | endif 97 | 98 | if target == 'Kobo' 99 | src += 'i2c-tools/lib/smbus.c' 100 | endif 101 | 102 | fbink_static_lib = static_library( 103 | 'fbink', 104 | src, 105 | c_args: c_args, 106 | dependencies: m_dep, 107 | include_directories: include_directories( 108 | 'i2c-tools/include', 109 | ), 110 | ) 111 | 112 | fbink_shared_lib = shared_library( 113 | 'fbink', 114 | src, 115 | c_args: c_args + '-DFBINK_SHAREDLIB', 116 | dependencies: m_dep, 117 | include_directories: include_directories( 118 | 'i2c-tools/include', 119 | ), 120 | ) 121 | 122 | fbink_dep = declare_dependency( 123 | include_directories: '.', 124 | link_with: fbink_static_lib, 125 | ) 126 | 127 | meson.override_dependency('fbink', fbink_dep) 128 | 129 | fbink_opt = get_option( 130 | 'fbink', 131 | ).require( 132 | bitmap_opt.allowed(), 133 | error_message: 'needs the bitmap feature', 134 | ) 135 | if fbink_opt.allowed() 136 | executable( 137 | 'fbink', 138 | 'fbink_cmd.c', 139 | c_args: c_args, 140 | include_directories: include_directories( 141 | 'i2c-tools/include', 142 | ), 143 | install: true, 144 | link_with: fbink_static_lib, 145 | ) 146 | endif 147 | 148 | if inputlib_opt.allowed() 149 | fbink_input_lib = library( 150 | 'fbink_input', 151 | 'fbink_input_scan.c', 152 | c_args: c_args + '-DFBINK_INPUT_LIB' + ( 153 | get_option('default_library') == 'shared' ? '-DFBINK_SHAREDLIB' : [] 154 | ) + cc.get_supported_arguments('-Wno-unused-function'), 155 | install: true, 156 | ) 157 | fbink_input_dep = declare_dependency( 158 | include_directories: '.', 159 | link_with: fbink_input_lib, 160 | ) 161 | meson.override_dependency('fbink_input', fbink_input_dep) 162 | endif 163 | 164 | fbdepth_opt = get_option('fbdepth') 165 | if fbdepth_opt.allowed() 166 | executable( 167 | 'fbdepth', 168 | 'utils/fbdepth.c', 169 | c_args: c_args, 170 | install: true, 171 | link_with: fbink_static_lib, 172 | ) 173 | endif 174 | 175 | fbink_input_scan_opt = get_option('input_scan') 176 | if fbink_input_scan_opt.allowed() 177 | executable( 178 | 'input_scan', 179 | 'utils/input_scan.c', 180 | c_args: c_args, 181 | install: true, 182 | link_with: fbink_static_lib, 183 | ) 184 | endif 185 | 186 | summary( 187 | { 188 | 'Bitmap' : bitmap_opt.allowed(), 189 | 'Button scan' : button_scan_opt.allowed(), 190 | 'Draw' : draw_opt.allowed(), 191 | 'Fonts' : fonts_opt.allowed(), 192 | 'Image' : image_opt.allowed(), 193 | 'Input library': inputlib_opt.allowed(), 194 | 'OpenType' : opentype_opt.allowed(), 195 | 'Target' : get_option('target'), 196 | 'Tools' : ', '.join( 197 | fbdepth_opt.allowed() ? 'fbdepth' : [], 198 | fbink_opt.allowed() ? 'fbink' : [], 199 | fbink_input_scan_opt.allowed() ? 'input_scan' : [], 200 | ), 201 | }, 202 | bool_yn: true, 203 | ) -------------------------------------------------------------------------------- /src/libotautils6: -------------------------------------------------------------------------------- 1 | ### 2 | # Logging/Progressbar handling for OTA update scripts 3 | # Based on libotautils5 from NiLuJe 4 | # Written by HackerDude 5 | # 6 | # (The 5 meant K5 not version 5 didn't it...) 7 | # Notable Changes 8 | # - Use an enum for models 9 | # - Remove dependency on eips (being deprecated in favour for eips_v2, might as well use fbink in case it happens again) 10 | # 11 | ## 12 | 13 | ### 14 | # Variables 15 | ### 16 | HOTFIX_VERSION="v2.3.2" 17 | KMC_PERSISTENT_STORAGE="/var/local/kmc" 18 | MKK_PERSISTENT_STORAGE="/var/local/mkk" 19 | KMC_BACKUP_STORAGE="/mnt/us/kmc" 20 | MKK_BACKUP_STORAGE="/mnt/us/mkk" 21 | RP_BACKUP_STORAGE="/mnt/us/rp" 22 | ARCH="armel" 23 | # Check if the Kindle is ARMHF or ARMEL 24 | if [ -f /lib/ld-linux-armhf.so.3 ]; then 25 | ARCH="armhf" 26 | fi 27 | 28 | ### 29 | # General helpers 30 | ### 31 | # Pull some helper functions for logging 32 | _FUNCTIONS=/etc/upstart/functions 33 | [ -f ${_FUNCTIONS} ] && source ${_FUNCTIONS} 34 | 35 | # Make sure HACKNAME is set (NOTE: This should be overriden in the update script) 36 | [ -z "${HACKNAME}" ] && HACKNAME="ota_script" 37 | 38 | FBINK_BIN="${KMC_PERSISTENT_STORAGE}/${ARCH}/bin/fbink" 39 | 40 | 41 | 42 | # Adapt the K5 logging calls to the simpler legacy syntax 43 | _LOGMSG_Y=2 44 | logmsg() 45 | { 46 | f_log "${1}" "${HACKNAME}" "${2}" "${3}" "${4}" 47 | # Add our own echo, like on legacy devices (useful for MRPI logging, since f_log's one is sent to /dev/console) 48 | if [ "${1}" != "D" ] ; then 49 | echo "system: ${1} ${HACKNAME}:${2}:${3}:${4}" 50 | fi 51 | if [ -f "$FBINK_BIN" ]; then 52 | ${FBINK_BIN} -x 1 -y $_LOGMSG_Y -r -S 3 "${1}: ${4}" 53 | fi 54 | _LOGMSG_Y=$(($_LOGMSG_Y + 1)) 55 | } 56 | 57 | # Find which chattr to use 58 | OLD_CHATTR="/bin/chattr" 59 | NEW_CHATTR="/bin/chattr.e2fsprogs" # KT6 5.18.1.5+ and PW6, KS, & KS2 5.18.5+ 60 | if [ -f "${OLD_CHATTR}" ]; then 61 | CHATTR="${OLD_CHATTR}" 62 | elif [ -f "${NEW_CHATTR}" ]; then 63 | CHATTR="${NEW_CHATTR}" 64 | else 65 | # We couldn't find one, show an error, and pretend it's the old one I guess 66 | logmsg "E" "find_chattr" "" "Could not find chattr command!" 67 | CHATTR="${OLD_CHATTR}" # won't be found, but better than nothing? 68 | fi 69 | 70 | 71 | 72 | ### 73 | # Progressbar stuff 74 | ### 75 | # Some constants... 76 | _BLANKET="com.lab126.blanket" 77 | _OTAMODULE="${_BLANKET}.ota" 78 | 79 | # Check if blanket is running 80 | if pkill -0 blanket ; then 81 | BLANKET_IS_UP="true" 82 | else 83 | BLANKET_IS_UP="false" 84 | fi 85 | 86 | # Send progress to blanket, or print it manually otherwise 87 | otautils_update_progress_indicator() 88 | { 89 | local cur_percentage="${1}" 90 | 91 | if [ "${BLANKET_IS_UP}" == "true" ] ; then 92 | lipc-send-event ${_OTAMODULE} otaSplashProgress -i ${cur_percentage} 93 | else 94 | # NOTE: We can actually draw a progress bar with FBInk! 95 | ${FBINK_BIN} -qP ${cur_percentage} -y $(( -6 )) 96 | fi 97 | } 98 | 99 | 100 | # Check if arg is an int 101 | is_integer() 102 | { 103 | # Cheap trick ;) 104 | [ "${1}" -eq "${1}" ] 2>/dev/null 105 | return $? 106 | } 107 | 108 | # The amount of steps needed to fill the progress bar 109 | # I'm lazy, so just count the amount of calls in the script itself ;) 110 | # NOTE: Yup, $0 still points to the original script that sourced us :). 111 | [ -z ${STEPCOUNT} ] && STEPCOUNT="$(grep -c '^[[:blank:]]*otautils_update_progressbar$' ${0} 2>/dev/null)" 112 | # Make sure it's sane... 113 | is_integer "${STEPCOUNT}" || STEPCOUNT=1 114 | # NOTE: If you need to for some strange reason, this can be overriden in the update script 115 | 116 | # In case we need to catch failure early... 117 | otautils_die() 118 | { 119 | local error_string="${1}" 120 | 121 | if [ "${BLANKET_IS_UP}" == "true" ] ; then 122 | lipc-send-event ${_OTAMODULE} otaSplashError -s "${error_string}" 123 | else 124 | ${FBINK_BIN} -qpmh -y -3 -S 6 "Error: ${error_string}" 125 | fi 126 | if [ $? -eq 0 ] ; then 127 | logmsg "D" "guierror" "" "display error screen: ${error_string}" 128 | else 129 | logmsg "W" "guierror" "status=fail" "display error screen: ${error_string}" 130 | fi 131 | 132 | # And it is called die, after all ;) 133 | sleep 5 134 | exit 1 135 | } 136 | 137 | # Fill up our progress bar, one step at a time 138 | # Keep track of what we're doing... 139 | _CUR_STEP=0 140 | _CUR_PERCENTAGE=0 141 | otautils_update_progressbar() 142 | { 143 | # One more step... 144 | _CUR_STEP=$((_CUR_STEP + 1)) 145 | # Bounds checking... 146 | if [ ${_CUR_STEP} -lt 0 ] ; then 147 | _CUR_STEP=0 148 | elif [ ${_CUR_STEP} -gt ${STEPCOUNT} ] ; then 149 | _CUR_STEP=${STEPCOUNT} 150 | fi 151 | 152 | # Make that a percentage 153 | local bar_percentage=$(( (${_CUR_STEP} * 100) / ${STEPCOUNT} )) 154 | # We can only *fill* the bar... 155 | if [ ${_CUR_PERCENTAGE} -lt ${bar_percentage} ] ; then 156 | _CUR_PERCENTAGE=${bar_percentage} 157 | fi 158 | 159 | # Make sure that percentage is sane... 160 | is_integer "${_CUR_PERCENTAGE}" || _CUR_PERCENTAGE=0 161 | # Bounds checking... 162 | if [ ${_CUR_PERCENTAGE} -gt 100 ] ; then 163 | _CUR_PERCENTAGE=100 164 | elif [ ${_CUR_PERCENTAGE} -lt 0 ] ; then 165 | _CUR_PERCENTAGE=0 166 | fi 167 | 168 | # Finally, refresh the bar 169 | otautils_update_progress_indicator "${_CUR_PERCENTAGE}" 170 | if [ $? -eq 0 ] ; then 171 | logmsg "D" "guiprogress" "progress=${_CUR_PERCENTAGE}" "update progress indicator" 172 | else 173 | logmsg "W" "guiprogress" "progress=${_CUR_PERCENTAGE},status=fail" "update progress indicator" 174 | fi 175 | } 176 | 177 | # This may come in handy for bridge related packages... 178 | make_mutable() { 179 | local my_path="${1}" 180 | # NOTE: Can't do that on symlinks, hence the hoop-jumping... 181 | if [ -d "${my_path}" ] ; then 182 | find "${my_path}" -type d -exec ${CHATTR} -i '{}' \; 183 | find "${my_path}" -type f -exec ${CHATTR} -i '{}' \; 184 | elif [ -f "${my_path}" ] ; then 185 | ${CHATTR} -i "${my_path}" 186 | fi 187 | } 188 | 189 | make_immutable() { 190 | local my_path="${1}" 191 | if [ -d "${my_path}" ] ; then 192 | find "${my_path}" -type d -exec ${CHATTR} +i '{}' \; 193 | find "${my_path}" -type f -exec ${CHATTR} +i '{}' \; 194 | elif [ -f "${my_path}" ] ; then 195 | ${CHATTR} +i "${my_path}" 196 | fi 197 | } 198 | 199 | # That's all, folks ;) -------------------------------------------------------------------------------- /src/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Pull libOTAUtils for logging & progress handling 4 | source ./libotautils6 5 | 6 | cleanup() 7 | { 8 | rm -f kmc.tar 9 | rm -f mkk.tar 10 | rm -f libotautils6 11 | } 12 | 13 | HACKNAME="HAKT" 14 | logmsg "I" "arch_check" "" "Detected architecture - $ARCH" 15 | logmsg "I" "hakt_installer" "" "Installing Hotfix (previously bridge)." 16 | 17 | ### 18 | ## Here we go :) 19 | ### 20 | otautils_update_progressbar 21 | 22 | 23 | logmsg "I" "install" "" "checking amount of free storage space..." 24 | 25 | # We track how much storage the currently installed hotfix takes (since we're gonna delete it, it shouldn't count) 26 | STORAGE_FREEABLE=$((0)) 27 | 28 | if [ -d "/var/local/kmc" ]; then 29 | STORAGE_FREEABLE=$(($STORAGE_FREEABLE + $(df -k /var/local/kmc | tail -n 1 | tr -s ' ' | cut -d' ' -f4))) 30 | fi 31 | if [ -d "/var/local/mkk" ]; then 32 | STORAGE_FREEABLE=$(($STORAGE_FREEABLE + $(df -k /var/local/mkk | tail -n 1 | tr -s ' ' | cut -d' ' -f4))) 33 | fi 34 | 35 | # Make sure we have enough space in /var/local to unpack our KMC and MKK tars 36 | if [ "$(df -k /var/local | tail -n 1 | tr -s ' ' | cut -d' ' -f4)" -lt "$(($(du kmc.tar | cut -f1) + $(du mkk.tar | cut -f1) - $STORAGE_FREEABLE))" ] ; then 37 | logmsg "C" "install" "code=1" "not enough space left in varlocal" 38 | logmsg "C" "storage_error" "Needed: $(($(du kmc.tar | cut -f1) + $(du mkk.tar | cut -f1) - $STORAGE_FREEABLE))" 39 | logmsg "C" "storage_error" "Available: $(df -k /var/local | tail -n 1 | tr -s ' ' | cut -d' ' -f4)" 40 | cleanup() 41 | 42 | otautils_die "Not enough space left on device!" 43 | return 1 44 | fi 45 | 46 | 47 | ### 48 | # Setup persistent storage folders in /var/local 49 | ### 50 | otautils_update_progressbar 51 | logmsg "I" "install" "" "Initialising persistent storages..." 52 | make_mutable "${KMC_PERSISTENT_STORAGE}" 53 | rm -rf "${KMC_PERSISTENT_STORAGE}" 54 | mkdir -p "${KMC_PERSISTENT_STORAGE}" 55 | chown framework: "${KMC_PERSISTENT_STORAGE}" # Framework needs to do stuff to this apparently? TODO: VALIDATE THIS 56 | chmod g-s "${KMC_PERSISTENT_STORAGE}" 57 | 58 | otautils_update_progressbar 59 | make_mutable "${MKK_PERSISTENT_STORAGE}" 60 | rm -rf "${MKK_PERSISTENT_STORAGE}" 61 | mkdir -p "${MKK_PERSISTENT_STORAGE}" 62 | chown root:root "${MKK_PERSISTENT_STORAGE}" 63 | chmod g-s "${MKK_PERSISTENT_STORAGE}" 64 | 65 | 66 | ### 67 | # Copy data from package to persistent storage 68 | ### 69 | otautils_update_progressbar 70 | logmsg "I" "install" "" "Unpacking persistent storage data" 71 | tar -xf mkk.tar -C "${MKK_PERSISTENT_STORAGE}" 72 | tar -xf kmc.tar -C "${KMC_PERSISTENT_STORAGE}" 73 | 74 | ### 75 | # Fix permissions for KMC (MKK doesn't need this) 76 | ### 77 | otautils_update_progressbar 78 | logmsg "I" "install" "" "Fixing KMC permissions" 79 | chmod -R a+rx "${KMC_PERSISTENT_STORAGE}"/armel/* 80 | chmod -R a+rx "${KMC_PERSISTENT_STORAGE}"/armhf/* 81 | chmod 0664 "${KMC_PERSISTENT_STORAGE}/hotfix/kmc.conf" 82 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/hotfix.sh" 83 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/run_hotfix.sh" 84 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/hotfix/libhotfixutils" 85 | chmod a+rx "${KMC_PERSISTENT_STORAGE}"/hotfix/jobs/* 86 | 87 | logmsg "I" "banner" "" "" 88 | logmsg "I" "banner" "" "" 89 | logmsg "I" "banner" "" "HAKT INSTALLER (${HOTFIX_VERSION})" 90 | logmsg "I" "banner" "" "Installing on arch=${ARCH}" 91 | logmsg "I" "banner" "" "Based on NiLuJe's hotfix & hotfix installer" 92 | logmsg "I" "banner" "" "Created by HackerDude" 93 | logmsg "I" "banner" "" "Special thanks to martysh & ThatOnePerson for beta testing this!" 94 | logmsg "I" "banner" "" "" 95 | logmsg "I" "banner" "" "" 96 | 97 | # Fix Gandalf permissions 98 | logmsg "I" "install" "" "Fixing KMC Gandalf permissions" 99 | for gandalf_arch in armel armhf; do 100 | make_mutable "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 101 | chown root:root "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 102 | chmod a+rx "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 103 | chmod +s "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 104 | make_immutable "${KMC_PERSISTENT_STORAGE}/${gandalf_arch}/bin/gandalf" 105 | done 106 | 107 | # Setup binaries 108 | logmsg "I" "install" "" "Setting up KMC binaries" 109 | ln -sf "${KMC_PERSISTENT_STORAGE}/${ARCH}/lib" "${KMC_PERSISTENT_STORAGE}/lib" 110 | ln -sf "${KMC_PERSISTENT_STORAGE}/${ARCH}/bin" "${KMC_PERSISTENT_STORAGE}/bin" 111 | 112 | ### 113 | # Install KMC upstart job 114 | ### 115 | otautils_update_progressbar 116 | logmsg "I" "install" "" "Installing kmc upstart job" 117 | make_mutable "/etc/upstart/kmc.conf" 118 | make_mutable "/etc/upstart/bridge.conf" 119 | rm -rf "/etc/upstart/bridge.conf" # Delete OLD bridge upstart job (Our KMC job is much neater) 120 | rm -rf "/etc/upstart/kmc.conf" 121 | cp -f "${KMC_PERSISTENT_STORAGE}/hotfix/kmc.conf" "/etc/upstart/kmc.conf" 122 | chmod 0664 "/etc/upstart/kmc.conf" 123 | make_immutable "/etc/upstart/kmc.conf" 124 | 125 | ### 126 | # Setup gandalf and fbink 127 | ### 128 | otautils_update_progressbar 129 | logmsg "I" "install" "" "Linking gandalf and su within KMC" 130 | ln -sf "${KMC_PERSISTENT_STORAGE}/armel/bin/gandalf" "${KMC_PERSISTENT_STORAGE}/armel/bin/su" 131 | ln -sf "${KMC_PERSISTENT_STORAGE}/armhf/bin/gandalf" "${KMC_PERSISTENT_STORAGE}/armhf/bin/su" 132 | 133 | logmsg "I" "install" "" "Linking gandalf to mkk" 134 | ln -sf "${KMC_PERSISTENT_STORAGE}/bin/gandalf" "${MKK_PERSISTENT_STORAGE}/gandalf" 135 | 136 | otautils_update_progressbar 137 | logmsg "I" "install" "" "Linking gandalf and su within MKK" 138 | ln -sf "${MKK_PERSISTENT_STORAGE}/gandalf" "${MKK_PERSISTENT_STORAGE}/su" 139 | 140 | # Install fbink 141 | logmsg "I" "install" "" "Installing fbink" 142 | mkdir -p "/mnt/us/libkh/bin" 143 | rm -f /mnt/us/libkh/bin/fbink 144 | cp -f "${KMC_PERSISTENT_STORAGE}/${ARCH}/bin/fbink" "/mnt/us/libkh/bin/fbink" 145 | chmod a+rx "/mnt/us/libkh/bin/fbink" 146 | 147 | otautils_update_progressbar 148 | 149 | logmsg "I" "install_dispatch" "" "Copying the dispatch script" 150 | make_mutable "/usr/bin/logThis.sh" 151 | rm -rf "/usr/bin/logThis.sh" 152 | cp -f "${MKK_PERSISTENT_STORAGE}/dispatch.sh" "/usr/bin/logThis.sh" 153 | chmod 0755 "/usr/bin/logThis.sh" 154 | make_immutable "/usr/bin/logThis.sh" 155 | 156 | logmsg "I" "install_dispatch" "" "Fixing KMCLog script permissions" 157 | make_mutable "/var/local/kmc/KMCLog.sh" 158 | chmod 0755 "/var/local/kmc/KMCLog.sh" 159 | make_immutable "/var/local/kmc/KMCLog.sh" 160 | 161 | otautils_update_progressbar 162 | 163 | logmsg "I" "install" "" "Installing the hotfix booklet" 164 | rm -f /mnt/us/documents/run_bridge.sh # Remove old runner 165 | rm -f /mnt/us/documents/run_hotfix.run_hotfix # One person got a beta with this lol 166 | echo "${HOTFIX_VERSION}" > "/mnt/us/documents/Run Hotfix.run_hotfix" 167 | 168 | 169 | logmsg "I" "install" "" "Modifying appreg.db" 170 | sqlite3 /var/local/appreg.db ".read ${KMC_PERSISTENT_STORAGE}/hotfix/appreg_register_sh_integration.sql" 171 | sqlite3 /var/local/appreg.db ".read ${KMC_PERSISTENT_STORAGE}/hotfix/appreg_register_hotfix_runner.sql" 172 | 173 | cleanup() 174 | make_immutable "${MKK_PERSISTENT_STORAGE}" 175 | logmsg "I" "install" "" "done" 176 | 177 | otautils_update_progressbar 178 | sleep 5 179 | return 0 180 | -------------------------------------------------------------------------------- /src/kmc/hotfix/libhotfixutils: -------------------------------------------------------------------------------- 1 | ### 2 | # Useful stuff for the hotfix 3 | # Based on libotautils5 from NiLuJe 4 | # Written by HackerDude 5 | # 6 | # Notable Changes 7 | # - Use an enum for models 8 | # - Remove dependency on eips (being deprecated in favour for eips_v2, might as well use fbink in case it happens again) 9 | # 10 | ## 11 | 12 | # Some variables 13 | HOTFIX_VERSION="v2.3.2" 14 | KMC_PERSISTENT_STORAGE="/var/local/kmc" 15 | MKK_PERSISTENT_STORAGE="/var/local/mkk" 16 | KMC_BACKUP_STORAGE="/mnt/us/kmc" 17 | MKK_BACKUP_STORAGE="/mnt/us/mkk" 18 | # Get the Kindle's architecture 19 | ARCH="armel" 20 | # Check if the Kindle is ARMHF or ARMEL 21 | if [ -f /lib/ld-linux-armhf.so.3 ]; then 22 | ARCH="armhf" 23 | fi 24 | FBINK_BIN="${KMC_PERSISTENT_STORAGE}/${ARCH}/bin/fbink" 25 | ROOTPART="$(rdev | cut -d' ' -f1)" # Hotfix is ran as a booklet, we are ALWAYS running from main 26 | 27 | ### 28 | # General helpers 29 | ### 30 | 31 | 32 | # Pull some helper functions for logging 33 | _FUNCTIONS=/etc/upstart/functions 34 | [ -f ${_FUNCTIONS} ] && source ${_FUNCTIONS} 35 | 36 | # Make sure HACKNAME is set (NOTE: This should be overriden in the update script) 37 | [ -z "${HACKNAME}" ] && HACKNAME="ota_script" 38 | 39 | # Create MODEL_* variables 40 | i=0 41 | for enumItem in K5 PW PW2 KV KT2 PW3 KOA KT3 KOA2 PW4 KOA3 PW5 KT5 KS PW6 KT6 CS; do 42 | eval "MODEL_${enumItem}=${i}" 43 | i=$((i+1)) 44 | done 45 | 46 | # Do the S/N dance... 47 | # Setup the KINDLE_MODEL variable with a valid value from the "enum" above 48 | kmfc="$(cut -c1 /proc/usid)" 49 | if [ "${kmfc}" == "B" ] || [ "${kmfc}" == "9" ] ; then 50 | # Older device ID scheme 51 | kmodel="$(cut -c3-4 /proc/usid)" 52 | case "${kmodel}" in 53 | "24" | "1B" | "1D" | "1F" | "1C" | "20" ) 54 | # PaperWhite 1 (2012) 55 | KINDLE_MODEL=$MODEL_PW 56 | ;; 57 | "D4" | "5A" | "D5" | "D6" | "D7" | "D8" | "F2" | "17" | "60" | "F4" | "F9" | "62" | "61" | "5F" ) 58 | # PaperWhite 2 (2013) 59 | KINDLE_MODEL=$MODEL_PW2 60 | ;; 61 | "13" | "54" | "2A" | "4F" | "52" | "53" ) 62 | # Voyage... 63 | KINDLE_MODEL=$MODEL_KV 64 | ;; 65 | "C6" | "DD" ) 66 | # KT2... 67 | KINDLE_MODEL=$MODEL_KT2 68 | ;; 69 | "0F" | "11" | "10" | "12" ) 70 | # Touch 71 | KINDLE_MODEL=$MODEL_K5 72 | ;; 73 | * ) 74 | # Fallback... We shouldn't ever hit that. 75 | KINDLE_MODEL=$MODEL_K5 76 | ;; 77 | esac 78 | else 79 | # Try the new device ID scheme... 80 | kmodel="$(cut -c4-6 /proc/usid)" 81 | case "${kmodel}" in 82 | "0G1" | "0G2" | "0G4" | "0G5" | "0G6" | "0G7" | "0KB" | "0KC" | "0KD" | "0KE" | "0KF" | "0KG" | "0LK" | "0LL" ) 83 | # PW3... 84 | KINDLE_MODEL=$MODEL_PW3 85 | ;; 86 | "0GC" | "0GD" | "0GR" | "0GS" | "0GT" | "0GU" ) 87 | # Oasis... 88 | KINDLE_MODEL=$MODEL_KOA 89 | ;; 90 | "0DU" | "0K9" | "0KA" ) 91 | # KT3... 92 | KINDLE_MODEL=$MODEL_KT3 93 | ;; 94 | "0LM" | "0LN" | "0LP" | "0LQ" | "0P1" | "0P2" | "0P6" | "0P7" | "0P8" | "0S1" | "0S2" | "0S3" | "0S4" | "0S7" | "0SA" ) 95 | # KOA2... 96 | KINDLE_MODEL=$MODEL_KOA2 97 | ;; 98 | "0PP" | "0T1" | "0T2" | "0T3" | "0T4" | "0T5" | "0T6" | "0T7" | "0TJ" | "0TK" | "0TL" | "0TM" | "0TN" | "102" | "103" | "16Q" | "16R" | "16S" | "16T" | "16U" | "16V" ) 99 | # PW4... 100 | KINDLE_MODEL=$MODEL_PW4 101 | ;; 102 | "10L" | "0WF" | "0WG" | "0WH" | "0WJ" | "0VB" ) 103 | # KT4... 104 | KINDLE_MODEL=$MODEL_KT4 105 | ;; 106 | "11L" | "0WQ" | "0WP" | "0WN" | "0WM" | "0WL" ) 107 | # KOA3... 108 | KINDLE_MODEL=$MODEL_KOA3 109 | ;; 110 | "1LG" | "1Q0" | "1PX" | "1VD" | "219" | "21A" | "2BH" | "2BJ" | "2DK" ) 111 | # PW5... 112 | KINDLE_MODEL=$MODEL_PW5 113 | ;; 114 | "22D" | "25T" | "23A" | "2AQ" | "2AP" | "1XH" | "22C" ) 115 | # KT5... 116 | KINDLE_MODEL=$MODEL_KT5 117 | ;; 118 | "27J" | "2BL" | "263" | "227" | "2BM" | "23L" | "23M" | "270" ) 119 | # KS... 120 | KINDLE_MODEL=$MODEL_KS 121 | ;; 122 | "349" | "346" | "33X" | "33W" | "3HA" | "3H5" | "3H3" | "3H8" | "3J5" | "3JS" ) 123 | # PW6 124 | KINDLE_MODEL=$MODEL_PW6 125 | ;; 126 | "3L5" | "3L6" | "3L4" | "3L3" | "A89" | "3L2" | "3KM" ) 127 | # KT6 128 | KINDLE_MODEL=$MODEL_KT6 129 | ;; 130 | "3H9" | "3H4" | "3HB" | "3H6" | "3H2" | "34X" | "3H7" | "3JT" | "3J6" | "456" ) 131 | # CS 132 | KINDLE_MODEL=$MODEL_CS 133 | ;; 134 | * ) 135 | # Fallback... We shouldn't ever hit that. 136 | KINDLE_MODEL=$MODEL_PW3 # PW3 because the new serial check indicates this is PW3+ 137 | ;; 138 | esac 139 | fi 140 | 141 | ## # Create FIRMWARE_* variables 142 | ## i=0 143 | ## for enumItem in OLD 5_4 5_12; do 144 | ## eval "FIRMWARE_${enumItem}=${i}" 145 | ## i=$((i+1)) 146 | ## done 147 | ## 148 | ## # Get the current Kindle's firmware 149 | ## if [ -f "/etc/upstart/contentpackd.conf" ] ; then 150 | ## logmsg "I" "check_version" "" "found a fw >= 5.4 feature" 151 | ## KINDLE_FIRMWARE=$FIRMWARE_5_4 # This is supposedly the "poor man's check" but I feel it's much more elegant than regexing the pretty_version.txt file 152 | ## fi 153 | 154 | 155 | 156 | # Adapt the K5 logging calls to the simpler legacy syntax 157 | _LOGMSG_Y=2 158 | logmsg() 159 | { 160 | f_log "${1}" "${HACKNAME}" "${2}" "${3}" "${4}" 161 | # Add our own echo, like on legacy devices (useful for MRPI logging, since f_log's one is sent to /dev/console) 162 | if [ "${1}" != "D" ] ; then 163 | echo "system: ${1} ${HACKNAME}:${2}:${3}:${4}" 164 | fi 165 | ${FBINK_BIN} -x 1 -y $_LOGMSG_Y -r -S 3 "${1}: ${4}" 166 | _LOGMSG_Y=$(($_LOGMSG_Y + 1)) 167 | } 168 | 169 | # Find which chattr to use 170 | OLD_CHATTR="/bin/chattr" 171 | NEW_CHATTR="/bin/chattr.e2fsprogs" # KT6 5.18.1.5+ and PW6, KS, & KS2 5.18.5+ 172 | if [ -f "${OLD_CHATTR}" ]; then 173 | CHATTR="${OLD_CHATTR}" 174 | elif [ -f "${NEW_CHATTR}" ]; then 175 | CHATTR="${NEW_CHATTR}" 176 | else 177 | # We couldn't find one, show an error, and pretend it's the old one I guess 178 | logmsg "E" "find_chattr" "" "Could not find chattr command!" 179 | CHATTR="${OLD_CHATTR}" # won't be found, but better than nothing? 180 | fi 181 | 182 | 183 | 184 | ### 185 | # Progressbar stuff 186 | ### 187 | # Some constants... 188 | _BLANKET="com.lab126.blanket" 189 | _OTAMODULE="${_BLANKET}.ota" 190 | 191 | # Check if blanket is running 192 | if pkill -0 blanket ; then 193 | BLANKET_IS_UP="true" 194 | else 195 | BLANKET_IS_UP="false" 196 | fi 197 | 198 | # Send progress to blanket, or print it manually otherwise 199 | otautils_update_progress_indicator() 200 | { 201 | local cur_percentage="${1}" 202 | 203 | if [ "${BLANKET_IS_UP}" == "true" ] ; then 204 | lipc-send-event ${_OTAMODULE} otaSplashProgress -i ${cur_percentage} 205 | else 206 | # NOTE: We can actually draw a progress bar with FBInk! 207 | ${FBINK_BIN} -qP ${cur_percentage} -y $(( -6 )) 208 | fi 209 | } 210 | 211 | 212 | # Check if arg is an int 213 | is_integer() 214 | { 215 | # Cheap trick ;) 216 | [ "${1}" -eq "${1}" ] 2>/dev/null 217 | return $? 218 | } 219 | 220 | # The amount of steps needed to fill the progress bar 221 | # I'm lazy, so just count the amount of calls in the script itself ;) 222 | # NOTE: Yup, $0 still points to the original script that sourced us :). 223 | [ -z ${STEPCOUNT} ] && STEPCOUNT="$(grep -c '^[[:blank:]]*otautils_update_progressbar$' ${0} 2>/dev/null)" || true 224 | # Make sure it's sane... 225 | is_integer "${STEPCOUNT}" || STEPCOUNT=1 226 | # NOTE: If you need to for some strange reason, this can be overriden in the update script 227 | 228 | # In case we need to catch failure early... 229 | otautils_die() 230 | { 231 | local error_string="${1}" 232 | 233 | if [ "${BLANKET_IS_UP}" == "true" ] ; then 234 | lipc-send-event ${_OTAMODULE} otaSplashError -s "${error_string}" 235 | else 236 | ${FBINK_BIN} -qpm -y -3 "Error: ${error_string}" 237 | fi 238 | if [ $? -eq 0 ] ; then 239 | logmsg "D" "guierror" "" "display error screen: ${error_string}" 240 | else 241 | logmsg "W" "guierror" "status=fail" "display error screen: ${error_string}" 242 | fi 243 | 244 | # And it is called die, after all ;) 245 | sleep 5 246 | exit 1 247 | } 248 | 249 | # Fill up our progress bar, one step at a time 250 | # Keep track of what we're doing... 251 | _CUR_STEP=0 252 | _CUR_PERCENTAGE=0 253 | otautils_update_progressbar() 254 | { 255 | # One more step... 256 | _CUR_STEP=$((_CUR_STEP + 1)) 257 | # Bounds checking... 258 | if [ ${_CUR_STEP} -lt 0 ] ; then 259 | _CUR_STEP=0 260 | elif [ ${_CUR_STEP} -gt ${STEPCOUNT} ] ; then 261 | _CUR_STEP=${STEPCOUNT} 262 | fi 263 | 264 | # Make that a percentage 265 | local bar_percentage=$(( (${_CUR_STEP} * 100) / ${STEPCOUNT} )) 266 | # We can only *fill* the bar... 267 | if [ ${_CUR_PERCENTAGE} -lt ${bar_percentage} ] ; then 268 | _CUR_PERCENTAGE=${bar_percentage} 269 | fi 270 | 271 | # Make sure that percentage is sane... 272 | is_integer "${_CUR_PERCENTAGE}" || _CUR_PERCENTAGE=0 273 | # Bounds checking... 274 | if [ ${_CUR_PERCENTAGE} -gt 100 ] ; then 275 | _CUR_PERCENTAGE=100 276 | elif [ ${_CUR_PERCENTAGE} -lt 0 ] ; then 277 | _CUR_PERCENTAGE=0 278 | fi 279 | 280 | # Finally, refresh the bar 281 | otautils_update_progress_indicator "${_CUR_PERCENTAGE}" 282 | if [ $? -eq 0 ] ; then 283 | logmsg "D" "guiprogress" "progress=${_CUR_PERCENTAGE}" "update progress indicator" 284 | else 285 | logmsg "W" "guiprogress" "progress=${_CUR_PERCENTAGE},status=fail" "update progress indicator" 286 | fi 287 | } 288 | 289 | # This may come in handy for bridge related packages... 290 | make_mutable() { 291 | local my_path="${1}" 292 | # NOTE: Can't do that on symlinks, hence the hoop-jumping... 293 | if [ -d "${my_path}" ] ; then 294 | find "${my_path}" -type d -exec ${CHATTR} -i '{}' \; 295 | find "${my_path}" -type f -exec ${CHATTR} -i '{}' \; 296 | elif [ -f "${my_path}" ] ; then 297 | ${CHATTR} -i "${my_path}" 298 | fi 299 | } 300 | 301 | make_immutable() { 302 | local my_path="${1}" 303 | if [ -d "${my_path}" ] ; then 304 | find "${my_path}" -type d -exec ${CHATTR} +i '{}' \; 305 | find "${my_path}" -type f -exec ${CHATTR} +i '{}' \; 306 | elif [ -f "${my_path}" ] ; then 307 | ${CHATTR} +i "${my_path}" 308 | fi 309 | } 310 | 311 | # That's all, folks ;) 312 | --------------------------------------------------------------------------------