aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--META-INF/com/google/android/update-binary33
-rw-r--r--META-INF/com/google/android/updater-script1
-rw-r--r--customize.sh26
-rwxr-xr-xdeploy.sh3
-rw-r--r--fstab.sh349
-rw-r--r--module.prop2
-rw-r--r--service.sh33
8 files changed, 275 insertions, 177 deletions
diff --git a/.gitignore b/.gitignore
index b983ed5..52b3dbe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
+}
diff --git a/deploy.sh b/deploy.sh
index 87fac55..9c20427 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -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?
diff --git a/fstab.sh b/fstab.sh
index e00dc16..61ae94b 100644
--- a/fstab.sh
+++ b/fstab.sh
@@ -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
diff --git a/service.sh b/service.sh
index 37f50dd..7740dc1 100644
--- a/service.sh
+++ b/service.sh
@@ -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