#!/usr/bin/perl

$nom_fichier_liste = shift;
# 1° paramère à la ligne de commande
chomp $nom_fichier_liste;
# enlever le passage à la ligne (= \n = newline) s'il existe

$alias_file="/etc/profile.d/alias.sh";

if ($nom_fichier_liste eq "") {
	$nom_fichier_liste = "/usr/local/etc/alias_liste";
	# valeur par défaut
	print "Utilisation du fichier par défaut $nom_fichier_liste\n";
}
# le fichier $nom_fichier_liste doit contenir un couple 
# $alias\t$commande_options
# séparés par un TAB (= \t) dans chaque ligne
# TAB au lieu espace car $commande_options peut contenir des espaces

if ( ! -f $nom_fichier_liste ) {
	print "$nom_fichier_liste n'existe pas dans le répertoire\n";
	exit;
}

$id = `whoami`;
chomp $id;
if ($id ne "root") {
	print "Il faut être 'root' pour pouvoir écrire dans $alias_file\n";
	exit;
}

$nom_du_script = $0;
# $0 est une variable prédéfinie qui contient la commande qui a lancée l'exdecution du script
$nom_du_script =~ s/.*\///;
# enlever l'éventuel chemin précédant le nom du script

# mise des définitions d'alias demandées dans un hash %liste_alias, après vérifications
open(LISTE, "<$nom_fichier_liste");
while (<LISTE>) {
	chomp;
	# enlever le passage à la ligne (= \n = newline) s'il existe (ce qui est le cas ici)
	($alias, $commande_options, $setuid) = split(/\t/, $_);
	# partager le string (par défaut) $_ en composantes d'un vecteur
	# avec comme sépérateur un TAB = \t
	# affecter directement la 1° composante du vecteur à la variable $alias
	# et affecter directement la 2° composante du vecteur à la variable $commande_options
	# (si jamais il y avait plus de composantes, on ne s'en occupe pas et ça n'a pas d'importance)
	$ligne++;
	# incrémenter la variable $ligne, non déclarée, comme toutes les autres, 
	# mais ici son initialisation importe :
	# comme on l'incrémente elle est considérée comme un nombre, et donc initialisée à 0
	# lors du 1° passage dans la boucle while elle vaut donc 1 à cet endroit-ci

	if ($commande_options eq "") {
		print "\nA la ligne numéro $ligne du fichier $nom_fichier_liste :\n";
		print "$_\n";
		print "Il faut 2 paramètres (séparés par un TAB) par ligne:\n";
		print "	1° = alias désiré pour une commande existante\n";
		print "	2° = nom d'une commande existante (avec éventuelles options)\n";
		next;
		# passer à la passe suivante du while, donc à la ligne suivante
	} else {
		# trouver le nom du programme
		$nom_programme = $commande_options;
		# en supprimant le premier espace et tout ce qui suit
		$nom_programme =~ s/ .*//;
		# trouver l'exécutable
		$chemin_executable = `which $nom_programme 2>/dev/null`;
		# supprimer la sortie erreur (2) 
		# (en la redirigeant vers le fichier "trou noir" /dev/null)
		# car elle n'est pas redirigée par la syntaxe ``
		# et serait affichée pendant l'exécution de ce script
		# ce qui serait désagréable
		# voir script sortie_erreur2
		chomp $chemin_executable;
		# vérifier qu'il existe
		if ($chemin_executable eq "") {
			print "\n$nom_programme n'est pas un exécutable dans un des répertoires du \$PATH\n";
			next;
			# passer à la passe suivante du while, donc à la ligne suivante
		}
	}
	$liste_alias{$alias} = $commande_options;
	# mettre le couple dans le hash %liste_alias
	if ($setuid eq "s") {
# mettre le bit 'setuid' à l'exécutable
# pour qu'il soit exécuté avec les droits du propriétaire de l'exécutable
# (dans ce cas-ci 'root')
# au lieu des droits de l'utilisateur qui demande l'exécution
# (pour que les alias soient utilisables par les utilisateurs 'ordinaires')
		system("chmod +s $chemin_executable");
	}

}


system("mv -f $alias_file $alias_file.old");
# sauvegarde du fichier original
open(IN, "<$alias_file.old");
open(OUT, ">$alias_file");
while (<IN>) {
	$ligne_existante = $_;
	# on sauvegarde la ligne dans une variable 'nommée' car le 'if' suivant redéfinit $_
	if (/# Les alias suivants ont .* par le script adaf/) {
		next;
		# passer à la passe suivante du while, donc à la ligne suivante
		# et donc ne pas recopier cette ligne dans le fichier
	}
	if (/^ *alias .+=/) {
	# si la ligne contient une définition d'alias
	# "^ *" permet d'éventuels espaces devant "alias"
	# ".+=" il faut au moins un caractère devant le signe "=" pour cela définisse un alias
		$alias_existant = $ligne_existante;
		chomp $alias_existant;
		$alias_existant =~ s/^ *alias (.+)=.*/$1/;
		# extraire l'alias de la ligne
		$supprimer_alias_existant = "false";
		# valeur par défaut
		foreach (keys %liste_alias) {
		# pour chaque alias existant, on va vérifier qu'il n'est pas dans la liste des nouveaux
			if ($alias_existant eq $_) {
			# si oui, on ne le recopiera pas (par le "if" qui suit)
				$supprimer_alias_existant = "true";
				$alias_supprime = $ligne_existante;
				$alias_remlacant = "alias $_='$liste_alias{$_}'\n";
				last;
				# plus la peine de continuer le foreach
			}
			
		}
		if ($supprimer_alias_existant eq "true") {
			print "La définition d'alias\n";
			print $alias_supprime;
			print "a été supprimée; elle sera remplacée par \n";
			print $alias_remlacant;
			next;
			# passer à la passe suivante du while, donc à la ligne suivante
			# et donc ne pas recopier cette ligne dans le fichier
		}
	}
	print OUT $ligne_existante;

}
close IN;
print OUT "# Les alias suivants ont été ajoutés par le script $nom_du_script :\n";
# ajouter une ligne de commentaire dans le fichier $alias_file
foreach (keys %liste_alias) {
	print OUT "alias $_='$liste_alias{$_}'\n";
	# ajouter les alias de la liste à la fin du fichier
}
close OUT;

system("chmod +x $alias_file");
# rendre le fichier $alias_file exécutable

