depdownloader/check_johnny4.sh
2025-12-03 11:39:26 -10:00

273 lines
11 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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