HEX
Server: Apache/2.4.66 (Ubuntu)
System: Linux nic2 5.15.0-177-generic #187-Ubuntu SMP Sat Apr 11 22:54:33 UTC 2026 x86_64
User: www-data (33)
PHP: 8.2.30
Disabled: NONE
Upload Files
File: //remove_htaccess_hacked/remove_htaccess_strict_debug.sh
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

MODE="${1:-dry}"   # dry | apply
BACKUP_EXT=".bak"
TMPDIR="$(mktemp -d)"

echo "Mode: $MODE"
echo "Temp dir: $TMPDIR"

# Perl program: legge dallo stdin il contenuto normalizzato, rimuove blocchi matching criteri,
# e stampa due righe diagnostiche al termine: "REMOVED:N" e il contenuto risultante.
# Questo permette allo script shell di capire se รจ cambiato qualcosa.
PERL_PROG='
use strict;
use warnings;
local $/ = undef;
my $orig = do { local $/; <STDIN> // "" };
$orig =~ s/\r\n?/\n/g;
my $s = $orig;
my $removed = 0;

# match all FilesMatch blocks (non-greedy)
# we capture the full match in $full, attributes in $attrs, inner in $inner
while ($s =~ m{(<FilesMatch\b([^>]*)>(.*?)</FilesMatch>)}gis) {
  my $full  = $1;
  my $attrs = $2 // "";
  my $inner = $3 // "";
  my $test = lc($attrs . " " . $inner);
  # Criterion short: contains .(py|exe|php or suspected) and "deny from all"
  if ($test =~ qr/\.\(py\|exe\|php\|suspected/ && $test =~ /deny\s+from\s+all/) {
    $s =~ s/\Q$full\E//si;
    $removed++;
    next;
  }
  # Criterion long: contains wp-blog-header.php and "allow from all"
  if ($test =~ /wp-blog-header\.php/ && $test =~ /allow\s+from\s+all/) {
    $s =~ s/\Q$full\E//si;
    $removed++;
    next;
  }
  # otherwise keep block
}

# collapse multiple blank lines and ensure final newline
$s =~ s/\n{3,}/\n\n/g;
$s .= "\n" unless $s =~ /\n\z/;

# print diagnostic header then content (caller will parse)
print "REMOVED:$removed\n";
print $s;
exit 0;
'

# find all .htaccess
mapfile -d '' FILES < <(find . -type f -name ".htaccess" -print0)

if [ "${#FILES[@]}" -eq 0 ]; then
  echo "Nessun file .htaccess trovato."
  rmdir "$TMPDIR"
  exit 0
fi

echo "Trovati ${#FILES[@]} file .htaccess"

for f in "${FILES[@]}"; do
  echo "---- Processing: $f ----"
  out="$TMPDIR/$(basename "$f").out"
  # pass file content to perl via stdin to avoid quoting problems
  if ! perl -0777 -e "$PERL_PROG" < "$f" > "$out".tmp 2>&1; then
    echo "  ERROR: perl failed on $f (see $out.tmp for stderr/stdout)"
    cat "$out".tmp | sed -n '1,200p'
    rm -f "$out".tmp
    continue
  fi

  # read first line REMOVED:N
  head -n1 "$out".tmp > "$out.header"
  removed=$(sed -n '1p' "$out".tmp | sed -n 's/^REMOVED:\([0-9]*\).*/\1/p')
  # write the rest as new content file
  tail -n +2 "$out".tmp > "$out.content"
  rm -f "$out".tmp

  if [ -z "$removed" ]; then
    echo "  DIAGNOSTIC ERROR: header REMOVED missing. Skipping."
    rm -f "$out.header" "$out.content"
    continue
  fi

  if [ "$removed" -eq 0 ]; then
    echo "  -> No matching FilesMatch blocks found (removed=0)."
    rm -f "$out.header" "$out.content"
    continue
  fi

  echo "  -> Found and removed $removed block(s) in $f"

  if [ "$MODE" = "dry" ]; then
    echo "  (dry) mostrando diff (prima 200 righe):"
    diff -u --label "orig: $f" --label "new: $f.new" "$f" "$out.content" | sed -n '1,200p' || true
    rm -f "$out.header" "$out.content"
    continue
  fi

  # apply mode: write backup and replace
  cp --preserve=mode,timestamps "$f" "$f${BACKUP_EXT}"
  mv "$out.content" "$f"
  echo "  (apply) aggiornato: $f (backup: $f${BACKUP_EXT})"
  rm -f "$out.header"
done

# cleanup
rmdir "$TMPDIR" 2>/dev/null || rm -rf "$TMPDIR"
echo "Completato."
exit 0