diff --git a/.continue/rules/project.md b/.continue/rules/project.md index ad5b1ec..f0ae761 100644 --- a/.continue/rules/project.md +++ b/.continue/rules/project.md @@ -4,25 +4,26 @@ description: mtm-ddwipe project conventions # Project conventions - Use English throughout the project. -- Keep shell scripts Bash-based when Bash is already used by the project. -- Preserve the current behavior of the main script: - - `mtm-ddwipe`: wipe devices. -- Strengthen destructive-action safety checks in `mtm-ddwipe` when making changes. -- Keep `mtm-ddwipe` interactive by default unless a change explicitly adds a safe opt-in flag. -- Keep user-facing messages short, clear, and in English. -- Prefer minimal, focused changes that do not alter the intent of the existing scripts, unless the script behavior is intentionally updated. -- Maintain `.continue/rules/project.md` whenever project conventions or script behavior change. +- Keep shell scripts Bash-based. +- Preserve the current behavior of the main script: `mtm-ddwipe` wipes block devices. +- Strengthen destructive-action safety checks in `mtm-ddwipe`. +- Keep `mtm-ddwipe` interactive by default. +- Require explicit confirmation before destructive actions. +- Keep user-facing messages short and clear. +- Keep error and help messages short and clear. +- Prefer minimal, focused changes that preserve intent. +- Keep `.continue/rules/project.md` aligned with project conventions and concise. - `mtm-ddwipe` is a small Bash script with helper functions. -- Keep the host and line-number removal behavior intact. +- Keep the host and line-number removal behavior intact for related output processing. - `mtm-ddwipe` must print a usage line and support `-h`/`--help`. - Validate that wipe targets are real block devices before operating on them. - Keep short, explicit confirmation prompts before destructive operations. -- Keep error and help messages short, clear, and in English. +- Prefer confirmation prompts that require typing the target device path. - Keep help text concise and usage-first. -- When changing `mtm-ddwipe`, keep destructive safeguards strict and explicit. +- Keep destructive safeguards strict and explicit. - If adding non-interactive support, make it an opt-in safety flag. - Keep device identification prompts clear and specific. -- Preserve the fallback wipe flow unless the change is intentionally about wiping behavior. +- Preserve the fallback wipe flow: secure discard, zero discard, then zero-fill with `dd`. # Project identity - Main script: `mtm-ddwipe` diff --git a/mtm-ddwipe b/mtm-ddwipe index 0d4afda..40bdb5e 100644 --- a/mtm-ddwipe +++ b/mtm-ddwipe @@ -1,108 +1,154 @@ #!/bin/bash +set -euo pipefail +IFS=$'\n\t' VERSION="0.0.3" -STARTDATE="" +STARTDATE=0 STARTDATESTRING="" +DEVICE_PATH="" -show_help() { - echo "Usage: mtm-ddwipe DEVICE" - echo "Wipe a block device." - echo "Version: ${VERSION}" +usage() { + cat <&2 + exit 1 } check_args() { - case "${1}" in + if [ $# -ne 1 ]; then + usage + exit 1 + fi + + case "$1" in -h|--help) - show_help + usage exit 0 ;; - "") - show_help - exit 1 - ;; -*) - echo "Invalid option." - show_help - exit 1 + die "Invalid option." ;; esac } -check_dev_exist() { - if [ ! -e "${1}" ]; then - echo "Missing device." - exit 1 - fi -} +check_device() { + local dev="$1" -check_dev_block() { - if [ ! -b "${1}" ]; then - echo "Not a block device." - exit 1 - fi + [ -e "$dev" ] || die "Missing device: $dev" + [ -b "$dev" ] || die "Not a block device: $dev" } confirm_wipe() { - lsblk "${1}" + local dev="$1" + local choice="" + + lsblk "$dev" echo "" - read -r -p "Wipe ${1} (y/[n])? " CHOICE - case "${CHOICE}" in - y|Y) - echo "" - ;; - *) - echo "Canceled" - exit 1 - ;; - esac + read -r -p "Type the device path to confirm wipe: " choice + [ "$choice" = "$dev" ] || die "Canceled" + echo "" +} + +confirm_root() { + if [ "${EUID:-$(id -u)}" -ne 0 ]; then + die "This tool must be run as root." + fi } print_time() { + local enddate calctime + echo "" echo "Start date :" - echo "${STARTDATESTRING}" + echo "$STARTDATESTRING" - ENDDATE=$(date +%s) + enddate=$(date +%s) echo "" echo "End date :" date - CALCTIME=$((ENDDATE-STARTDATE)) + calctime=$((enddate - STARTDATE)) echo "" echo "Total time :" - date -d@${CALCTIME} -u +%H:%M:%S + date -d@"${calctime}" -u +%H:%M:%S +} + +wipe_with_blkdiscard_secure() { + local dev="$1" + + log "blkdiscard secure" + blkdiscard -f -p 500M -s -v "$dev" +} + +wipe_with_blkdiscard_zero() { + local dev="$1" + + log "blkdiscard zero" + blkdiscard -f -p 500M -z -v "$dev" +} + +wipe_with_dd() { + local dev="$1" + + log "dd zero" + dd if=/dev/zero of="$dev" bs=1M status=progress conv=fsync + log "Wiped with dd, check if full size is written." + log "Otherwise use a mechanical destruction of the device." } wipe_dev() { + local dev="$1" + STARTDATE=$(date +%s) STARTDATESTRING="$(date)" - echo "Begin wiping device ${1}" + DEVICE_PATH="$dev" + + log "Begin wiping device $dev" echo "" - echo "Start date :" - echo "${STARTDATESTRING}" + log "Start date :" + log "$STARTDATESTRING" echo "" - echo "blkdiscard secure" - if ! blkdiscard -f -p 500M -s -v "${1}"; then + + if wipe_with_blkdiscard_secure "$dev"; then echo "" - echo "blkdiscard zero" - if ! blkdiscard -f -p 500M -z -v "${1}"; then - echo "" - echo "dd zero" - if ! dd if=/dev/zero of="${1}" bs=1M status=progress; then - echo "Wiped with dd, check if full size is writed." - echo "Otherwise use a mechanical destruction of the device." - print_time - exit 1 - fi - fi + log "Device $dev wiped." + return fi + echo "" - echo "Device ${1} wiped." + if wipe_with_blkdiscard_zero "$dev"; then + echo "" + log "Device $dev wiped." + return + fi + + echo "" + if wipe_with_dd "$dev"; then + echo "" + log "Device $dev wiped." + return + fi + + die "Wipe failed. The device may not be fully overwritten." } -check_args "${1}" -check_dev_exist "${1}" -check_dev_block "${1}" -confirm_wipe "${1}" -wipe_dev "${1}" -print_time +main() { + check_args "$@" + confirm_root + check_device "$1" + confirm_wipe "$1" + wipe_dev "$1" + print_time +} + +main "$@"