depdownloader/check_johnny4.sh
2025-12-03 11:50:46 -10:00

273 lines
11 KiB
Bash
Executable File

#!/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