karnel-termux 4.10.0 → 4.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +1 -1
  2. package/karnel/cli/commands/backup.sh +238 -42
  3. package/karnel/cli/commands/install.sh +1 -0
  4. package/karnel/cli/commands/restore.sh +70 -36
  5. package/karnel/cli/karnel.sh +231 -2
  6. package/karnel/tools/security/aircrack-ng/install.sh +34 -0
  7. package/karnel/tools/security/all.sh +20 -0
  8. package/karnel/tools/security/amass/install.sh +58 -0
  9. package/karnel/tools/security/binwalk/install.sh +34 -0
  10. package/karnel/tools/security/burpsuite/install.sh +59 -0
  11. package/karnel/tools/security/dirb/install.sh +34 -0
  12. package/karnel/tools/security/dnsrecon/install.sh +47 -0
  13. package/karnel/tools/security/enum4linux/install.sh +45 -0
  14. package/karnel/tools/security/exiftool/install.sh +34 -0
  15. package/karnel/tools/security/ffuf/install.sh +60 -0
  16. package/karnel/tools/security/foremost/install.sh +34 -0
  17. package/karnel/tools/security/gobuster/install.sh +59 -0
  18. package/karnel/tools/security/hashcat/install.sh +34 -0
  19. package/karnel/tools/security/hydra/install.sh +34 -0
  20. package/karnel/tools/security/john/install.sh +34 -0
  21. package/karnel/tools/security/masscan/install.sh +51 -0
  22. package/karnel/tools/security/metasploit/install.sh +66 -0
  23. package/karnel/tools/security/netcat/install.sh +34 -0
  24. package/karnel/tools/security/nikto/install.sh +45 -0
  25. package/karnel/tools/security/nmap/install.sh +34 -0
  26. package/karnel/tools/security/smbclient/install.sh +34 -0
  27. package/karnel/tools/security/sqlmap/install.sh +45 -0
  28. package/karnel/tools/security/steghide/install.sh +34 -0
  29. package/karnel/tools/security/subfinder/install.sh +54 -0
  30. package/karnel/tools/security/tcpdump/install.sh +34 -0
  31. package/karnel/tools/security/theharvester/install.sh +47 -0
  32. package/karnel/tools/security/wafw00f/install.sh +36 -0
  33. package/karnel/tools/security/whatweb/install.sh +45 -0
  34. package/karnel/tools/security/whois/install.sh +34 -0
  35. package/karnel/tools/security/wpscan/install.sh +36 -0
  36. package/karnel/tools/security/zap/install.sh +73 -0
  37. package/karnel/utils/env.sh +1 -1
  38. package/package.json +1 -1
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://github.com/israelmarques1024-dotcom/karnel-termux">
11
- <img src="https://img.shields.io/badge/version-4.9.6-0078D4?style=for-the-badge" alt="Version">
11
+ <img src="https://img.shields.io/badge/version-4.11.0-0078D4?style=for-the-badge" alt="Version">
12
12
  </a>
13
13
  <a href="https://www.npmjs.com/package/karnel-termux">
14
14
  <img src="https://img.shields.io/npm/v/karnel-termux?style=for-the-badge&logo=npm&color=cb3837" alt="npm">
@@ -4,64 +4,89 @@ import "@/utils/log"
4
4
  import "@/utils/colors"
5
5
  import "@/tools/osint/robin/common"
6
6
 
7
+ BACKUP_DIR="${KARNEL_DATA}/backups"
8
+ mkdir -p "$BACKUP_DIR"
9
+
7
10
  backup_main() {
8
- if [[ "$1" == "--help" || "$1" == "-h" ]]; then
9
- echo
10
- box "◈ KARNEL BACKUP ◈"
11
- echo
12
- log_info "Save ALL your Termux configs + installed tools"
13
- echo
14
- list_item "karnel backup Backup local"
15
- list_item "karnel backup --cloud Backup + upload to Google Drive"
16
- list_item "karnel restore Restore latest backup"
17
- list_item "karnel restore --cloud Restore from Google Drive"
18
- echo
19
- return
20
- fi
11
+ local cmd="${1:-}"
12
+ shift 2>/dev/null || true
21
13
 
22
- local cloud=false
23
- [[ "$1" == "--cloud" ]] && cloud=true
14
+ case "$cmd" in
15
+ --help|-h) backup_help ;;
16
+ list|ls) backup_list ;;
17
+ info|show) backup_info "$@" ;;
18
+ snapshot) backup_snapshot "$@" ;;
19
+ --cron) backup_cron ;;
20
+ --cloud) backup_run true ;;
21
+ restore) backup_restore "$@" ;;
22
+ *) backup_run false ;;
23
+ esac
24
+ }
25
+
26
+ backup_help() {
27
+ echo
28
+ box "Backup & Restore"
29
+ echo
30
+ log_info "Usage: karnel backup [subcommand]"
31
+ echo
32
+ separator_section "Subcommands"
33
+ printf " ${D_CYAN}%-20s${NC} %s\n" "backup" "Create a new backup"
34
+ printf " ${D_CYAN}%-20s${NC} %s\n" "backup --cloud" "Backup + upload to cloud"
35
+ printf " ${D_CYAN}%-20s${NC} %s\n" "backup snapshot <n>" "Named snapshot"
36
+ printf " ${D_CYAN}%-20s${NC} %s\n" "backup list" "List all backups"
37
+ printf " ${D_CYAN}%-20s${NC} %s\n" "backup info <file>" "Show backup contents"
38
+ printf " ${D_CYAN}%-20s${NC} %s\n" "backup --cron" "Run automated daily backup"
39
+ printf " ${D_CYAN}%-20s${NC} %s\n" "restore" "Restore latest backup"
40
+ printf " ${D_CYAN}%-20s${NC} %s\n" "restore <file>" "Restore specific backup"
41
+ echo
42
+ separator_section "Examples"
43
+ echo " karnel backup"
44
+ echo " karnel backup snapshot before-update"
45
+ echo " karnel backup list"
46
+ echo " karnel restore"
47
+ echo " karnel restore termux-20240723_120000.tar.gz"
48
+ echo
49
+ }
24
50
 
25
- local dir="${KARNEL_DATA}/backups"
26
- mkdir -p "$dir"
51
+ backup_run() {
52
+ local cloud="${1:-false}"
27
53
  local ts
28
54
  ts=$(date +%Y%m%d_%H%M%S)
29
- local file="$dir/termux-$ts.tar.gz"
55
+ local file="$BACKUP_DIR/termux-$ts.tar.gz"
30
56
 
31
57
  echo
32
- box " KARNEL BACKUP ◈"
58
+ box "Karnel Backup"
33
59
  echo
34
60
 
35
61
  # Package list
36
- dpkg --get-selections > "$dir/packages-$ts.list" 2>/dev/null
62
+ dpkg --get-selections > "$BACKUP_DIR/packages-$ts.list" 2>/dev/null
37
63
  local pkgs
38
- pkgs=$(wc -l < "$dir/packages-$ts.list")
64
+ pkgs=$(wc -l < "$BACKUP_DIR/packages-$ts.list")
39
65
  log_success "Saved $pkgs installed packages"
40
66
 
41
67
  # Karnel tool manifest
42
- local tools=()
68
+ local -a tools=()
43
69
  for m in "$KARNEL_PATH/tools/"*/; do
44
70
  local mod
45
71
  mod=$(basename "${m%/}")
46
72
  for t in "$m"*/; do
47
73
  local tool
48
74
  tool=$(basename "${t%/}")
49
- local bins
50
- bins=$(grep -F "\"$tool:" "$m/all.sh" 2>/dev/null | cut -d: -f3 | tr -d '"')
75
+ [[ "$tool" == "all.sh" ]] && continue
51
76
  local found=false
52
- for b in ${bins//,/ }; do
53
- command -v "$b" &>/dev/null && found=true && break
77
+ for f in "$t"/*.sh; do
78
+ [[ -f "$f" ]] && found=true && break
54
79
  done
55
80
  $found && tools+=("$mod:$tool")
56
81
  done
57
82
  done
58
- printf "%s\n" "${tools[@]}" > "$dir/manifest-$ts.list"
83
+ printf "%s\n" "${tools[@]}" > "$BACKUP_DIR/manifest-$ts.list"
59
84
  log_success "Saved ${#tools[@]} Karnel tools"
60
85
 
61
86
  # Configs
62
87
  local tmp
63
88
  tmp=$(mktemp -d)
64
- mkdir -p "$tmp/config"/{home,termux,ssh,config,prefix-etc}
89
+ mkdir -p "$tmp/config"/{home,termux,ssh,config,prefix-etc,env}
65
90
 
66
91
  for f in .bashrc .zshrc .profile .zshenv .inputrc; do
67
92
  [[ -f "$HOME/$f" ]] && cp "$HOME/$f" "$tmp/config/home/"
@@ -69,8 +94,14 @@ backup_main() {
69
94
  [[ -d "$HOME/.termux" ]] && cp -r "$HOME/.termux" "$tmp/config/termux/" 2>/dev/null
70
95
  if [[ -d "$HOME/.ssh" ]]; then
71
96
  log_warn "Including SSH keys in backup — these are sensitive!"
97
+ mkdir -p "$tmp/config/ssh"
72
98
  cp "$HOME/.ssh/id_"* "$HOME/.ssh/config" "$HOME/.ssh/known_hosts" "$tmp/config/ssh/" 2>/dev/null
73
99
  fi
100
+
101
+ # Karnel env vars
102
+ env | grep -E '^(KARNEL_|OPENAI_|ANTHROPIC_|GEMINI_|GROQ_)' > "$tmp/config/env/karnel.env" 2>/dev/null
103
+ log_info "Saved environment variables"
104
+
74
105
  for d in "$HOME/.config"/*; do
75
106
  if [[ -d "$d" ]]; then
76
107
  local base; base=$(basename "$d")
@@ -79,8 +110,7 @@ backup_main() {
79
110
  fi
80
111
  fi
81
112
  done
82
- # Robin API keys and investigations are intentionally excluded from ordinary,
83
- # unencrypted backups. The acknowledgement file is harmless to retain.
113
+
84
114
  if [[ "$ROBIN_CONFIG_DIR" == "$HOME/.config/"* ]]; then
85
115
  local robin_config_relative="${ROBIN_CONFIG_DIR#"$HOME/.config/"}"
86
116
  rm -f "$tmp/config/config/$robin_config_relative"/.env* 2>/dev/null
@@ -98,22 +128,188 @@ backup_main() {
98
128
  log_success "Backup: $(basename "$file") ($size)"
99
129
  log_success "Checksum (SHA256): ${checksum:0:16}...${checksum: -16}"
100
130
 
101
- # Cloud
102
131
  if $cloud; then
103
- if ! command -v rclone &>/dev/null; then
104
- pkg install rclone -y &>/dev/null || log_warn "Install rclone: pkg install rclone"
105
- fi
106
- if command -v rclone &>/dev/null; then
107
- if rclone listremotes 2>/dev/null | grep -q "^karnel:"; then
108
- loading "Uploading" rclone copy "$file" "karnel:backups/"
109
- log_success "Uploaded to Google Drive"
110
- else
111
- log_warn "Run 'rclone config' and name the remote 'karnel'"
112
- fi
113
- fi
132
+ _backup_cloud "$file"
114
133
  fi
115
134
 
116
135
  echo
117
136
  log_success "Done! Restore with: karnel restore"
118
137
  echo
119
138
  }
139
+
140
+ backup_snapshot() {
141
+ local name="${1:-manual}"
142
+ local file="$BACKUP_DIR/snapshot-$name.tar.gz"
143
+ local ts
144
+ ts=$(date +%Y%m%d_%H%M%S)
145
+
146
+ echo
147
+ box "Karnel Snapshot: $name"
148
+ echo
149
+
150
+ local tmp
151
+ tmp=$(mktemp -d)
152
+ mkdir -p "$tmp/config"/{home,termux,config}
153
+
154
+ for f in .bashrc .zshrc .profile; do
155
+ [[ -f "$HOME/$f" ]] && cp "$HOME/$f" "$tmp/config/home/"
156
+ done
157
+ [[ -d "$HOME/.termux" ]] && cp -r "$HOME/.termux" "$tmp/config/termux/" 2>/dev/null
158
+ for d in "$HOME/.config"/*; do
159
+ [[ -d "$d" ]] && cp -r "$d" "$tmp/config/config/" 2>/dev/null
160
+ done
161
+
162
+ echo "$ts" > "$tmp/meta-snapshot.txt"
163
+ echo "$name" >> "$tmp/meta-snapshot.txt"
164
+
165
+ dpkg --get-selections > "$tmp/packages.list" 2>/dev/null
166
+ log_info "Snapshot includes $(wc -l < "$tmp/packages.list") packages"
167
+
168
+ tar -czf "$file" -C "$tmp" . 2>/dev/null
169
+ rm -rf "$tmp"
170
+
171
+ local checksum
172
+ checksum=$(sha256sum "$file" | awk '{print $1}')
173
+ echo "$checksum" > "$file.sha256"
174
+ log_success "Snapshot '$name' saved ($(du -h "$file" | awk '{print $1}'))"
175
+ }
176
+
177
+ backup_list() {
178
+ echo
179
+ box "Backups"
180
+ echo
181
+ local -a files=()
182
+ for f in "$BACKUP_DIR"/termux-*.tar.gz "$BACKUP_DIR"/snapshot-*.tar.gz; do
183
+ [[ -f "$f" ]] || continue
184
+ files+=("$f")
185
+ done
186
+ if [[ ${#files[@]} -eq 0 ]]; then
187
+ echo " No backups found."
188
+ echo " Create one: karnel backup"
189
+ return
190
+ fi
191
+ printf "${D_CYAN}%-30s${NC} ${D_GREEN}%-8s${NC} %s\n" "FILE" "SIZE" "CHECKSUM"
192
+ echo " $(printf '%0.s-' {1..70})"
193
+ for f in "${files[@]}"; do
194
+ local name size csum
195
+ name=$(basename "$f")
196
+ size=$(du -h "$f" | awk '{print $1}')
197
+ csum=""
198
+ [[ -f "$f.sha256" ]] && csum="$(cut -c1-16 < "$f.sha256")..."
199
+ printf " %-30s %-8s %s\n" "$name" "$size" "$csum"
200
+ done
201
+ echo
202
+ log_info "Total: ${#files[@]} backup(s)"
203
+ }
204
+
205
+ backup_info() {
206
+ local file="${1:-}"
207
+ if [[ -z "$file" ]]; then
208
+ # Find latest
209
+ file=$(ls -t "$BACKUP_DIR"/termux-*.tar.gz 2>/dev/null | head -1)
210
+ [[ -z "$file" ]] && log_error "No backups found" && return 1
211
+ fi
212
+ [[ "$file" != /* ]] && file="$BACKUP_DIR/$file"
213
+ [[ ! -f "$file" ]] && log_error "Backup not found: $file" && return 1
214
+
215
+ echo
216
+ box "Backup Info: $(basename "$file")"
217
+ echo
218
+ log_info "Size: $(du -h "$file" | awk '{print $1}')"
219
+ log_info "Created: $(date -r "$file" "+%Y-%m-%d %H:%M:%S" 2>/dev/null)"
220
+ [[ -f "$file.sha256" ]] && log_info "SHA256: $(cat "$file.sha256")"
221
+ echo
222
+ separator_section "Contents"
223
+ tar -tzf "$file" 2>/dev/null | head -40
224
+ local total
225
+ total=$(tar -tzf "$file" 2>/dev/null | wc -l)
226
+ [[ "$total" -gt 40 ]] && echo " ... and $(($total - 40)) more files"
227
+ echo
228
+ log_info "Total: $total files"
229
+ }
230
+
231
+ backup_cron() {
232
+ local cron_job="0 3 * * * ${KARNEL_BIN:-karnel} backup"
233
+ if crontab -l 2>/dev/null | grep -q "karnel backup"; then
234
+ log_info "Cron backup already configured"
235
+ return 0
236
+ fi
237
+ (crontab -l 2>/dev/null; echo "$cron_job") | crontab -
238
+ log_success "Daily backup scheduled at 3:00 AM"
239
+ echo " Edit with: crontab -e"
240
+ }
241
+
242
+ backup_restore() {
243
+ local file="${1:-}"
244
+ if [[ -z "$file" ]]; then
245
+ file=$(ls -t "$BACKUP_DIR"/termux-*.tar.gz 2>/dev/null | head -1)
246
+ [[ -z "$file" ]] && log_error "No backups found to restore" && return 1
247
+ log_info "Restoring latest backup: $(basename "$file")"
248
+ else
249
+ [[ "$file" != /* ]] && file="$BACKUP_DIR/$file"
250
+ [[ ! -f "$file" ]] && log_error "Backup not found: $file" && return 1
251
+ fi
252
+
253
+ echo
254
+ box "Restore"
255
+ echo
256
+ log_warn "This will overwrite your current configuration files!"
257
+ echo " Backup: $(basename "$file")"
258
+ echo " Size: $(du -h "$file" | awk '{print $1}')"
259
+ echo " Date: $(date -r "$file" "+%Y-%m-%d %H:%M:%S" 2>/dev/null)"
260
+ echo
261
+
262
+ # Verify checksum
263
+ local expected actual
264
+ if [[ -f "$file.sha256" ]]; then
265
+ expected=$(cat "$file.sha256")
266
+ actual=$(sha256sum "$file" | awk '{print $1}')
267
+ if [[ "$expected" != "$actual" ]]; then
268
+ log_error "Checksum mismatch! Backup may be corrupted."
269
+ log_info "Expected: $expected"
270
+ log_info "Actual: $actual"
271
+ return 1
272
+ fi
273
+ log_success "Checksum verified"
274
+ fi
275
+
276
+ local tmp
277
+ tmp=$(mktemp -d)
278
+ tar -xzf "$file" -C "$tmp" 2>/dev/null
279
+ log_success "Extracted backup"
280
+
281
+ # Restore configs
282
+ [[ -d "$tmp/config/home" ]] && cp -r "$tmp/config/home/." "$HOME/" 2>/dev/null
283
+ [[ -d "$tmp/config/termux" ]] && cp -r "$tmp/config/termux/." "$HOME/.termux/" 2>/dev/null && termux-reload-settings 2>/dev/null || true
284
+ [[ -d "$tmp/config/ssh" ]] && cp -r "$tmp/config/ssh/." "$HOME/.ssh/" 2>/dev/null && chmod 600 "$HOME/.ssh/id_"* 2>/dev/null
285
+ for d in "$tmp/config/config"/*/; do
286
+ [[ -d "$d" ]] && cp -r "$d" "$HOME/.config/" 2>/dev/null
287
+ done
288
+ [[ -f "$tmp/config/prefix-etc/sources.list" ]] && cp "$tmp/config/prefix-etc/sources.list" "$PREFIX/etc/apt/sources.list" 2>/dev/null
289
+
290
+ # Restore env vars
291
+ if [[ -f "$tmp/config/env/karnel.env" ]]; then
292
+ local env_bak="$HOME/.karnel-env-backup"
293
+ cp "$tmp/config/env/karnel.env" "$env_bak" 2>/dev/null
294
+ log_info "Env vars saved to $env_bak — source it to restore: source $env_bak"
295
+ fi
296
+
297
+ rm -rf "$tmp"
298
+ log_success "Restore complete! Restart your terminal."
299
+ echo
300
+ }
301
+
302
+ _backup_cloud() {
303
+ local file="$1"
304
+ if ! command -v rclone &>/dev/null; then
305
+ pkg install rclone -y &>/dev/null || log_warn "Install rclone: pkg install rclone"
306
+ fi
307
+ if command -v rclone &>/dev/null; then
308
+ if rclone listremotes 2>/dev/null | grep -q "^karnel:"; then
309
+ loading "Uploading" rclone copy "$file" "karnel:backups/"
310
+ log_success "Uploaded to cloud"
311
+ else
312
+ log_warn "Run 'rclone config' and name the remote 'karnel'"
313
+ fi
314
+ fi
315
+ }
@@ -23,6 +23,7 @@ install_main() {
23
23
  list_item "npm - Node.js global modules (npm packages)"
24
24
  list_item "osint - OSINT tools (Robin — Dark Web + LLM)"
25
25
  list_item "network - Network tools (Dark Web OSINT, DedSec Network)"
26
+ list_item "security - Security tools (Nmap, Hydra, SQLMap, Metasploit, etc.)"
26
27
  list_item "utils - Utility scripts (File Converter, Notes, QR Code, etc.)"
27
28
  list_item "shell - ZSH + Oh My Zsh + plugins"
28
29
  list_item "ui - Termux UI (font, cursor, extra-keys, banner)"
@@ -3,55 +3,92 @@
3
3
  import "@/utils/log"
4
4
  import "@/utils/colors"
5
5
 
6
- restore_main() {
7
- if [[ "$1" == "--help" || "$1" == "-h" ]]; then
8
- echo
9
- box "◈ KARNEL RESTORE ◈"
10
- echo
11
- list_item "karnel restore Restore latest backup"
12
- list_item "karnel restore <arquivo> Restore specific file"
13
- list_item "karnel restore --cloud Restore from Google Drive"
14
- echo
15
- return
16
- fi
6
+ BACKUP_DIR="${KARNEL_DATA}/backups"
17
7
 
18
- local dir="${KARNEL_DATA}/backups"
8
+ restore_main() {
19
9
  local file=""
20
10
  local cloud=false
11
+ local list_only=false
21
12
 
22
13
  for arg in "$@"; do
23
- [[ "$arg" == "--cloud" ]] && cloud=true && continue
24
- [[ -f "$arg" ]] && file="$arg"
14
+ case "$arg" in
15
+ --help|-h)
16
+ echo
17
+ box "Restore"
18
+ echo
19
+ log_info "Usage: karnel restore [options] [file]"
20
+ echo
21
+ printf " ${D_CYAN}%-24s${NC} %s\n" "karnel restore" "Restore latest backup"
22
+ printf " ${D_CYAN}%-24s${NC} %s\n" "karnel restore <file>" "Restore specific backup"
23
+ printf " ${D_CYAN}%-24s${NC} %s\n" "karnel restore --cloud" "Restore from cloud"
24
+ printf " ${D_CYAN}%-24s${NC} %s\n" "karnel restore --list" "List available backups"
25
+ echo
26
+ return
27
+ ;;
28
+ --cloud) cloud=true ;;
29
+ --list|-l) list_only=true ;;
30
+ *)
31
+ if [[ -z "$file" ]]; then
32
+ if [[ -f "$arg" ]]; then
33
+ file="$arg"
34
+ elif [[ -f "$BACKUP_DIR/$arg" ]]; then
35
+ file="$BACKUP_DIR/$arg"
36
+ else
37
+ log_error "File not found: $arg"
38
+ return 1
39
+ fi
40
+ fi
41
+ ;;
42
+ esac
25
43
  done
26
44
 
27
- # Download from cloud
45
+ if $list_only; then
46
+ echo
47
+ box "Available Backups"
48
+ echo
49
+ local count=0
50
+ for f in "$BACKUP_DIR"/termux-*.tar.gz "$BACKUP_DIR"/snapshot-*.tar.gz; do
51
+ [[ -f "$f" ]] || continue
52
+ ((count++))
53
+ local name size csum
54
+ name=$(basename "$f")
55
+ size=$(du -h "$f" | awk '{print $1}')
56
+ csum=""
57
+ [[ -f "$f.sha256" ]] && csum="$(cut -c1-16 < "$f.sha256")..."
58
+ printf " ${D_GREEN}%-30s${NC} %-8s %s\n" "$name" "$size" "$csum"
59
+ done
60
+ [[ $count -eq 0 ]] && echo " No backups found." && echo " Create one: karnel backup"
61
+ echo
62
+ return
63
+ fi
64
+
28
65
  if $cloud; then
29
66
  command -v rclone &>/dev/null || { log_error "Install rclone: pkg install rclone"; return 1; }
30
67
  rclone listremotes 2>/dev/null | grep -q "^karnel:" || { log_error "Run 'rclone config' and name remote 'karnel'"; return 1; }
31
-
32
- log_info "Downloading from Google Drive..."
33
- rclone copy "karnel:backups/" "$dir/" --include "termux-*.tar.gz" 2>/dev/null
68
+ log_info "Downloading from cloud..."
69
+ rclone copy "karnel:backups/" "$BACKUP_DIR/" --include "termux-*.tar.gz" 2>/dev/null
70
+ log_success "Downloaded from cloud"
34
71
  fi
35
72
 
36
- # Find file
37
- [[ -z "$file" ]] && file=$(ls -t "$dir"/termux-*.tar.gz 2>/dev/null | head -1)
73
+ [[ -z "$file" ]] && file=$(ls -t "$BACKUP_DIR"/termux-*.tar.gz 2>/dev/null | head -1)
38
74
  [[ -z "$file" || ! -f "$file" ]] && { log_error "No backup found. Run 'karnel backup' first"; return 1; }
39
75
 
40
76
  local ts
41
77
  ts=$(basename "$file" .tar.gz | sed 's/termux-//')
42
- local pkgs="$dir/packages-$ts.list"
43
- local manifest="$dir/manifest-$ts.list"
78
+ local pkgs="$BACKUP_DIR/packages-$ts.list"
79
+ local manifest="$BACKUP_DIR/manifest-$ts.list"
44
80
 
45
81
  echo
46
- box " KARNEL RESTORE ◈"
82
+ box "Restore: $(basename "$file")"
47
83
  echo
48
- log_info "Restoring: $(basename "$file")"
84
+ log_info "Size: $(du -h "$file" | awk '{print $1}')"
85
+ log_info "Date: $(date -r "$file" "+%Y-%m-%d %H:%M:%S" 2>/dev/null)"
49
86
  [[ -f "$manifest" ]] && log_info "$(wc -l < "$manifest") tools to reinstall"
87
+ [[ -f "$pkgs" ]] && log_info "$(wc -l < "$pkgs") packages to restore"
50
88
 
51
- # Checksum verification
89
+ # Checksum
52
90
  local checksum_file="$file.sha256"
53
91
  if [[ -f "$checksum_file" ]]; then
54
- log_info "Verifying checksum..."
55
92
  if sha256sum -c "$checksum_file" &>/dev/null; then
56
93
  log_success "Checksum verified"
57
94
  else
@@ -59,31 +96,29 @@ restore_main() {
59
96
  read_confirm "Continue anyway?" confirm
60
97
  [[ "$confirm" != "y" ]] && { log_info "Cancelled"; return 1; }
61
98
  fi
62
- else
63
- log_warn "No checksum file found (pre-checksum backup)"
64
99
  fi
65
100
 
66
101
  echo
67
-
68
102
  read_confirm "Proceed with restore?" confirm
69
103
  [[ "$confirm" != "y" ]] && { log_info "Cancelled"; return 0; }
70
104
 
71
- # Configs — extract to temp then copy to correct locations
72
105
  local tmp
73
106
  tmp=$(mktemp -d)
74
107
  tar -xzf "$file" -C "$tmp" 2>/dev/null
75
108
 
109
+ # Configs
76
110
  if [[ -d "$tmp/config/home" ]]; then
77
111
  log_info "Restoring shell configs..."
78
112
  for f in "$tmp/config/home/"*; do
79
- cp "$f" "$HOME/$(basename "$f")" 2>/dev/null
113
+ [[ -f "$f" ]] && cp "$f" "$HOME/$(basename "$f")" 2>/dev/null
80
114
  done
81
115
  log_success "Shell configs restored"
82
116
  fi
83
117
 
84
118
  if [[ -d "$tmp/config/termux" ]]; then
85
119
  log_info "Restoring Termux configs..."
86
- cp -r "$tmp/config/termux/.termux" "$HOME/" 2>/dev/null
120
+ cp -r "$tmp/config/termux/." "$HOME/.termux/" 2>/dev/null
121
+ termux-reload-settings 2>/dev/null || true
87
122
  log_success "Termux configs restored"
88
123
  fi
89
124
 
@@ -92,7 +127,7 @@ restore_main() {
92
127
  mkdir -p "$HOME/.ssh"
93
128
  chmod 700 "$HOME/.ssh"
94
129
  for f in "$tmp/config/ssh/"*; do
95
- cp "$f" "$HOME/.ssh/$(basename "$f")" 2>/dev/null
130
+ [[ -f "$f" ]] && cp "$f" "$HOME/.ssh/$(basename "$f")" 2>/dev/null
96
131
  done
97
132
  chmod 600 "$HOME/.ssh/id_"* 2>/dev/null
98
133
  log_success "SSH keys restored"
@@ -125,15 +160,14 @@ restore_main() {
125
160
  if [[ -f "$manifest" ]]; then
126
161
  log_info "Reinstalling tools..."
127
162
  local ok=0 total=0
128
- while IFS= read -r line; do
163
+ while IFS=: read -r mod tool; do
129
164
  ((total++))
130
- local mod="${line%%:*}" tool="${line#*:}"
131
165
  karnel install "$mod" "--$tool" &>/dev/null && ((ok++))
132
166
  done < "$manifest"
133
167
  log_success "$ok/$total tools reinstalled"
134
168
  fi
135
169
 
136
170
  echo
137
- log_success "All done! Restart Termux or run: source ~/.zshrc"
171
+ log_success "Done! Restart Termux or run: source ~/.zshrc"
138
172
  echo
139
173
  }