#!/bin/bash

###############################################################################
# MajMageia 1.0	paiiou@free.fr
###############################################################################
# Programme non interactif d'actualisation des fichiers d'un miroir personnel de Mageia.
# Le miroir local peut comprendre plusieurs branches ou sous-branches
# telles que : core, nonfree, tainted ...
# Destination : /var/ftp/pub/perso/version
# Journal : /var/ftp/pub/perso/~MajMga.version.date
################################################################################

### Déroulement du programme
### Appel à l'aide
### Définition de la distribution et contrôle
### Options de la commande rsync (pour info)
### Définition du miroir distant avec l'emplacement de la distribution Mageia. Contrôle
### Création du journal
### Création du fichier Excludes (répertoires et fichiers à exclure)
### Actualisation du miroir
### Épuration du répertoire media/media_info

### Appel à l'aide
help ()
{
	echo ""
	echo "Objet :"
	echo "$0 actualise les fichiers d'un miroir local de Mageia."
	echo "Le miroir local peut comprendre plusieurs branches telles que : core_release, core_backports ..."
	echo "Usage :"
	echo "$0 [ h | help | -h | --help ] : affiche ce message"
	echo "$0 Chemin_vers_la_racine"
	echo "Ex $0 /var/ftp/pub/perso/cauldron/i586"
	exit 1
}

###
# Entrée principale
###

### Appel à l'aide
[ -z "$1" ] && help
[ "$1" == "h" -o "$1" == "help" -o "$1" == "-h" -o "$1" == "--help" ] && help
# Format de la date
Date=`date +"%Y%m%d"`

### Définition de la distribution
Distri_root=$1
Arch=${Distri_root##*/}
Temp=${Distri_root%/$Arch}
Ver=${Temp##*/}

# Contrôle du répertoire racine de la distribution
while [ "$Arch" != "i586" -a "$Arch" != "x86_64" -o  ! -d "$Distri_root" ]; do
	echo "Le répertoire indiqué ne semble pas exister ou n'est pas un répertoire racine de distribution !"
	echo "Indiquez la racine de la distribution :"
	read Distri_root
	Arch=${Distri_root##*/}
done
Media_root=$Distri_root/media
Info_root=$Media_root/media_info

### Options de la commande rsync (pour info)
# rsync [options] Source Destination
# -u = remplacement uniquement si le fichier source est plus récent
# -n = dry-run = montre uniquement ce qui se serait passé
# -i = affiche un résumé des changements pour chaque mise à jour
# -a = archive ( = rlptgoD : recursif, conserve liens, permissions, date, groupe, proprio)
# -r = récursif
# -l = copie les liens symboliques comme liens symboliques
# -p = conserve les permissions
# -t = préserve les dates
# -g = conserve le groupe
# -o = conserve le propriétaire
# -D = conserve les périphériques (root uniquement)
# -v = verbeux
# -S = traiter efficacement les fichiers éclatés
# -H = conserve les liens matériels
# -- delete-after = supprime les anciens fichiers après avoir chargé les nouveaux
# --log-format=FORMAT = affiche les noms fichiers selon le format spécifié
# --safe-links = ignore les liens hors arborescence
# --existing = met à jour uniquement les fichiers qui existent déjà
# --delete = supprime les fichiers de locaux non existants dans la source
# --delete-excluded = supprime les fichiers exclus, s'ils sont déjà présents
# --excludes=
# --only-write-batch=FICHIER = ne fait pas la mise à jour, mais indique les changements
# pour connaître les modules, faire par exemple, rsync ftp.ciril.fr::
# pour connaître les répertoires, faire par exemple, rsync ftp.ciril.fr::module/

### Définition du miroir distant avec l'emplacement de la distribution Mageia.
#Url=ftp.LinuxCabal.org::Mageia/distrib/$Ver/$Arch
Url=distrib-coffee.ipsl.jussieu.fr::mageia/distrib/$Ver/$Arch
#Url=ftp.belnet.be::mageia/distrib/$Ver/$Arch

# Contrôle si le serveur répond
rsync -rnt --quiet $Url/misc/ ./
if [ "$?" != "0" ]; then
	echo "Impossible de contacter le serveur"
	exit 1
else
	echo "Le serveur répond bien"
fi

### Création du journal
Log=$Distri_root/log/MajMga.$Ver.$Arch.$Date
[[ -d $Distri_root/log ]] || mkdir $Distri_root/log
echo "Actualisation des fichiers du miroir $Distri_root" > $Log
echo "" >> $Log

### Création du fichier Excludes (répertoires et fichiers à exclure)
# Les répertoires 'doc, dosutils et isolinux' ne sont généralement pas nécessaires.
# Le répertoire 'log' ne doit pas être effacé.
RepBase="doc dosutils isolinux log"
ExcBase=""
for Rep in $RepBase; do
	ExcBase="$ExcBase $Rep/"
done
echo "Liste des répertoires de base exclus : $ExcBase" >> $Log

# Les branches 'debug, backports et testing' ne sont généralement pas souhaitables
Bran="debug backports testing"
echo "Liste des branches exclues : $Bran" >> $Log
# Détermination des répertoires et fichiers à exclure
RepBran=""
Hdl="*hdlist*.src.cz pubkey*sources"
for Item in $Bran; do
	# Répertoires des branches à exclure
	RepBran="$RepBran *$Item/"
	# Fichiers hdlist à exclure
	Hdl="$Hdl *hdlist*$Item*.cz"
	# Fichiers pubkey à exclure
	Hdl="$Hdl pubkey*$Item*"
done

# Création du fichier des exclusions
rm -f $Distri_root/log/Excludes
for Item in $ExcBase $RepBran $Hdl; do
 echo "$Item" >> $Distri_root/log/Excludes
done

### Actualisation du miroir
# synchronise le répertoire de base, récursivement, en préservant les dates,
# en effaçant les fichiers supprimés dans la source à la fin de la synchronisation, en excluant les répertoires non désirés.
echo ""
echo "L'actualisation démarre. Soyez patient"
rsync -rlpStH --delete-after --exclude-from $Distri_root/log/Excludes --log-format="%o %f" $Url/ $Distri_root/ 2>/dev/null | grep -E "^del.|^recv" >> $Log

### Épuration du répertoire media/media_info
echo "Épuration du répertoire media/media_info" >> $Log

## Options de sed, utilisées ici
# -n : n'affiche que la ou les ligne(s) concernées, pas le restant du texte
# -i : modifie directement dans le fichier
# "/\[.*$Cle/p" : affiche les lignes commençant par "[" et contenant le motif $Cle
# commande /xxx/p : afficher la ligne contenant le motif xxx
# commande /xxx/d : supprimer la ligne contenant le motif xxx
# commande /xxx/= : afficher le numéro de la ligne contenant le motif xxx

## Options de grep, utilisées ici
# grep [options] chaîne fichier
# -n : affiche le numéro de ligne, suivi du texte
# -m 1 : n'affiche que la première occurrence

## Effacement des données relatives aux banches non conservées
echo ""
sed -i "/srpms/d" $Distri_root/media/media_info/media.cfg

## Branches non conservées
for Item in $Bran SRPMS; do
	# Fichier media/media_info/hdlists et fichiers hdlist
	sed -i "/$Item/d" $Distri_root/media/media_info/hdlists

	# Effacement des paragraphes non voulus dans le fichier media.cfg
	# P est le premier titre de paragraphe, contenant le motif, N son numéro de ligne
	P=$(grep -n -m 1 "\[.*$Item.*\]" $Distri_root/media/media_info/media.cfg)
	N=${P%%:*}
	# Effacer tant qu'il reste un paragraphe avec le motif
	while [ -n "$P" ]; do # tant qu'il y a un paragraphe
		# L = contenu de la ligne N
		L=$(sed -n "${N}p" $Distri_root/media/media_info/media.cfg)
		while [ -n "$L" ] ; do # tant que la ligne numéro N n'est pas vide'
			sed -i ${N}d $Distri_root/media/media_info/media.cfg # efface la ligne
			L=$(sed -n "${N}p" $Distri_root/media/media_info/media.cfg) # nouvelle ligne N
		done
		sed -i ${N}d $Distri_root/media/media_info/media.cfg # efface la ligne vide
		# nouveau titre de paragraphe et son numéro
		P=$(grep -n -m 1 "\[.*$Item.*\]" $Distri_root/media/media_info/media.cfg)
		N=${P%%:*}
	done
done
echo "Le fichier hdlists est corrigé" >> $Log
echo "Le fichier media_info est corrigé" >> $Log

echo "" >> $Log
echo "Fin du programme" >> $Log
echo "" >> $Log

exit 0