blob: cf4c23cc5781b2566abfec7d7ad0a455e8a27612 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#!/usr/bin/env bash
# ─── Configuration ──────────────────────────────────────────────────
WATCH_DIR="$HOME/Downloads"
CLAMSCAN_OPTS="--infected --recursive --remove=no"
LOG_FILE="$HOME/download-guardian.log"
# ────────────────────────────────────────────────────────────────────
# Ensure required commands exist:
for cmd in inotifywait clamscan zenity notify-send freshclam; do
if ! command -v "$cmd" &>/dev/null; then
echo "ERROR: '$cmd' is required but not found in PATH." >&2
exit 1
fi
done
# Update ClamAV database on startup:
if command -v freshclam &>/dev/null; then
/usr/bin/freshclam --quiet
fi
# Helper: pop up a Yes/No dialog for a given path
confirm_scan() {
local path="$1"
zenity --question \
--title="Download Guardian" \
--width=350 \
--text="New item detected:\n$path\n\nScan with Download Guardian?" \
--ok-label="Yes, scan" \
--cancel-label="No, skip"
return $?
}
# Helper: send a desktop notification
# Usage: notify "Title" "Message"
notify() {
local title="$1"
local msg="$2"
# -u normal sets normal urgency; -t 5000 gives 5s timeout
notify-send -i system -a DownloadGuardian -u normal -t 5000 "$title" "$msg"
}
echo "[INFO] Download Guardian: watching $WATCH_DIR"
echo " Logs → $LOG_FILE"
# Start watching for newly closed files and moved-in items
inotifywait -m -e close_write -e moved_to \
--format '%w%f' "$WATCH_DIR" | while read -r NEWPATH; do
# Skip if it no longer exists:
[[ ! -e "$NEWPATH" ]] && continue
# Skip zero-byte or temp files (.part, .crdownload, .tmp, etc.):
filename=$(basename "$NEWPATH")
if [[ "$filename" =~ \.part$ ]] \
|| [[ "$filename" =~ \.crdownload$ ]] \
|| [[ "$filename" =~ \.tmp$ ]] \
|| ([[ "$filename" =~ ^\. ]] && [[ ! -d "$NEWPATH" ]]); then
echo "[SKIP] Temp/incomplete file: $NEWPATH" >> "$LOG_FILE"
continue
fi
# Skip if it’s an empty directory
if [[ -d "$NEWPATH" && -z "$(ls -A "$NEWPATH")" ]]; then
echo "[SKIP] Empty directory: $NEWPATH" >> "$LOG_FILE"
continue
fi
echo "[EVENT] $(date '+%Y-%m-%d %H:%M:%S') Detected: $NEWPATH" >> "$LOG_FILE"
if confirm_scan "$NEWPATH"; then
echo "[ACTION] Scanning: $NEWPATH" >> "$LOG_FILE"
notify "Download Guardian" "Scanning: $(basename "$NEWPATH") …"
# Run clamscan and capture output
SCAN_OUTPUT=$(clamscan $CLAMSCAN_OPTS "$NEWPATH" 2>&1)
SCAN_EXIT=$?
# Append to log
{
echo "------ $(date '+%Y-%m-%d %H:%M:%S') Scan Result for: $NEWPATH ------"
echo "$SCAN_OUTPUT"
echo
} >> "$LOG_FILE"
# Determine completion notification
if [[ $SCAN_EXIT -eq 0 ]]; then
# No virus found
notify "Download Guardian: Clean" "$(basename "$NEWPATH") is clean."
elif [[ $SCAN_EXIT -eq 1 ]]; then
# At least one virus found
INF_LINES=$(echo "$SCAN_OUTPUT" | grep -E "FOUND$")
[[ -z "$INF_LINES" ]] && INF_LINES="(infected, but cannot parse name)"
notify "Download Guardian: Infected!" "$(basename "$NEWPATH") → $INF_LINES"
else
# Exit code >1 → clamscan error
notify "Download Guardian: Error" "Error scanning $(basename "$NEWPATH"). Check logs."
fi
else
echo "[ACTION] Skipped scanning: $NEWPATH" >> "$LOG_FILE"
fi
done
|