From f5531fde328eaac6b6582931b75b0388985b9999 Mon Sep 17 00:00:00 2001 From: YZ-Bruh Date: Sun, 26 May 2024 10:49:33 +0300 Subject: [PATCH] pmt: initial 2.0.0 update --- CHANGELOG.md | 9 - DISCLAIMER | 4 +- LICENSE | 0 Makefile | 211 ------------------ NOTICE | 2 +- README.md | 78 ------- config/INS_STAT.mk | 1 - config/UNINS_STAT.mk | 1 - config/env.mk | 53 ----- config/vars.mk | 64 ------ debutils/DEBIAN/control_32 | 3 +- debutils/DEBIAN/control_64 | 3 +- .../data/data/com.termux/files/usr/bin/dummy | 1 - .../com.termux/files/usr/share/Man/man1/dummy | 1 - .../com.termux/files/usr/share/man/man1/dummy | 0 debutils/mandoc/pmt.1 | 1 - jni/Android.mk | 48 ++++ config/ndk.sh => jni/Application.mk | 15 +- {src => jni}/checkers.c | 53 ++--- config/source.mk => jni/config/env.mk | 21 +- {src => jni}/docs.c | 11 +- src/error.c => jni/include/pmt-docs.h | 25 +-- jni/include/pmt-versioning.h | 32 +++ {src => jni}/include/pmt.h | 23 +- {src => jni}/listpart.c | 31 +-- {src => jni}/pmt.c | 107 +++------ {src => jni}/tools.c | 171 ++++++-------- {src => jni}/versioner.c | 25 +-- make-deb.sh | 116 ++++++++++ pmt-2.0.0-ndk.zip | Bin 0 -> 24754 bytes 30 files changed, 380 insertions(+), 730 deletions(-) delete mode 100644 CHANGELOG.md mode change 100644 => 100755 DISCLAIMER mode change 100644 => 100755 LICENSE delete mode 100644 Makefile mode change 100644 => 100755 NOTICE delete mode 100644 README.md delete mode 100644 config/INS_STAT.mk delete mode 100644 config/UNINS_STAT.mk delete mode 100644 config/env.mk delete mode 100644 config/vars.mk mode change 100644 => 100755 debutils/DEBIAN/control_32 mode change 100644 => 100755 debutils/DEBIAN/control_64 mode change 100644 => 100755 debutils/data/data/com.termux/files/usr/bin/dummy delete mode 100644 debutils/data/data/com.termux/files/usr/share/Man/man1/dummy create mode 100755 debutils/data/data/com.termux/files/usr/share/man/man1/dummy mode change 100644 => 100755 debutils/mandoc/pmt.1 create mode 100755 jni/Android.mk rename config/ndk.sh => jni/Application.mk (78%) mode change 100644 => 100755 rename {src => jni}/checkers.c (65%) mode change 100644 => 100755 rename config/source.mk => jni/config/env.mk (54%) mode change 100644 => 100755 rename {src => jni}/docs.c (96%) mode change 100644 => 100755 rename src/error.c => jni/include/pmt-docs.h (64%) mode change 100644 => 100755 create mode 100755 jni/include/pmt-versioning.h rename {src => jni}/include/pmt.h (79%) mode change 100644 => 100755 rename {src => jni}/listpart.c (76%) mode change 100644 => 100755 rename {src => jni}/pmt.c (85%) mode change 100644 => 100755 rename {src => jni}/tools.c (61%) mode change 100644 => 100755 rename {src => jni}/versioner.c (69%) mode change 100644 => 100755 create mode 100755 make-deb.sh create mode 100755 pmt-2.0.0-ndk.zip diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 6a0d235..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -#### Version 1.9.0 (code 190): - - New features have been added to the compilation system. pmt can now be built with two mods. One is normal and the other is debugging. - - debugging is no longer the default - - In flashing and backup, completely C features are used instead of dd. The code is dd based. bought from toybox - - option trading logic changed - - more details - -| END OF VERSION 1.8.0 CHANGELOG | -|------------------------------------| diff --git a/DISCLAIMER b/DISCLAIMER old mode 100644 new mode 100755 index 7137df7..45cc003 --- a/DISCLAIMER +++ b/DISCLAIMER @@ -1,6 +1,6 @@ WARNING: Disclaimer of Liability Regarding the Use of the C Library - - This library is intended for the user to backup the C android partitions. However, we do not accept responsibility for any problems or losses that may arise during its use. + - This library is intended for the user to manage the C android partitions. However, we do not accept responsibility for any problems or losses that may arise during its use. - Users should carefully test the library functions and, if necessary, implement their own error management mechanisms. - The authors reserve the right to make any changes or updates related to the library. - - This library is intended for backing up android partitions and its suitability for any specific project or application is not guaranteed. It is important for users to evaluate the suitability of their own projects. \ No newline at end of file + - This library is intended for management android partitions and its suitability for any specific project or application is not guaranteed. It is important for users to evaluate the suitability of their own projects. \ No newline at end of file diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile deleted file mode 100644 index 7a89605..0000000 --- a/Makefile +++ /dev/null @@ -1,211 +0,0 @@ -# By YZBruh - -# Copyright 2024 Partition Manager -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -include config/env.mk -include config/vars.mk -include config/source.mk --include config/INS_STAT.mk --include config/UNINS_STAT.mk - -# start build (if no custom target) -.PHONY: all -all: - @printf " ---- Building Partition Manager ---- \n\n"; \ - printf " - Version: $(VERSION)\n"; \ - printf " - Version code: $(VERSION_CODE)\n\n"; \ - printf " -------------------------------- \n\n"; \ - printf " - Building... Please waith.\n"; \ - sleep 2; \ - $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) || exit 1; \ - mkdir -p $(OUT_DIR); \ - mkdir -p $(BINARY_DIR); \ - mkdir -p $(PACKAGE_DIR); \ - mv pmt $(BINARY_DIR) || exit 1; \ - printf " - Generating xz package...\n"; \ - cp $(BINARY_DIR)/pmt $(PACKAGE_DIR) || exit 1; \ - xz $(PACKAGE_DIR)/pmt; \ - mv $(PACKAGE_DIR)/pmt.xz $(PACKAGE_DIR)/pmt-$(TARGET_ARCH)-$(LANG).xz || exit 1; \ - printf " - Success\n\n"; \ - printf " ------------------------------------ \n"; - -# cleaner functions -.PHONY: clean -clean: - @printf "Cleaning with rm force mode (builded binary)...\n"; \ - sleep 1; \ - rm -rf $(OUT_DIR); \ - printf "Success\n"; - -# helper function -.PHONY: help -help: - @printf " ------- Partition Manager help -------\n"; \ - printf " \n"; \ - printf " Commands;\n"; \ - printf " make ==> Build Partition Manager\n"; \ - printf " make deb ==> Generate deb (debian) package (compatibility => termux)\n"; \ - printf " make clean ==> Clear builded binary.\n"; \ - printf " make install ==> If you are using termux, it installs the compiled pmt into termux. So it allows you to use it like a normal command.\n"; \ - printf " make uninstall ==> If you are using termux, it uninstalls the compiled pmt into termux. So it allows you to use it like a normal command.\n"; \ - printf " make help ==> Display help message\n\n"; - -# deb maker -.PHONY: deb -deb: - @printf " --------- Making deb package ---------\n"; \ - printf " - Checking all files and directories (only neededs)...\n"; \ - if [ ! -d $(DEBUTILS_DIR) ]; then \ - printf " - Not found: $(DEBUTILS_DIR) \n"; \ - exit 1; \ - fi; \ - if [ ! -d $(DEBUTILS_DIR)/DEBIAN ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/DEBIAN \n"; \ - exit 1; \ - fi; \ - if [ ! -d $(DEBUTILS_DIR)/mandoc ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/mandoc \n"; \ - exit 1; \ - fi; \ - if [ ! -d $(DEBUTILS_DIR)/data/data/com.termux ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/data/data/com.termux \n"; \ - exit 1; \ - fi; \ - if [ ! -d $(DEBUTILS_DIR)/data/data/com.termux/files/usr ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/data/data/com.termux/files/usr \n"; \ - exit 1; \ - fi; \ - if [ ! -d $(DEBUTILS_DIR)/data/data/com.termux/files/usr/bin ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/data/data/com.termux/files/usr/bin \n"; \ - exit 1; \ - fi; \ - if [ ! -d $(DEBUTILS_DIR)/data/data/com.termux/files/usr/share/man/man1 ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/data/data/com.termux/files/usr/share/man/man1 \n"; \ - exit 1; \ - fi; \ - if [ ! -f $(DEBUTILS_DIR)/mandoc/pmt.1 ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/mandoc/pmt.1 \n"; \ - exit 1; \ - fi; \ - if [ ! -f $(DEBUTILS_DIR)/DEBIAN/control_32 ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/DEBIAN/control_32 \n"; \ - exit 1; \ - fi; \ - if [ ! -f $(DEBUTILS_DIR)/DEBIAN/control_64 ]; then \ - printf " - Not found: $(DEBUTILS_DIR)/DEBIAN/control_64 \n"; \ - exit 1; \ - fi; \ - if [ ! -f $(BINARY_DIR)/pmt ]; then \ - printf " - Package not builded! Please build package and try again \n"; \ - exit 1; \ - fi; \ - printf " - Generating template dir...\n"; \ - mkdir -p $(DEBUTILS_DIR)/temp; \ - printf " - Generating out dir...\n"; \ - mkdir -p $(DEB_DIR); \ - printf " - Copying files...\n"; \ - cp -r $(DEBUTILS_DIR)/data $(DEBUTILS_DIR)/temp || exit 1; \ - rm -f $(DEBTERMUX_USR)/share/man/man1/dummy; \ - rm -f $(DEBTERMUX_USR)/bin/dummy; \ - mkdir -p $(DEBUTILS_DIR)/temp/DEBIAN; \ - if [ "$(ARCH)" = "aarch64" ] || [ "$(ARCH)" = "armv8l" ]; then \ - printf " - Selected arm-64 package control file.\n"; \ - cp $(DEBUTILS_DIR)/DEBIAN/control_64 $(DEBUTILS_DIR)/temp/DEBIAN/control || exit 1; \ - elif [ "$(ARCH)" = "aarch32" ] || [ "$(ARCH)" = "armv7l" ]; then \ - printf " - Selected arm-32 package control file.\n"; \ - cp $(DEBUTILS_DIR)/DEBIAN/control_32 $(DEBUTILS_DIR)/temp/DEBIAN/control || exit 1; \ - fi; \ - cp $(DEBUTILS_DIR)/mandoc/pmt.1 $(DEBTERMUX_USR)/share/man/man1 || exit 1; \ - cp $(BINARY_DIR)/pmt $(DEBTERMUX_USR)/bin || exit 1; \ - printf " - Starting dpkg-deb...\n"; \ - sleep 2; \ - chmod -R 755 *; \ - dpkg-deb -b $(DEBUTILS_DIR)/temp $(DEB_DIR)/pmt-$(ARCH)-$(LANG).deb || exit 1; \ - rm -r $(DEBUTILS_DIR)/temp || exit 1; \ - printf " - Done! Package: $(DEB_DIR)/pmt-$(ARCH)-$(LANG).deb\n" - -# installer -.PHONY: install -install: - @if [ -f $(TERMUX_BIN)/termux-open ]; then \ - printf " ------------ pmt installer ------------ \n"; \ - if [ -f $(TERMUX_BIN)/pmt ]; then \ - printf " - pmt already installed\n"; \ - exit; \ - fi; \ - if [ ! "$(INSTALL_SUCCESS)" = "true" ] && [ ! "$(INSTALL_SUCCESS)" = "" ]; then \ - printf " - Warning: a previously-stayed failed installation process found\n"; \ - fi; \ - printf " - Checking files...\n"; \ - if [ ! -f $(BINARY_DIR)/pmt ]; then \ - printf " - Package not builded! Please build package and try again \n"; \ - echo "INSTALL_SUCCESS := false" > $(CUR_DIR)/config/INS_STAT.mk; \ - exit 1; \ - fi; \ - printf " - Copying files...\n"; \ - if [ "`cp $(BINARY_DIR)/pmt /data/data/com.termux/files/usr/bin/pmt`" = "" ]; then \ - printf " - Setting up permissions...\n"; \ - else \ - echo "INSTALL_SUCCESS := false" > $(CUR_DIR)/config/INS_STAT.mk; \ - exit 1; \ - fi; \ - if [ "`chmod 777 $(TERMUX_BIN)/pmt`" = "" ]; then \ - printf " - Saving current status...\n"; \ - echo "INSTALL_SUCCESS := true" > $(CUR_DIR)/config/INS_STAT.mk; \ - else \ - echo "INSTALL_SUCCESS := false" > $(CUR_DIR)/config/INS_STAT.mk; \ - exit 1; \ - fi; \ - printf " - Success.\n\n"; \ - echo "INSTALL_SUCCESS := true" > $(CUR_DIR)/config/INS_STAT.mk; \ - echo "UNINSTALLED_SUCCESS := " > $(CUR_DIR)/config/UNINS_STAT.mk; \ - else \ - printf " - This function is only available on Termux.\n"; \ - fi - -# uninstaller -.PHONY: uninstall -uninstall: - @if [ -f $(TERMUX_BIN)/termux-open ]; then \ - printf " ----------- pmt uninstaller ----------- \n"; \ - if [ ! -f $(TERMUX_BIN)/pmt ]; then \ - printf " - pmt already uninstalled\n"; \ - exit; \ - fi; \ - if [ ! "$(UNINSTALL_SUCCESS)" = "true" ] && [ ! "$(UNINSTALL_SUCCESS)" = "" ]; then \ - printf " - Warning: a previously-stayed failed uninstallation process found\n"; \ - fi; \ - if [ -f $(TERMUX_USR)/share/man/man1/pmt.1 ]; then \ - printf " - It was found to be established by pmt's deb pack. It's removed with apt...\n"; \ - apt remove -y pmt || exit 1; \ - printf " - Success.\n\n"; \ - echo "UNINSTALLED_SUCCESS := true" > $(CUR_DIR)/config/UNINS_STAT.mk; \ - echo "INSTALL_SUCCESS := " > $(CUR_DIR)/config/INS_STAT.mk; \ - else \ - printf " - It was found that pmt was manually established (with this makefile or copying). Manually removed...\n"; \ - if [ "`rm $(TERMUX_BIN)/pmt`" = "" ]; then \ - printf " - Success.\n\n"; \ - echo "UNINSTALLED_SUCCESS := true" > $(CUR_DIR)/config/UNINS_STAT.mk; \ - echo "INSTALL_SUCCESS := " > $(CUR_DIR)/config/INS_STAT.mk; \ - else \ - echo "UNINSTALLED_SUCCESS := false" > $(CUR_DIR)/config/UNINS_STAT.mk; \ - exit 1; \ - fi; \ - fi; \ - else \ - printf "This function is only available on Termux.\n"; \ - fi - -# end diff --git a/NOTICE b/NOTICE old mode 100644 new mode 100755 index 1cf7eed..ae94e78 --- a/NOTICE +++ b/NOTICE @@ -10,4 +10,4 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -limitations under the License. +limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 4315b24..0000000 --- a/README.md +++ /dev/null @@ -1,78 +0,0 @@ -## Partition Manager (pmt) - -This binary C is for manage partitions of android devices. -It offers a lot of options. I will place these below. But first let me talk about the operation... - -``` -1. The partition name is obtained (with the -p or --partition argument) -2. Other arguments (if used) are processed. -3. The backup and flashing processes were written according to DD's code. So there is a piece of toybox code -``` - -#### Presented arguments (options) - -``` -Usage: - -b | --backup backup mode - -F | --flash flash mode - -r | --format format mode (only ext2/3/4 file systems) - -p | --partition name of the partition to be backed up - -l | --logical know that the partition that will be backed up is logical - -o | --out (only backups) the output name of the backed-up partition (default: partition name) - -d | --outdir (only backups) directory where the backup partition will be saved (default: /storage/emulated/0) - -c | --context it is meant to specify a custom /dev context. Only classic partitions (default: /dev/block/by-name) - -D | --list list partitions - -f | --force force mode. Output is not produced. Even if it's a mistake. But if the target is not a mode, the error is given. If you want to work stable, it is important to specify this option first. - -v | --version see version - --help see help message - -L | --license see license - -Examples: - -b --partition boot_a -o boot_slot_a_image -d /sdcard/backup -c /dev/block/platform/bootdevice/by-name - --flash /sdcard/twrp/boot.img -p boot_a -c /dev/block/platform/bootdevice/by-name - -c /dev/block/platform/bootdevice/by-name --list - -Report bugs to -``` - -#### Some notes - -- Feel free to ask any questions you want. -- Packages are available in publications. -- İt is mandatory to use the `-b` | `--backup` or `-f` | `--flash` and `-p` | `--partition` argument. After all, a partition name and progress type is required to be progress. -- If the logical partition flag is not used, a classic partition is tried to be processing by default. -- [Click to see special version changes](https://github.com/YZBruh/pbt/blob/1.9.0-en/CHANGELOG.md) -- Let me know your suggestions! - -### How is it built? -Android NDK is required to build. [Click for usage information](https://developer.android.com/ndk/guides/other_build_systems). [Click for NDK downloads](https://developer.android.com/ndk/downloads). - - NOTE 1: The current configuration is configured for compilation with NDK. The configuration was configured according to the NDK guide (I gave the link). You may need to replace it depending on the situation. You just need to set the `CC` variable in the compile command. - - NOTE 2: Use NDK 22+ - - NOTE 3: The current target architecture is aarch64. You can change this in the configuration or by adding it to the compile command. Be careful. While making this current configuration, the following was considered (directory structure): - -``` -pmt android-ndk other-directories -``` - - - The directory structure was thought exactly like this. Be careful. - -If you want to change something, take a look at the configuration. You can change him. -it is located in the `config` folder. His name is `env.mk`. I gave the information in the file. You can ask more. - -To build; -``` -make -``` - -Special `make` commands (pmt offers :) ; -``` -------- Partition Manager help ------- - - Commands; - make ==> Build Partition Manager - make deb ==> Generate deb (debian) package (compatibility => termux) - make clean ==> Clear builded binary. - make install ==> If you are using termux, it installs the compiled pmt into termux. So it allows you to use it like a normal command. - make uninstall ==> If you are using termux, it uninstalls the compiled pmt into termux. So it allows you to use it like a normal command. - make help ==> Display help message -``` diff --git a/config/INS_STAT.mk b/config/INS_STAT.mk deleted file mode 100644 index f977edb..0000000 --- a/config/INS_STAT.mk +++ /dev/null @@ -1 +0,0 @@ -INSTALL_SUCCESS := diff --git a/config/UNINS_STAT.mk b/config/UNINS_STAT.mk deleted file mode 100644 index 3fff8db..0000000 --- a/config/UNINS_STAT.mk +++ /dev/null @@ -1 +0,0 @@ -UNINSTALL_SUCCESS := diff --git a/config/env.mk b/config/env.mk deleted file mode 100644 index e02f71c..0000000 --- a/config/env.mk +++ /dev/null @@ -1,53 +0,0 @@ -# By YZBruh - -# Copyright 2024 Partition Manager -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -######################################### -# # -# Configuration Flags # -# # -# Warning: you can edit # -# # -######################################### - -# addionital gcc flags -EXTRA_GCC_FLAGS ?= - -# arch config. 32-bit = armv7a | 64-bit = aarch64 | default = aarch64 -TARGET_BUILD_ARCH ?= aarch64 - -# debugging mode (binary) -ENABLE_BINARY_DEBUGGING ?= false - -######################################### -######################################### - -######################################### -# # -# Apply Configuration # -# # -# Warning: please do not edit # -# # -######################################### - -# gcc flag settings -ifeq ($(ENABLE_BINARY_DEBUGGING), true) - CFLAGS ?= -O3 -g -Wall -Wextra $(EXTRA_GCC_FLAGS) -else ifeq ($(ENABLE_BINARY_DEBUGGING), false) - CFLAGS ?= -O3 -Wall $(EXTRA_GCC_FLAGS) -endif - -######################################### -######################################### diff --git a/config/vars.mk b/config/vars.mk deleted file mode 100644 index bdb9cf6..0000000 --- a/config/vars.mk +++ /dev/null @@ -1,64 +0,0 @@ -# By YZBruh - -# Copyright 2024 Partition Manager -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# speficy -VERSION := 1.9.0 -VERSION_CODE := 190 -TARGET := pmt -LANG := en - -# device arch info -ARCH := $(shell uname -m) -OS := $(shell uname) - -# current directory -CUR_DIR := $(shell pwd) - -# NDK config -NDK_DIR := $(shell dirname ../android-ndk/file) -$(shell chmod 777 $(CUR_DIR)/config/ndk.sh) -$(shell $(CUR_DIR)/config/ndk.sh) - -ifeq ($(OS),Darwin) - TOOLCHAIN := $(NDK_DIR)/toolchains/llvm/prebuilt/darwin-x86_64 -else ifeq ($(OS),Linux) - TOOLCHAIN := $(NDK_DIR)/toolchains/llvm/prebuilt/linux-x86_64 -endif - -ifeq ($(TARGET_BUILD_ARCH),aarch64) - TARGET_ARCH := aarch64-linux-android -else ifeq ($(TARGET_BUILD_ARCH),armv7a) - TARGET_ARCH := armv7a-linux-androideabi -endif - -API := 29 - -# compiler -ifeq "$(origin CC)" "default" - undefine CC -endif -CC ?= $(TOOLCHAIN)/bin/$(TARGET_ARCH)$(API)-clang - -# source config -SOURCE_DIR ?= $(CUR_DIR)/src -OUT_DIR := $(CUR_DIR)/out -BINARY_DIR := $(OUT_DIR)/binary -PACKAGE_DIR := $(OUT_DIR)/package -DEB_DIR := $(OUT_DIR)/deb -DEBUTILS_DIR := $(CUR_DIR)/debutils -DEBTERMUX_USR := $(DEBUTILS_DIR)/temp/data/data/com.termux/files/usr -TERMUX_BIN := /data/data/com.termux/files/usr/bin -TERMUX_USR := /data/data/com.termux/files/usr diff --git a/debutils/DEBIAN/control_32 b/debutils/DEBIAN/control_32 old mode 100644 new mode 100755 index 0d1ab70..6a3eb75 --- a/debutils/DEBIAN/control_32 +++ b/debutils/DEBIAN/control_32 @@ -1,10 +1,9 @@ Source: pmt Package: pmt -Version: 1.9.0 +Version: 1.2.0 Architecture: arm Description: pmt is for reading, writing and formatting partitions of android devices Section: misc Priority: optional Maintainer: YZBruh -Build-Depends: debhelper (>= 10), clang, make Standards-Version: 4.5.0 diff --git a/debutils/DEBIAN/control_64 b/debutils/DEBIAN/control_64 old mode 100644 new mode 100755 index e6bb0ac..ac6f7a1 --- a/debutils/DEBIAN/control_64 +++ b/debutils/DEBIAN/control_64 @@ -1,10 +1,9 @@ Source: pmt Package: pmt -Version: 1.9.0 +Version: 2.0.0 Architecture: aarch64 Description: pmt is for reading, writing and formatting partitions of android devices Section: misc Priority: optional Maintainer: YZBruh -Build-Depends: debhelper (>= 10), clang, make Standards-Version: 4.5.0 diff --git a/debutils/data/data/com.termux/files/usr/bin/dummy b/debutils/data/data/com.termux/files/usr/bin/dummy old mode 100644 new mode 100755 index 8b13789..e69de29 --- a/debutils/data/data/com.termux/files/usr/bin/dummy +++ b/debutils/data/data/com.termux/files/usr/bin/dummy @@ -1 +0,0 @@ - diff --git a/debutils/data/data/com.termux/files/usr/share/Man/man1/dummy b/debutils/data/data/com.termux/files/usr/share/Man/man1/dummy deleted file mode 100644 index 8b13789..0000000 --- a/debutils/data/data/com.termux/files/usr/share/Man/man1/dummy +++ /dev/null @@ -1 +0,0 @@ - diff --git a/debutils/data/data/com.termux/files/usr/share/man/man1/dummy b/debutils/data/data/com.termux/files/usr/share/man/man1/dummy new file mode 100755 index 0000000..e69de29 diff --git a/debutils/mandoc/pmt.1 b/debutils/mandoc/pmt.1 old mode 100644 new mode 100755 index bcf84c0..6a3f042 --- a/debutils/mandoc/pmt.1 +++ b/debutils/mandoc/pmt.1 @@ -22,4 +22,3 @@ EXAMPLES: BUGS: Report bugs to - diff --git a/jni/Android.mk b/jni/Android.mk new file mode 100755 index 0000000..84bc3f3 --- /dev/null +++ b/jni/Android.mk @@ -0,0 +1,48 @@ +# By YZBruh + +# Copyright 2024 Partition Manager +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) +ENVCONF := $(LOCAL_PATH)/config/env.mk + +include $(CLEAR_VARS) +include $(ENVCONF) + +# configration +LOCAL_MODULE = pmt +LOCAL_SRC_FILES = \ + pmt.c \ + versioner.c \ + tools.c \ + checkers.c \ + listpart.c \ + docs.c + +# include dirs +LOCAL_C_INCLUDES = $(LOCAL_PATH)/include + +# compiler flags settings +ifeq ($(ENABLE_DEBUGGING), true) + LOCAL_CFLAGS = -O3 -g -Wall -Wextra $(EXTRA_COMPILER_FLAGS) +else ifeq ($(ENABLE_DEBUGGING), false) + LOCAL_CFLAGS = -O3 -Wall $(EXTRA_COMPILER_FLAGS) +else + $(warning Unknown debugging flag: $(ENABLE_DEBUGGING). Please see: $(PREDIR)/config/env.mk. Using non-debugging flags) + LOCAL_CFLAGS = -O3 -Wall $(EXTRA_COMPILER_FLAGS) +endif + +include $(BUILD_EXECUTABLE) + +# end \ No newline at end of file diff --git a/config/ndk.sh b/jni/Application.mk old mode 100644 new mode 100755 similarity index 78% rename from config/ndk.sh rename to jni/Application.mk index 93c65df..212e244 --- a/config/ndk.sh +++ b/jni/Application.mk @@ -1,5 +1,3 @@ -#!/bin/bash - # By YZBruh # Copyright 2024 Partition Manager @@ -16,8 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -if [ ! -d ../android-ndk ]; then - printf "warning; ndk directory not found. And the current configuration may create problems...\n\n" -fi +# architecture +APP_ABI := \ + arm64-v8a \ + armeabi-v7a -# end of script +APP_PLATFORM := android-21 + +APP_OPTIM := release + +# end \ No newline at end of file diff --git a/src/checkers.c b/jni/checkers.c old mode 100644 new mode 100755 similarity index 65% rename from src/checkers.c rename to jni/checkers.c index 412da5d..41b28c1 --- a/src/checkers.c +++ b/jni/checkers.c @@ -16,20 +16,17 @@ * limitations under the License. */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif #include -#include #include #include #include #include -#include #include - -#include "include/pmt.h" +#include extern bool pmt_use_cust_cxt; extern bool pmt_ab; @@ -40,46 +37,28 @@ extern char *cust_cxt; /* check parts */ void check_psf() { - struct stat abinf; /* true = ab | false = a */ if (pmt_use_cust_cxt) { static char cust_cxt_ck_path[150]; sprintf(cust_cxt_ck_path, "%s/boot_a", cust_cxt); - if (stat(cust_cxt_ck_path, &abinf) != 0) - { - pmt_ab = false; - } else { - pmt_ab = true; - } + if (access(cust_cxt_ck_path, F_OK) != 0) pmt_ab = false; + else pmt_ab = true; } else { - if (stat("/dev/block/by-name/boot_a", &abinf) != 0) - { - pmt_ab = false; - } else { - pmt_ab = true; - } + if (access("/dev/block/by-name/boot_a", F_OK) != 0) pmt_ab = false; + else pmt_ab = true; } - struct stat logcinf; /* true = logical | false = classic */ if (pmt_use_cust_cxt) { static char cust_cxt_ckl_path[150]; sprintf(cust_cxt_ckl_path, "%s/super", cust_cxt); - if (stat(cust_cxt_ckl_path, &logcinf) != 0) - { - pmt_logical = false; - } else { - pmt_logical = true; - } + if (access(cust_cxt_ckl_path, F_OK) != 0) pmt_logical = false; + else pmt_logical = true; } else { - if (stat("/dev/block/by-name/super", &logcinf) != 0) - { - pmt_logical = false; - } else { - pmt_logical = true; - } + if (access("/dev/block/by-name/super", F_OK) != 0) pmt_logical = false; + else pmt_logical = true; } } @@ -87,20 +66,18 @@ void check_psf() void check_root() { /* a quick, easy method to verify root :D */ - if (chdir("/dev/block") != 0) + if (getuid() != 0) { if (!pmt_force_mode) { fprintf(stderr, ANSI_RED "Root privileges could not be detected! Please run this binary with root. Error reason: %s\n" ANSI_RESET, strerror(errno)); exit(27); - } else { - exit(27); - } + } else exit(27); } } -#ifdef __cplusplus +#if defined(__cplusplus) } -#endif +#endif /* __cplusplus */ -/* end of code */ +/* end of code */ \ No newline at end of file diff --git a/config/source.mk b/jni/config/env.mk old mode 100644 new mode 100755 similarity index 54% rename from config/source.mk rename to jni/config/env.mk index 7f91e5c..67d5052 --- a/config/source.mk +++ b/jni/config/env.mk @@ -1,6 +1,6 @@ # By YZBruh -# Copyright 2024 YZBruh - Partition Manager +# Copyright 2024 Partition Manager # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,11 +14,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -# sources -SRCS := \ - $(wildcard $(SOURCE_DIR)/*.c) +######################################### +# # +# Configuration Flags # +# # +# Warning: you can edit # +# # +######################################### -# only the reason why the resource list is available is that: -# construction of a code was made with a different make sub-process in the old compilation logic. And then the built files were saved. And the main structure was created. But no longer needs it. According to new logic... +# addionital compiler flags +EXTRA_COMPILER_FLAGS ?= -# end +# debugging mode (binary) +ENABLE_DEBUGGING ?= false + +# end of environment configuration diff --git a/src/docs.c b/jni/docs.c old mode 100644 new mode 100755 similarity index 96% rename from src/docs.c rename to jni/docs.c index 58051eb..62e5962 --- a/src/docs.c +++ b/jni/docs.c @@ -16,15 +16,12 @@ * limitations under the License. */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif #include -#include -#include - -#include "include/pmt.h" +#include void licenses() { @@ -62,8 +59,8 @@ void help() printf("Report bugs to \n"); } -#ifdef __cplusplus +#if defined(__cplusplus) } -#endif +#endif /* __cplusplus */ /* end of code */ diff --git a/src/error.c b/jni/include/pmt-docs.h old mode 100644 new mode 100755 similarity index 64% rename from src/error.c rename to jni/include/pmt-docs.h index c978adf..91c4aa6 --- a/src/error.c +++ b/jni/include/pmt-docs.h @@ -16,26 +16,15 @@ * limitations under the License. */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { -#endif +#endif /* __cplusplus */ -#include -#include -#include -#include +void help(); +void licenses(); -#include "include/pmt.h" - -/* shorter error messages will be functional xd */ -void error(const char *err_msg, uint32_t errcode) -{ - fprintf(stderr, ANSI_RED "%s" ANSI_RESET, err_msg); - exit(errcode); +#if defined(__cplusplus) } +#endif /* __cplusplus */ -#ifdef __cplusplus -} -#endif - -/* end of code */ +/* end */ \ No newline at end of file diff --git a/jni/include/pmt-versioning.h b/jni/include/pmt-versioning.h new file mode 100755 index 0000000..a813b36 --- /dev/null +++ b/jni/include/pmt-versioning.h @@ -0,0 +1,32 @@ +/* By YZBruh */ + +/* + * Copyright 2024 Partition Manager + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/* versioning */ +#define PMT_MAJOR 2 +#define PMT_LEVEL 0 +#define PMT_PATCH 0 + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* end */ \ No newline at end of file diff --git a/src/include/pmt.h b/jni/include/pmt.h old mode 100644 new mode 100755 similarity index 79% rename from src/include/pmt.h rename to jni/include/pmt.h index cfe07a9..21d2f68 --- a/src/include/pmt.h +++ b/jni/include/pmt.h @@ -16,24 +16,20 @@ * limitations under the License. */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif -#ifndef _PMT_H -#define _PMT_H +#if !defined(__PMT_H_) +#define __PMT_H_ -/* color definations */ +/* some definations */ #define ANSI_RED "\033[31m" #define ANSI_YELLOW "\033[33m" #define ANSI_GREEN "\033[32m" #define ANSI_RESET "\033[0m" -/* info */ -#define PMT_VERSION "1.9.0" -#define PMT_VERSION_CODE "190" #define PMT_PACKAGE_NAME "Partition Manager" -#define PMT_PACKAGE_LANG "en" /* variable definations */ extern char *out; @@ -54,18 +50,15 @@ extern bool pmt_force_mode; /* function definations */ void listpart(); -void error(const char *err_msg, uint32_t errcode); void check_psf(); void check_root(); -void pmt(short progress_code); +void pmt(unsigned short progress_code); void version(); -void help(); -void licenses(); -#endif /* _PMT_H */ +#endif /* __PMT_H_ */ -#ifdef __cplusplus +#if defined(__cplusplus) } -#endif +#endif /* __cplusplus */ /* end of code */ diff --git a/src/listpart.c b/jni/listpart.c old mode 100644 new mode 100755 similarity index 76% rename from src/listpart.c rename to jni/listpart.c index ada6a24..099e664 --- a/src/listpart.c +++ b/jni/listpart.c @@ -16,20 +16,18 @@ * limitations under the License. */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif #include -#include #include #include #include #include #include #include - -#include "include/pmt.h" +#include extern bool pmt_use_cust_cxt; extern bool pmt_ab; @@ -50,9 +48,7 @@ void listpart() { if (!pmt_force_mode) { fprintf(stderr, "Could not open: `%s`. Error reason: %s\n", cust_cxt, strerror(errno)); exit(62); - } else { - exit(62); - } + } else exit(62); } } else { dir = opendir("/dev/block/by-name"); @@ -62,9 +58,7 @@ void listpart() { { fprintf(stderr, "Could not open: `/dev/block/by-name`. Error reason: %s\n", strerror(errno)); exit(63); - } else { - exit(63); - } + } else exit(63); } } @@ -79,23 +73,18 @@ void listpart() { printf("List of logical partitions (/dev/block/mapper): \n"); if (system("ls /dev/block/mapper") != 0 && !pmt_force_mode) { - error("An error occurred when the logical partition list appears!\n", 64); + fprintf(stderr, "%sAn error occurred when the logical partition list appears!%s\n", ANSI_RED, ANSI_RESET); + exit(64); } } - if (pmt_ab && !pmt_force_mode) - { - printf("%sWarning: device using A/B partition style.%s\n", ANSI_YELLOW, ANSI_RESET); - } + if (pmt_ab && !pmt_force_mode) printf("%sWarning: device using A/B partition style.%s\n", ANSI_YELLOW, ANSI_RESET); - if (pmt_logical && !pmt_force_mode) - { - printf("%sWarning: device using logical partition type.%s\n", ANSI_YELLOW, ANSI_RESET); - } + if (pmt_logical && !pmt_force_mode) printf("%sWarning: device using logical partition type.%s\n", ANSI_YELLOW, ANSI_RESET); } -#ifdef __cplusplus +#if defined(__cplusplus) } -#endif +#endif /* __cplusplus */ /* end of code */ diff --git a/src/pmt.c b/jni/pmt.c old mode 100644 new mode 100755 similarity index 85% rename from src/pmt.c rename to jni/pmt.c index ea6ecd7..faaaa47 --- a/src/pmt.c +++ b/jni/pmt.c @@ -17,13 +17,12 @@ */ /* force use C std (if default is C++) */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif /* include needed libs (headers) */ #include -#include #include #include #include @@ -31,9 +30,8 @@ extern "C" { #include #include #include - -/* include custom pmt header */ -#include "include/pmt.h" +#include +#include /* add value to variables that are added globally and are not worth */ char *out = NULL; @@ -89,7 +87,7 @@ int main(int argc, char *argv[]) static bool use_cust_outdir = false; static char *opt_symbol = "-"; static char *common_symbol_rule; - common_symbol_rule = "When entering the attached argument of an option, an argument of another option type cannot be used. In short, the rule is: there can be no '-' at the beginning of the attached argument.\n"; + common_symbol_rule = "When entering the attached argument of an option, an argument of another option type cannot be used. In short, the rule is: there can be no '-' at the beginning of the attached argument."; int opt; @@ -110,10 +108,9 @@ int main(int argc, char *argv[]) { if (!pmt_force_mode) { - error(common_symbol_rule, 19); - } else { + fprintf(stderr, "%s%s%s\n", ANSI_RED, common_symbol_rule, ANSI_RESET); exit(19); - } + } else exit(19); } pmt_flash = true; break; @@ -124,11 +121,9 @@ int main(int argc, char *argv[]) { if (!pmt_force_mode) { - fprintf(stderr, "%s", common_symbol_rule); - exit(71); - } else { - exit(71); - } + fprintf(stderr, "%s%s%s\n", ANSI_RED, common_symbol_rule, ANSI_RESET); + exit(19); + } else exit(19); } pmt_format = true; break; @@ -139,10 +134,9 @@ int main(int argc, char *argv[]) { if (!pmt_force_mode) { - error(common_symbol_rule, 19); - } else { + fprintf(stderr, "%s%s%s\n", ANSI_RED, common_symbol_rule, ANSI_RESET); exit(19); - } + } else exit(19); } break; /* logical partitions option */ @@ -155,10 +149,9 @@ int main(int argc, char *argv[]) } else { if (!pmt_force_mode) { - error("This device does not have logical partitions!\n", 17); - } else { + fprintf(stderr, "This device does not have logical partitions!\n"); exit(17); - } + } else exit(17); } break; /* output file option */ @@ -168,10 +161,9 @@ int main(int argc, char *argv[]) { if (!pmt_force_mode) { - error(common_symbol_rule, 19); - } else { + fprintf(stderr, "%s%s%s\n", ANSI_RED, common_symbol_rule, ANSI_RESET); exit(19); - } + } else exit(19); } break; /* output dir option */ @@ -187,20 +179,16 @@ int main(int argc, char *argv[]) { if (!pmt_force_mode) { - error(common_symbol_rule, 19); - } else { + fprintf(stderr, "%s%s%s\n", ANSI_RED, common_symbol_rule, ANSI_RESET); exit(19); - } + } else exit(19); } break; /* partition lister function */ case 'D': list_partitions = true; /* check combo wiewer options and progress */ - if (wiew_version || wiew_help || wiew_licenses) - { - combo_wiewers = true; - } + if (wiew_version || wiew_help || wiew_licenses) combo_wiewers = true; break; /* force mode option */ case 'f': @@ -210,28 +198,19 @@ int main(int argc, char *argv[]) case 'v': wiew_version = true; /* check combo wiewer options and progress */ - if (list_partitions || wiew_help || wiew_licenses) - { - combo_wiewers = true; - } + if (list_partitions || wiew_help || wiew_licenses) combo_wiewers = true; break; /* help message opption */ case 0: wiew_help = true; /* check combo wiewer options and progress */ - if (wiew_version || list_partitions || wiew_licenses) - { - combo_wiewers = true; - } + if (wiew_version || list_partitions || wiew_licenses) combo_wiewers = true; break; /* license wiewer option */ case 'L': wiew_licenses = true; /* check combo wiewer options and progress */ - if (wiew_version || wiew_help || list_partitions) - { - combo_wiewers = true; - } + if (wiew_version || wiew_help || list_partitions) combo_wiewers = true; break; /* for invalid options */ case '?': @@ -283,10 +262,9 @@ int main(int argc, char *argv[]) { if (!pmt_force_mode) { - error("Backup and flash functions cannot be used in the same command.\n", 9); - } else { + fprintf(stderr, "Backup and flash functions cannot be used in the same command.\n"); exit(9); - } + } else exit(9); } /* checks */ @@ -301,9 +279,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: formatter: unsupported filesystem: %s", argv[0], format_fs); exit(41); - } else { - exit(41); - } + } else exit(41); } } @@ -313,10 +289,9 @@ int main(int argc, char *argv[]) { if (!pmt_force_mode) { - error(common_symbol_rule, 19); - } else { + fprintf(stderr, "%s\n", common_symbol_rule); exit(19); - } + } else exit(19); } struct stat out_info; if (stat(outdir, &out_info) != 0) @@ -325,9 +300,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: cannot stat '%s': %s\n", argv[0], outdir, strerror(errno)); exit(18); - } else { - exit(18); - } + } else exit(18); } else { if (!S_ISDIR(out_info.st_mode)) { @@ -335,9 +308,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: %s: is a not directory.\n", argv[0], outdir); exit(20); - } else { - exit(20); - } + } else exit(20); } } } @@ -351,9 +322,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: cannot stat '%s': %s\n", argv[0], target_flash_file, strerror(errno)); exit(15); - } else { - exit(15); - } + } else exit(15); } else { if (!S_ISREG(flashf_info.st_mode)) { @@ -361,9 +330,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: %s: is a not file.\n", argv[0], target_flash_file); exit(16); - } else { - exit(16); - } + } else exit(16); } } } @@ -380,18 +347,14 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: %s: is a not directory.\n", argv[0], cust_cxt); exit(8); - } else { - exit(8); - } + } else exit(8); } } else { if (!pmt_force_mode) { fprintf(stderr, "%s: %s: %s\n", argv[0], cust_cxt, strerror(errno)); exit(6); - } else { - exit(6); - } + } else exit(6); } if (strstr(cust_cxt, "/dev") == NULL && !pmt_force_mode) { @@ -406,9 +369,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s: required partition name.\nTry `%s --help' for more information.\n", argv[0], argv[0]); exit(5); - } else { - exit(5); - } + } else exit(5); } else { /** * @@ -436,7 +397,7 @@ int main(int argc, char *argv[]) } } -#ifdef __cplusplus +#if defined(__cplusplus) } #endif diff --git a/src/tools.c b/jni/tools.c old mode 100644 new mode 100755 similarity index 61% rename from src/tools.c rename to jni/tools.c index 2405373..25dbd79 --- a/src/tools.c +++ b/jni/tools.c @@ -16,12 +16,11 @@ * limitations under the License. */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif #include -#include #include #include #include @@ -31,8 +30,7 @@ extern "C" { #include #include #include - -#include "include/pmt.h" +#include #define BFSIZE 1024 @@ -60,7 +58,22 @@ extern bool pmt_force_mode; * 3 = format mode */ -void pmt(short progress_code) +static double +calc_flsz(char *filepath) +{ + static int calc_flsz_file; + calc_flsz_file = open(filepath, O_RDONLY); + if (calc_flsz_file == -1) return -1; + + off_t flsz = lseek(calc_flsz_file, 0, SEEK_END); + close(calc_flsz_file); + + if (flsz == (off_t)-1) return -1; + + return (double)flsz / (1024 * 1024); +} + +void pmt(unsigned short progress_code) { /* required variables */ static int srcf, targetf; @@ -78,61 +91,46 @@ void pmt(short progress_code) { if (!pmt_use_logical) { - if (pmt_use_cust_cxt) - { - sprintf(backupper_path, "%s/%s", cust_cxt, target_partition); - } else { - sprintf(backupper_path, "/dev/block/by-name/%s", target_partition); - } - } else if (pmt_use_logical) - { - sprintf(backupper_path, "/dev/block/mapper/%s", target_partition); - } else { + if (pmt_use_cust_cxt) sprintf(backupper_path, "%s/%s", cust_cxt, target_partition); + else sprintf(backupper_path, "/dev/block/by-name/%s", target_partition); + } else if (pmt_use_logical) sprintf(backupper_path, "/dev/block/mapper/%s", target_partition); + else { if (!pmt_force_mode) { - error("İnvalid partition type!\n", 28); - } else { + fprintf(stderr, "İnvalid partition type!\n"); exit(28); - } + } else exit(28); } if (access(backupper_path, F_OK) == -1) { if (!pmt_force_mode) { - error("Partition not found!\n", 29); - } else { + fprintf(stderr, "Partition not found!\n"); exit(29); - } + } else exit(29); } + if (calc_flsz(backupper_path) != -1 && !pmt_force_mode) printf("Disk size of the partition to be backed up: %.2f\n", calc_flsz(backupper_path)); + else printf("%sFailed to target partition disk size%s\n", ANSI_YELLOW, ANSI_RESET); + srcf = open(backupper_path, O_RDONLY); if (srcf == -1) { if (!pmt_force_mode) { fprintf(stderr, "Couldn't read: %s: %s", backupper_path, strerror(errno)); exit(39); - } else { - exit(39); - } + } else exit(39); } /* determine output */ if (outdir != NULL) { - if (out != NULL) - { - sprintf(outf, "%s/%s.img", outdir, out); - } else { - sprintf(outf, "%s/%s.img", outdir, target_partition); - } + if (out != NULL) sprintf(outf, "%s/%s.img", outdir, out); + else sprintf(outf, "%s/%s.img", outdir, target_partition); } else { - if (out != NULL) - { - sprintf(outf, "/storage/emulated/0/%s.img", out); - } else { - sprintf(outf, "/storage/emulated/0/%s.img", target_partition); - } + if (out != NULL) sprintf(outf, "/storage/emulated/0/%s.img", out); + else sprintf(outf, "/storage/emulated/0/%s.img", target_partition); } targetf = open(outf, O_WRONLY | O_CREAT | O_TRUNC, 0666); @@ -141,9 +139,7 @@ void pmt(short progress_code) { fprintf(stderr, "Couldn't generate: %s: %s", outf, strerror(errno)); exit(37); - } else { - exit(37); - } + } else exit(37); } @@ -169,19 +165,11 @@ void pmt(short progress_code) /* Print the output information by evaluating all situations */ if (outdir != NULL) { - if (out != NULL) - { - printf("%sSuccess. Output: %s/%s.img%s\n", ANSI_GREEN, outdir, out, ANSI_RESET); - } else { - printf("%sSuccess. Output: %s/%s.img%s\n", ANSI_GREEN, outdir, target_partition, ANSI_RESET); - } + if (out != NULL) printf("%sSuccess. Output: %s/%s.img%s\n", ANSI_GREEN, outdir, out, ANSI_RESET); + else printf("%sSuccess. Output: %s/%s.img%s\n", ANSI_GREEN, outdir, target_partition, ANSI_RESET); } else { - if (out != NULL) - { - printf("%sSuccess. Output: /storage/emulated/0/%s.img%s\n", ANSI_GREEN, out, ANSI_RESET); - } else { - printf("%sSuccess. Output: /storage/emulated/0/%s.img%s\n", ANSI_GREEN, target_partition, ANSI_RESET); - } + if (out != NULL) printf("%sSuccess. Output: /storage/emulated/0/%s.img%s\n", ANSI_GREEN, out, ANSI_RESET); + else printf("%sSuccess. Output: /storage/emulated/0/%s.img%s\n", ANSI_GREEN, target_partition, ANSI_RESET); } } else if (progress_code == 2) { @@ -189,23 +177,16 @@ void pmt(short progress_code) /* for classic */ if (!pmt_use_logical) { - if (pmt_use_cust_cxt) - { - sprintf(flasher_path, "%s/%s", cust_cxt, target_partition); - } else { - sprintf(flasher_path, "/dev/block/by-name/%s", target_partition); - } + if (pmt_use_cust_cxt) sprintf(flasher_path, "%s/%s", cust_cxt, target_partition); + else sprintf(flasher_path, "/dev/block/by-name/%s", target_partition); /* for logical */ - } else if (pmt_use_logical) - { - sprintf(flasher_path, "/dev/block/mapper/%s", target_partition); - } else { + } else if (pmt_use_logical) sprintf(flasher_path, "/dev/block/mapper/%s", target_partition); + else { if (!pmt_force_mode) { - error("İnvalid partition type!\n", 30); - } else { + fprintf(stderr, "İnvalid partition type!\n"); exit(30); - } + } else exit(30); } /* check partition */ @@ -213,21 +194,24 @@ void pmt(short progress_code) { if (!pmt_force_mode) { - error("Partition not found!\n", 31); - } else { + fprintf(stderr, "Partition not found!\n"); exit(31); - } + } else exit(31); } + if (calc_flsz(target_flash_file) != -1 && !pmt_force_mode) printf("Size of flash file: %.2f\n", calc_flsz(target_flash_file)); + else printf("%sFailed to get flash file size%s\n", ANSI_YELLOW, ANSI_RESET); + + if (calc_flsz(target_partition) != -1 && !pmt_force_mode) printf("Disk size of the target partition: %.2f\n", calc_flsz(target_partition)); + else printf("%sFailed to get target partition disk size%s\n", ANSI_YELLOW, ANSI_RESET); + srcf = open(target_flash_file, O_RDONLY); if (srcf == -1) { if (!pmt_force_mode) { fprintf(stderr, "Couldn't read: %s: %s", target_flash_file, strerror(errno)); exit(39); - } else { - exit(39); - } + } else exit(39); } targetf = open(target_partition, O_WRONLY | O_CREAT | O_TRUNC, 0666); @@ -236,9 +220,7 @@ void pmt(short progress_code) { fprintf(stderr, "Couldn't read: %s: %s", target_partition, strerror(errno)); exit(37); - } else { - exit(37); - } + } else exit(37); } /* start writing */ @@ -257,32 +239,22 @@ void pmt(short progress_code) close(srcf); close(targetf); - if (!pmt_force_mode) - { - printf("%sSuccess.%s\n", ANSI_GREEN, ANSI_RESET); - } + if (!pmt_force_mode) printf("%sSuccess.%s\n", ANSI_GREEN, ANSI_RESET); } else if (progress_code == 3) { /* generate partition extn */ if (!pmt_use_logical) { - if (pmt_use_cust_cxt) - { - sprintf(ppath, "%s/%s", cust_cxt, target_partition); - } else { - sprintf(ppath, "/dev/block/by-name/%s", target_partition); - } + if (pmt_use_cust_cxt) sprintf(ppath, "%s/%s", cust_cxt, target_partition); + else sprintf(ppath, "/dev/block/by-name/%s", target_partition); /* for logical */ - } else if (pmt_use_logical) - { - sprintf(ppath, "/dev/block/mapper/%s", target_partition); - } else { + } else if (pmt_use_logical) sprintf(ppath, "/dev/block/mapper/%s", target_partition); + else { if (!pmt_force_mode) { - error("İnvalid partition type!\n", 30); - } else { + fprintf(stderr, "İnvalid partition type!\n"); exit(49); - } + } else exit(49); } /* check partition */ @@ -290,10 +262,8 @@ void pmt(short progress_code) { if (!pmt_force_mode) { - error("Partition not found!\n", 31); - } else { - exit(31); - } + fprintf(stderr, "Partition not found!\n"); + } else exit(31); } /* get target partition block size */ @@ -304,9 +274,7 @@ void pmt(short progress_code) { fprintf(stderr, "The partition block size could not be obtained!\n"); exit(49); - } else { - exit(49); - } + } else exit(49); } /* generate mke2fs command */ @@ -317,16 +285,15 @@ void pmt(short progress_code) { if (!pmt_force_mode) { - error("Formatting failed! There may be a chance that something has been damaged!\n", 71); - } else { + fprintf(stderr, "Formatting failed! There may be a chance that something has been damaged!\n"); exit(71); - } + } else exit(71); } } } -#ifdef __cplusplus +#if defined(__cplusplus) } -#endif +#endif /* __cplusplus */ /* end of code */ diff --git a/src/versioner.c b/jni/versioner.c old mode 100644 new mode 100755 similarity index 69% rename from src/versioner.c rename to jni/versioner.c index 8e4065a..06b6957 --- a/src/versioner.c +++ b/jni/versioner.c @@ -16,19 +16,16 @@ * limitations under the License. */ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif -#include -#include #include - -#include "include/pmt.h" +#include void version() { - printf("Version: %s (code %s) ", PMT_VERSION, PMT_VERSION_CODE); + printf("Version: %d.%d.%d (code %d%d%d) ", PMT_MAJOR, PMT_LEVEL, PMT_PATCH, PMT_MAJOR, PMT_LEVEL, PMT_PATCH); #if __SIZEOF_POINTER__ == 4 printf("32-bit binary\n"); @@ -38,21 +35,17 @@ void version() printf("\n"); #endif - #ifdef __clang__ - printf("Compiler: clang %s ", __clang_version__); - #endif - - #ifdef __GNUC__ - printf("(GNUC %d.%d.%d)\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); - #else - printf("\n"); + #if defined(__clang__) + printf("Compiler: clang %s\n", __clang_version__); + #elif defined(__gcc__) + printf("Compiler: gcc %s\n", __gcc_version__) #endif printf("See licenses with -L argument.\n"); } -#ifdef __cplusplus +#if defined(__cplusplus) } -#endif +#endif /* __cplusplus */ /* end of code */ diff --git a/make-deb.sh b/make-deb.sh new file mode 100755 index 0000000..a21331d --- /dev/null +++ b/make-deb.sh @@ -0,0 +1,116 @@ +#!/usr/bin/bash +# By YZBruh + +# Copyright 2024 Partition Manager +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +RED='\e[31m' +NC='\e[0m' + +abort() { + printf "${RED}$1${NC}" + exit 1 +} + +case $1 in + arm64-v8a) + PREFIX="64" + ;; + armeabi-v7a) + PREFIX="32" + ;; + *) + abort " - Error: unknown architecture flag: $1. Avaiable: arm64-v8a & armeabi-v7a\n" +esac + +VERSION="2.0.0" +CUR_DIR=$(pwd) +LIB_DIR=${CUR_DIR}/libs +ARMV8A_DIR=${OUT_DIR}/arm64-v8a +ARMV7A_DIR=${OUT_DIR}/armeabi-v7a +DEB_DIR=${OUT_DIR}/deb +DEBUTILS_DIR=${CUR_DIR}/debutils +DEBTERMUX_USR=${DEBUTILS_DIR}/data/data/com.termux/files/usr + +chmod -R 755 * + +printf " --------- Making pmt deb package ---------\n"; +printf " - Checking all files and directories (only +eededs)...\n"; +if [ ! -d ${DEBUTILS_DIR} ]; then + abort " - Not found: ${DEBUTILS_DIR}\n" +fi +if [ ! -d ${DEBUTILS_DIR}/DEBIAN ]; then + abort " - Not found: ${DEBUTILS_DIR}/DEBIAN\n" +fi +if [ ! -d ${DEBUTILS_DIR}/mandoc ]; then + abort " - Not found: ${DEBUTILS_DIR}/mandoc\n" +fi +if [ ! -d ${DEBUTILS_DIR}/data/data/com.termux ]; then + abort " - Not found: ${DEBUTILS_DIR}/data/data/com.termux\n" +fi +if [ ! -d ${DEBUTILS_DIR}/data/data/com.termux/files/usr ]; then + abort " - Not found: ${DEBUTILS_DIR}/data/data/com.termux/files/usr\n" +fi +if [ ! -d ${DEBUTILS_DIR}/data/data/com.termux/files/usr/bin ]; then + abort " - Not found: ${DEBUTILS_DIR}/data/data/com.termux/files/usr/bin\n" +fi +if [ ! -d ${DEBUTILS_DIR}/data/data/com.termux/files/usr/share/man/man1 ]; then + abort " - Not found: ${DEBUTILS_DIR}/data/data/com.termux/files/usr/share/man/man1\n" +fi +if [ ! -f ${DEBUTILS_DIR}/mandoc/pmt.1 ]; then + abort " - Not found: ${DEBUTILS_DIR}/mandoc/pmt.1\n" +fi +if [ ! -f ${DEBUTILS_DIR}/DEBIAN/control_32 ]; then + abort " - Not found: ${DEBUTILS_DIR}/DEBIAN/control_32\n" +fi +if [ ! -f ${DEBUTILS_DIR}/DEBIAN/control_64 ]; then + abort " - Not found: ${DEBUTILS_DIR}/DEBIAN/control_64\n" +fi +if [ ! -f ${ARMV8A_DIR}/pmt ]; then + abort " - Package not comptely builded! Please build package and try again\n" +elif [ ! -f ${ARMV7A_DIR}/pmt ]; then + abort " - Package not comptely builded! Please build package and try again\n" +fi + +printf " - Generating template dir...\n" +mkdir -p ${DEBUTILS_DIR}/temp + +printf " - Generating out dir...\n" +mkdir -p ${DEB_DIR} + +printf " - Copying files...\n" +cp -r ${DEBUTILS_DIR}/data ${DEBUTILS_DIR}/temp || exit 1 +rm -f ${DEBTERMUX_USR}/share/man/man1/dummy +rm -f ${DEBTERMUX_USR}/bin/dummy +mkdir -p ${DEBUTILS_DIR}/temp/DEBIAN + +printf " - Selected arm-${PREFIX} package control file.\n" +cp ${DEBUTILS_DIR}/DEBIAN/control_${PREFIX} ${DEBUTILS_DIR}/temp/DEBIAN/control || exit 1 +cp ${DEBUTILS_DIR}/mandoc/pmt.1 ${DEBTERMUX_USR}/share/man/man1 || exit 1 +if [ "${PREFIX}" = "64" ]; then + cp ${ARMV8A_DIR}/pmt ${DEBTERMUX_USR}/bin || exit 1 +elif [ "${PREFIX}" = "32" ]; then + cp ${ARMV7A_DIR}/pmt ${DEBTERMUX_USR}/bin || exit 1 +fi + +printf " - Starting dpkg-deb...\n" +sleep 2 +chmod -R 755 * +dpkg-deb -b ${DEBUTILS_DIR}/temp ${DEB_DIR}/pmt-${VERSION}-arm${PREFIX}.deb || exit 1; +rm -rf ${DEBUTILS_DIR}/temp || exit 1; + +printf " - Done! Package: ${DEB_DIR}/pmt-${VERSION}.deb\n" + +# end of script \ No newline at end of file diff --git a/pmt-2.0.0-ndk.zip b/pmt-2.0.0-ndk.zip new file mode 100755 index 0000000000000000000000000000000000000000..c4d23842626ee84277a74007525574c09d028d14 GIT binary patch literal 24754 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 O1E&aa+_t2PwEhE3Ynwm- literal 0 HcmV?d00001