diff --git a/config/niri/.config/niri/config/misc.kdl b/config/niri/.config/niri/config/misc.kdl index db5af45..8c18b91 100644 --- a/config/niri/.config/niri/config/misc.kdl +++ b/config/niri/.config/niri/config/misc.kdl @@ -1,7 +1,7 @@ screenshot-path "~/Pictures/Screenshots/niri_screenshot_%Y-%m-%d_%H-%M-%S.png" debug { - render-drm-device "/dev/dri/renderD128" + render-drm-device "/dev/dri/renderD129" } // gestures { diff --git a/config/scripts/.local/scripts/luks-mount b/config/scripts/.local/scripts/luks-mount index 2f83df4..67954e6 100755 --- a/config/scripts/.local/scripts/luks-mount +++ b/config/scripts/.local/scripts/luks-mount @@ -7,17 +7,107 @@ # - LUKS_PARTITION: Path to the LUKS partition (overrides auto-detection). # - LUKS_MAPPER_NAME: Name for the LUKS mapper (default: luks_mount_). # - LUKS_MOUNT_POINT: Mount point for the decrypted volume (default: /mnt/luks). +# - LUKS_NESTED_UUID: UUID of a device containing a LUKS image file (overrides normal selection). +# - LUKS_NESTED_PATH: Relative path to the LUKS image file inside the partition defined by LUKS_NESTED_UUID. +# - LUKS_SHELL: Shell to use inside the mounted directory (defaults to $SHELL). +# - LUKS_SHELL_COMMAND: Optional command to run instead of an interactive shell (e.g. "ls -la" or "htop"). +# - LUKS_KEYFILE: Optional path to a keyfile for unlocking the LUKS volume (instead of password prompt). # - Cleans up on exit (unmounts and closes the LUKS volume). # Requirements: # - cryptsetup # - sudo privileges # - fzf (optional, for selecting among multiple LUKS devices) +# - util-linux (findmnt, lsblk) set -euo pipefail -[ "$(id -u)" -eq 0 ] && { - echo "[ERROR] Do not run this script in sudo mode." >&2 - exit 1 +# [ "$(id -u)" -eq 0 ] && { +# echo "[ERROR] Do not run this script in sudo mode." >&2 +# exit 1 +# } + +LUKS_PARTITION="${LUKS_PARTITION:-}" +# Default to a unique name based on timestamp +LUKS_MAPPER_NAME="${LUKS_MAPPER_NAME:-luks_mount_$(date +%s)}" +# Fixed default mount point though +LUKS_MOUNT_POINT="${LUKS_MOUNT_POINT:-/mnt/luks}" +LUKS_NESTED_UUID="${LUKS_NESTED_UUID:-}" +LUKS_NESTED_PATH="${LUKS_NESTED_PATH:-}" +LUKS_SHELL="${LUKS_SHELL:-${SHELL:-/bin/bash}}" +LUKS_SHELL_COMMAND="${LUKS_SHELL_COMMAND:-}" +LUKS_KEYFILE="${LUKS_KEYFILE:-}" + +# Flag to track if we created the mount point directory +mountpoint_created=0 + +# --- Cleanup Logic --- +cleanup() { + echo "[INFO] Cleaning up..." >&2 + # Make sure we are not in the mount point when unmounting + popd &>/dev/null || cd "$HOME" || cd / || true + if mountpoint -q "$LUKS_MOUNT_POINT"; then + echo "[INFO] Unmounting LUKS volume..." >&2 + sudo umount "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to unmount." >&2 + fi + if [ -e "/dev/mapper/$LUKS_MAPPER_NAME" ]; then + echo "[INFO] Closing LUKS mapper..." >&2 + sudo cryptsetup close "$LUKS_MAPPER_NAME" || echo "[WARNING] Failed to close LUKS mapper." >&2 + fi + if [ $mountpoint_created -eq 1 ] && [ -d "$LUKS_MOUNT_POINT" ]; then + echo "[INFO] Removing mount point..." >&2 + sudo rmdir "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to remove mount point." >&2 + fi + # Cleanup Outer Partition if it exists + if [ -n "$OUTER_MOUNT_POINT" ]; then + if mountpoint -q "$OUTER_MOUNT_POINT"; then + echo "[INFO] Unmounting outer partition..." >&2 + sudo umount "$OUTER_MOUNT_POINT" || echo "[WARNING] Failed to unmount outer partition." >&2 + fi + if [ -d "$OUTER_MOUNT_POINT" ]; then + echo "[INFO] Removing outer mount point..." >&2 + rmdir "$OUTER_MOUNT_POINT" || echo "[WARNING] Failed to remove outer mount point." >&2 + fi + fi + echo "[INFO] Done." >&2 +} +trap cleanup EXIT INT TERM + +# --- Nested Partition Logic --- +OUTER_MOUNT_POINT="" +handle_nested_partition() { + local uuid="$1" + local NESTED_path="$2" + + # Find the device node for the given UUID + local outer_device + outer_device=$(lsblk -nplo NAME,UUID | awk -v uuid="$uuid" '$2 == uuid {print $1}') + + if [ -z "$outer_device" ]; then + echo "[ERROR] Could not find device with UUID=$uuid" >&2 + exit 1 + fi + + echo "[INFO] Found outer device: $outer_device" >&2 + + # Create a temporary mount point for the outer partition + OUTER_MOUNT_POINT=$(mktemp -d -t luks_outer_XXXXXX) + + echo "[INFO] Mounting outer device to $OUTER_MOUNT_POINT..." >&2 + if ! sudo mount "$outer_device" "$OUTER_MOUNT_POINT"; then + echo "[ERROR] Failed to mount outer device." >&2 + rmdir "$OUTER_MOUNT_POINT" + exit 1 + fi + + local luks_image="$OUTER_MOUNT_POINT/$NESTED_path" + if [ ! -f "$luks_image" ]; then + echo "[ERROR] LUKS image not found at: $luks_image" >&2 + sudo umount "$OUTER_MOUNT_POINT" + rmdir "$OUTER_MOUNT_POINT" + exit 1 + fi + + LUKS_PARTITION="$luks_image" } find_luks_device() { @@ -43,58 +133,54 @@ find_luks_device() { fi } -LUKS_PARTITION="${LUKS_PARTITION:-$(find_luks_device)}" -[ -z "$LUKS_PARTITION" ] && exit 1 +if [ -n "$LUKS_NESTED_UUID" ]; then + if [ -z "$LUKS_NESTED_PATH" ]; then + echo "[ERROR] LUKS_NESTED_PATH must be set when using LUKS_NESTED_UUID." >&2 + exit 1 + fi + handle_nested_partition "$LUKS_NESTED_UUID" "$LUKS_NESTED_PATH" +elif [ -z "$LUKS_PARTITION" ]; then + LUKS_PARTITION=$(find_luks_device) +fi -# Default to a unique name based on timestamp -LUKS_MAPPER_NAME="${LUKS_MAPPER_NAME:-luks_mount_$(date +%s)}" -# Fixed default mount point though -LUKS_MOUNT_POINT="${LUKS_MOUNT_POINT:-/mnt/luks}" +[ -z "$LUKS_PARTITION" ] && exit 1 echo "[INFO] Partition: $LUKS_PARTITION" >&2 echo "[INFO] Mapper: $LUKS_MAPPER_NAME" >&2 echo "[INFO] Mount: $LUKS_MOUNT_POINT" >&2 -mount_point_created=0 if [ ! -d "$LUKS_MOUNT_POINT" ]; then sudo mkdir -p "$LUKS_MOUNT_POINT" - mount_point_created=1 + mountpoint_created=1 fi -if ! sudo cryptsetup open "$LUKS_PARTITION" "$LUKS_MAPPER_NAME"; then +CRYPT_ARGS=() +if [ -n "$LUKS_KEYFILE" ]; then + if [ ! -f "$LUKS_KEYFILE" ]; then + echo "[ERROR] Key file not found: $LUKS_KEYFILE" >&2 + exit 1 + fi + CRYPT_ARGS+=(--key-file "$LUKS_KEYFILE") +fi + +if ! sudo cryptsetup open "${CRYPT_ARGS[@]}" "$LUKS_PARTITION" "$LUKS_MAPPER_NAME"; then echo "[ERROR] Failed to open device." >&2 exit 1 fi -cleanup() { - echo "[INFO] Cleaning up..." >&2 - # Make sure we are not in the mount point when unmounting - cd "$HOME" || true - if mountpoint -q "$LUKS_MOUNT_POINT"; then - sudo umount "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to unmount." >&2 - fi - if [ -e "/dev/mapper/$LUKS_MAPPER_NAME" ]; then - sudo cryptsetup close "$LUKS_MAPPER_NAME" || echo "[WARNING] Failed to close LUKS mapper." >&2 - fi - if [ $mount_point_created -eq 1 ] && [ -d "$LUKS_MOUNT_POINT" ]; then - sudo rmdir "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to remove mount point." >&2 - fi - echo "[INFO] Done." >&2 -} -trap cleanup EXIT INT TERM - sudo mount "/dev/mapper/$LUKS_MAPPER_NAME" "$LUKS_MOUNT_POINT" echo "[INFO] Successfully mounted at $LUKS_MOUNT_POINT." >&2 echo "[INFO] Exit this shell to unmount and close the LUKS volume." >&2 -cd "$LUKS_MOUNT_POINT" -USER_SHELL="${SHELL:-/bin/bash}" -if [[ "$USER_SHELL" == *"/bash" ]]; then - "$USER_SHELL" --rcfile <( +pushd "$LUKS_MOUNT_POINT" &>/dev/null +if [[ -n "$LUKS_SHELL_COMMAND" ]]; then + eval "$LUKS_SHELL_COMMAND" +elif [[ "$LUKS_SHELL" == *"/bash" ]]; then + "$LUKS_SHELL" --rcfile <( cat ~/.bashrc 2>/dev/null printf '%s\n' 'PS1="\[\e[1;31m\][LUKS]\[\e[0m\][\u@\h \W]\$ "' ) -i else - "$USER_SHELL" + "$LUKS_SHELL" fi diff --git a/memo/terminals.md b/memo/terminals.md index 722eb62..1568de4 100644 --- a/memo/terminals.md +++ b/memo/terminals.md @@ -24,9 +24,8 @@ - [快速检测](#快速检测) - [显示效果](#显示效果) - [性能测试](#性能测试) - - [KGP Unicode Placeholders](#kgp-unicode-placeholders) - - [特性](#特性) - - [使用](#使用) + - [Kitty 图像协议](#kitty-图像协议) + - [Unicode Placeholders](#unicode-placeholders) - [实现](#实现) - [默认 Shell](#默认-shell) - [一些概念](#一些概念) @@ -469,9 +468,9 @@ KGP 既支持直接传输 PNG 二进制数据, 也支持传输 24bit 与 32bit 是的, 限制宽度并不会减少控制序列的大小, 反而会因为 `,width=100` 元数据增加 10 字节. -### KGP Unicode Placeholders +### Kitty 图像协议 -#### 特性 +#### Unicode Placeholders Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法之一, 它允许使用占位符嵌入图像, 这提供了一些有意思的特性: @@ -487,15 +486,13 @@ Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法 需要注意的是, Unicode Placeholders 仅仅是 KGP 所涉及的一种放置方法, 并不是一种全新的协议或控制序列. 因此, 只有支持 KGP 的终端模拟器才可能支持 Unicode Placeholders, 但反过来说, 支持 KGP 的终端模拟器不一定支持 Unicode Placeholders. -#### 使用 - 该特性可通过 `kitty +kitten icat` 的 `--unicode-placeholders` 参数启用. 虽然这个特性很有趣, 但就目前而言真正实现它的终端模拟器寥寥无几, 在[前面的表格](#各终端支持情况)中只有 Kitty 和 Ghostty 位于此列, 其他终端模拟器即便支持 KGP, 也只会同时显示占位符和正常的图片, 效果非常诡异. #### 实现 -指编码端的实现. 如前文所说, Unicode Placeholders 是 KGP 的一个子功能, 因此实现 Unicode Placeholders 的同时也可以(或者说必须)实现 KGP 的基础部分. 以下摘取[前面](#性能测试)提到的 idog 的部分实现思路. 完整实现可见 [Uyanide/idog](https://github.com/Uyanide/idog). +指编码端的实现. 如前文所说, Unicode Placeholders 是 KGP 的一个子功能, 因此 KGP 的基础部分后也可以~~(顺便)~~实现 Unicode Placeholders. 以下摘取[前面](#性能测试)提到的 idog 的部分实现思路. 完整实现可见 [Uyanide/idog](https://github.com/Uyanide/idog). - 构造 KGP 检测序列 可以大致分为四个部分: @@ -505,7 +502,7 @@ Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法 - `t`: 通过临时文件传输像素数据, 传输完成后临时文件**会被终端模拟器删除**. - `f`: 通过文件传输像素数据, 传输完成后不会删除. - - 检测是否支持特定图片数据格式 + - 检测是否支持特定数据格式 - `24`: 24bit RGB 原始像素数据 - `32`: 32bit RGBA 原始像素数据 - `100`: PNG 二进制数据 @@ -532,16 +529,16 @@ Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法 - `payload` 包含了图片数据, 格式取决于 `t` 和 `f` 选项的值: - | Medium (`t`) | Format (`f`) | Payload | - | ------------ | ------------ | --------------------------------------------------- | - | `d` | `24` / `32` | 经过 Base64 编码和可选的 zlib 压缩的像素数据 | - | `d` | `100` | 经过 Base64 编码和可选的 zlib 压缩的 PNG 二进制数据 | - | `s` | `24` / `32` | 经过 Base64 编码的共享内存名称, 存储原始像素数据 | - | `s` | `100` | 经过 Base64 编码的共享内存名称, 存储 PNG 二进制数据 | - | `t` | `24` / `32` | 经过 Base64 编码的临时文件路径, 存储原始像素数据 | - | `t` | `100` | 经过 Base64 编码的临时文件路径, 存储 PNG 二进制数据 | - | `f` | `24` / `32` | 经过 Base64 编码的文件路径, 存储原始像素数据 | - | `f` | `100` | 经过 Base64 编码的文件路径, 存储 PNG 二进制数据 | + | Medium (`t`) | Format (`f`) | Payload | + | ------------ | ------------ | ---------------------------------------------- | + | `d` | `24` / `32` | Base64 编码和可选的 zlib 压缩的像素数据 | + | `d` | `100` | Base64 编码和可选的 zlib 压缩的 PNG 二进制数据 | + | `s` | `24` / `32` | Base64 编码的共享内存名称, 存储原始像素数据 | + | `s` | `100` | Base64 编码的共享内存名称, 存储 PNG 二进制数据 | + | `t` | `24` / `32` | Base64 编码的临时文件路径, 存储原始像素数据 | + | `t` | `100` | Base64 编码的临时文件路径, 存储 PNG 二进制数据 | + | `f` | `24` / `32` | Base64 编码的文件路径, 存储原始像素数据 | + | `f` | `100` | Base64 编码的文件路径, 存储 PNG 二进制数据 | 需要注意的是, **共享内存名称**不包含路径, 也不包含前缀的`/`. 例如某共享内存完整路径为 `/dev/shm/idog_12345678`, 则共享内存名称为 `idog_12345678`.