diff options
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | META-INF/com/google/android/update-binary | 33 | ||||
-rw-r--r-- | META-INF/com/google/android/updater-script | 1 | ||||
-rw-r--r-- | customize.sh | 26 | ||||
-rwxr-xr-x | deploy.sh | 3 | ||||
-rw-r--r-- | fstab.sh | 349 | ||||
-rw-r--r-- | module.prop | 2 | ||||
-rw-r--r-- | service.sh | 33 |
8 files changed, 275 insertions, 177 deletions
@@ -98,3 +98,8 @@ $RECYCLE.BIN/ # End of https://www.toptal.com/developers/gitignore/api/linux,windows,macos,vim + + +# Added by cargo + +/target diff --git a/META-INF/com/google/android/update-binary b/META-INF/com/google/android/update-binary deleted file mode 100644 index 28b48e5..0000000 --- a/META-INF/com/google/android/update-binary +++ /dev/null @@ -1,33 +0,0 @@ -#!/sbin/sh - -################# -# Initialization -################# - -umask 022 - -# echo before loading util_functions -ui_print() { echo "$1"; } - -require_new_magisk() { - ui_print "*******************************" - ui_print " Please install Magisk v20.4+! " - ui_print "*******************************" - exit 1 -} - -######################### -# Load util_functions.sh -######################### - -OUTFD=$2 -ZIPFILE=$3 - -mount /data 2>/dev/null - -[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk -. /data/adb/magisk/util_functions.sh -[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk - -install_module -exit 0 diff --git a/META-INF/com/google/android/updater-script b/META-INF/com/google/android/updater-script deleted file mode 100644 index 11d5c96..0000000 --- a/META-INF/com/google/android/updater-script +++ /dev/null @@ -1 +0,0 @@ -#MAGISK diff --git a/customize.sh b/customize.sh index 7e61433..3e271bb 100644 --- a/customize.sh +++ b/customize.sh @@ -1,4 +1,22 @@ -set_perm $MODPATH/service.sh 0 0 0755
-set_perm $MODPATH/fstab.sh 0 0 0755
-set_perm $MODPATH/config/main.conf 0 0 0755
-set_perm $MODPATH/config/fstab.conf 0 0 0755
+SKIPUNZIP=1
+
+print_modname() {
+ ui_print "magisk-fstab"
+}
+
+on_install() {
+ ui_print "- Extracting module files"
+ unzip -o "$ZIPFILE" -d "$MODPATH" >&2
+}
+
+set_permissions() {
+ ui_print "- Setting permissions"
+ set_perm_recursive "$MODPATH" 0 0 0755 0644
+
+ set_perm "$MODPATH/service.sh" 0 0 0755
+ set_perm "$MODPATH/fstab.sh" 0 0 0755
+
+ set_perm "$MODPATH/config" 0 0 0755
+ set_perm "$MODPATH/config/main.conf" 0 0 0644
+ set_perm "$MODPATH/config/fstab.conf" 0 0 0644
+}
@@ -2,10 +2,11 @@ set -euo pipefail INCLUDES=( - "META-INF" "service.sh" "fstab.sh" "module.prop" + "config" + "customize.sh" ) # Welche Dateien/Ordner sollen ausgeschlossen werden? @@ -1,179 +1,286 @@ #!/system/bin/sh # fstab.sh # Reads an fstab-style config and performs mounts/swapon without touching /etc/fstab. -# - Messages go to console AND to $LOG_FILE. -# - Privileged commands (mkdir, mount, swapon) run via: su --mount-master -c "…" # -# Usage: ./fstab.sh path/to/fstab.conf -# Override log file by exporting LOG_FILE before running. +# Usage: +# ./fstab.sh [--su-options '<opts>'] [--log-file <path>] path/to/fstab.conf +# Examples: +# ./fstab.sh --su-options '--mount-master --test' /path/to/fstab.conf +# LOG_FILE=/sdcard/fstab.log ./fstab.sh /path/to/fstab.conf -FSTAB_FILE="$1" +set -u -if [ -z "$FSTAB_FILE" ]; then - echo "Usage: $0 path/to/fstab.conf" +# ---- defaults --------------------------------------------------------------- +su_options="--mount-master" # kann per --su-options überschrieben werden +: "${LOG_FILE:=}" # optional via Environment + +# ---- helpers --------------------------------------------------------------- +usage() { + cat >&2 <<EOF +Usage: $0 [--su-options '<opts>'] [--log-file <path>] path/to/fstab.conf + +Options: + --su-options String with options for su (default: '--mount-master') + --log-file Path to log file + +Example: + $0 --su-options '--mount-master --test' /path/to/fstab.conf +EOF +} + +# ---- parse args ------------------------------------------------------------ +args="$*" +while [ "$#" -gt 0 ]; do + case "$1" in + --su-options) + [ "$#" -ge 2 ] || { + echo "ERROR: --su-options needs exactly 1 argument." >&2 + usage + exit 2 + } + su_options="$2" + shift 2 + ;; + --log-file) + [ "$#" -ge 2 ] || { + echo "ERROR: --log-file needs exactly 1 argument." >&2 + usage + exit 2 + } + LOG_FILE="$2" + shift 2 + ;; + --help | -h) + usage + exit 0 + ;; + --) + shift + break + ;; + -*) + echo "Unknown option: $1" >&2 + usage exit 2 + ;; + *) + break + ;; + esac +done + +FSTAB_FILE="${1:-}" + +if [ -z "$FSTAB_FILE" ]; then + usage + exit 2 fi if [ ! -r "$FSTAB_FILE" ]; then - echo "File '$FSTAB_FILE' not readable." - exit 2 + echo "File '$FSTAB_FILE' not readable." >>"${LOG_FILE:-/dev/null}" 2>&1 + echo "File '$FSTAB_FILE' not readable." >&2 + exit 2 fi # Ensure 'su' exists if ! command -v su >/dev/null 2>&1; then - echo "ERROR: 'su' not found. Cannot perform privileged operations." - exit 2 + echo "ERROR: 'su' not found. Cannot perform privileged operations." >>"${LOG_FILE:-/dev/null}" 2>&1 + echo "ERROR: 'su' not found. Cannot perform privileged operations." >&2 + exit 2 fi error_count=0 line_no=0 # --- logging helpers (both console and file) --- -log() { echo "$*" | tee -a "$LOG_FILE"; } -warn() { echo "WARN: $*" | tee -a "$LOG_FILE"; } -err() { echo "ERROR: $*" | tee -a "$LOG_FILE"; error_count=`expr $error_count + 1`; } +log() { if [ -n "${LOG_FILE:-}" ]; then echo "$*" | tee -a "$LOG_FILE"; else echo "$*"; fi; } +warn() { if [ -n "${LOG_FILE:-}" ]; then echo "WARN: $*" | tee -a "$LOG_FILE"; else echo "WARN: $*"; fi; } +err() { + if [ -n "${LOG_FILE:-}" ]; then echo "ERROR: $*" | tee -a "$LOG_FILE"; else echo "ERROR: $*"; fi + error_count=$(expr $error_count + 1) +} # --- safe single-quoting for building a command string for su -c --- shell_quote() { - # Output a single-quoted representation of $1, handling internal single quotes - # 'abc'd' -> 'abc'"'"'d' - printf "'%s'" "$(printf "%s" "$1" | sed "s/'/'\"'\"'/g")" + # Output a single-quoted representation of $1, handling internal single quotes + # 'abc'd' -> 'abc'"'"'d' + printf "'%s'" "$(printf "%s" "$1" | sed "s/'/'\"'\"'/g")" } -# --- run a command as root via su --mount-master -c "..." preserving args safely --- +# --- run a command as root via su $su_options -c "..." preserving args safely --- # Usage: run_root CMD ARG1 ARG2 ... run_root() { - cmd="$1"; shift - # Build a single string: CMD 'ARG1' 'ARG2' ... - cmdline=$(shell_quote "$cmd") - for a in "$@"; do - cmdline="$cmdline $(shell_quote "$a")" - done - log "RUN (as root): $cmd $*" - # Execute - su $su_options -c "$cmdline" - rc=$? - [ $rc -ne 0 ] && err "Command failed (exit $rc): $cmd $*" - return $rc + cmd="$1" + shift + # Build a single string: CMD 'ARG1' 'ARG2' ... + cmdline=$(shell_quote "$cmd") + for a in "$@"; do + cmdline="$cmdline $(shell_quote "$a")" + done + log "RUN (as root): $cmd $*" + # Execute + # shellcheck disable=SC2086 + su $su_options -c "$cmdline" + rc=$? + [ $rc -ne 0 ] && err "Command failed (exit $rc): $cmd $*" + return $rc } # --- check if a mountpoint is already mounted (no root needed) --- is_mounted() { - mp="$1" - if command -v mountpoint >/dev/null 2>&1; then - mountpoint -q "$mp" - return $? - fi + mp="$1" + + if [ -r /proc/mounts ]; then grep -qs " $mp " /proc/mounts return $? + fi + + return 1 } # --- check if swap device is already active (no root needed) --- is_swap_active() { - spec="$1" - if command -v swapon >/dev/null 2>&1; then - # Prefer swapon --show if available - run_root swapon --show=NAME --noheadings 2>/dev/null | grep -Fxq "$spec" && return 0 - basename_spec=`basename "$spec"` - run_root swapon --show=NAME --noheadings 2>/dev/null | awk -F/ '{print $NF}' | grep -Fxq "$basename_spec" && return 0 - return 1 - fi - grep -qs "^$spec[[:space:]]" /proc/swaps - return $? + spec="$1" + base="$(basename "$spec")" + + if [ -r /proc/swaps ]; then + awk 'NR>1{print $1}' /proc/swaps | grep -Fxq "$spec" && return 0 + awk 'NR>1{n=$1; sub(".*/","",n); print n}' /proc/swaps | grep -Fxq "$base" && return 0 + fi + + return 1 } +log "$0 $args" + # --- process each fstab line --- while IFS= read -r rawline || [ -n "$rawline" ]; do - line_no=`expr $line_no + 1` - line=`echo "$rawline" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'` - - case "$line" in - ""|\#*) continue ;; - esac - - # spec file vfstype mntops dump pass (default 0 for last two if missing) - set -- `echo "$line" | awk '{print $1, $2, $3, $4, ($5? $5:0), ($6? $6:0)}'` - fs_spec=$1 - fs_file=$2 - fs_vfstype=$3 - fs_mntops=$4 - fs_freq=$5 - fs_pass=$6 - - if [ -z "$fs_spec" ] || [ -z "$fs_file" ] || [ -z "$fs_vfstype" ]; then - warn "Line $line_no: Invalid entry, skipped." - continue - fi + line_no=$(expr $line_no + 1) + line=$(echo "$rawline" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') - echo "$fs_mntops" | grep -qw noauto && { - log "Line $line_no: 'noauto' found, skipping $fs_spec -> $fs_file." - continue - } + case "$line" in + "" | \#*) continue ;; + esac - # --- swap handling --- - if [ "$fs_vfstype" = "swap" ]; then - if is_swap_active "$fs_spec"; then - log "Line $line_no: Swap '$fs_spec' already active — skipped." - continue - fi - if command -v swapon >/dev/null 2>&1; then - log "Line $line_no: Activating swap: $fs_spec" - if [ "$fs_mntops" = "-" ]; then - run_root swapon "$fs_spec" || true - else - run_root swapon -o "$fs_mntops" "$fs_spec" || true - fi - else - err "Line $line_no: swapon not available." - fi - continue - fi + # spec file vfstype mntops dump pass (default 0 for last two if missing) + set -- $(echo "$line" | awk '{print $1, $2, $3, $4, ($5? $5:0), ($6? $6:0)}') + fs_spec=$1 + fs_file=$2 + fs_vfstype=$3 + fs_mntops=$4 + fs_freq=$5 + fs_pass=$6 - # --- bind / rbind mounts --- - echo "$fs_mntops" | grep -q bind && { - if is_mounted "$fs_file"; then - log "Line $line_no: $fs_file already mounted — skipped." - continue - fi - if [ ! -e "$fs_file" ]; then - log "Line $line_no: Creating mountpoint $fs_file" - run_root mkdir -p "$fs_file" || { err "Line $line_no: mkdir failed for $fs_file"; continue; } - fi - if echo "$fs_mntops" | grep -qw rbind; then - log "Line $line_no: rbind mount: $fs_spec -> $fs_file" - run_root mount --rbind "$fs_spec" "$fs_file" || true - else - log "Line $line_no: bind mount: $fs_spec -> $fs_file" - run_root mount --bind "$fs_spec" "$fs_file" || true - fi - continue - } + if [ -z "$fs_spec" ] || [ -z "$fs_file" ] || [ -z "$fs_vfstype" ]; then + warn "Line $line_no: Invalid entry, skipped." + continue + fi + + echo "$fs_mntops" | grep -qw noauto && { + log "Line $line_no: 'noauto' found, skipping $fs_spec -> $fs_file." + continue + } - # --- regular filesystem mounts --- + # --- swap handling --- + if [ "$fs_vfstype" = "swap" ]; then + if is_swap_active "$fs_spec"; then + log "Line $line_no: Swap '$fs_spec' already active — skipped." + continue + fi + if command -v swapon >/dev/null 2>&1; then + log "Line $line_no: Activating swap: $fs_spec" + if [ "$fs_mntops" = "sw" ]; then + run_root swapon "$fs_spec" || true + elif [ "$fs_mntops" = "-" ]; then + log "Mount option '-' on swap, skipping." + else + run_root swapon -o "$fs_mntops" "$fs_spec" || true + fi + else + err "Line $line_no: swapon not available." + fi + continue + fi + + # --- bindfs filesystem mounts --- + if [ "$fs_vfstype" = "bindfs" ]; then if is_mounted "$fs_file"; then - log "Line $line_no: $fs_file already mounted — skipped." + log "Line $line_no: $fs_file already mounted — skipped." + continue + fi + if ! command -v bindfs >/dev/null 2>&1; then + err "Line $line_no: bindfs not available but requested (vfstype=bindfs)." + continue + fi + if [ ! -e "$fs_file" ]; then + log "Line $line_no: Creating mountpoint $fs_file" + run_root mkdir -p "$fs_file" || { + err "Line $line_no: mkdir failed for $fs_file" continue + } + fi + if [ "$fs_mntops" = "-" ]; then + log "Line $line_no: bindfs mount: $fs_spec -> $fs_file" + run_root bindfs "$fs_spec" "$fs_file" || true + else + # bindfs versteht FUSE-Optionen via -o "<opts>" + log "Line $line_no: bindfs mount: $fs_spec -> $fs_file (opts=$fs_mntops)" + run_root bindfs -o "$fs_mntops" "$fs_spec" "$fs_file" || true fi + continue + fi + # --- bind / rbind mounts --- + echo "$fs_mntops" | grep -q bind && { + if is_mounted("$fs_file"); then + log "Line $line_no: $fs_file already mounted — skipped." + continue + fi if [ ! -e "$fs_file" ]; then - log "Line $line_no: Creating mountpoint $fs_file" - run_root mkdir -p "$fs_file" || { err "Line $line_no: mkdir failed"; continue; } + log "Line $line_no: Creating mountpoint $fs_file" + run_root mkdir -p "$fs_file" || { + err "Line $line_no: mkdir failed for $fs_file" + continue + } fi - - if [ "$fs_mntops" = "-" ]; then - log "Line $line_no: Mounting $fs_spec -> $fs_file (type=$fs_vfstype)" - run_root mount -t "$fs_vfstype" "$fs_spec" "$fs_file" || true + if echo "$fs_mntops" | grep -qw rbind; then + log "Line $line_no: rbind mount: $fs_spec -> $fs_file" + run_root mount --rbind "$fs_spec" "$fs_file" || true else - log "Line $line_no: Mounting $fs_spec -> $fs_file (type=$fs_vfstype, opts=$fs_mntops)" - run_root mount -t "$fs_vfstype" -o "$fs_mntops" "$fs_spec" "$fs_file" || true + log "Line $line_no: bind mount: $fs_spec -> $fs_file" + run_root mount --bind "$fs_spec" "$fs_file" || true fi -done < "$FSTAB_FILE" + continue + } + + # --- regular filesystem mounts --- + if is_mounted "$fs_file"; then + log "Line $line_no: $fs_file already mounted — skipped." + continue + fi + + if [ ! -e "$fs_file" ]; then + log "Line $line_no: Creating mountpoint $fs_file" + run_root mkdir -p "$fs_file" || { + err "Line $line_no: mkdir failed" + continue + } + fi + + if [ "$fs_mntops" = "-" ]; then + log "Line $line_no: Mounting $fs_spec -> $fs_file (type=$fs_vfstype)" + run_root mount -t "$fs_vfstype" "$fs_spec" "$fs_file" || true + else + log "Line $line_no: Mounting $fs_spec -> $fs_file (type=$fs_vfstype, opts=$fs_mntops)" + run_root mount -t "$fs_vfstype" -o "$fs_mntops" "$fs_spec" "$fs_file" || true + fi +done <"$FSTAB_FILE" if [ $error_count -gt 0 ]; then - echo "Done: $error_count errors occurred." | tee -a "$LOG_FILE" - exit 1 + echo "Done: $error_count errors occurred." | { [ -n "${LOG_FILE:-}" ] && tee -a "$LOG_FILE" || cat; } + exit 1 else - echo "Done: all entries processed successfully." | tee -a "$LOG_FILE" - exit 0 + echo "Done: all entries processed successfully." | { [ -n "${LOG_FILE:-}" ] && tee -a "$LOG_FILE" || cat; } + exit 0 fi diff --git a/module.prop b/module.prop index 068ea02..0e1f82f 100644 --- a/module.prop +++ b/module.prop @@ -1,5 +1,5 @@ id=magisk-fstab -name=FSTAB loader +name=magisk-fstab version=v1.0.0 versionCode=1 author=lionheart1810 @@ -8,7 +8,7 @@ export LOG_FILE="${MODDIR}/magisk-fstab.log" LOG_MAX_LINES=1000 BOOTWAIT_MAX_COUNT=20 -BOOTWAIT_COUNT_INTERVAL=15s +BOOTWAIT_COUNT_INTERVAL=15 CONF_MAIN="${MODDIR}/config/main.conf" CONF_FSTAB="${MODDIR}/config/fstab.conf" @@ -16,38 +16,39 @@ CONF_FSTAB="${MODDIR}/config/fstab.conf" # Check if configs are readable if [ ! -r "$CONF_MAIN" ]; then - echo "File '$CONF_MAIN' not readable." - exit 2 + echo "File '$CONF_MAIN' not readable." >>"${LOG_FILE}" 2>&1 + exit 2 fi if [ ! -r "$CONF_FSTAB" ]; then - echo "File '$CONF_FSTAB' not readable." - exit 2 + echo "File '$CONF_FSTAB' not readable." >>"${LOG_FILE}" 2>&1 + exit 2 fi # Read main config -. "${CONF_MAIN}" >> "${LOG_FILE}" 2>&1 +. "${CONF_MAIN}" >>"${LOG_FILE}" 2>&1 # wait for system boot to complete bootwait_count=0 -until [[ $(getprop sys.boot_completed) || ${bootwait_count} -ge ${BOOTWAIT_MAX_COUNT} ]]; do - sleep ${BOOTWAIT_COUNT_INTERVAL} - bootwait_count=$((bootwait_count+1)) +while [ "$(getprop sys.boot_completed)" != "1" ] && [ ${bootwait_count} -lt ${BOOTWAIT_MAX_COUNT} ]; do + sleep ${BOOTWAIT_COUNT_INTERVAL} + bootwait_count=$((bootwait_count + 1)) done if [ ${bootwait_count} -ge ${BOOTWAIT_MAX_COUNT} ]; then - exit 1 + echo "Boot wait timeout" >>"${LOG_FILE}" 2>&1 + exit 1 fi # prevent log file from growing too large -tail -n "${LOG_MAX_LINES}" "${LOG_FILE}" > "${LOGFILE}.tmp" -mv "${LOGFILE}.tmp" "${LOG_FILE}" +tail -n "${LOG_MAX_LINES}" "${LOG_FILE}" >"${LOG_FILE}.tmp" +mv "${LOG_FILE}.tmp" "${LOG_FILE}" -echo "=== $(date) ===" >> "${LOG_FILE}" 2>&1 +echo "=== $(date) ===" >>"${LOG_FILE}" 2>&1 -if [ -f "${CONF}" ] - "${MODDIR}/fstab.sh" "${CONF_FSTAB}" & +if [ -f "${CONF_FSTAB}" ]; then + /system/bin/sh "${MODDIR}/fstab.sh" --su-options "${su_options}" --log-file "${LOG_FILE}" "${CONF_FSTAB}" & else - echo "${CONF} not found." >> "${LOG_FILE}" 2>&1 + echo "${CONF_FSTAB} not found." >>"${LOG_FILE}" 2>&1 fi wait |