1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 15:04:42 +00:00

Adding more protection

This commit is contained in:
Tw93
2025-10-04 22:15:57 +08:00
parent 33a9820c81
commit 9fac7a7068

View File

@@ -17,14 +17,12 @@ WHITELIST_PATTERNS=(
"$HOME/Library/Caches/ms-playwright*"
"$HOME/.cache/huggingface*"
)
# Load user-defined whitelist file if present (~/.config/mole/whitelist)
# Load user-defined whitelist
if [[ -f "$HOME/.config/mole/whitelist" ]]; then
while IFS= read -r line; do
# Trim leading/trailing whitespace without relying on external tools
line="${line#${line%%[![:space:]]*}}"
line="${line%${line##*[![:space:]]}}"
[[ -z "$line" || "$line" =~ ^# ]] && continue
# Expand leading ~ for user convenience
[[ "$line" == ~* ]] && line="${line/#~/$HOME}"
WHITELIST_PATTERNS+=("$line")
done < "$HOME/.config/mole/whitelist"
@@ -64,17 +62,12 @@ SPINNER_PID=""
start_spinner() {
local message="$1"
# Check if we're in an interactive terminal
if [[ ! -t 1 ]]; then
# Non-interactive, just show static message
echo -n " ${BLUE}🔍${NC} $message"
return
fi
# Display message without newline
echo -n " ${BLUE}🔍${NC} $message"
# Start simple dots animation for interactive terminals
(
local delay=0.5
while true; do
@@ -95,7 +88,6 @@ stop_spinner() {
local result_message="${1:-Done}"
if [[ ! -t 1 ]]; then
# Non-interactive, just show result
echo "$result_message"
return
fi
@@ -104,16 +96,12 @@ stop_spinner() {
kill "$SPINNER_PID" 2>/dev/null
wait "$SPINNER_PID" 2>/dev/null
SPINNER_PID=""
# Clear the line and show result
printf "\r ${GREEN}${NC} %s\n" "$result_message"
else
# No spinner was running, just show result
echo " ${GREEN}${NC} $result_message"
fi
}
# Cleanup background processes on exit
start_section() {
TRACK_SECTION=1
SECTION_ACTIVITY=0
@@ -148,11 +136,9 @@ safe_clean() {
local total_size_bytes=0
local total_count=0
# Optimized: skip size calculation for empty checks, just try to delete
# Size calculation is the slowest part - do it in parallel
# Optimized parallel processing for better performance
local -a existing_paths=()
for path in "${targets[@]}"; do
# Skip if path matches whitelist
local skip=false
for w in "${WHITELIST_PATTERNS[@]}"; do
if [[ "$path" == $w ]]; then
@@ -168,11 +154,10 @@ safe_clean() {
return 0
fi
# Fast parallel processing for multiple targets
if [[ ${#existing_paths[@]} -gt 3 ]]; then
local temp_dir=$(mktemp -d)
# Launch parallel du jobs (bash 3.2 compatible)
# Parallel processing (bash 3.2 compatible)
local -a pids=()
for path in "${existing_paths[@]}"; do
(
@@ -182,19 +167,15 @@ safe_clean() {
) &
pids+=($!)
# Limit to 15 parallel jobs (bash 3.2 compatible)
if (( ${#pids[@]} >= 15 )); then
wait "${pids[0]}" 2>/dev/null || true
pids=("${pids[@]:1}")
fi
done
# Wait for remaining jobs
for pid in "${pids[@]}"; do
wait "$pid" 2>/dev/null || true
done
# Collect results and delete
for path in "${existing_paths[@]}"; do
local hash=$(echo -n "$path" | shasum -a 256 | cut -d' ' -f1)
if [[ -f "$temp_dir/$hash" ]]; then
@@ -212,7 +193,6 @@ safe_clean() {
rm -rf "$temp_dir"
else
# Serial processing for few targets (faster than parallel overhead)
for path in "${existing_paths[@]}"; do
local size_bytes=$(du -sk "$path" 2>/dev/null | awk '{print $1}' || echo "0")
local count=$(find "$path" -type f 2>/dev/null | wc -l | tr -d ' ')
@@ -228,7 +208,6 @@ safe_clean() {
done
fi
# Only show output if something was actually cleaned
if [[ $removed_any -eq 1 ]]; then
local size_human
if [[ $total_size_bytes -gt 1048576 ]]; then # > 1GB
@@ -285,7 +264,7 @@ start_cleanup() {
echo -en "${BLUE}Enter admin password to enable, or press Enter to skip: ${NC}"
read -s password
echo ""
if [[ -n "$password" ]] && echo "$password" | sudo -S true 2>/dev/null; then
SYSTEM_CLEAN=true
# Start sudo keepalive with error handling
@@ -640,7 +619,8 @@ perform_cleanup() {
safe_clean ~/Library/Caches/SentryCrash/* "Sentry crash reports"
safe_clean ~/Library/Caches/KSCrash/* "KSCrash reports"
safe_clean ~/Library/Caches/com.crashlytics.data/* "Crashlytics data"
safe_clean ~/Library/HTTPStorages/* "HTTP storage cache"
# Note: HTTPStorages contains cookies and login sessions, NOT safe to delete
# safe_clean ~/Library/HTTPStorages/* "HTTP storage cache"
end_section
@@ -765,13 +745,15 @@ perform_cleanup() {
end_section
# ===== 12. Orphaned leftovers =====
start_section "Orphaned app files"
# ===== 12. Orphaned app caches =====
# Note: We only clean orphaned caches (regenerable) but preserve:
# - Preferences (small, contain settings users may want when reinstalling)
# - Application Support data (may contain user documents/databases)
start_section "Orphaned app caches"
# Build a list of installed application bundle identifiers
echo -n " ${BLUE}🔍${NC} Scanning installed applications..."
local installed_bundles=$(mktemp)
# More robust approach that won't hang
for app in /Applications/*.app; do
if [[ -d "$app" && -f "$app/Contents/Info.plist" ]]; then
bundle_id=$(defaults read "$app/Contents/Info.plist" CFBundleIdentifier 2>/dev/null || echo "")
@@ -781,13 +763,10 @@ perform_cleanup() {
local app_count=$(wc -l < "$installed_bundles" | tr -d ' ')
echo " ${GREEN}${NC} Found $app_count apps"
local found_orphaned=false
local cache_count=0
local data_count=0
local pref_count=0
# Check for orphaned caches (with protection for critical system settings)
echo -n " ${BLUE}🔍${NC} Scanning cache directories..."
# Check for orphaned caches (safe to remove - caches are regenerable)
echo -n " ${BLUE}🔍${NC} Scanning orphaned cache directories..."
if ls ~/Library/Caches/com.* >/dev/null 2>&1; then
for cache_dir in ~/Library/Caches/com.*; do
[[ -d "$cache_dir" ]] || continue
@@ -798,85 +777,15 @@ perform_cleanup() {
fi
if ! grep -q "$bundle_id" "$installed_bundles" 2>/dev/null; then
safe_clean "$cache_dir" "Orphaned cache: $bundle_id"
found_orphaned=true
((cache_count++))
fi
done
fi
echo " ${GREEN}${NC} Complete ($cache_count removed)"
# Check for orphaned application support data (with protection for critical system settings)
echo -n " ${BLUE}🔍${NC} Scanning application data..."
if ls ~/Library/Application\ Support/com.* >/dev/null 2>&1; then
for support_dir in ~/Library/Application\ Support/com.*; do
[[ -d "$support_dir" ]] || continue
local bundle_id=$(basename "$support_dir")
# CRITICAL: Skip system-essential and protected app data
if should_protect_data "$bundle_id"; then
continue
fi
if ! grep -q "$bundle_id" "$installed_bundles" 2>/dev/null; then
safe_clean "$support_dir" "Orphaned data: $bundle_id"
found_orphaned=true
((data_count++))
fi
done
fi
# Also check for non-com.* folders that may contain user data
for support_dir in ~/Library/Application\ Support/*; do
[[ -d "$support_dir" ]] || continue
local dir_name=$(basename "$support_dir")
# Skip if it starts with com. (already processed) or is in dot directories
[[ "$dir_name" == com.* || "$dir_name" == .* ]] && continue
# CRITICAL: Protect important data folders (JetBrains, database tools, etc.)
if should_protect_data "$dir_name"; then
continue
fi
# Only clean if significant size and looks like app data, but be conservative
# Skip common system/user folders
case "$dir_name" in
"CrashReporter"|"AddressBook"|"CallHistoryDB"|"CallHistoryTransactions"|\
"CloudDocs"|"icdd"|"IdentityServices"|"Mail"|"CallServices"|\
"com.apple."*|"Adobe"|"Google"|"Mozilla"|"Netscape"|"Yahoo"|\
"AddressBook"|"iCloud"|"iLifeMediaBrowser"|"MobileSync"|\
"CallHistory"|"FaceTime"|"Twitter")
# System or commonly used folders, skip
continue
;;
esac
done
echo " ${GREEN}${NC} Complete ($data_count removed)"
# Check for orphaned preferences (with protection for critical system settings)
echo -n " ${BLUE}🔍${NC} Scanning preference files..."
if ls ~/Library/Preferences/com.*.plist >/dev/null 2>&1; then
for pref_file in ~/Library/Preferences/com.*.plist; do
[[ -f "$pref_file" ]] || continue
local bundle_id=$(basename "$pref_file" .plist)
# CRITICAL: Skip system-essential and protected app preferences
if should_protect_data "$bundle_id"; then
continue
fi
if ! grep -q "$bundle_id" "$installed_bundles" 2>/dev/null; then
safe_clean "$pref_file" "Orphaned preference: $bundle_id"
found_orphaned=true
((pref_count++))
fi
done
fi
echo " ${GREEN}${NC} Complete ($pref_count removed)"
# Clean up temp file
rm -f "$installed_bundles"
# Clean test data
safe_clean ~/Library/Application\ Support/TestApp* "Test app data"
safe_clean ~/Library/Application\ Support/MyApp/* "Test app data"
safe_clean ~/Library/Application\ Support/GitHub*/* "GitHub test data"
safe_clean ~/Library/Application\ Support/Twitter*/* "Twitter test data"
safe_clean ~/Library/Application\ Support/TestNoValue/* "Test data"
safe_clean ~/Library/Application\ Support/Wk*/* "Test data"
end_section
# ===== 13. Apple Silicon optimizations =====
@@ -889,14 +798,12 @@ perform_cleanup() {
end_section
fi
# System cleanup was moved to the beginning (right after password verification)
# ===== 14. iOS device backups =====
start_section "iOS device backups"
backup_dir="$HOME/Library/Application Support/MobileSync/Backup"
if [[ -d "$backup_dir" ]] && find "$backup_dir" -mindepth 1 -maxdepth 1 | read -r _; then
backup_kb=$(du -sk "$backup_dir" 2>/dev/null | awk '{print $1}')
if [[ -n "${backup_kb:-}" && "$backup_kb" -gt 102400 ]]; then # >100MB
if [[ -n "${backup_kb:-}" && "$backup_kb" -gt 102400 ]]; then
backup_human=$(du -sh "$backup_dir" 2>/dev/null | awk '{print $1}')
note_activity
echo -e " ${BLUE}💾${NC} Found ${GREEN}${backup_human}${NC} iOS backups"
@@ -926,7 +833,6 @@ perform_cleanup() {
fi
if [[ "$DRY_RUN" != "true" ]]; then
# Add some context when actually freed
if [[ $(echo "$freed_gb" | awk '{print ($1 >= 1) ? 1 : 0}') -eq 1 ]]; then
local movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}')
if [[ $movies -gt 0 ]]; then
@@ -941,7 +847,7 @@ perform_cleanup() {
echo "💾 No significant space was freed (system was already clean) | Free space: $(get_free_space)"
fi
fi
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
echo "📊 Files cleaned: $files_cleaned | Categories processed: $total_items"
elif [[ $files_cleaned -gt 0 ]]; then
@@ -983,7 +889,9 @@ main() {
DRY_RUN=true
;;
"--whitelist")
echo "Active whitelist patterns:"; for w in "${WHITELIST_PATTERNS[@]}"; do echo " $w"; done; exit 0
source "$SCRIPT_DIR/../lib/whitelist_manager.sh"
manage_whitelist
exit 0
;;
"--help"|"-h")
echo "Mole - Deeper system cleanup"
@@ -992,7 +900,7 @@ main() {
echo "Options:"
echo " --help, -h Show this help"
echo " --dry-run, -n Preview what would be cleaned without deleting"
echo " --whitelist Show active whitelist patterns"
echo " --whitelist Manage protected caches"
echo ""
echo "Interactive cleanup with smart password handling"
echo ""