|
24 | 24 | # set -x |
25 | 25 |
|
26 | 26 | # Path settings |
27 | | -# Important: Verify that the following directory path is correct |
28 | | -readonly WORK_DIR="/home/domain-filter-mikrotik" |
| 27 | +# Automatically determine working directory based on script location |
| 28 | +readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 29 | +readonly WORK_DIR="${WORK_DIR:-${SCRIPT_DIR%/*}}" |
29 | 30 | readonly SOURCES_FILE="${WORK_DIR}/sources.txt" |
30 | 31 | readonly SOURCESSPECIAL_FILE="${WORK_DIR}/sources_special.txt" |
31 | 32 | readonly WHITELIST_FILE="${WORK_DIR}/sources_whitelist.txt" |
@@ -88,6 +89,76 @@ mkdir -p "$(dirname "$LOG_FILE")" |
88 | 89 | # Clear old log |
89 | 90 | : > "$LOG_FILE" |
90 | 91 |
|
| 92 | +# Function to display help |
| 93 | +show_help() { |
| 94 | + cat << EOF |
| 95 | +Mikrotik Domain Filter Script v2.0 |
| 96 | +
|
| 97 | +USAGE: |
| 98 | + $(basename "$0") [OPTIONS] |
| 99 | +
|
| 100 | +DESCRIPTION: |
| 101 | + A robust Bash solution for filtering and processing domain lists for Mikrotik devices, |
| 102 | + enabling straightforward management of blocklists or allowlists. |
| 103 | +
|
| 104 | +OPTIONS: |
| 105 | + -h, --help Show this help message and exit |
| 106 | + -v, --version Show version information |
| 107 | +
|
| 108 | +CONFIGURATION: |
| 109 | + Working Directory: $WORK_DIR (auto-detected from script location) |
| 110 | + |
| 111 | + Required files: |
| 112 | + - sources.txt Main domain list URLs |
| 113 | + - sources_special.txt Special domain list URLs |
| 114 | + |
| 115 | + Optional files: |
| 116 | + - sources_whitelist.txt Whitelist domain URLs |
| 117 | + - .env Environment configuration |
| 118 | +
|
| 119 | +ENVIRONMENT VARIABLES: |
| 120 | + WORK_DIR Override working directory |
| 121 | + EXPORT_GISTS Enable GitHub Gist exports (true/false) |
| 122 | + GITHUB_TOKEN GitHub Personal Access Token |
| 123 | + GIST_ID_MAIN Main list Gist ID |
| 124 | + GIST_ID_SPECIAL Special list Gist ID |
| 125 | +
|
| 126 | +For detailed documentation, visit: |
| 127 | +https://github.com/smkrv/mikrotik-domain-filter-script |
| 128 | +
|
| 129 | +EOF |
| 130 | +} |
| 131 | + |
| 132 | +# Function to display version |
| 133 | +show_version() { |
| 134 | + echo "Mikrotik Domain Filter Script v2.0" |
| 135 | + echo "License: CC BY-NC-SA 4.0" |
| 136 | + echo "Author: SMKRV" |
| 137 | + echo "Repository: https://github.com/smkrv/mikrotik-domain-filter-script" |
| 138 | +} |
| 139 | + |
| 140 | +# Parse command line arguments |
| 141 | +parse_arguments() { |
| 142 | + while [[ $# -gt 0 ]]; do |
| 143 | + case $1 in |
| 144 | + -h|--help) |
| 145 | + show_help |
| 146 | + exit 0 |
| 147 | + ;; |
| 148 | + -v|--version) |
| 149 | + show_version |
| 150 | + exit 0 |
| 151 | + ;; |
| 152 | + *) |
| 153 | + echo "Unknown option: $1" |
| 154 | + echo "Use --help for usage information" |
| 155 | + exit 1 |
| 156 | + ;; |
| 157 | + esac |
| 158 | + shift |
| 159 | + done |
| 160 | +} |
| 161 | + |
91 | 162 | # Check for required files |
92 | 163 | check_required_files() { |
93 | 164 | local missing_files=() |
@@ -226,23 +297,29 @@ cleanup() { |
226 | 297 | if [[ -d "$TMP_DIR" && "$TMP_DIR" =~ ^${WORK_DIR}/tmp ]]; then |
227 | 298 | log "Cleaning temporary directory..." |
228 | 299 |
|
229 | | - # Create list of protected files |
230 | | - local protected_files=( |
| 300 | + # Create list of protected files patterns |
| 301 | + local protected_patterns=( |
231 | 302 | "*md5" |
232 | 303 | "domain_registry.*" |
233 | 304 | "previous_state.*" |
234 | 305 | "update_state.dat" |
235 | 306 | "*.backup" |
236 | 307 | ) |
237 | 308 |
|
238 | | - # Build exclude pattern |
239 | | - local exclude_pattern |
240 | | - exclude_pattern=$(printf " ! -name '%s'" "${protected_files[@]}") |
| 309 | + # Remove files that don't match protected patterns |
| 310 | + local find_cmd=(find "$TMP_DIR" -type f) |
| 311 | + |
| 312 | + # Add exclusion patterns |
| 313 | + for pattern in "${protected_patterns[@]}"; do |
| 314 | + find_cmd+=("!" "-name" "$pattern") |
| 315 | + done |
| 316 | + |
| 317 | + find_cmd+=("-delete") |
241 | 318 |
|
242 | | - # Remove files |
243 | | - eval "find '$TMP_DIR' -type f $exclude_pattern -delete" || { |
| 319 | + # Execute find command safely |
| 320 | + if ! "${find_cmd[@]}" 2>/dev/null; then |
244 | 321 | log "WARNING: Failed to clean temporary files" |
245 | | - } |
| 322 | + fi |
246 | 323 |
|
247 | 324 | # Remove empty directories except protected ones |
248 | 325 | find "$TMP_DIR" -type d -empty ! -name "downloads" ! -name "state" -delete 2>/dev/null || { |
@@ -1520,6 +1597,42 @@ restore_backups() { |
1520 | 1597 | [[ -f "${OUTPUT_FILESPECIAL}.bak" ]] && mv "${OUTPUT_FILESPECIAL}.bak" "$OUTPUT_FILESPECIAL" |
1521 | 1598 | } |
1522 | 1599 |
|
| 1600 | +# Function to process a single domain list |
| 1601 | +process_domain_list() { |
| 1602 | + local list_name=$1 |
| 1603 | + local raw_file=$2 |
| 1604 | + local tmp_dir_prefix=$3 |
| 1605 | + |
| 1606 | + log "Processing ${list_name} list..." |
| 1607 | + |
| 1608 | + # Extract domains |
| 1609 | + if ! extract_domains "$raw_file" "${TMP_DIR}/${tmp_dir_prefix}_extracted.txt"; then |
| 1610 | + log "ERROR: Failed to extract ${list_name} domains" |
| 1611 | + return 1 |
| 1612 | + fi |
| 1613 | + |
| 1614 | + # Initial filtering |
| 1615 | + if ! initial_filter "$raw_file" "${TMP_DIR}/${tmp_dir_prefix}_initial.txt"; then |
| 1616 | + log "ERROR: Failed to filter ${list_name} domains" |
| 1617 | + return 1 |
| 1618 | + fi |
| 1619 | + |
| 1620 | + # Process and classify domains |
| 1621 | + if ! process_domains "${TMP_DIR}/${tmp_dir_prefix}_initial.txt" "${TMP_DIR}/${tmp_dir_prefix}"; then |
| 1622 | + log "ERROR: Failed to process ${list_name} domain list" |
| 1623 | + return 1 |
| 1624 | + fi |
| 1625 | + |
| 1626 | + # Prepare domains for DNS check |
| 1627 | + if ! prepare_domains_for_dns_check "${TMP_DIR}/${tmp_dir_prefix}" "${TMP_DIR}/${tmp_dir_prefix}_filtered.txt"; then |
| 1628 | + log "ERROR: Failed to prepare ${list_name} domains for DNS check" |
| 1629 | + return 1 |
| 1630 | + fi |
| 1631 | + |
| 1632 | + log "${list_name} list processing completed successfully" |
| 1633 | + return 0 |
| 1634 | +} |
| 1635 | + |
1523 | 1636 | # Main function |
1524 | 1637 | main() { |
1525 | 1638 | log "Script started..." |
@@ -1624,42 +1737,15 @@ main() { |
1624 | 1737 | log "Backup of special list created" |
1625 | 1738 | fi |
1626 | 1739 |
|
1627 | | - # Process main list |
1628 | | - log "Processing main list..." |
1629 | | - if ! extract_domains "$main_raw" "${TMP_DIR}/main_extracted.txt"; then |
1630 | | - log "ERROR: Failed to extract main domains" |
1631 | | - restore_backups |
1632 | | - release_lock |
1633 | | - return 1 |
1634 | | - fi |
1635 | | - |
1636 | | - if ! initial_filter "$main_raw" "${TMP_DIR}/main_initial.txt"; then |
1637 | | - log "ERROR: Failed to filter main domains" |
1638 | | - restore_backups |
1639 | | - release_lock |
1640 | | - return 1 |
1641 | | - fi |
1642 | | - |
1643 | | - if ! process_domains "${TMP_DIR}/main_initial.txt" "${TMP_DIR}/main"; then |
1644 | | - log "ERROR: Failed to process main domain list" |
1645 | | - restore_backups |
1646 | | - release_lock |
1647 | | - return 1 |
1648 | | - fi |
1649 | | - |
1650 | | - if ! prepare_domains_for_dns_check "${TMP_DIR}/main" "${TMP_DIR}/main_filtered.txt"; then |
1651 | | - log "ERROR: Failed to prepare main domains for DNS check" |
| 1740 | + # Process main and special lists using the unified function |
| 1741 | + if ! process_domain_list "main" "$main_raw" "main"; then |
| 1742 | + log "ERROR: Failed to process main list" |
1652 | 1743 | restore_backups |
1653 | 1744 | release_lock |
1654 | 1745 | return 1 |
1655 | 1746 | fi |
1656 | 1747 |
|
1657 | | - # Process special list |
1658 | | - log "Processing special list..." |
1659 | | - if ! extract_domains "$special_raw" "${TMP_DIR}/special_extracted.txt" || \ |
1660 | | - ! initial_filter "$special_raw" "${TMP_DIR}/special_initial.txt" || \ |
1661 | | - ! process_domains "${TMP_DIR}/special_initial.txt" "${TMP_DIR}/special" || \ |
1662 | | - ! prepare_domains_for_dns_check "${TMP_DIR}/special" "${TMP_DIR}/special_filtered.txt"; then |
| 1748 | + if ! process_domain_list "special" "$special_raw" "special"; then |
1663 | 1749 | log "ERROR: Failed to process special list" |
1664 | 1750 | restore_backups |
1665 | 1751 | release_lock |
@@ -1752,6 +1838,8 @@ main() { |
1752 | 1838 | } |
1753 | 1839 |
|
1754 | 1840 | # Main execution |
| 1841 | +parse_arguments "$@" |
| 1842 | + |
1755 | 1843 | if ! main "$@"; then |
1756 | 1844 | error "Script terminated with error" |
1757 | 1845 | exit 1 |
|
0 commit comments