#!/usr/bin/env sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) APP_DIR="$SCRIPT_DIR" PKG_ROOT_NAME=${PKG_ROOT_NAME:-vmess} OUT_TAR=${OUT_TAR:-"$APP_DIR/vmess.tar.gz"} TMP_DIR=${TMP_DIR:-"/tmp/vmess_pkg.$$"} ROUTER_CONF=${ROUTER_CONF:-"$APP_DIR/router_local.conf"} HTTP_SCRIPT=${HTTP_SCRIPT:-"$APP_DIR/scripts/router_local_http.sh"} UPDATE_SCRIPT=${UPDATE_SCRIPT:-"$APP_DIR/scripts/router_local_update.sh"} # Defaults aligned with current repo layout. BUSYBOX_SRC=${BUSYBOX_SRC:-"$APP_DIR/busybox/busybox-armv7l"} CFST_SRC_DIR=${CFST_SRC_DIR:-"$APP_DIR/cfst_linux_armv5"} VERBOSE=${VERBOSE:-1} log() { if [ "${VERBOSE}" = "1" ]; then printf '%s\n' "$*" fi } warn() { printf '[warn] %s\n' "$*" >&2 } err() { printf '[error] %s\n' "$*" >&2 exit 1 } require_file() { p="$1" [ -f "$p" ] || err "required file missing: $p" } require_dir() { p="$1" [ -d "$p" ] || err "required directory missing: $p" } cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT INT TERM parse_conf_var() { conf="$1" key="$2" if [ ! -r "$conf" ]; then return 1 fi sed -n "s|^${key}=\"\\(.*\\)\"$|\\1|p" "$conf" | head -n 1 } resolve_from_conf_dir() { conf="$1" val="$2" conf_dir=$(CDPATH= cd -- "$(dirname -- "$conf")" && pwd) case "$val" in "") printf '%s\n' "" ;; /*) printf '%s\n' "$val" ;; *) printf '%s/%s\n' "$conf_dir" "$val" ;; esac } check_busybox_httpd() { bb="$1" if [ ! -x "$bb" ]; then warn "BusyBox is not executable: $bb (run: chmod +x \"$bb\")" return 1 fi if "$bb" --list 2>/dev/null | grep '^httpd$' >/dev/null 2>&1; then return 0 fi warn "BusyBox has no httpd applet: $bb" return 1 } log "[pkg] app dir: $APP_DIR" log "[pkg] output: $OUT_TAR" require_file "$ROUTER_CONF" require_file "$HTTP_SCRIPT" require_file "$UPDATE_SCRIPT" require_dir "$CFST_SRC_DIR" require_file "$BUSYBOX_SRC" bb_from_conf_raw=$(parse_conf_var "$ROUTER_CONF" "BUSYBOX_BIN" || true) if [ -n "${bb_from_conf_raw:-}" ]; then bb_from_conf=$(resolve_from_conf_dir "$ROUTER_CONF" "$bb_from_conf_raw") if [ "$bb_from_conf" != "$BUSYBOX_SRC" ]; then warn "BUSYBOX_BIN in conf points to: $bb_from_conf_raw -> $bb_from_conf" warn "packaging source busybox is: $BUSYBOX_SRC" warn "if needed, set BUSYBOX_SRC to keep packaging and runtime consistent" fi fi if ! check_busybox_httpd "$BUSYBOX_SRC"; then warn "continuing packaging, but router HTTP may fail later" fi mkdir -p "$TMP_DIR/$PKG_ROOT_NAME/scripts" "$TMP_DIR/$PKG_ROOT_NAME/cfst" cp "$ROUTER_CONF" "$TMP_DIR/$PKG_ROOT_NAME/router_local.conf" cp "$HTTP_SCRIPT" "$TMP_DIR/$PKG_ROOT_NAME/scripts/router_local_http.sh" cp "$UPDATE_SCRIPT" "$TMP_DIR/$PKG_ROOT_NAME/scripts/router_local_update.sh" cp "$BUSYBOX_SRC" "$TMP_DIR/$PKG_ROOT_NAME/busybox_armv7l" cp -R "$CFST_SRC_DIR"/. "$TMP_DIR/$PKG_ROOT_NAME/cfst/" chmod +x \ "$TMP_DIR/$PKG_ROOT_NAME/busybox_armv7l" \ "$TMP_DIR/$PKG_ROOT_NAME/scripts/router_local_http.sh" \ "$TMP_DIR/$PKG_ROOT_NAME/scripts/router_local_update.sh" || true rm -f "$OUT_TAR" tar -czf "$OUT_TAR" -C "$TMP_DIR" "$PKG_ROOT_NAME" log "[pkg] tar created: $OUT_TAR" log "[pkg] tar size: $(ls -lh "$OUT_TAR" | awk '{print $5}')" log "[pkg] tar content preview:" tar -tzf "$OUT_TAR" | sed -n '1,120p' if ! tar -tzf "$OUT_TAR" | grep "^$PKG_ROOT_NAME/busybox_armv7l$" >/dev/null; then err "package validation failed: busybox_armv7l missing" fi if ! tar -tzf "$OUT_TAR" | grep "^$PKG_ROOT_NAME/scripts/router_local_http.sh$" >/dev/null; then err "package validation failed: router_local_http.sh missing" fi if ! tar -tzf "$OUT_TAR" | grep "^$PKG_ROOT_NAME/cfst/cfst$" >/dev/null; then err "package validation failed: cfst binary missing" fi log "[pkg] validation passed"