\documentclass{article}
\usepackage[latin1]{inputenc}
\usepackage{fullpage}

\title{TD 3 d'Environnement Logiciel: le corrigé}
\date{Mardi 21 septembre 2004}

\begin{document}
\maketitle

\textbf{Scripts shell}

\begin{itemize}

\item Le script suivant définit une fonction \verb+wcsimple+ qui
répond à peu près aux premières questions (c'est le cas de base). La
fonction \verb+wcrec+ quand à elle gère le problème de la récursion en
regardant pour tous les fichiers (au sens large) du répertoire donné
en argument s'il s'agit d'un répertoire (auquel cas on se rappelle
récursivement) ou d'un fichier source \verb+C+. Remarquez deux façons
différentes de faire de l'arithmétique en shell avec \verb+$(( ))+ et
la commande \verb+expr+.

\begin{verbatim}
#! /bin/bash

wcsimple () {
    case $1 in
        L*)
            arg="-l"
            ;;
        C*)
            arg="-c"
            ;;
        M*)
            arg="-w"
            ;;
    esac
    cat $2 | wc $arg | sed -e 's/ *//'
}

wcrec () {
    local total=0
    for i in ${1}/*; do
        if [ -f $i ]; then
            case $i in
                *.c)
                    tmp=`wcsimple $2 $i`
                    total=`expr $total + $tmp`
                    ;;

                *.h)
                    tmp=`wcsimple $1 $i`
                    total=$(($total + $tmp))
                    ;;
            esac
        fi
        if [ -d $i ]; then
            tmp=`wcrec $1 $i`
            total=$(($total + $tmp))
        fi
    done
    echo $total
}

wcrec $2 $1
\end{verbatim}

\item Il est possible de rajouter des tests supplémentaires sur les
fichiers à tester. Par exemple, pour tester la présence du mot
\emph{copyright} dans le fichier,
\verb+if grep -i copyright $i > /dev/null; then+...

Il est possible aussi de rajouter plus de traitement sur chaque
fichier. Pour changer chaque ligne contenant le mot \emph{copyright},
on pourrait utiliser par exemple:
\verb+sed -i -e s/^copyright$/C'est à moi!/+.

\end{itemize}

\textbf{Un peu d'awk}

\begin{itemize}

\item \verb+wc+ en \verb+awk+:

\begin{verbatim}
#! /bin/awk -f
BEGIN {  tmots = 0; tchar = 0 }
{ tmots += NF; tchar += length + 1 }
END { print tmots, tchar, NR }
\end{verbatim}

\item Un script \verb+awk+ qui renverse les champs de l'entrée
standard en insérant un espace entre les champs:

\begin{verbatim}
#! /usr/bin/awk -f
{ for (i = NF; i > 0; i--) printf("%s ", $i); printf("\n") }
\end{verbatim}

Attention à la boucle, il faut s'arrêter avant \verb+$0+ qui
correspond à la ligne complète.

\end{itemize}

\textbf{Un peu de sed}

\begin{itemize}

\item Un rot13 en \verb+sed+:

\verb+sed -e y/abcdefghijklmnopqrstuvwxyz/nopqrstuvwxyzabcdefghijklm/+
Il y a plus simple avec \verb+tr+:
\verb+tr a-mn-z n-za-m+.

La fonction rot13 est bien sûr son propre inverse.

\item \verb+tr 0-45-9 5-90-4+ fait une rotation de $5$ sur les
chiffres. En combinant les deux, avec sed:\\
\verb+sed -e y/abcdefghijklmnopqrstuvwxyz0123456789/nopqrstuvwxyzabcdefghijklm5678901234/+

\item Un filtre \verb+sed+ en ligne de commande qui enlève un
commentaire sur une ligne:

\verb+sed -r -e 's/\/\*(([^*]|(\*[^\/]))|\n)*\*\///'+
Ça ne répond pas tout à fait à la question, mais un programmeur
sérieux aurait fait ça en perl...
\end{itemize}

\textbf{Du perl?}

\begin{itemize}

\item Le filtre demandé est le suivant:

\begin{verbatim}
#!/bin/bash

base-64-encode | tr A-MN-Zam-n-z N-ZA-Mn-za-m | base-64-decode
\end{verbatim}

\item
\begin{verbatim}
#!/bin/bash

while true; do
    echo "Veuillez entrer un nom de fichier à coder:"
    read fichier
    if [ -f $fichier ]; then
        base-64-encode < $fichier | tr A-MN-Zam-n-z N-ZA-Mn-za-m |
        base-64-decode > ${fichier}.sec
    fi
done
\end{verbatim}

\item L'opération de décodage est identique à l'opération de codage.

\item 
\begin{verbatim}
#!/bin/bash

echo "Veuillez entrer un fichier clef:"
read clef

index=0
clair=""
code=""

cat $clef | while read a b; do
                clair=${clair}$a
                code=${code}$b
            done

echo "Entrez le sens de chiffrement (0/1) :"
read sens

if [ $sens = 0 ]; then
    echo "Veuillez entrer un fichier à coder:"
    read input
else
    echo "Veuillez entrer un fichier à déchiffrer:"
    read input
    tmp=$clair
    clair=$code
    code=$tmp
fi

base-64-encode < $input | tr $clair $code | base-64-decode > ${input}.$sens

\end{verbatim}
\end{itemize}

\end{document}
