From 52db00f2f07514c8b90018303524316e210f7f92 Mon Sep 17 00:00:00 2001 From: Antoine Finet Date: Wed, 3 Dec 2025 11:39:26 -1000 Subject: [PATCH] Premier commit --- check_johnny4.sh | 273 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100755 check_johnny4.sh diff --git a/check_johnny4.sh b/check_johnny4.sh new file mode 100755 index 0000000..062f3b7 --- /dev/null +++ b/check_johnny4.sh @@ -0,0 +1,273 @@ +#!/bin/bash + +REQUIREMENTS="wget" + +display_help() { +cat << EOF +Usage: $0 [OPTIONS] + +OPTIONS: + -v, --verbose Active le mode verbeux. + -d, --distro NAME Spécifie la distribution (defaut: bookworm). + -a, --arch ARCH Spécifie l'architecture (defaut: amd64). + -p, --packages LIST Liste des paquets à analyser (séparés par des virgules et sans espace, + exemple : vim,openssh-server,netcat-traditional) +EOF +exit 0 +} + +if [[ "$#" == 0 ]]; then + display_help + return 1 +fi + +while [[ "$#" -gt 0 ]]; do + case "$1" in + -v|--verbose) + VERBOSE=1 + echo "Mode Verbeux activé." + shift + ;; + + # -d|--distro) + # if [ -n "$2" ]; then + # OUTPUT_DIR="$2" + # echo "Dossier de sortie : $OUTPUT_DIR" + # shift 2 # Déplace de 2 positions ($1 = -o, $2 = valeur) + # else + # echo "Erreur: --distro requiert un argument." >&2 + # exit 1 + # fi + # ;; + + # -a|--arch) + # if [ -n "$2" ]; then + # OUTPUT_DIR="$2" + # echo "Dossier de sortie : $OUTPUT_DIR" + # shift 2 # Déplace de 2 positions ($1 = -o, $2 = valeur) + # else + # echo "Erreur: --arch requiert un argument." >&2 + # exit 1 + # fi + # ;; + + -p|--packages) + if [ -n "$2" ]; then + PACKAGE_LIST="$2" + echo "Paquets à analyser : $PACKAGE_LIST" + shift 2 # Déplace de 2 positions ($1 = -o, $2 = valeur) + else + echo "Erreur: --packages requiert un argument." >&2 + exit 1 + fi + ;; + + -h|--help) + display_help + shift + ;; + + # Marqueur de fin d'options + --) + shift + break # Arrête le traitement des options + ;; + + # Autres arguments + *) + echo "Argument non reconnu: $1" >&2 + display_help + exit 1 + ;; + esac +done + +# Variables utilisateur +MAX_PARALLEL=5 # On prévoit un nombre de thread curl/wget pour le téléchargement +PACKAGES_FILE=Packages.gz # Autant variabiliser le nom de la liste des paquets +PACKAGES_FILE_MAX_AGE=86400 # Age maximum autorisé pour la copie locale du fichier Packages + +# Liste des paquets non souhaités ou déjà installés +EXCLUDED_PACKAGES=" debconf-2.0 adduser apparmor apt apt-utils base-files base-passwd bash bsdutils busybox console-setup console-setup-linux coreutils cpio cron cron-daemon-common dash debconf debconf-i18n debian-archive-keyring debianutils diffutils dmeventd dmidecode dmsetup dpkg e2fsprogs eject fdisk findutils firmware-linux-free gcc-12-base gettext-base gpgv grep grub-common grub-pc grub-pc-bin grub2-common gzip hostname ifupdown init init-system-helpers initramfs-tools initramfs-tools-core intel-microcode iproute2 iputils-ping isc-dhcp-client isc-dhcp-common iucode-tool kbd keyboard-configuration klibc-utils kmod less libacl1 libaio1 libapparmor1 libapt-pkg6.0 libargon2-1 libattr1 libaudit-common libaudit1 libblkid1 libbpf1 libbrotli1 libbsd0 libbz2-1.0 libc-bin libc-l10n libc6 libcap-ng0 libcap2 libcap2-bin libcom-err2 libcrypt1 libcryptsetup12 libdb5.3 libdebconfclient0 libdevmapper-event1.02.1 libdevmapper1.02.1 libedit2 libefiboot1 libefivar1 libelf1 libext2fs2 libfdisk1 libffi8 libfreetype6 libfuse2 libgcc-s1 libgcrypt20 libgmp10 libgnutls30 libgpg-error0 libgssapi-krb5-2 libhogweed6 libidn2-0 libip4tc2 libjansson4 libjson-c5 libk5crypto3 libkeyutils1 libklibc libkmod2 libkrb5-3 libkrb5support0 liblocale-gettext-perl liblvm2cmd2.03 liblz4-1 liblzma5 libmd0 libmnl0 libmount1 libncursesw6 libnettle8 libnewt0.52 libnftables1 libnftnl11 libp11-kit0 libpam-modules libpam-modules-bin libpam-runtime libpam0g libpci3 libpcre2-8-0 libpng16-16 libpopt0 libproc2-0 libreadline8 libseccomp2 libselinux1 libsemanage-common libsemanage2 libsepol2 libslang2 libsmartcols1 libss2 libssl3 libstdc++6 libsystemd-shared libsystemd0 libtasn1-6 libtext-charwidth-perl libtext-iconv-perl libtext-wrapi18n-perl libtinfo6 libtirpc-common libtirpc3 libudev1 libunistring2 libusb-1.0-0 libuuid1 libxtables12 libxxhash0 libzstd1 linux-base locales login logrotate logsave lvm2 mawk mount nano ncurses-base ncurses-bin netbase nftables os-prober passwd pci.ids pciutils perl-base procps readline-common sed sensible-utils systemd systemd-sysv sysvinit-utils tar tasksel tasksel-data tzdata ucf udev usbutils usr-is-merged util-linux util-linux-extra vim-common vim-tiny whiptail xkb-data zlib1g zstd " + +# Nécessaire pour télécharger la liste des paquets et les paquets eux mêmes (pourront être écrasées si on voulait porter +# le script vers une autre distribution) +BASE_URL="https://deb.debian.org/debian/" +PACKAGES_FILE_URL="dists/bookworm/main/binary-amd64/Packages.gz" + +# Initialiser les queues +declare -A packages_to_download +declare -a packages_queue + +get_package_info() { + local current_package="$1" + + # Si le lien de téléchargement n'a pas encore été déterminé + if [ -z "${packages_to_download["$current_package"]}" ]; then + + # Extraire les informations du paquet + _PACKAGE_BLOCK=$(zcat $PACKAGES_FILE | sed -n "/^Package: $current_package$/,/^$/{p;/^$/q}") + + # Contrôler que l'on a bien des informations concernant le paquet + if [ -n "$_PACKAGE_BLOCK" ]; then + + # Extraire le lien de téléchargement et l'affecter à la liste des paquets à télécharger + _PACKAGE_RELATIVE_LINK=$(echo "$_PACKAGE_BLOCK" | grep -E "^Filename:" | cut -d ' ' -f 2) + packages_to_download["$current_package"]="$_PACKAGE_RELATIVE_LINK" + + # Récupérer le noms des dépendances sous forme de string dont les noms des paquets sont séparés par des espaces + _DEPENDENCY_LIST=$(echo "$_PACKAGE_BLOCK" | grep -E "^Depends:" | sed "s/([^)]*)/()/g" | sed "s/()//g" | sed 's/,//g' | sed 's/|//g' | tr -s ' '| cut -d ':' -f 2) + + # Ajouter les dépendances à la liste d'attente + if [ -n "$_DEPENDENCY_LIST" ]; then + for _DEPENDENCY in $_DEPENDENCY_LIST; do + + # Si la dépendance est présente dans la liste noire, on passe au suivant + if [[ $EXCLUDED_PACKAGES == *" $_DEPENDENCY "* ]]; then + continue + fi + + # Si la dépendance est absente du tableau des paquets à télécharger, on l'y ajoute (clé vide ou non vide) + if [ -z ${packages_to_download["$_DEPENDENCY"]+x} ]; then + packages_to_download["$_DEPENDENCY"]="" # Ajout avec valeur vide + packages_queue+=("$_DEPENDENCY") # Ajout dans la file d'attente + fi + done + fi + fi + fi +} + +populate_packages_to_download() { + echo "Recherche des dépendances..." + # Tant qu'il y a des paquets dans la file d'attente + while [ ${#packages_queue[@]} -gt 0 ]; do + # Récupérer le premier élément de la queue + PACKAGE_TO_PROCESS="${packages_queue[0]}" + + # Traiter l'élément + get_package_info "$PACKAGE_TO_PROCESS" + + # Enlever l'élément de la queue + packages_queue=("${packages_queue[@]:1}") + done +} + +get_packagelist_file() { # Récupérer le fichier Packages.gz si la version locale est trop ancienne + local download_needed="0" + + # Vérifier si le fichier est présent et s'il est suffisamment récent + if [ -f $PACKAGES_FILE ]; then + _PACKAGE_FILE_AGE=$(($(date +%s) - $(stat -c %Z "$PACKAGES_FILE"))) + if [ $_PACKAGE_FILE_AGE -gt $PACKAGES_FILE_MAX_AGE ]; then + download_needed=1 + fi + else + download_needed=1 + fi + + # Télécharger le fichier + if [ $download_needed -eq 1 ]; then + echo "Téléchargement de $PACKAGES_FILE" + $_WGET $_WGET_PARAM "$BASE_URL$PACKAGES_FILE_URL" + else + if [[ $VERBOSE == 1 ]]; then + echo "$PACKAGES_FILE est suffisamment récent" + fi + fi +} + +download_package() { + if [[ $VERBOSE == 1 ]]; then + echo "Démarrage du téléchargement parallèle (max $MAX_PARALLEL) en arrière-plan..." + fi + local PIDS=() + + # Itérer sur les clés (les noms de paquets) + for PACKAGE_NAME in "${!packages_to_download[@]}"; do + + # Récupérer le lien relatif du paquet + local PACKAGE_RELATIVE_LINK="${packages_to_download[$PACKAGE_NAME]}" + + # Si le lien est vide (ce qui ne devrait pas arriver si populate_packages_to_download a fonctionné) + if [ -z "$PACKAGE_RELATIVE_LINK" ]; then + echo "Avertissement : Lien de téléchargement introuvable pour $PACKAGE_NAME. Saut." >&2 + continue + fi + + # Lancer le téléchargement en arrière-plan + if [[ $VERBOSE == 1 ]]; then + echo "Lancement du téléchargement pour $PACKAGE_NAME..." + fi + $_WGET $_WGET_PARAM -P "deb_files" "$BASE_URL$PACKAGE_RELATIVE_LINK" & + + # Enregistrer le PID (Process ID) + PIDS+=($!) + + # Supprimer le paquet du tableau associatif pour le marquer comme "en cours/traité" + unset packages_to_download["$PACKAGE_NAME"] + + # Si on atteint le maximum de processus parallèles, attendre qu'ils se terminent + if [[ ${#PIDS[@]} -ge $MAX_PARALLEL ]]; then + if [[ $VERBOSE == 1 ]]; then + echo "--- $MAX_PARALLEL téléchargements lancés. Attente de la fin des processus... ---" + fi + wait "${PIDS[@]}" + PIDS=() # Vider le tableau de PID pour la prochaine batch + fi + done + + # Attendre la fin des derniers processus lancés (la dernière batch) + if [[ ${#PIDS[@]} -gt 0 ]]; then + if [[ $VERBOSE == 1 ]]; then + echo "Attente de la fin des derniers processus ($?) en cours..." + fi + wait "${PIDS[@]}" + fi + + echo "Téléchargement terminé." +} + +debug_array() { + echo "--- Liste finale des paquets uniques requis ---" + for _KEY in ${!packages_to_download[@]}; do + echo "$_KEY ----- ${packages_to_download[$_KEY]}" + done +} + +main() { + if (which wget > /dev/null); then + _WGET=$(which wget) + else + echo "Wget est requis" + return 1 + fi + + if [ -z "$PACKAGE_LIST" ]; then + echo "Aucun paquet spécifié. Utilisez l'option -p ou --packages." >&2 + return 1 # Sortir de la fonction main avec un code d'erreur + fi + + if [[ $VERBOSE == 1 ]]; then + _WGET_PARAM="" + else + _WGET_PARAM="-q" + fi + + get_packagelist_file + + if [ -n "$PACKAGE_LIST" ]; then + OLD_IFS=$IFS + IFS=',' + for PACKAGE in $PACKAGE_LIST; do + PACKAGE=$(echo "$PACKAGE" | xargs) + packages_to_download["$PACKAGE"]="" + packages_queue+=("$PACKAGE") + done + IFS=$OLD_IFS + populate_packages_to_download + fi + download_package +} + +main \ No newline at end of file