upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBitflash <btf01@proton.me>2026-07-27 17:53:00 -0300
committerGitHub <noreply@github.com>2026-07-27 17:53:00 -0300
commit8261c39527032485b0e14b4e4a230768218e9b21 (patch)
tree83ce382fc8fa3c58881fb17ba960dbaec2778895
parent6ca1a1d6799474f8ca977b93ab630af7ace879c2 (diff)
Update install-bitflash-wine.sh
-rw-r--r--install-bitflash-wine.sh192
1 files changed, 124 insertions, 68 deletions
diff --git a/install-bitflash-wine.sh b/install-bitflash-wine.sh
index 3fa18a1..91fef59 100644
--- a/install-bitflash-wine.sh
+++ b/install-bitflash-wine.sh
@@ -1,5 +1,6 @@
1#!/usr/bin/env bash 1#!/usr/bin/env bash
2# Bitflash GUI installer for Linux (via Wine) 2# Bitflash GUI installer for Linux (via Wine) — hardened
3set -euo pipefail
3 4
4INSTALL_DIR="$HOME/.btf-wine" 5INSTALL_DIR="$HOME/.btf-wine"
5WINE_DATA="$HOME/.wine/drive_c/users/$USER/AppData/Roaming/Bitflash" 6WINE_DATA="$HOME/.wine/drive_c/users/$USER/AppData/Roaming/Bitflash"
@@ -10,146 +11,201 @@ REPO="Bitflash-sh/bitflash"
10echo "==> Bitflash GUI installer" 11echo "==> Bitflash GUI installer"
11echo 12echo
12 13
14# ---- Safety: don't run as root (breaks Wine + pollutes /root)
15if [ "$(id -u)" -eq 0 ]; then
16 echo "ERROR: do not run this as root. Run as your normal user (it will call sudo only when needed)." >&2
17 exit 1
18fi
19
20need() { command -v "$1" >/dev/null 2>&1; }
21
13# ---- Wine 22# ---- Wine
14echo "==> Checking Wine..." 23echo "==> Checking Wine..."
15if ! command -v wine &>/dev/null; then 24if ! need wine; then
16 echo " Installing Wine..." 25 echo " Installing Wine..."
17 sudo apt-get update -qq && sudo apt-get install -y wine 26 if ! need apt-get; then
27 echo "ERROR: apt-get not found. Install 'wine' manually, then re-run." >&2
28 exit 1
29 fi
30 sudo apt-get update -qq
31 sudo apt-get install -y wine
18fi 32fi
19echo " Wine: $(wine --version)" 33echo " Wine: $(wine --version)"
20 34
21# ---- db-util 35# ---- db-util (db_dump / db_load for wallet conversion)
22echo "==> Checking db-util..." 36echo "==> Checking db-util..."
23if ! command -v db_dump &>/dev/null; then 37if ! need db_dump; then
24 echo " Installing db-util..." 38 echo " Installing db-util..."
25 sudo apt-get install -y db-util 39 sudo apt-get install -y db-util
26fi 40fi
27echo " db_dump: $(which db_dump)" 41echo " db_dump: $(command -v db_dump)"
28 42
29# ---- Download 43# ---- unzip + sha256sum must exist
30echo "==> Fetching latest release from GitHub..." 44for tool in unzip sha256sum curl; do
31RELEASE_URL=$(curl -s "https://api.github.com/repos/$REPO/releases/latest" \ 45 if ! need "$tool"; then
32 | grep "browser_download_url" \ 46 echo " Installing $tool..."
33 | grep -i "win\|windows\|gui" \ 47 sudo apt-get install -y "$tool"
34 | head -1 | cut -d '"' -f 4) 48 fi
49done
35 50
36if [ -z "$RELEASE_URL" ]; then 51# ---- Resolve latest release (single API call)
37 RELEASE_URL=$(curl -s "https://api.github.com/repos/$REPO/releases/latest" \ 52echo "==> Fetching latest release metadata from GitHub..."
38 | grep "browser_download_url" | head -1 | cut -d '"' -f 4) 53API_JSON=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest")
39fi 54
55RELEASE_URL=$(printf '%s\n' "$API_JSON" | grep '"browser_download_url"' \
56 | grep -iE 'win|windows|gui' | head -1 | cut -d '"' -f 4 || true)
57[ -z "$RELEASE_URL" ] && RELEASE_URL=$(printf '%s\n' "$API_JSON" | grep '"browser_download_url"' \
58 | grep -iE '\.zip"?$' | head -1 | cut -d '"' -f 4 || true)
40 59
41if [ -z "$RELEASE_URL" ]; then 60if [ -z "$RELEASE_URL" ]; then
42 echo "ERROR: No release found at https://github.com/$REPO/releases" 61 echo "ERROR: no downloadable release asset found at https://github.com/$REPO/releases" >&2
43 exit 1 62 exit 1
44fi 63fi
64ASSET_NAME=$(basename "$RELEASE_URL")
65echo " Asset: $ASSET_NAME"
45 66
46echo " URL: $RELEASE_URL" 67# checksum manifest published alongside the release (SHA256SUMS)
68SUMS_URL=$(printf '%s\n' "$API_JSON" | grep '"browser_download_url"' \
69 | grep -iE 'sha256sums|checksums|\.sha256"?$' | head -1 | cut -d '"' -f 4 || true)
70
71# ---- Download the release
47TMPZIP=$(mktemp /tmp/bitflash-XXXXXX.zip) 72TMPZIP=$(mktemp /tmp/bitflash-XXXXXX.zip)
48echo " Downloading..." 73cleanup() { rm -f "$TMPZIP" "${TMPSUMS:-}"; }
49curl -L -o "$TMPZIP" "$RELEASE_URL" 74trap cleanup EXIT
75echo "==> Downloading release..."
76curl -fL --retry 3 --retry-delay 2 -o "$TMPZIP" "$RELEASE_URL"
50echo " Downloaded: $(du -h "$TMPZIP" | cut -f1)" 77echo " Downloaded: $(du -h "$TMPZIP" | cut -f1)"
51 78
79# ---- MANDATORY integrity check
80echo "==> Verifying integrity..."
81GOT=$(sha256sum "$TMPZIP" | awk '{print $1}')
82if [ -n "${EXPECTED_SHA256:-}" ]; then
83 # Strongest: user pinned a known-good hash out-of-band.
84 if [ "$GOT" != "$EXPECTED_SHA256" ]; then
85 echo "ERROR: checksum mismatch. expected $EXPECTED_SHA256, got $GOT" >&2
86 exit 1
87 fi
88 echo " OK (matches pinned EXPECTED_SHA256)"
89elif [ -n "$SUMS_URL" ]; then
90 TMPSUMS=$(mktemp /tmp/bitflash-sums-XXXXXX)
91 curl -fsSL --retry 3 -o "$TMPSUMS" "$SUMS_URL"
92 WANT=$(grep -iF "$ASSET_NAME" "$TMPSUMS" | awk '{print $1}' | head -1 || true)
93 if [ -z "$WANT" ]; then
94 echo "ERROR: no checksum for $ASSET_NAME in published SHA256SUMS." >&2
95 exit 1
96 fi
97 if [ "$GOT" != "$WANT" ]; then
98 echo "ERROR: checksum mismatch. published $WANT, got $GOT" >&2
99 exit 1
100 fi
101 echo " OK (matches published SHA256SUMS)"
102else
103 echo "ERROR: no checksum available for this release." >&2
104 echo " Publish a SHA256SUMS asset with the release, or re-run with" >&2
105 echo " EXPECTED_SHA256=<hash> to verify against a known-good value." >&2
106 echo " (To bypass at your own risk: ALLOW_UNVERIFIED=1)" >&2
107 if [ "${ALLOW_UNVERIFIED:-0}" != "1" ]; then
108 exit 1
109 fi
110 echo " WARNING: proceeding UNVERIFIED (ALLOW_UNVERIFIED=1). sha256=$GOT"
111fi
112
52# ---- Extract 113# ---- Extract
53echo "==> Extracting to $INSTALL_DIR..." 114echo "==> Extracting to $INSTALL_DIR..."
54rm -rf "$INSTALL_DIR" 115rm -rf "$INSTALL_DIR"
55mkdir -p "$INSTALL_DIR" 116mkdir -p "$INSTALL_DIR"
56echo " Running unzip -j..." 117unzip -j -o "$TMPZIP" -d "$INSTALL_DIR" >/dev/null
57unzip -j "$TMPZIP" -d "$INSTALL_DIR" 2>&1 | grep -v "^warning" || true
58echo " Files after extract: $(ls "$INSTALL_DIR" | wc -l)"
59 118
60# ---- Rename backslash files 119# ---- Rename backslash-mangled entries (Windows zip paths)
61echo "==> Renaming files..."
62count=0 120count=0
63for f in "$INSTALL_DIR"/*; do 121for f in "$INSTALL_DIR"/*; do
64 [ -f "$f" ] || continue 122 [ -f "$f" ] || continue
65 base=$(basename "$f") 123 base=$(basename "$f")
66 newname=$(echo "$base" | sed 's/.*\\//') 124 newname=$(printf '%s' "$base" | sed 's/.*\\//')
67 if [ "$newname" != "$base" ]; then 125 if [ "$newname" != "$base" ]; then
68 mv "$f" "$INSTALL_DIR/$newname" 126 mv "$f" "$INSTALL_DIR/$newname"
69 count=$((count+1)) 127 count=$((count+1))
70 fi 128 fi
71done 129done
72echo " Renamed $count files" 130echo " Renamed $count files; total: $(ls "$INSTALL_DIR" | wc -l)"
73echo " Files now: $(ls "$INSTALL_DIR" | wc -l)"
74 131
75rm -f "$TMPZIP" 132# Locate the Bitflash exe case-insensitively (zip may ship Bitflash.exe or bitflash.exe)
76 133EXE=$(find "$INSTALL_DIR" -maxdepth 1 -iname 'bitflash.exe' | head -1)
77# ---- Verify 134if [ -z "$EXE" ]; then
78if [ ! -f "$INSTALL_DIR/bitflash.exe" ]; then 135 echo "ERROR: bitflash exe not found after extract. Contents:" >&2
79 echo "ERROR: bitflash.exe not found. Files present:" 136 ls "$INSTALL_DIR" >&2
80 ls "$INSTALL_DIR"
81 exit 1 137 exit 1
82fi 138fi
83echo " bitflash.exe found ✓" 139echo " Found $(basename "$EXE")"
84 140
85# ---- Init Wine data dir 141# ---- Init Wine data dir
86echo "==> Initializing Wine Bitflash data directory..." 142echo "==> Initializing Wine data directory..."
87echo " Starting Wine to create data dir (may take a moment)..." 143WINEDLLOVERRIDES="libdb_cxx-6.2=n" wine "$EXE" &
88WINEDLLOVERRIDES="libdb_cxx-6.2=n" wine "$INSTALL_DIR/bitflash.exe" &
89WINE_PID=$! 144WINE_PID=$!
90# Wait until wallet.dat is created, max 30 seconds 145created=0
91for i in $(seq 1 30); do 146for i in $(seq 1 30); do
92 sleep 1 147 sleep 1
93 if [ -f "$WINE_DATA/wallet.dat" ]; then 148 if [ -f "$WINE_DATA/wallet.dat" ]; then
94 echo " wallet.dat created after ${i}s" 149 echo " wallet.dat created after ${i}s"
150 created=1
95 break 151 break
96 fi 152 fi
97 echo " Waiting for Wine to initialize... ${i}s"
98done 153done
99kill $WINE_PID 2>/dev/null || true 154kill "$WINE_PID" 2>/dev/null || true
100wait $WINE_PID 2>/dev/null || true 155wait "$WINE_PID" 2>/dev/null || true
101sleep 1 156sleep 1
102mkdir -p "$WINE_DATA" 157mkdir -p "$WINE_DATA"
103echo " Wine data dir ready" 158[ "$created" -eq 1 ] || echo " NOTE: Wine did not create wallet.dat in 30s; continuing."
104 159
105# ---- Wallet 160# ---- Optional wallet import (with backup)
106echo 161echo
107if [ -f "$LINUX_DATA/wallet.dat" ]; then 162if [ -f "$LINUX_DATA/wallet.dat" ]; then
108 echo "==> Found existing Linux wallet at $LINUX_DATA/wallet.dat" 163 echo "==> Found existing Linux wallet at $LINUX_DATA/wallet.dat"
109 read -p " Import it into the GUI wallet? [Y/n] " ans 164 read -r -p " Import it into the GUI wallet? [Y/n] " ans
110 ans=${ans:-Y} 165 ans=${ans:-Y}
111 if [[ "$ans" =~ ^[Yy] ]]; then 166 if [[ "$ans" =~ ^[Yy] ]]; then
112 echo " Dumping Linux wallet..." 167 if [ -f "$WINE_DATA/wallet.dat" ]; then
113 DUMP=$(mktemp) 168 BK="$WINE_DATA/wallet.dat.bak.$(date +%Y%m%d%H%M%S)"
114 CONVERTED=$(mktemp) 169 cp "$WINE_DATA/wallet.dat" "$BK"
115 rm "$CONVERTED" # db_load needs a non-existing file 170 echo " Backed up existing GUI wallet -> $BK"
171 fi
172 DUMP=$(mktemp); CONVERTED=$(mktemp); rm -f "$CONVERTED"
173 echo " Converting Linux wallet format..."
116 db_dump -p "$LINUX_DATA/wallet.dat" > "$DUMP" 174 db_dump -p "$LINUX_DATA/wallet.dat" > "$DUMP"
117 echo " Converting format..."
118 db_load -f "$DUMP" "$CONVERTED" 175 db_load -f "$DUMP" "$CONVERTED"
119 echo " Installing converted wallet..."
120 cp "$CONVERTED" "$WINE_DATA/wallet.dat" 176 cp "$CONVERTED" "$WINE_DATA/wallet.dat"
121 rm "$DUMP" "$CONVERTED" 177 rm -f "$DUMP" "$CONVERTED"
122 echo " Wallet imported ✓" 178 echo " Wallet imported."
123 else 179 else
124 echo " Skipping. Re-run script to import later." 180 echo " Skipped. Re-run to import later."
125 fi 181 fi
126else 182else
127 echo "==> No Linux wallet found, starting fresh." 183 echo "==> No Linux wallet found, starting fresh."
128fi 184fi
129 185
130# ---- Launcher 186# ---- Launcher
131echo "==> Creating bitflash command..." 187echo "==> Creating 'bitflash' command..."
132mkdir -p "$BIN_DIR" 188mkdir -p "$BIN_DIR"
133LAUNCHER_FILE="$BIN_DIR/bitflash" 189LAUNCHER_FILE="$BIN_DIR/bitflash"
134printf '#!/usr/bin/env bash\n' > "$LAUNCHER_FILE" 190cat > "$LAUNCHER_FILE" <<EOF
135printf 'RELAY="${BTF_RELAY:-}"\n' >> "$LAUNCHER_FILE" 191#!/usr/bin/env bash
136printf 'ANNOUNCE=""\n' >> "$LAUNCHER_FILE" 192RELAY="\${BTF_RELAY:-}"
137printf '[ -n "$RELAY" ] && ANNOUNCE="-announcerelay=$RELAY"\n' >> "$LAUNCHER_FILE" 193ANNOUNCE=""
138printf 'WINEDLLOVERRIDES="libdb_cxx-6.2=n" wine "%s/bitflash.exe" $ANNOUNCE "$@"\n' "$INSTALL_DIR" >> "$LAUNCHER_FILE" 194[ -n "\$RELAY" ] && ANNOUNCE="-announcerelay=\$RELAY"
195WINEDLLOVERRIDES="libdb_cxx-6.2=n" wine "$EXE" \$ANNOUNCE "\$@"
196EOF
139chmod +x "$LAUNCHER_FILE" 197chmod +x "$LAUNCHER_FILE"
140echo " Launcher created: $(cat "$LAUNCHER_FILE" | wc -l) lines"
141 198
142if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then 199if [[ ":$PATH:" != *":$BIN_DIR:"* ]] && ! grep -qF 'export PATH="$HOME/.local/bin:$PATH"' "$HOME/.bashrc" 2>/dev/null; then
143 echo "==> Adding ~/.local/bin to PATH..."
144 echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc" 200 echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc"
201 echo " Added ~/.local/bin to PATH (restart shell or: source ~/.bashrc)"
145fi 202fi
146export PATH="$HOME/.local/bin:$PATH"
147 203
148echo 204echo
149echo "==================================================================" 205echo "=================================================================="
150echo " DONE." 206echo " DONE."
151echo " Launch: bitflash" 207echo " Launch: bitflash"
152echo " Mine: bitflash -gen" 208echo " Mine: bitflash -gen"
153echo " Relay: bitflash -announcerelay=YOUR_HOST:8434" 209echo " Relay: bitflash -announcerelay=YOUR_HOST:8434"
154echo " Data: $WINE_DATA" 210echo " Data: $WINE_DATA"
155echo "==================================================================" 211echo "=================================================================="