From 59ef0fd51366851a900d688c32c5b58945a85fa5 Mon Sep 17 00:00:00 2001 From: Dan Church Date: Fri, 25 Nov 2022 14:58:27 -0600 Subject: [PATCH 1/3] Limit file clobbering during update Don't clobber files in-place unless there's actual changes. --- update.sh | 64 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/update.sh b/update.sh index 81b68f5..14d7a95 100755 --- a/update.sh +++ b/update.sh @@ -36,6 +36,34 @@ cleanup() { } trap 'cleanup' EXIT +copy_perms() { + local -r FROM=$1 TO=$2 + chmod --reference="$FROM" -- "$TO" + if [[ $UID -eq 0 ]]; then + chown --reference="$FROM" -- "$TO" + fi +} + +replace_with() { + local -r ORIG=$1 NEW=$2 + if ! diff -q -- "$ORIG" "$NEW" &>/dev/null; then + # There's a change + if [[ -f $ORIG ]]; then + copy_perms "$ORIG" "$NEW" + if [[ -n $BACKUPSUFFIX ]]; then + mv -- "$ORIG" "$ORIG$BACKUPSUFFIX" + fi + else + mkdir -p -- "${ORIG%/*}" + fi + mv -- "$NEW" "$ORIG" + else + printf 'File "%s" not modified\n' \ + "$ORIG" \ + >&2 + fi +} + (cd "$WORKDIR" && git submodule update --init --remote) for (( I = 0 ; I < ${#OUT[@]} ; ++I )); do @@ -52,44 +80,16 @@ for (( I = 0 ; I < ${#OUT[@]} ; ++I )); do TEMP_OUT=$(mktemp -p "$TEMP_DIR") - if [[ -f $MY_OUT ]]; then - cp -a -- "$MY_OUT" "$TEMP_OUT" - fi - wget \ -O "$TEMP_OUT" \ "$MY_URL" - if [[ -f $MY_OUT ]]; then - chmod --reference="$MY_OUT" "$TEMP_OUT" - if [[ -n $BACKUPSUFFIX ]]; then - mv -- "$MY_OUT" "$MY_OUT$BACKUPSUFFIX" - fi - fi - - mkdir -p -- "${MY_OUT%/*}" - mv -- "$TEMP_OUT" "$MY_OUT" - - # If the old one is the same, don't keep it around - if [[ -n $BACKUPSUFFIX && -f $MY_OUT$BACKUPSUFFIX ]]; then - if diff -q "$MY_OUT" "$MY_OUT$BACKUPSUFFIX"; then - rm -f -- "$MY_OUT$BACKUPSUFFIX" - fi - fi - + replace_with "$MY_OUT" "$TEMP_OUT" done -if [[ -n $BACKUPSUFFIX && -f $BLOCKLIST ]]; then - mv -- "$BLOCKLIST" "$BLOCKLIST$BACKUPSUFFIX" -fi -"$WORKDIR/make-block.pl" --out="$BLOCKLIST" - -# If the old one is the same the same, don't keep it around -if [[ -n $BACKUPSUFFIX && -f $BLOCKLIST$BACKUPSUFFIX ]]; then - if diff -q "$BLOCKLIST" "$BLOCKLIST$BACKUPSUFFIX"; then - rm -f -- "$BLOCKLIST$BACKUPSUFFIX" - fi -fi +TEMP_BLOCKLIST=$(mktemp -p "$TEMP_DIR") +"$WORKDIR/make-block.pl" --out="$TEMP_BLOCKLIST" +replace_with "$BLOCKLIST" "$TEMP_BLOCKLIST" if [[ ${#DNSMASQ_RESTART_COMMAND[@]} -gt 0 ]]; then "${DNSMASQ_RESTART_COMMAND[@]}" From fd8061714f6c5c097dd56d60d567fc9d24849a50 Mon Sep 17 00:00:00 2001 From: Dan Church Date: Fri, 25 Nov 2022 15:40:20 -0600 Subject: [PATCH 2/3] Use a common method of reading lines Adds comment support for domain lists. --- make-block.pl | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/make-block.pl b/make-block.pl index 43d2fd1..ac9be32 100755 --- a/make-block.pl +++ b/make-block.pl @@ -25,13 +25,7 @@ my $dupes = 0; my $skip = 0; sub add_domain_list { my $file = shift; - - open my $fni, '<', $file - or die "Failed to open file $file for reading: $!"; - - foreach my $line (<$fni>) { - chomp $line; - $line =~ s/^\s+|\s+$//; + foreach my $line (&read_stripped($file)) { my $domain = lc $line; ++$dupes if defined $domains{$domain}; $domains{$domain} = 1; @@ -40,15 +34,7 @@ sub add_domain_list { sub add_host_file { my $file = shift; - - open my $fni, '<', $file - or die "Failed to open file $file for reading: $!"; - - foreach my $line (<$fni>) { - chomp $line; - # strip whitespace and comments - $line =~ s/^\s+|\s+$|\s*#.*$//; - next unless $line; + foreach my $line (&read_stripped($file)) { my @parts = split /\s+/, $line; die "Malformed line in $file: $line; @parts" unless @parts > 1; @@ -66,6 +52,20 @@ sub add_host_file { } } +sub read_stripped { + my $file = shift; + + open my $fni, '<', $file + or die "Failed to open file $file for reading: $!"; + + map { + chomp; + # Strip whitespace and comments + s/^\s+|\s+$|\s*#.*$//; + $_ || () + } <$fni>; +} + MAIN: { my $out; my $block_ip = '0.0.0.0 ::1'; From 1a97ec83653c5ea26b62ebabd615f584552b5512 Mon Sep 17 00:00:00 2001 From: Dan Church Date: Fri, 25 Nov 2022 16:15:13 -0600 Subject: [PATCH 3/3] Add support for allowlists --- allowlists/.gitignore | 6 ++++++ allowlists/allowlist.domains.example | 8 ++++++++ make-block.pl | 13 +++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 allowlists/.gitignore create mode 100644 allowlists/allowlist.domains.example diff --git a/allowlists/.gitignore b/allowlists/.gitignore new file mode 100644 index 0000000..57d81ac --- /dev/null +++ b/allowlists/.gitignore @@ -0,0 +1,6 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore +# ... And some others +!/allowlist.domains.example diff --git a/allowlists/allowlist.domains.example b/allowlists/allowlist.domains.example new file mode 100644 index 0000000..923103e --- /dev/null +++ b/allowlists/allowlist.domains.example @@ -0,0 +1,8 @@ +# Omit these domains from the blocklist. +# +# Must be in a file called *.domains in this directory. +# Comments are allowed. One domain per line. +# +# Examples: +# domain1.example.com +# domain2.example.com diff --git a/make-block.pl b/make-block.pl index ac9be32..1ac0d8a 100755 --- a/make-block.pl +++ b/make-block.pl @@ -23,6 +23,7 @@ use FindBin qw//; my %domains; my $dupes = 0; my $skip = 0; +my $removed_allowed = 0; sub add_domain_list { my $file = shift; foreach my $line (&read_stripped($file)) { @@ -82,6 +83,7 @@ MAIN: { my @domain_lists = glob "$workdir/lists/*.domains"; my @hosts_lists = glob "$workdir/lists/*.hosts"; + my @allow_lists = glob "$workdir/allowlists/*.domains"; foreach my $listfile (@domain_lists) { &add_domain_list($listfile); @@ -90,6 +92,16 @@ MAIN: { &add_host_file($hostfile); } + # Apply allowlists + my @allow_domains; + foreach my $allowlist (@allow_lists) { + push @allow_domains, &read_stripped($allowlist); + } + my $before = %domains; + delete %domains{@allow_domains}; + # Count number removed + $removed_allowed = $before - %domains; + my $written = 0; my $fho = \*STDOUT; if (defined $out && length $out) { @@ -109,5 +121,6 @@ MAIN: { printf STDERR " - %d .domains files\n", (scalar @domain_lists); printf STDERR " - %d .hosts files\n", (scalar @hosts_lists); printf STDERR "(%d duplicates)\n", $dupes if $dupes; + printf STDERR "(%d domains removed via allowlist)\n", $removed_allowed if $removed_allowed; printf STDERR "(%d skipped)\n", $skip if $skip; }