Tutoriels GNU / Linux

Ici, vous trouverez de nombreux tutoriels vous aidant à profiter au maximum de GNU/Linux et des logiciels libres en général, surtout en programmation (C, SQLite, Latex, subversion, etc.).

N'hésitez pas à soumettre votre tutoriel !

Programmation et langages

Quelques bases de divers langages de programmation.

AJAX Fundamental

Les fondamentaux d'Ajax

Fichier attachéTaille
PDF icon totoriels.ajax_.fundamentals.pdf96.39 Ko

Exercice

Vous trouverez dans cette rubrique quelques exercices d'entraînement, afin de se perfectionner ou de passer le temps pendant les compilations.

Algorithmique

Quelques exercices de réflexion sur de l'algo.

Remplir son disque dur

Calculer la taille final des fichiers plop et plip :

echo "plop" > plop
for i in `seq 0 255`
do
  cat plop >> plip
  cat plip >> plop
done

Indice : beaucoup !
Pour 16 itération (0 -> 15) j'obtiens 17Mo pour plop !

Langage C

Cette section contient de nombreux tutoriels pour devenir un programmeur aguerri en C.

C Propre

Le but de ce document est, à partir de connaissances de base en C, d'expliquer comment faire un projet "propre" c'est à dire organisé clairement et dont le code est lisible.

Ce petit tutoriel est divisé en 3 parties:

  1. la première partie concerne la Compilation. Il est nécessaire pour faire du code propre de savoir ce qui va lui être fait au moment de la Compilation. Nous expliquerons donc les différentes étapes de la Compilation, et leur rôle.
  2. La deuxième partie s'occupe de l'Organisation du Projet: tout mettre dans un seul gros fichier nuit à la lisibilité et ralentit la Compilation.
  3. La troisième partie C Avancé traite de petits "Tips and tricks" en C, pour une utilisation encore plus claire, et plus optimisée.

Commentaires de Duke : il pourrait être intéressant de rajouter un paragraphe/chapitre
sur les options de gcc utiles comme de -Wall. Et eventuellement un petit rappele
des options de base que sont -o et -l -L -I etc.

Compilation

La compilation est une succession d'étapes qui transforment votre code en C en un fichier exécutable par la machine. Voici ces différentes étapes:

le Preprocessing

Le préprocesseur est un élément du compilateur qui va transformer le code en fonction de directives qui lui sont propres afin de préparer le code à être compilé.

En C, les directives du préprocesseur commencent toutes par #. Les plus connues sont #include et #define, mais dans la partie [[C Avancé]] on verra qu'il existe aussi #ifdef et #ifndef, #else, #endif, et bien d'autres.
C'est notament au niveau du préprocesseur que les fichiers .h sont inclus avec les fichiers C.

Une fois que le fichier a été préparer, le compilateur analyse le code pour passer à la génération du code assembleur correspondant.

La compilation

La compilation transforme le code C en assembleur propre au processeur: à partir de cet instant les fichiers compilés deviennent donc spécifiques à la machine.
Le code assembleur est déduit du code C et c'est à ce moment la qu'intervienne les optimisations éventuelles: déroulage de boucles, rotation de registre, etc.

La génération des fichiers objets - Assemblage

Une fois que la compilation est finie, il faut transformer ce code assembleur en code objet (code machine) utilisable par le microprocesseur. Le fichier devient alors complètement illisible. Il y a un fichier objet par fichier source en C. Ces fichiers portent l'extension .o.

Attention, c'est du code objet, mais pas du code exécutable! En effet, il ne doit y avoir qu'un seul exécutable, mais il peut y avoir plein de fichiers objets. La création de ce fichier "binaire" exécutable est dédiée au linker.

La liaison des objets pour la création du binaire

Lorsqu'un projet est divisé en plusieurs fichiers sources, il y a plusieurs fichiers objets: le but de cette étape est de lier les objets entre eux, ainsi que les bibliothèques (''librairies'' en anglais) statiques et dynamiques, afin de faire un fichier exécutable.

Le fichier créé par le linker est un fichier exécutable (binaire).

Intérêt de comprendre ces étapes

Mais pourquoi doit-on connaitre ces étapes? tout simplement parce que dans un projet dont le résultat doit être propre, il faut maitriser chacune des étapes: le bon programmeur:
* Ecrit des directives de preprocessing intelligente pour limiter le travail du compilateur
* Vérifie son code assembleur pour l'optimiser encore plus si besoin est (notamment en systèmes embarqués)
* Débuggue son programme en se servant d'un debugger qui agit sur les fichiers objets
* Fait de la programmation multifichier afin d'avoir des morceaux séparés, remplaçables, et si possibles liés dynamiquement afin de limiter la taille du binaire

Commentaire de Duke
Eventuellement ajouter le fait que l'on peut aussi créer des librairies.

Comprendre les erreurs de compilation

Comme la compilation se déroule en plusieurs phases, des erreurs peuvent intervenir dans chacune des phases. Pour les débugger correctement, il est important de savoir les identifier. En effet, ce n'est pas la peine de chercher dans les directives de preprocessing des erreurs de liens. Nous allons voir quelques erreurs classiques, apprendre à les identifier, et surtout à les corriger.

Les erreurs de préprocesseur

Les erreurs de préprocesseur arrivent vite: avant même que le code soit transformé en assembleur. En voici un exemple de programme qui va échouer au moment du preprocessing, avant meme la compilation (l'erreur du printf n'est même pas signalée):

 #include <stdio.h>
 #ifdef WIN32
 #include <conio.h>
 int main()
 {       
         printf(5);
 
         return 0;
 }

On voit que le #ifdef n'a pas été fermé par un #endif. Voici l'erreur correspondante:

f1.c:2:1: unterminated #ifdef

Les erreurs du préprocesseur sont donc très claires et faciles à corriger.

Les erreurs de code C

La première erreur est la plus fréquente:

f1.c: In function `main':
f1.c:6: error: syntax error before "return"

Cette erreur est provoquée à la compilation, par une erreur de syntaxe dans le code: un point virgule ou une parenthèse oubliée. Mais attention, l'erreur n'est pas à l'endroit indiqué, mais avant! Voici le code qui a provoquée l'erreur:

 int main()
 {
     printf("Hello World ! \n")
     return 0;
 }

On voit qu'il manque un ";" après le printf. On aurait l'erreur suivante si par exemple nous oubliions la ")" et pas le ";"

f1.c: In function `main':
f1.c:5: error: syntax error before ';' token

Une autre erreur classique est de se tromper de type lors d'un passage de paramètre: voici l'erreur correspondante:

f1.c: In function `main':
f1.c:5: warning: passing arg 1 of `printf' makes pointer from integer without a cast

provoquée par exemple par un
printf(4);

4 est un entier, et printf attend un pointeur. L'erreur inverse peut aussi se produire, lorsqu'on passe un pointeur à la place d'un entier. Il faut donc, dans une erreur de ce type, faire attention aux types signalés par le message d'erreur.

Pour la correction de cette erreur, il faut revérifier les prototypes des fonctions et les types des arguments passés.

Les erreurs de liens

Voila l'erreur de lien la plus courante:

/tmp/cconpIvx.o(.text+0x11): In function `main':
: undefined reference to `print_toto'
collect2: ld returned 1 exit status

Et le code correspondant:

 int main (){
         print_toto();
         return 0;
 }

La raison est que la fonction print_toto() est définie ailleurs (ou pas), mais déclarée nulle part dans le fichier de test. Au moment du lien, le linker ne trouve pas la définition du symbole, donc il n'est pas content.
En réalité, cette erreur est précédée d'un warning, souvent masqué (à moins d'utiliser l'option -Wall du compilateur), qui indique que la fonction est déclarée implicitement:

f1.c: In function `main':
f1.c:2: warning: implicit declaration of function `print_toto'

Voici l'autre erreur très courante que l'on rencontre au moment du link:

/tmp/ccr2MjbC.o(.text+0x0): In function `print_toto':
: multiple definition of `print_toto'
/tmp/ccYyznn1.o(.text+0x0): first defined here
/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/../../../../i686-pc-linux-gnu/bin/ld: Warning: size of symbol `print_toto' changed from 20 in /tmp/ccYyznn1.o to 25 in /tmp/ccr2MjbC.o
collect2: ld returned 1 exit status

Le problème ici est que la fonction print_toto() est définie à deux endroits différents: c'est uniquement au moment du link que le problème apparait car les 2 fichiers sont compilés séparément, et c'est au moment de la construction de la table des symboles générale, que le linker voit que le même symbole a été défini à deux endroits différents.

Le dénominateur commun de ces erreurs de link est qu'elles commencent toutes par:
/tmp/ccr2MjbC.o(.text+0x0):
ou quelque chose de similaire, et qu'elles finissent par:
collect2: ld returned 1 exit status

Comprendre les erreurs d'exécution

C'est l'heure de la légendaire...
Segmentation fault

La raison de cette erreur est que le programme tente d'accéder à une zone de mémoire non autorisée. Voila le code correspondant:

 char *s1, *s2;
 strcat(s1,s2);

Les deux chaines ont été déclarées, il n'y a donc aucune erreur à la compilation. En revanche, Ni l'une ni l'autre ne se sont vues allouées de mémoire. Dès lors, quand strcat() tente de les concatener, elle se heurte au fait que les pointeurs s1 et s2 sont NULL. C'est pourquoi au moment de l'exécution, la concaténation échoue.

D'une manière générale, les segmentation faults (segfaults pour les intimes) sont dues a une allocation mémoire oubliée: il faut donc revoir les pointeurs utilisés dans la zone du segfault, et vérifier que la mémoire vers laquelle ils pointent a été correctement initialisée.

La prochaine étape de ce cours (Organisation du Projet]) sera justement de voir comment améliorer son code et ses interventions dans ces différentes parties.

Commentaire de Duke :
Il pourrait être intéressant de rajouter les commandes gcc permettant de decouper la compilation :
par exemple gcc -E pour avoir le code apres le preprocesseur
Ceci juste comme une addition pour les "curieux" qui voudrait appronfondir d'eux meme
ce qu'il se passe exactement pendant la comilation

Sinon attention il y a des textes qui depassent dans les boites en pointillés
car elles ne retourne pas à la ligne toutes seules

Organisation du Projet

un bon projet, c'est quoi?

* Un projet qui marche (normal)
* Un projet qui est débuggué (ah ben oui, quand meme)
* Un projet qui est débuggable (ne vous faites pas d'illusion il reste toujours des bugs)
* Un projet dont le code peut être compris par quelqu'un d'autre que le concepteur (et c'est la que ca se corse...)

Mais que faire?

Alors comment faire pour qu'un projet satisfasse ces exigences?
* Réfléchir avant de coder, et tester ses résultats
* Ecrire des tests pour l'utilisation du projet, et pas pour le code du projet (la nuance est de taille...): par exemple, on peut écrire les tests avant d'écrire le code du projet afin d'être sur de ne pas être influencé par la façon dont le code a été fait.
* Utiliser des outils de monitoring pour vérifier les fuites de mémoires, etc
* Et bien sur, écrire du code propre, et le ranger correctement.

A titre d'exemple, les projets de plusieurs milliers de lignes de code de C sont légions. Imaginez un fichier de 10000 lignes de code: déjà c'est très lourd à utiliser et ensuite, pour comprendre le code, ca se corse: si le main est tout en bas, et la fonction qu'on veut voir tout en haut....

Il est donc très rapidement nécessaire de séparer son code en morceaux.

Séparer son code

''' Les Headers '''

Déjà il faut séparer les déclarations globales du reste du code: ces déclarations globales sont:
* Les macros
* Les constantes
* Les déclarations de fonctions
* Les déclaration de types (struct, enum, typedef ...)
* Les déclaration de variables globales (beurk!)

Il existe un type de fichier particulier pour accueillir ces déclarations: les fichiers "headers", dont l'extension est ".h" (ca doit vous rappeler des choses)

Donc pour chaque fichier .c, il faut un fichier .h qui contienne la déclaration des fonctions, des macros, des constantes, etc qui y sont utilisées.

Petit rappel...

Ca c'est une '''déclaration''':

 void fonction(int arg1, char arg2);

Ca c'est une '''définition''':

 void fonction(int arg1, char arg2) {
     int i;
     for(i=0; i<arg1; i++)
         printf("%c\n", arg2);
 }

On parle bien ici des déclarations, et pas des définitions. Ca ne compilera pas si vous avez vos définitions dans vos headers. En effet vos headers risquent d'être inclus par plusieurs fichiers c, et donc à chaque fois les fonctions redéfinies...

''' Utiliser plusieurs fichiers '''

Il est aussi bon de séparer son code en blocs logiques: par exemple, un fichier s'occupera des fonctions d'affichage, pendant qu'un autre s'occupera de l'interface avec le système, pendant qu'un autre contiendra les algorithmes de calcul.
Attention! il ne faut pas se tromper d'objectifs: on fait ca pour pouvoir facilement retrouver le bout de code qui nous intéresse: pas pour avoir des petits fichiers!! Ca ne sert à rien d'avoir "fichier1.c fichier2.c fichier3.c" et des contenus tous liés entre eux: au contraire, ca risque d'être encore moins clair qu'un seul gros fichier.
C'est quand on utilise plusieurs fichiers que les headers deviennent important: en effet, peut etre que les fonctions du fichier d'algorithmes se serviront de l'affichage ou de l'interface systeme: il faut donc qu'ils connaissent les déclarations de ces fonctions: il faudra donc include les headers des fichiers d'affichage et systeme dans le fichier C des algorithmes...

Votre projet commence à ressembler à quelque chose

''' Ecrire des tests '''

Tester le programme à la main, c'est bien, mais pas efficace quand le programme devient complexe: on ne peut pas imaginer tous les cas et les taper à la main. En conséquence de quoi il est utile d'écrire des scripts de tests, qui appeleront par exemple 1000 fois le binaire avec des arguments différents et qui renverront des erreurs si le programme bug ou renvoie des résultats incohérents.
Un script de test bien fait, c'est tout un tas de mauvaises surprises en moins lors de la correction ou de la démo du projet :)

On a parlé des headers, des définitions, déclarations, etc. Il y a des outils pour optimiser la compilation de toutes ces choses: c'est ce qu'on verra dans la troisième partie du cours, [[C Avancé]].

C Avancé

Du C Avancé, c'est du C compliqué. Avant de faire compliquer il faut faire propre.

Du code propre

Du code propre c'est quoi?
Ca se lit facilement

  1. Donc c'est indenté, c'est net, ca bave pas: si y'a trop d'indentation c'est qu'il faut probablement revoir le bout de code...
  2. Pas de lignes de 3 km
  3. C'est pas du C syntaxe C++ ou un truc moche du style
  4. Des fonctions pas trop longues: si ca fait plus d'une page, c'est que ca doit être divisé

Ca se comprend vite

  1. Ca se lit comme une histoire
  2. C'est commenté quand ca se corse MAIS...
  3. C'est commenté uniquement quand c'est nécessaire

Ca fait ce qu'on veut et pas plus

  1. Pas la peine de faire 3 fois la même chose
  2. Pas la peine de tester ces choses qui ne peuvent pas arriver
  3. Pas la peine de mettre des options dont on ne va pas se servir
  4. On ne se branle pas au nombre de lignes

C'est du code réfléchi:

  1. Pas de fuite de mémoire (on détruit ce qu'on alloue)
  2. Pas de boucles inutiles (ca prend du temps)
  3. Des variables dont la portée est controlée
  4. Des fonctions qui ne font qu'une seule chose à la fois
  5. Ca gère les situations d'erreurs

Les ptites feintes du préprocesseur

'''#define'''

permet de définir des constantes et des macros. Lorsque des valeurs constantes vont êtres utilisées au cours du programme, il est bon de les définir avec des '''#define''': le préprocesseur remplacera les constantes dans le code par leur valeur au moment de la compilation. C'est une utilisation à privilégier par rapport à définir des variables globales constantes.

'''#if #ifdef, #ifndef, #else, #endif'''

Sont des structures conditionnelles du préprocesseur. Cela permet notamment de "condamner" du code. Par exemple, si vous avez un morceau de code de debug que vous ne voulez pas exécuter au final, vous pouvez procéder de la sorte:

 #define DEBUG 1
 ...
 #if DEBUG
 printf("debug: %d\n", toto);
 #endif

Au moment de la compilation si DEBUG est strictement supérieur à 0 alors le code dans le '''#if''' sera compilé et vous aurez votre affichage de debug. Au moment de la compilation finale quand vous ne débuggerez plus, il suffira de mettre DEBUG à 0 pour que le code soit supprimé de la compilation.

Il est aussi possible de définir des constantes du préprocesseur directement dans la ligne de commande de gcc en utilisant l'option '''-D='''

L'autre façon de faire est d'utiliser #ifdef comme le montre l'example suivant. Dans ce cas, l'option de compilation serra simplement '''-D'''

 #define DEBUG
 ...
 #ifdef DEBUG
 printf("debug: %d\n", toto);
 #endif

Les petits mots clefs qui changent tout

'''static'''

Ce mot clef s'utilise lors de la déclaration d'une variable, avant d'en spécifier le type: par exemple:

 static int i;

Une variable déclarée statique voit sa portée étendue (ou limitée) à tout le fichier. L'utilité est surtout de limiter la portée d'une variable globale dans un projet multifichier, ou alors d'utiliser 2 fonctions ayant le même nom dans des fichiers différents.

'''inline'''

Ce mot clef s'utilise avec les procédures et fonctions dont le code au moment de l'assemblage du fichier doit être inclus directement dans la fonction appelante. L'utilité est d'augmenter la lisibilité du code en séparant les fonctions, mais de limiter les branchements et donc l'overhead des sauvegardes et restaurations de contexte au moment de l'exécution.

Il ne faut pas confondre l'utilisation d''''inline''' avec l'utilisation de macros: en effet, le code d'une macro est adapté dans le code appelant par le préprocesseur, alors que le code d'une procédure "'''inline'''" est adapté au moment de la construction du code assembleur. Dans le premier cas, la transformation de la macro en code assembleur est donc effectuée autant de fois que le code est recopié. Ce n'est pas le cas de la fonction '''inline'''.

Exemple:

 inline int max(int i1, int i2);

'''extern'''

Ce mot clef est utilisé pour éviter de déclarer deux fois une variable dans deux fichiers différents: il indique que la déclaration a déjà été effectuée, et qu'il n'est pas nécessaire d'allouer a nouveau de la mémoire et un espace dans la table des symboles, la variable y sera placée par le linker à partir d'un autre fichier.

Exemple:

extern int i;

'''const'''

Ce mot clef, placé comme les autres devant le type des variables, permet d'indiquer au compilateur que la variable ne doit pas être modifiée, autrement dit, elle doit être considérée comme une constante. Si, lors de la compilation, la valeur de la variable est modifiée, une erreur sera générée.

On peut par exemple l'utiliser avec les paramètres d'une fonction pour éviter qu'ils soient modifiés dans la fonction. C'est surtout utilisé pour les pointeurs, afin de s'assurer que la mémoire sur laquelle ils pointent n'est pas modifiée.

Exemple:

 void print_string(const char *s);

La gestion d'erreurs

En utilisant un header spécial du système, '''errno.h''', une variable de type entier dont le nom est '''errno''' est déclarée. Cette variable est utilisée pour contenir les codes de retour des appels systèmes, si ceux-ci plantent. Par exemple, si le mode d'ouverture de fichier passé à fopen est erroné, fopen placera la valeur '''-EINVAL''' dans errno.

Il existe un appel système dont le nom est '''perror''' qui prend en argument une chaine de caractère. Il consultera la valeur de errno, affichera l'erreur correspondante et enrichira le message d'erreur de la chaine de caractère passée en argument.

D'une manière générale, il est bon pour contrôler le déroulement du programme, particulièrement les parties sensibles, d'utiliser la gestion d'erreur afin d'éviter des failles. Par exemple, si le programme n'arrive pas à ouvrir le fichier de configuration, ce n'est pas la peine qu'il continue à tourner.

Voici un exemple très simple d'utilisation de '''perror()''':

 FILE *fd;
 if((fd = fopen("toto.conf","r")) == NULL) {
     perror("Erreur d'ouverture du fichier de configuration");
     exit(-1);
 }

Ce code permet de sortir du programme en affichant une erreur qui, au moment de l'exécution, est explicite.

Création de greffon (plugin) en C

Pré-requis

  • Base en C
  • Compilation d'une librairie dynamique (voir tutoriel librairie C).
  • Un cerveau, un pc, un compilateur C, un pot de cacahuètes...

Pourquoi ?

La capacité à charger des modules externes pour un programme peut être utile dans le sens ou elle permet :

  • D'obtenir un exécutable plus léger
  • De permettre une évolutivité par l'ajout de fonctionnalités
  • De permettre une collaboration plus facile au projet (l'ajoute d'un plugin est souvent plus simple que de modifier le code source directement)
  • distribution de fonctionnalités supplémentaire simple

Le principe

Nous devons placer le code de notre greffon dans un fichier à part. Pour cela nous utiliserons des librairies dynamiques (.so sous Linux ou .dll sous windows). Le logiciel ne peut connaître à priori les fonctionnalités du module, il doit alors faire de l'instrospection sur la librairie pour la découvrir.

En action

Pour charger la librairie lors de l'exécution de notre programme nous utiliserons a fonction dlopen(). Pour charger une fonction de la lib, nous utiliserons dlsym() et dlclose() pour la fermer.

Un peu comme dans tous les langages de programmation, nous devons avoir une fonction référence pour entrer dans notre librairie. Libre a nous de l'appeler comme bon nous semble. Mais tous les autres greffons devrons avoir la même fonction, avec la même structure. Cette fonction aura pour rôle de présenter la librairie a notre programme et entre autre lui lister les fonctions présentes.

#include <dlfcn.h>		/* dlopen dlsyms dlclose */
#include <stdio.h>
#include <stdlib.h>
 
#include <trax.h>		/* include de la librairie */
 
typedef int fonc(int);
 
int main(){
	void *lib;
	fonc *myFonc;
	if((lib = dlopen("libtrax.so", RTLD_LAZY)) == NULL){ /* charge la librairie */
		fprintf(stderr, "Impossible de charger le librairie\n");
		return -1;
	}
 
	if ((myFonc = dlsym(lib, "test")) == NULL){ /* charge la fonction "test" de la librairie */
		fprintf(stderr, "Impossible de charger la fonction d'initialisation\n");
		return -1;
	}
	myFonc(42); /* utilise la fonction test de la librairie*/
 
	printf("%d\n",test(42));
	dlclose(lib);
	return 0;
}

Création de librairies en C

Pré-requis

  • Base (pH > 7) en C
  • Compilation sépare
  • Ce tutoriel

Pourquoi ?

Depuis son invention, la roue a été de pierre, de bois, de caoutchouc, mais toujours de la même forme. Réinventer une nouvelle méthode de faire un cylindre, n'a souvent que peu d'importance.
Les librairies permettent de factoriser du code réutilisé fréquemment. Le développeur doit alors rajouter la couche qui fera de sa roue une roue différentes de celles pré-existants.

Il existe deux types de librairies : statiques ou dynamiques.

Le premier permet de de créer des librairies qui seront inclus dans le binaire lors de la compilation. Cela permet de ne pas se soucier de la présence ou non de la librairies sur le pc sur lequel va être exécute le programme. L'inconvénient étant bien évidement un binaire plus lourd.

Quant aux librairies dynamiques elles créent des objets (fichier en .so sous Linux, .dll sous Wind...) qui sont chargées par l'OS à l'exécution (à ne pas confondre avec avec le chargement dynamique vu dans un autre tutoriel).

Le principe

Les librairies ne différents des programmes > que par leur point d'entre : il n'y a pas besoin de fonction main(). Il n'y a qu'a écrire le code des fonctions comme vous l'auriez fait de manière classique.

La compilation se fait de la même manière (la compilation seulement et non l'édition de lien). Nous commençons donc par créer nos objet (.o) puis nos fichiers librairies.

En action

soit les fichiers lib0.c et lib0.h

lib0.c

  1. #include "lib0.h"
  2. int test (int x){
  3. return x+42;
  4. }

lib0.h

  1. #ifndef LIB0_H
  2. #define LIB0_H
  3. int test (int);
  4. #endif

Ligne de compilation :

  1. gcc -Wall -c -fPIC lib0.c -o lib0.o
  2. gcc -shared -Wl,-soname,libtest.so lib0.o -o libtest.so

Il est possible de donner un nom de librairie différent de celui du fichier de la librairie en utilisant l'option soname.

Les fichiers lib0.o et libtest.so sont alors généré.

Ecrivons maintenant un code qui utilise notre librairie.

  1. #include <stdio.h>
  2. #include "lib0.h"
  3.  
  4. int main(){
  5. printf("%d\n",test(42));
  6. return 0;
  7. }

que nous compilons avec la ligne

gcc -Wall -L./ -ltest main.c -o prog 

-L indique le répertoire ou cherche la librairie : ici, c'est le répertoire courant
-l précise le nom de la librairie sans le préfixe "lib"

Création de processus avec fork();

La fonction fork permet la duplication de processus. A l'issu de son appel il existera donc deux processus : le père et le fils. Il ne seront différencié que par le retour de la fonction fork et leur valeur de PID (processor Identifiant)

fork() renvoie

  • -1 en cas d'erreur
  • 0 pour le fils
  • >0 pour le fils : le nombre renvoyé est le pid du fils (qui ne peut pas être 0 puisque 0 est le pid du noyau)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h> //fork
  4.  
  5. #include <sys/wait.h> //wait
  6. int main(){
  7. int partage = 42;
  8. int pid;
  9. switch(pid = fork()){
  10. case -1:
  11. fprintf(stderr, "Avortement\n");
  12. exit(EXIT_FAILURE);
  13.  
  14. case 0:
  15. printf("f>Je suis le fils, mon pid est %d\n",getpid());
  16. printf("f>Le pid de mon pere est : %d\n",getppid());
  17. printf("f>Je partage avec mon pere la variable partage == %d\n", partage);
  18. break;
  19.  
  20. default:
  21. printf("p>Je suis le pere. Mon pid est : %d\n",getpid());
  22. printf("p>Le pid de mon fils est : %d\n",pid);
  23. printf("p>Je partage avec mon fils la variable partage == %d\n", partage);
  24.  
  25. wait(NULL); // permet d'attendre la mort du fils
  26. }
  27. return 0;
  28. }

Le code dans les "case 0" et default sont exécuté en parallèle. Les lignes peuvent donc être entrelacées.

Un processus fils dont le père est mort renverra 1 (le pid d'init) comme ppid. Pour éviter cela nous utilison la fonction wait (ligne 25) qui fera est bloquant jusqu'au changement de status d'un fils du processus. En l'occurence nous attendons la mort du processus fils, pour que ce dernier ait le temps de demander le pid de son père.

Mesure du temps d'éxecution en C

Il peut être utile de mesurer le temps que prends l'exécution d'une partie de code et non de tout le programme. Par exemple pour comparer différentes techniques et optimisations...

Nous pouvons obtenir deux types de temps : le temps d'utilisation du processeur ou le temps d'exécution du programme. Ils peuvent différer pour les raisons suivantes :

  • le programme est exécuter sur une plateforme multi-tâches qui accorde à chaque tâche un temps processeurs.
  • votre programme utilise de entrées/sorties ou des appels systèmes qui ne demande pas ou peu d'utilisation processeurs, mais qui prennent néanmoins du temps.

Dans un premier temps, nous présenterons la fonction > qui permet d'obtenir de le temps d'utilisation processeur.

#include <stdio.h>
#include <stdlib.h>
 
/*========== parttie relative a la mesure du temps ===========*/
#include <sys/times.h>
#include <unistd.h>
typedef struct tms sTms;
typedef struct{
	int debut,fin;
	sTms sdebut, sfin;
}temps_exec;
/*========== parttie relative a la mesure du temps ===========*/
 
void temp(temps_exec *tmps){
    printf("temps réel :\t %d\ntemps utilisateur :\t %ld\ntemps system :\t %ld\n",
		tmps->fin - tmps->debut,
		tmps->sfin.tms_utime - tmps->sdebut.tms_utime,
		tmps->sfin.tms_stime - tmps->sdebut.tms_stime);
}
 
 
void attente (){
    int *temp;
    for (int i = 0 ; i < 420000 ; i++){ /* boucle d'atente */
        temp = (int *)malloc(sizeof(int)*4207);
        free(temp);
        printf("plop\n");
	}
	sleep(1);							/* attent 1 seconde */
}
 
int main(){
    temps_exec temps;
    int top = sysconf(_SC_CLK_TCK); /* recupere le nombre de tips seconde */
 
    temps.debut = times(&temps.sdebut);
	attente();
    temps.fin = times(&temps.sfin);
    temp(&temps);
 
    return 0;
}

Il est possible d'obtenir séparément, grâce a cette même fonction, le temps utilisateur et system, pour le processus père et pour ses fils (voir man).

Avec getrusage :

#include <sys/time.h>
#include <sys/resource.h>
 
void mesureTime (struct rusage *temps0, struct rusage *temps1){
 
        printf("temps utilisateur %d\ntemps systeme %d\n",
                temps1->ru_utime.tv_usec -
                temps0->ru_utime.tv_usec,
                temps1->ru_stime.tv_usec -
                temps0->ru_stime.tv_usec
 
        );
 
}
 
int main(){
        struct rusage temps0;
        struct rusage temps1;
        getrusage(RUSAGE_SELF, &temps0);
// temps à mesurer
        getrusage(RUSAGE_SELF, &temps1);
        mesureTime(&temps0, &temps1);
}

Tutorial sqlite

SQLite ?? C'est quoi ?

Non ce n'est un pas un SQL pour l'élite mais une petite librairie C qui permet d'utiliser une base de donnée embarquée.

Prérequis

Caractéristiques :

  • ACID : transaction Atomique, Cohérence, Isolation, Durabilité
  • Aucune configuration demandée
  • Implémente la plupart des requêtes SQL92
  • Toute la base de donnée en un fichier
  • Support des base de plusieurs tera octets
  • Libre (pas comme la bière)

Début en console

commande crée la base de donnée (fichier bdd.bd).

tutorial_SQLite@Club*Nix $ sqlite3 bdd.db
SQLite version 3.4.1
Enter ".help" for instructions
sqlite> CREATE TABLE table1 (id INTEGER, nom varchar(30), prenom varchar(30), message TEXT);
sqlite> INSERT INTO table1 values(42, "trax", "traxou", "je n'ai rien à dire de plus");
sqlite> SELECT * FROM table1;
42|trax|traxou|je n'ai rien à dire de plus
sqlite> .exit
  1. ouvre sqlite3 avec lui demandant d'utiliser le fichier "bdd.db" comme base de données. Si celui ci n'existe pas il est crée.
  2. Réponse de sqlite3
  3. Création d'une table "table1" à trois champs : "id" nombre entier, nom "chaine limité à 30 caractères", prénom idem, message de type text (longeur inderterminée)
  4. Insertion de valeurs
  5. Lecture de valeurs
  6. Les valeurs lues
  7. Sortie du programme (à noter le "." devant "exit"

Code C

L'exemple suivant présente l'exécution de requêtes sur la base de données.
Deux méthodes sont utilisées. La première étant une exécution dynamique : l'analyse de la reqête se fait pendant son exécution. La seconde méthode consiste à compiler la requête et à injecter les valeurs à chaque appelle (avec la méthode sqlite3_bind_le_type). Cela permet d'accroitre ma rapidité lors d'appels fréquents à une requête de même structure.

  1. #include <stdio.h>
  2. #include <sqlite3.h>
  3. #include <stdlib.h>
  4.  
  5. void step (int i){
  6. printf("step : ");
  7. switch (i){
  8. case SQLITE_DONE:
  9. printf ("ok ");
  10. break;
  11. case SQLITE_BUSY:
  12. printf ("oqp ");
  13. break;
  14. case SQLITE_ERROR:
  15. printf ("err ");
  16. break;
  17. case SQLITE_ROW:
  18. printf ("row ");
  19. break;
  20. case SQLITE_MISUSE:
  21. printf ("mis ");
  22. break;
  23. default:
  24. printf ("??? ");
  25. }
  26. printf("\n");
  27.  
  28. }
  29.  
  30. int callback (void *lokis, int nbCol, char **data, char **nomCol){
  31. for (int i = 0; i < nbCol; i++){
  32. printf ("%s \t", data[i]);
  33. }
  34. printf ("\n");
  35. return 0;
  36. }
  37. int main (int argc, char **argv){
  38. sqlite3 *db;
  39. char *zErrMsg = 0;
  40. int rc;
  41.  
  42. if (argc != 3){
  43. fprintf (stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
  44. }
  45.  
  46. rc = sqlite3_open ("bdd.db", &db);
  47. if (rc){
  48. fprintf (stderr, "Can't open database: %s\n", sqlite3_errmsg (db));
  49. sqlite3_close (db);
  50. exit (1);
  51. }
  52. /*-------------------------------- Créer une table ---------------------------*/
  53. char *requete0 = "CREATE TABLE table1 (id INTEGER, login varchar(30), pass varchar(30));";
  54. if (sqlite3_exec (db, requete0, callback, 0, &zErrMsg) != SQLITE_OK){
  55. printf (":(\n");
  56. }
  57.  
  58.  
  59. /*------------------------------- Créer un enregistrement première méthode ---*/
  60. char *requete1 = "INSERT INTO table1 values (0, 'trax', 'plop');";
  61. if (sqlite3_exec (db, requete1, callback, 0, &zErrMsg) != SQLITE_OK){
  62. printf (":(\n");
  63. }
  64.  
  65.  
  66. /*------------------------------- Créer un enregistrement deuxième méthode ---*/
  67. char *requete2 = "INSERT INTO table1 values(?, ?, ?);";
  68. sqlite3_stmt *stmt = NULL;
  69. if (sqlite3_prepare_v2 (db, requete2, 50, &stmt, NULL) != SQLITE_OK){
  70. printf (":(\n");
  71. }
  72.  
  73. sqlite3_bind_int (stmt, 1, 42);
  74. sqlite3_bind_text (stmt, 2, "traxou", 7, NULL);
  75. sqlite3_bind_text (stmt, 3, "plip", 5, NULL);
  76. step(sqlite3_step(stmt));
  77. sqlite3_reset (stmt);
  78.  
  79.  
  80. /*------------------------------- Lecture d'enregistrement -------------------*/
  81. char *requete3 = "SELECT * FROM table1;";
  82. if (sqlite3_exec (db, requete3, callback, 0, &zErrMsg) != SQLITE_OK){
  83. printf (":(\n");
  84. }
  85.  
  86. sqlite3_close (db);
  87. return 0;
  88. }

Comment compiler :
gcc test.c -o prog -lsqlite3

Tutoriel utilisation des socket réseaux

Connection d'un client TCP/IP

#define TRUE 1
#define FALSE 0
/**
 * \fn BOOL sockConnect (char *addr, int port, int *socketID)
 * \brief create and connect a socket to a given address/port
 * \param addr address to connecto on
 * \param port port to connect on
 * \param socketID socket to be created
 * \return TRUE if success, FALSE if failed
 */
int sockConnect (char *addr, int port, int *socketID){
  struct sockaddr_in sockname;
  struct hostent *host_address;
 
  if ((host_address = gethostbyname(addr)) == NULL){ // addresse translation => IP
    fprintf (stderr, "Error while converting %s to inet address", addr);
    return FALSE;
  }
  #ifdef DEBUG
  else{
    printf ("official name : %s\n",host_address->h_name);
  }
  #endif
 
 
  if ((*socketID = socket(AF_INET ,SOCK_STREAM, 0)) == -1){ // TPC/IP socket
    fprintf (stderr; "Error while creating socket");
    return FALSE;
  }
 
  sockname.sin_family = host_address->h_addrtype;
  sockname.sin_port = htons (port);
  memcpy ((char *)&sockname.sin_addr.s_addr, host_address->h_addr,host_address->h_length);
 
  if((connect(*socketID, (struct sockaddr *)&sockname, sizeof(struct sockaddr_in))) == -1){
    fprintf (stderr, "Error while connecting socket to %s:%d",addr, port);
    return FALSE;
  }
  return TRUE;
 
‹ Effectuer des requêtes sur un serveur mysqlhautGestion des signaux ›

warning: enumeration value LES not handled in switch

L'Erreur

warning: enumeration value LES not handled in switch
#include <stdio.h>
 
typedef enum {PLOP, LES, GENS}LOL;
int main(){
        LOL i = PLOP;
        switch(i){
                case 0:
                printf("plop\n");
        }
        return 0;
}

Explications

Dans le cas ou le switch doit évaluer une énumération il faut que tous les cas soit prit en compte ou utiliser la règle default

Solution

#include <stdio.h>
 
typedef enum {PLOP, LES, GENS}LOL;
int main(){
        LOL i = PLOP;
        switch(i){
                case 0:
                printf("plop\n");
                default:
                (void)NULL;
        }
        return 0;
}

Latex

Latex

Fichier attachéTaille
PDF icon exemple.pdf670.53 Ko
Fichier entete2.tex3.14 Ko

Tutoriel LaTeX (avancé)

Ici vous trouverez toutes les astuces qui vous éviterons de devenir fou (ou pas), pour compiler, éditer, visualiser son document LaTeX.

Compendre et utiliser les différents formats de documents

Au cours des tutoriels précédents, nous avons seulement parlé de pdflatex pour générer ses fichiers finaux. Il arrive que dans certains cas, pdflatex ne puisse pas compiler le document. Cela arrive notamment quand on utilise pstricks et/ou des fichiers .ps (postscript) et .eps (encapsulated postscript) dans son document.

Mais comment faire dans ce cas ?
La solution consiste à compiler son document non pas avec pdflatex mais latex. La double (voir triple) compilation est toujours nécessaire ça ne change rien de ce côté. Par contre le fichier de sortie est maintenant un fichier .dvi. Pour le transformer en .ps on utilise la commande dvips monfichier.ps dans un shell.
Ah ouais c'est bien cool mais ça sert à quoi un fichier .ps ? Le pdf caymieux.
Bon ok c'est vrai. Bonne nouvelle on peut convertir un fichier ps en pdf facilement grâce à ps2pdf :
ps2pdf monfichier.ps

Tutoriel LaTeX (débutant)

Sommaire du tutoriel :

partie 1 : Avant propos et histoire de TeX/LaTeX

Avant propos

Ce tutoriel est une reprise de celui rédigé par Rémi Cardonna suite au cours du Club*Nix et du Club PC en juin 2005 à l'ESIEE.

Prérequis : Savoir utiliser un editeur de texte de type bloc note et savoir enregistrer un fichier avec une extension.
Les informations données on été testées sur un pc équipé de Arch Linux. Cependant, les exemples donnés devraient pouvoir fonctionner sur les pc du smig (Debian GNU/Linux) à condition de faire attention à bien enregistrer ses documents en ISO 8559 15 ; car les ordinnateurs du smig ne gère pas (ou pas bien) l'UNICODE.

Cette précaution prise nous allons pouvoir commencer à apprendre à se servir de LaTeX.

Qu'est-ce que c'est LaTeX ?

LaTeX est un système de mise en page inventé par un professeur de Mathématique et d'Informatique au milieu des années 70. Certes à l'époque Word n'existait pas encore, mais encore aujourd'hui LaTeX est très utilisé dans les domaines scientifiques et techniques, car celui-ci a été conçu pour ce type d'utilisation.

Il y a deux concepts importants à retenir pour LaTeX
* Le premier est qu'il s'agit d'un ''langage de mise en page''. Ce n'est donc pas un éditeur. Le LaTeX s'écrit donc comme du C ou du Java : on écrit le code dans un éditeur de texte, et ensuite le fichier est passé dans un compilateur. Ce dernier convertira le LaTeX en PDF, PostScript, HTML, ...
* LaTeX donne beaucoup plus d'importance à la '''structure''' d'un document, qu'à la mise en page finale. Évidemment, celle-ci peut être modifiée mais ce n'est pas le but premier de LaTeX.

On comprend bien pourquoi LaTeX est donc parfait pour écrire des rapports de TP ou de stage, des cours, etc.

partie 2 : Les premiers pas

Premiers pas en LaTeX sous Linux

Pous allons maintenant créer notre premier document LaTeX, voici la marche à suivre :
ouvrir un editeur de texte (n'importe lequel fera l'affaire) par exemple « kate » ou encore « gedit » ou alors en ligne de commande : « vim essai.tex », « emacs essai.tex » etc. Ensuite sauvegarde ton document avec le nom que tu voudra mais avec l'extension « .tex » par exemple essai.tex.

Maintenant penchons nous plus en détails sur la structure d'un document : comme nous l'avons vu, LaTeX est un language de mise en page similaire au HTML ; il utilise des « balises » pour décrire le document. Nous allons voir les premières « balises » au travers d'un premier exemple :

Les signes « % » servent à commenter des lignes dans le document ; elle n'apparaîtront pas dans le document final.

 % documentclass définit le type de texte que tu veux écrire
 % tu as le choix entre article, book, report, ...
 % chacun d'eux a des propriétés différentes
 \documentclass{article} 
 
 % \begin{} et \end{} permettent de délimiter des environnements
 % c'est à dire des zones de travail
 % ici l'environnement document représente ce qui va être
 % affiché dans le document final 
 \begin{document}
 
 \end{document}

Que remarque-t-on : les 3 premières lignes sont des commentaires et n'appraîtront pas dans le fichier final. A la 4ème ligne, on remarque le « \documentclass{article} » cette commande sert à indiquer à l'environnement LaTeX que le document est un « article ».

Il existe plusieurs sortes de documentclass : book, report, article, slide, beamer etc. Chacune de ces classes à des propriétés bien différentes, notamment pour la numérotation des chapitres. A notre niveau, et pour la plupart des travaux/rapports que nous aurons à faire à l'ESIEE, la classe article ets amplement suffisante. Les classes repport et book serait plus adaptées si l'on écrivait une thèse ou un mémoire (ce qui n'est pas notre cas).

Ensuite on remarque deux commandes :  \begin{document} et \end{document}. Ces deux commandes servent à indiquer à LaTeX que l'on débute le document (\begin{}) et que l'on termine le document (\end{}).

Bien maintenant que nous avons terminé notre document il ne reste plus qu'à le visualiser. Mais comment fait-on ? Et bien taper son texte et le mettre en forme à l'aide balises LaTeX n'est pas suffisant il faut compiler son texte afin d'avoir un résultat. En effet le fichier « .tex » n'a pas de sens en lui-même : il ne prend sa signification que pour le compilateur qui se charge de « transformer » notre fichier « .tex » en un fichier pdf lisible partout et par tous.

L'étape suivante consiste à compiler son fichier source afin d'obtenir un pdf. Comment procèder ? c'est très simple : sur les pc du smig ouvrez votre naviguateur de fichier (Konqueror) naviguez jusqu'au répertoire contenant votre fichier source et appuyez sur F4 pour lancer une console (Konsole). Ensuite tapez la commande suivante :

pdflatex essai.tex && pdflatex essai.tex

Qu'est que ça fait ? cette commande vous permet de compiler votre fichier source 2 fois d'affilé afin
de générer un document pdf. Pourquoi compiler 2 fois une fois n'est pas suffisant ? la réponse est oui compiler une fois n'est pas suffisant. Mais alors pourquoi ? tout simplement parque lors de la première compilation, LaTeX génère un fichier spécial « .toc » qui lui permet de générer la table des matières en fonction des chapitres du document ; ce fichier n'est pris en compte que lors de la compilation suivante d'où la nécessité de compiler une 2ème fois. Nous verrons comment générer une table des matières plus tard.

Revenons à notre fichier : les plus observateurs remarqueront que nous n'avons mis aucun texte entre le balises de début et fin du document. Donc n'espérez pas trouver votre fichier pdf : il n'existera pas car LaTeX remarquera que votre document est vide et ne fera... rien (enfin pas exactement).

partie 3 : l'entête ou préambule

Le préambule

Il y a une chose que je n'ai pas encore mentionnée : le prémabule qu'est-ce que c'est, à quoi sert-il. Comme dans tout texte, un fichier LaTeX commence toujours par un préambule ; le préambule défini l(es)'environnement(s) à utiliser pour créer un document, le dictionnaire des césures, les largeurs de marges, la pagination etc. Bref tout ce qui est utile pour faire un beau document. De plus le préambule contient un certain nombre d'information utiles comme l'auteur, le titre, la date etc.
Vous allez mieux comprendre avec cet exemple assez complet :

\documentclass[a4paper, 12pt]{article}
\usepackage{a4wide}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage{graphicx}
\usepackage{amsfonts}
\usepackage{amsmath}
 
\author{Moi}
\title{Mon premier document \LaTeX{}}

On retrouve évidemment le \documentclass{} mais cette fois ci avec un petit changement : [a4paper, 12 pt]. Explications : les commandes entre « [ » et « [ » sont des arguments optionnels c'est à dire qu'ils ne sont pas obigatoires. a4paper sert à indiquer au compilateur de produire un document destiné à être imprimer sur du papier A4 ce qui est du au fait que LaTeX est l'invention d'un américain et que le format du papier standart aux US est différent des standarts français. Enfin le 12pt sert à demander une police de 12 points pour le texte normal ; la valeur par défaut est 10 pt on peu soit ne rien mettre pour garder une police de 10 pt, soit changer en mettant 12pt ou 11pt (évitez les autres valeurs qui rendent votre document chiant à lire).

Les usepackage servent à importer des commandes déjà toutes faites afin que n'ayez pas à vous soucier de comment couper votre texte en fin de ligne gérer les accents etc. Je vais éviter de m'attarder sur les détails cependant il me faut expliquer à quoi servent les usepackage. La 2ème et la 3ème ligne servent à configurer LaTeX afin qu'il utilise des caractères unicode et un dictionnaire de césure français et des autres choses utiles pour la typographie. Nota : si après compilation votre fichier pdf affiche des caractère bizards à la place des accents c'est que votre système d'exploitation gère mal les caractères unicode ; aussi je suggère de remplacer le « utf8 » par « latin1 ». \usepackage{graphicx} sert à incorporer des images dans votre document ; attention LateX considère que vous êtes grand et ne compressera pas les images pour vous. Donc on compresse ses photos de 5 Méga Pixels avant de les mettre dans le pdf sinon on se retrouve avec un fichier de plusieurs Mo long à charger en mémoire.

Enfin \usepackage{amsfonts} et \usepackage{amsmath} servent à importer de nombreux symboles utiles pour les maths et la physique (alphabet grec, fractions etc.)

partie 4 : tables des matières, titres et sections

Table des matières, titre et sections
Pour générer le titre du document il suffit d'utiliser la commande \maketitle à insérer entre le \begin{document} et le \end{document} qui s'occuper pour nous de faire un belle page de titre à condition d'avoir bien rempli les commandes \author et \title dans le prémabule (cf préambule). Maintenant il ne me reste plus qu'à vous parler des sections et de la tables des matières avan d'avoir terminer la plus grosse partie de ce tutoriel.

Les sections : dans un document LaTeX, les sections sont comme les chapitres d'un livre : elles sont numérotées et permettent de structurer votre texte ce qui est au moins aussi important que le texte en lui même. Maintenant que vous commencez à comprendre comment se compose un document LaTeX je vais vous montrer un exemple que je commenterai après :

%préambule : à vous de faire le votre%
\begin{document}
\maketitle
\tableofcontents
\section{\LaTeX{} c'est kikoulol}
\subsection{\LaTeX  est super cool}
Non seulement il permet de faire des symboles mathématiques comme celui-ci~:$2\pi \omega t$
Ou encore des truc comme ça : $$\sum{\dfrac{z^{n}}{n+(-1)^{n-1}}}$$
\section{conclusion}
C'est génial
\end{document}

Comme vous l'avez tous compris, l'instruction \section permet de créer une nouvelle section ; \subsection permet de créer une sous section de niveau 1. Il également possible de créer une sous section de niveau 2 en utilisant l'instrcution \subsubsection. LaTeX va automatiquement numéroter les sections et sous sections pour vous grâce à l'instruction \tableofcontents qui va en prime générer une jolie tables des matières cliquable.

partie 5 : insérer des équations et gérer des listes

Liste à puces et mode mathématiques
Juste un dernier truc à savoir avant l'exemple final qui résume tout le tutoriel : comment entrer sortir de mode mathématques et faire des énumerations et des listes. Pour entre dans le mode maths on dispose de plusieurs commandes : $ $ qui va vous permettre d'écrire un symbole/une variable de manière ponctuelle entre les symboles « $ » ; $$ $$ qui va vous permettre d'écrire une ligne de calcul (idéal pour poser une égalité) et le \begin{maths} \end{maths} pour les calculs demandant plusieurs lignes. Je vous laisse découvrir les possibilités du package maths dans l'exemple a le mérite d'être plus parlant qu'un long discour ; rien ne vaut la pratique.

Une autre fonction très utilisée est la liste à puces et/ou l'énumération. Pour l'utiliser rien de plus simple : il suffit d'indiquer à LaTeX que vous voulez commencer un nouvel environnement, vous devriez avoir l'habitude maintenant, et de lui dire où le finir. Pour une liste cela donne :

\begin{itemize}
\item un premier point ;
\item un deuxième point ;
\item etc.
\item \ldots
\end{itemize}

et pour une énumération :

 
\begin{enumerate}
\item un premier point ;
\item un deuxième point ;
\item etc.
\item \ldots
\end{enumerate}

Voilà j'espère que vous avez appris plein de choses qui vous seront utiles maintenant vous n'auvez plus aucune excuse pour utiliser de Word et rendre des rapports de TP et de SH tout moches. Si vous avez un soucis ou bien des questions n'hésitez pas à passer au club, des gens compétants vous répondront.

partie 6 : Cas pratique un fichier TeX complet

On se quite sur ce dernier exemple complet et rédigé par mon prédecesseur :

Exemple complet de fichier LaTeX

  \documentclass{article} 
 % categorie de document
 
 \usepackage[latin1]{inputenc}
 % c pour les accents 
 
 \usepackage{a4wide}
 %\usepackage{amsfonts}
 %\usepackage{amsmath}
 %\usepackage{latexsym}
 \usepackage[frenchb]{babel}
 % c'est pour afficher le document comme en typographie FR %
 
 \usepackage[draft]{graphicx}
 % gère les images png, jpeg, gif
 % "draft" permet de gagner du temps pour les recompilation comportant des images
 % il ne les affiche pas mais grade les boites vides de la taille des images
 % l'option "final" est en général mise par défaut et sert à ravoir les images
 
 \title{utiliser irc}
 \author{Linda}
 % on les a pas encore afficher
 \date{21 juin 2005}
 % ça c parce que si on le dit pas, latex met la date de compilation par défaut
 
 \begin{document}
 
 \maketitle
 \newpage
 
 \tableofcontents
 \newpage
 %il faut compiler deux fois pour avoir la table des matières
 
 \section{Qu'est-ce que l'IRC ?}
 
 \subsection{Présentation rapide}
 
 L'IRC, "Internet Relay Chat", est techniquement un protocole ...
 
 \subsection{Comment se connecter à un réseau IRC}
 Il faut utiliser un client IRC, un logiciel adapté, comme ...
 
 \section{Installation de X-Chat 2}
 
 \begin{center}
 \includegraphics[width=10cm]{xchat.png}
 % 0.8*\linewidth en param si on veut que l'image fasse 80 pourcent de la page
 
 % si on veut qu'il le fasse proportionnellement sinon on rajoute height
 
 \hspace{2cm}
 % sert à espacer verticalement 2 images
 
 \includegraphics[width=10cm]{xchat.png}
 
 \end{center}
 %sert à centrer l'image
 
 
 Il faut d'abord aller télécharger le logiciel ...
 
 \subsection{Configuration X-Chat 2}
 Lorsque vous lancerez X-Chat pour la première fois ...
 
 Cliquez alors sur "Mode d'édition"...
 
 Réglez ensuite les paramètres comme suit. 
 \begin{enumerate}
    \item  Choisissez comme Pseudonyme le nom que vous aurez sur IRC...
    \item Comme nom de serveur, choisissez celui correspond à ...
    \item Dans joindre les canaux rentrez le salon clubnix...
    \item Comme jeu de caractères sélectionnez ...
    \item Cochez la case connections automatique au démarrage ...
 \end{enumerate}
 Vous pouvez vous connecter en utilisant le bouton Connexion ...
 
 \subsection{Utilisation de X-Chat 2}
 \begin{enumerate}
    \item Sur la droite il y a la liste des personnes présentes ...
    \item Ici c'est la fenêtre principale des discussions. ...
    \item Ici, c'est le sujet (aka topic) de discussion. ...
    \item Le champ où vous tapez vos messages.
    \item Les onglets des serveurs auxquels vous ...
  \end{enumerate}
 Il est possible de dialoguer en privé avec une ...
 
 Dans le menu contextuel, sélectionnez Ouvrir la ...
 
 \subsection{Aller plus loin}
 Je vous laisse maintenant découvrir par vous-même ...
 
 $$ \pi $$
 % les dollars sont un raccourci pour dire formule mathématiques
 
 $$ \frac{\pi}{2} $$
 % pi/2
 
 $$ \sqrt{\frac{\pi}{2}} $$
 % racine
 
 texte $\frac{\pi}{2}$
 %force à intégrer un paragraphe
 
 %caractères spéciaux:
 $$ \mu \vec{A}$$
 $$ \alpha $$
 %$$ \Alpha $$
 
 $$ \leq $$
 % <=
 
 $$ A_i $$
 % indice
 
 $$ A^2 $$
 %carre
 
 $$ \times $$
 
 
 $$ A_{ij}^2 $$
 
 $$ \int_0^\infty{x dx} $$
 %intégrale de x sur 0 à infini
 
 $$ \geq $$
 % >=
 
 $$\neq$$
 % =!
 \end{document}

Tutoriel LaTeX (intermédiaire)

Dans cette section vous trouverez de nombreux tutoriels pour vous expliquer le fonctionnement des différents packages disponibles pour LaTeX. Tous les tutoriels et exemples ont été réalisés par les membres du club*nix.

Document recto et recto-verso

J'ai longtemps cherché à savoir comment faire pour que lorsque je créer un document recto-verso latex me mette la table des matières sur une page impaire et non directement après la page de titre. Je viens seulement de trouver l'astuce alors je la partage dans cette section. En fait il faut utiliser un \cleardoublepage à la place du \clearpage dans l'entête du club.
Pour avoir une page vide après la page de titre (sans numéro de page ou titre) il suffit de faire :

\begin{document}
\maketitle
\thispagestyle{empty}
\clearpage
\thispagestyle{empty}
\cleardoublepage
 
\tableofcontents
\thispagestyle{empty}
\clearpage
\thispagestyle{empty}
\cleardoublepage

Les images et les figures

Il existe plusieurs manières d'ajouter des images à un document LaTeX. Nous allons voir ensemble quelques possibilités offertes par LaTeX pour la gestion des images.

La commande la plus utile est \includegraphics{image.png}. Cette commande permet de spécifier une image de type binaire (bmp, png, jpeg, etc.), pour pdflatex ou vectoriel (ps, eps, dvi ...) pour latex. Il est possible de faire une mise à l'échelle ou de forcer une taille précise (largeur ou hauteur) avec les options suivantes :

\includegraphics[scale=0.8]{image.png}
\includegraphics[heigth=10cm]{image.png}
\includegraphics[width=0.5\textwidth]{image.png}

La première commande aura pour effet d'inclure image.png avec une mise à l'échelle de 80%,
la deuxième commande aura pour effet d'inclure image.png avec une hauteur de 10cm, la largeur sera automatiquement réduite/agrandie si nécessaire,
la dernière commande aura pour effet d'inclure image.png avec une largeur égale à 50% de la largeur du texte.

Partie 1 : Les tableaux

Réaliser un tableau avec latex peut sembler simple, pourtant il arrive souvent que le résultat obtenu n'est pas du tout ce que l'on souhaitait. Dans cet article vous allez apprendre à utiliser les différents types de tableaux en latex.

Ce tutoriel s'adresse à tous ceux qui utilisent déjà latex, la lecture du tutoriel latex du club*nix est nécessaire si vous voulez profiter pleinement du présent tutoriel. Je vous invite à copier/coller ces exemples pour bien voir ce qu'ils font, note : les exemples ont étés compilés et testés sans problèmes avec Texlive mais si vous utilisez Tetex il ne devrait pas y avoir de soucis. Si jamais vous avez un problème pensez à bien vérifier que vous utilisez les bon packages. Je mets en pièce attachée le fichier entête utilisé pour compiler les exemples.

Tabular

C'est le tableau de base le plus utilisé. Son emploi est très simple : on commence avec \begin{tabular} et \end{tabular}. De plus on doit indiquer le nombre de colonne au tableau ainsi que on alignement ; pour cela on déclare le tableau comme ce qui suit :

\begin{tablular}{lcr}
1ere cellule & 2eme cellule & 3eme cellule\\
une autre ligne : & plip & plop\\
etc & \ldots & \vdots\\ 
\end{tabular}

Bon comme vous l'avez deviné, {lcr} sert à indiquer l'alignement du texte dans la cellule du tableau. Ainsi les cellules dans la première colonne seront justifiée à gauche, celles dans la deuxième colonne seront centrées, et celles dans la dernière colonne justifiées à droite. De plus on utilise le symbole & pour séparer les colonnes du tableau.

Marquer les séparateurs

Voilà vous avez appris à construire un tableau. La question qui se pose c'est comment est-ce que je fais pour pouvoir tracer des lignes qui séparent les différentes colonnes ? C'est très simple : il faut utiliser le pipe (caractère obtenu en tapant Alt gr + 6 sur un clavier azerty : | ) pour ça. Exemple :

\begin{tablular}{|l|c|r|}
\hline
1ere cellule & 2eme cellule & 3eme cellule\\ \hline
une autre ligne : & plip & plop\\ \hline
etc & \ldots & \vdots\\ \hline
\end{tabular}

Ici on note que le pipe, |, se place dans {lcr} ; il n'est pas obligatoire de mettre qu'une seule fois ainsi {|l||c|r} est tout aussi correct. De plus on peut aussi tracer des lignes horizontales avec \hline. Essayez de tester vous même les autres possibilités.

Tracer des lignes horizontales sur une ou plusieurs colonnes

On peut utiliser \cline qui prend 1 argument obligatoire : {colonne départ - colonne arrivée}
Exemple :

\begin{tabular}{|c|c|c|}
\hline
plop & plip & plup\\
\cline{1-1}
plop & plip & plup\\
\cline{2-3}
plop & plip & plup\\
\cline{1-2}
plop & plip & plup\\
\hline
\end{tabular}

Fusionner des cellules avec multicolumn

Le package multicolumn permet de "fusionner" des cellules horizontales. Il prend en argument : le nombre de colonnes, le motif, le texte à afficher dans la cellule. Exemple :

\multicolumn{5}{||c||}{plop}

multicolumn s'utilise à l'intérieur de l'environnement tabular.
Exemple :

\begin{tabular}{|c|c|c|c|}
\hline
\multicolumn{4}{|c|}{\textbf{Club*nix}}\\
\hline
\multicolumn{2}{|c|}{\LaTeX{}} & \multicolumn{2}{c|}{C}\\
\hline
furet & pdflatex & gcc & -Wall\\
\hline
debian & evinces & make & gentoo\\
\hline
\end{tabular}

Note il est également possible de fusionner des cellules verticalement avec la commande \multirow qui s'utilise presque comme \multicolumn

Package array

Le package array permet d'ajouter des nouvelles manières de formater son texte dans les cellules. Il ajoute principalement trois nouveaux mots clés : p, b et m. Ces mots doivent obligatoirement être suivis de la taille de la cellule. p permet de réaliser un alignement vertical du texte vers le haut, b un alignement vertical vers le bas et m de centrer verticalement le texte.

Exemple sans utiliser m, b ou p :

\begin{tabular}{|l|c|}
\hline
gcc &  When you invoke GCC, it normally does preprocessing, compilation, assembly and linking. The "overall options" allow you to stop this process at an intermediate stage.  For example, the -c option says not to run the linker. Then the output consists of object files output by the assembler\ldots{}\\
\hline
\end{tabular}

Vous avez remarqué ? Le texte est beaucoup trop long pour tenir sur une seule cellule et est tronqué. Pour remedier au problème on peut utiliser m{6cm}. Il faut penser à utiliser le package array :
\usepackage{array}
Exemple :

\begin{tabular}{|l|m{6cm}|}
\hline
gcc &  When you invoke GCC, it normally does preprocessing, compilation, assembly and linking. The "overall options" allow you to stop this process at an intermediate stage.  For example, the -c option says not to run the linker. Then the output consists of object files output by the assembler\ldots{}\\
\hline
\end{tabular}

Bien entendu on peut augmenter la taille du paragraphe si l'on veut plus de place mais il faut faire attention à ne pas dépasser la largeur de la page.

tableaux dont la largeur est spécifiée en argument

Dans les exemples qui suivent, la largeur du tableau est donnée en argument de la manière suivante :
\begin{tabular[xy]}{largeur}{colonnes}
où largeur correspond à celle du tableau et [xy] à x ou y comme nous allons le voir. Pour connaitre la largeur de la page, on utilise la commande \linewidth

tabularx

Tabularx fonctionne de manière similaire à tabular, sauf que celui-ci permet l'utilisation d'un nouveau motif : X qui permet d'entre en mode paragraphe (de type p). Sachant que les cellules se partagent l'espace disponible en largeur. Il faut utiliser le package tabularx :
\usepackage{tabularx}
Exemple :

\begin{tabularx}{\linewidth}{|l|X|X|}
\hline
plop & plip plip plip pliplipliplipliplip\ldots & pluplupluplupluplupluppluplup\ldots\\
\hline
\end{tabularx}

tabulary

Tabulary s'utilise de manière similaire à tabularx sauf que nous utilisons les motifs en L, C, R et J à la place de X et permettent d'entrer en mode paragraphe aligné à gauche, centré, aligné à droite et justifié. Il faut utiliser pour ça les packages tabulary et calc :

\usepackage{tabulary}
\usepackage{calc}

Exemple :

\begin{tabulary}{\linewidth}{|L|J|J|}
\hline
plop & plip plip plip pliplipliplipliplip & pluplupluplupluplupluppluplup\\
\hline
\end{tabulary}

Il s'agit en fait de l'exemple précédent on note tout de même une petite différence entre le rendu de tabularx et celui de tabulary.

Fichier attachéTaille
Fichier entete.tex373 octets

Partie 2 : Bibliographie

Il y a 2 manières pour créer une bibliographie avec latex :

  • La manière dégeulasse avec thebibliography
  • La manière propre avec BibTeX

Je vais détailler les 2 manières de faire, la première peut vous servir si vous moins de 3 références bibliographiques, si ce n'est pas votre cas, tournez vous vers BibTeX qui est bien plus puissant.

thebibliography

Faire un bibliographie avec thebibliography est assez simple. Il suffit de d'abord de construire sa bibliographie avec l'environnement thebibliography. Chaque référence doit être insérée à l'aide de la commande \bibitem{ref} avec entre acolades ref le nom de votre référence. Pour citer vos références il faut utiliser la commande \cite{ref}ref est évidemment la référence à citer.

Voici un exemple concret :

\begin{document}
 
Un peu de blabla qui sert à rien…
 
Ce livre\cite{ol9} est un bon bouquin à mettre sur sa table de chevet.
 
\begin{thebibliography}{99}
\bibitem{ol1} "OpenLDAP, Main Page" . Internet : http://www.openldap.org . Mar. 28, 2008 [May. 1, 2008]
\bibitem{ol2} "OpenLDAP Software 2.4 Administrator's Guide: Introduction to OpenLDAP Directory Services" . Internet: http://www.openldap.org/doc/admin24/intro.html#Wha\
t\%20is\%20LDAP . [May. 1, 2008]
\bibitem{ol3}  "OpenLDAP Software 2.4 Administrator's Guide: A Quick-Start guide" . Internet: http://www.openldap.org/doc/admin24/quickstart.html. [May. 1, 2008]
\bibitem{ol4} "OpenLDAP Software 2.4 Administrator's Guide: The slapd Configuration File". Internet: http://www.openldap.org/doc/admin24/slapdconfig.html. [May. 1, 200\
8]
\bibitem{ol5} "OpenLDAP, Software, Man Pages: ldif" . Internet: http://www.openldap.org/software/man.cgi . [May. 12, 2008]
\bibitem{ol6} J.H.M. Dassen (Ray), Chuck Stickelman, Susan G. Kleinmann, Sven Rudolph, Santiago Vila, Josip Rodin, Javier Fernandez-Sanguino . (2006, June 17). The Deb\
ian GNU/Linux FAQ. version CVS . [On-line]. Available: http://www.debian.org/doc/FAQ/index.en.html. [May. 1, 2006]
\bibitem{ol7} Gustavo Noronha Silva . (2005, March). APT HOWTO. version 1.8.10.4. [On-line]. Available: http://www.debian.org/doc/manuals/apt-howto . [May 1, 2008]
\bibitem{ol8} "The Horde Project" . Internet: http://www.horde.org/ . [May. 12, 2008]
\bibitem{ol9}  G. Carter. "OpenLDAP: Building a Company white Pages" in LDAP System Administration, 2nd ed. O'Reilly Editions.
\end{thebibliography}
 
\end{document}

BibTeX

Avec BibTex, c'est un peu moins simple, il vous faut procéder en 3 étapes.

Étape 1 : créer le fichier bibli.bib

Ce fichier possède une syntaxe propre. Pour créer une nouvelle entrée, il faut commencer par décrire le type de référence dont il s'agit. Cela peut être un livre (book), un passage de livre (in-book), un manuel (manual), …
Chaque type d'entrée, commençant par un @. Ainsi si je veux insérer un livre, avec ast_tfot comme référence, je commencerai mon fichier par :

@book={ast_tfot,
 
}

Ensuite il faut indiquer l'auteur du livre, manuel, etc. Ceci étant fait grâce à la séquence author = {auteur}. On peut aussi renseigner le titre, title = {titre}. Il existe plein d'autres arguments, mais je ne vais pas tout détailler ici, ça serait trop long. Sachez juste qu'il existe des champs obligatoires, en général author, et que les champs qu'il est possible de renseigner changent en fonction du type d'entrée (book, manual, …). Donc je vous laisse chercher pour les autres types d'entrées.

Voici ce que donne une entrée complète de bibliographie, notez la virgule pour séparer chaque champs :

@book{ast_tfot,
author = {Van Meggelen, Jim \and Madsen,  Leif \and Smith,  Jared},
title = {Asterisk ; The Future of Telephony},
publisher = {O'Reilly},
isbn = {0-596-51048-9, 978-0-596-51048-0},
year = {2007},
edition = {second}
}

Étape 2 : Insérer la bibligraphie dans votre fichier .tex

Construire la bibliographie ne suffit pas ; il faut maintenant dire à LaTeX d'utiliser vos références.
Ceci est fait grâce à la commande \bibliography{blibli.bib}. Mais il faut aussi dire quel style nous allons utiliser pour construire notre bibliographie. On utilise la commande \bibliographystyle{plain} avant \bibliography{blibli.bib}, pour indiquer que l'on utilise le style plain pour construire la bibliographie.
Il existe de nombreux styles pour constuire une bibliographie, on retiendra en particulier : plain, abbrv, alpha. Je vous laisse découvrir l'effet de chaque style sur la bibliographie et les citations, qui se font aussi avec la commande \cite{ref} ; par exemple pour citer mon bouquin sur Asterisk, je vais procéder de la manière suivante : \cite{ast_tfot}.

Étape 3 : compiler le tout

La compilation d'un document comportant une bibliographie externe se fait en 3 passes latex et 1 passe bibtex :

pdflatex rapport.tex
bibtex rapport
pdflatex rapport.tex
pdflatex rapport.tex

Petite explication : lors du premier passage de pdflatex, le fichier rapport.aux va être généré, c'est de ce fichier dont bibtex a besoin pour fonctionner. Ensuite l'appel à bibtex va générer les fichiers, rapport.bbl et rapport.blg dont pdflatex va se servir pour insérer la bibliographie. Le dernier passage sert en fait à construire correctement les références croisées (comme dans le cas de la table des matières et les footnotes).

Le prochain chapitre portera sur la création d'un index/glossaire, qui arrivera quand j'aurais le courage de le rédiger.
Au passage, je vous conseille d'aller voir sur ce site pour appendre à gérer les compilations LaTeX avec GNU Make.

Tutoriel LyX (IDE LaTeX)

LyX est un IDE LaTeX WYSIWYM (What You See Is What You Mean)

Qui permet de faire du LaTeX au clic en ayant un rendu en temps réel. Il est possible de mélanger les commandes LaTeX et utiliser uniquement l'interface.

Voici une petite vidéo pour crée un présentation beamer grâce à LyX


lyx.png

Fichier attachéTaille
Image icon lyx.png46.66 Ko

Installation LaTeX

Linux

Sous Linux, la distribution de LaTeX la plus utilisée est texlive. Pour l'installer, il suffit de télécharger les fichiers binaires de texlive qui sont disponibles dans les packets d'installation de la plupart des distributions. Par example, sur Ubuntu, le package à instaler est "texlive-base" ainsi que "texlive-common".
Un tutoriel d'installation avec des liens vers les codes sources est disponible ici. pour ceux qui ne veulent pas utiliser les gestionnaires de packets. Mais texlive n'est pas le seul à pouvoir compiler du latex, il existe aussi un autre environnement : "teTeX" mais il n'est plus mis à jour et peu de personnes l'utilisent encore.
Comme enviroment de développement, vous pouvez utiliser Kile, ou encore TeXMaker, .

Pour visonner les pdf, vous pouvez installer : gpdf pour Gnome, kpdf sous KDE, ou bien encore evince pour tous les bureaux.

MacOS X (beurk!)

Tout ce qu'il faut savoir sur LaTeX pour MacOS X se trouve sur cette page.

LaTeX s'installe avec le gestionaire de packagesi-Installer. Une fois l'image disque montée, copiez l'application quelque part sur votre disque.

Au premier (et unique normalement) lancement, il aura besoin d'avoir les droit d'écriture sur son dossier. Utilisez cet utilitaire pour installer les packages ''TeX'', ''Ghostscript'' et ''CM Super for TeX''.

Ensuite, vous pouvez utiliser l'environement de développement TeXShop. S'il ne vous plais pas, il y a un large choix ici

Windows®

Il suffit d'installer MikTeX qui est téléchargeable sur http://www.miktex.org/

Remarque : Sous Windows®, j'aime bien utiliser TeXnicCenter qui est un environnement intégré de développement pour LaTeX très puissant. http://www.toolscenter.org/

N'oubliez pas d'installer Ghostscript et GSview pour pouvoir visualiser et imprimer des fichiers PostScript.
http://www.ghostscript.com/

L'installation d'un environnement LaTeX sous Windows® étant souvent un véritable supplice, je vous conseille de vous tourner vers la framkey spéciale LaTeX

Présentation avec Beamer

Marre des ppt qui plantent lors de tes présentations ?
Marre des ppt qui sont tout moche parce que tu es une quiche ?
Tu as vraiment envie de te la péter ?
Tu es bien tombé

Beamer c'est quoi ?

Beamer est un paquet LaTeX qui permet de créer des présentation style power point, mais en pdf. et Donc tu n'as plus besoin de power point.
Fonctionne parfaitement sous Linux/OpenBSD/OS-X/et le reste... Plus de problèmes de version MsOffice !
Comme la plupart des documents produits avec LaTeX tu obtiens une présentation claire, un organisation propre !

Mais le pdf c'est pas tout statique ??

Avec Beamer tu peux faire presque les mêmes chose qu'avec power point, mais de manière plus stable (tu as pas tes photos/schémas qui se barrre).
Tu peux :

  • Faire apparaitre/disparaitre des item de liste
  • Jouer avec la transparence
  • Mettre des images/schéma
  • Mettre des transitions
  • Et plein d'autre trucs

Installation

Ben commencer par installer LaTeX (installation LaTeX)
Et installer le paquet "latex-beamer"

Petit exemple :

Cette exemple n'est pas vraiment un tutoriel mais présente quelque possibilité de base de Beamer. Bien évidement le code est fournit avec ce qui te permettra de reproduire les effets voulu.

Pour le visualiser correctement, le mettre en plein écran.
presentation.pdf

 
\documentclass{beamer}
 
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage{graphicx}%@@final
\usepackage{hyperref}
\usepackage{amsmath}
\usepackage{listings}
 
\lstset{tabsize=2, numbers=left, numberstyle=\tiny, stepnumber=5, numbersep=5pt,breaklines=true,
    emph={int}, emphstyle=\color{red},
    emph={[2]int,for}, emphstyle={[2]\color{red}},
    emph={[3]int,for,printf}, emphstyle={[3]\color{blue}},
    morecomment=[s][\color{green}]{/*}{*/}
}
 
\usetheme{Warsaw}
\setbeamercovered{transparent}
 
\hypersetup{%colorlinks,%
%citecolor=black,%
%filecolor=black,%
%linkcolor=black,%
urlcolor=blue}
 
\author {GIVERNAUD Omar \\ givernao@esiee.fr}
\title{Beamer par l'exemple\\ }
\institute{Club*Nix}
 
 
\begin{document}
 
\begin{frame}
	\maketitle
	\begin{center}
		\includegraphics[width =2cm]{logo.png}
	\end{center}
\end{frame}
 
\begin{frame}
	\tableofcontents
\end{frame}
 
\section{Liste de puces}
\begin{frame}
\frametitle{Liste de puces}
Mes puces
	\begin{itemize}
		\item<1->Morpions
		\item<2->Tiques
		\item<3->Mithes
	\end{itemize}
 
Le club
	\begin{enumerate}
		\item<4->{Prez : trax}
		\item<5->{Vice : tatane}
		\item<6->{Trez : phroddon}
		\item<7->{Secrétaire : dennewan}
	\end{enumerate}
 
\end{frame}
 
\section{Utilisation de blocs}
\begin{frame}{Utilisation de blocs I}
	\begin{theorem}<1->
		Laisser son écran allumer tue des TUX
	\end{theorem}
	\begin{proof}<2->
		\begin{itemize}
			\item{Fait consommer de l'électricité}
			\item{Production de $CO_2$}
			\item{Trou dans la couche d'ozone}
			\item{Réchauffement des pôles}
		\end{itemize}
	\end{proof}
	\begin{example}<3->
		En 1982, 77\% de la population a disparu pour ne laisser que 463 manchots
	\end{example}
 
 
\end{frame}
\begin{frame}{Utilisation de blocs II}
	 \begin{block}{Question}
      Calculer :
	$$\left[\sum_{n=0}^{+\infty} \left(\dfrac{5}{6}\right)^n \right]
	  \left[\sum_{n=0}^{+\infty}\left(\dfrac{7n - 3}{n^3 + 2n^2 - n -2} - \dfrac{4}{n^2+3n+2}\right)\right]$$
    \end{block}
    \begin{block}{Réponses possibles}
    	\begin{itemize}[<+-| alert@+>]
			\item 0
			\item 7
			\item 42
			\item 1
		\end{itemize}
    \end{block}
\end{frame}
 
\section{Et pour les tétards ??}
\begin{frame}[fragile]
	\frametitle{Et pour les tétards ??}
	\begin{columns}
	\column{.6\textwidth}
	\begin{semiverbatim}
\only<4->{void permute(int *a, int *b);}
int main (void)\{
	\uncover<2->{	int a = 42, b = 7;}
	\only<3->{	permute(\alert<1->{\&}a, \alert<1->{\&}b);}
{	return 0;}
	\}
\only<4->{void permute(int *a, int *b)\{}
\only<4->{\uncover<5->{	int r;}}
\only<5->{\uncover<6->{	r = \alert<5->{*}a;}}
\only<5->{\uncover<6->{	\alert<5->{*}b = \alert<5->{*}a;}}
\only<5->{\uncover<6->{	\alert<5->{*}a = r;}}
\only<4->{\}}
	\end{semiverbatim}
	\column{.4\textwidth}
	\begin{block}{Commentaire}
		Ce code effectue une permutation des variables $a$ et $b$
	\end{block}
	\end{columns}
\end{frame}
 
\begin{frame}{Contacts}
 
{\color[rgb]{0,.7,0}{Réalisé par/pour le Club*Nix}}
 
{\color[rgb]{0,0,0.7}\href{http://clubnx.esiee.fr}{http://clubnix.esiee.fr}}
 
{\color[rgb]{0,0.7,0}{Documentation officiel}}
 
{\color[rgb]{0,0,0.7}\href{http://latex-beamer.sourceforge.net}{http://latex-beamer.sourceforge.net}}
\end{frame}
 
 
\end{document}
Fichier attachéTaille
PDF icon presentation.pdf276.35 Ko

Lisp Emacs

Apprendre à scripter pour Emacs (le seul et unique editeur)
Je me suis basé sur les articles suivants :

http://xahlee.org/emacs/elisp.html

Début rapide

Pré-requis ?

  • Votre meilleurs éditeur de texte : emacs (XEmacs, ou Micro Emacs pour certains)
  • Un minimum de notion en programmation : savoir ce qu'est une variable, une condition ou une boucle
  • De la patience et un cerveau

Comment exécuter du code ?

  • Pour une seule ligne :

    C-x C-e
  • Le code sera exécuté jusqu'au curseur.

  • Un buffer entier :
    Bien que le Lisp ne soit pas à proprement parler compilé, emacs a besoin de l'analyser (parser) avant que vous n'exécutiez des commandes.
    M-x eval-buffer
    Vous pouvez par la suite appeler une fonction comme décrit plus haut.

Exemple :

(+ 2 3)

Renverra dans le mini-buffer 5.

Cette écriture inverse s'appelle Polonaise inversée (http://fr.wikipedia.org/wiki/Notation_polonaise_inverse).
Brièvement cela consiste à placer la fonction en premier puis les arguments. Finalement c'est ce qui est fait dans la plupart des langages pour les fonctions autre que celles arithmétiques : en C

printf("plop %d\n" , 42);

La fonction est bien positionnée en premier printf puis ses arguments "plop %d\n" et 42. Nous comprenons donc que + est non pas un opérateur mais bien une fonction, qu'il est d'ailleurs possible de redéfinir.

Fonction d'affichage

(print 'bonjour)

En exécutant ( C-x C-e cette ligne vous devriez voir apparaître deux fois la ligne bonjour. Nous expliquerons cela dans la partie d'écriture de fonction.

Poser une question

Question binaire (Yes or No question)

(y-or-n-p "Aimez-vous ce tutoriel Emacs Lisp ?")

Le retour est soit nil pour une réponse négative ou t pour une réponse positive.

Question ouverte

(interactive "MEntrez votre login : ")

Le "M" spécifie que la réponse est une chaîne de caractères.

Notions de base en Emacs Lisp

Listes

En Emacs Lisp presque tout est une liste, du moins tout ce qui est entre "()".

  • Le premier argument ("+") est la fonction à exécuter. Les autres sont les argument de la fonction.

    (+ 2 3) ; est une liste
  • Cette liste ne sera pas interprété par emacs parce que précédé d'un apostrophe. Cela signifie donc que c'est une liste d'éléments.

    '(bonjour les gens) ; est aussi une liste 
  • Est la liste vide. Elle équivaut exactement à nil.

    ()

"nil" et "t"

Sont respectivement les valeurs de vérité FAUX et VRAI.

Fonction

(defun plop (arg0 arg1 arg2)
)

Nous venons de déclarer la fonction plop qui prend trois arguments arg0, arg1 et arg2 en entré.

Chaque fonction en Emacs Lisp est un object et chaque object renvoie une valeur. Si celle ci n'est pas définie, la valeur renvoyé est nil.

Pour appeller notre fonction il suffit de faire :

(plop 1 2 3)

1, 2 et 3 étant les arguement passé à la fonction.

Quelques opérateurs

Optimisation de code C

Pas mal de gens disent souvent que le plus important est d'optimiser sont algorithme plutôt que sont code. Certe, mais il est également possible de tourner le problème autrement et dire que l'implémentation fait partie de l'agorithme.

Optimisation des boucles

Commençons fort !

Condition de boucle

int main() {
  int a = 42;
  int b = 72;
  int t = 0;
  for (int i = 0; i < a + b; i++) {
    t++;
  }
 
  return 0;
}

Sans optimisation de la part de gcc, le programme va effectuer 114 tour de boucle en recalculant la somme a + b à chaque tour de boucle.
En spécifiant à gcc d'optimiser ce code, la boucle va tout simple être supprimé.

Nous pouvons alors demander à gcc d'afficher le résultat. Il ne faut pas sous estimer gcc, qui aura vu que le résultat est constant et qui supprimera quand même la boucle, et affichera un résultat prés calculé.

Bis

Dans la vraie vie on fait rarement de boucles comme-ca, le resultat n'est pas constant ou voir non constant ou defois, pas de resultat :P

void faire_quelquechose(int i);
 
int main() {
  int a = 42;
  int b = 72;
  int t = 0;
  for (int i = 0, max = a + b; i < max; i++) {
    faire_quelquechose(t);
  }
 
  return 0;
}

Et la le a + b est calcule une seule fois pour plein de tour de boucle !
Et un peu plus de memoire est utilisee.

Optimisation pour les tableaux

Allocation

Histoire de commencer par le commencement, lire http://clubnix.fr/allocation_dynamique_2_dimensions_C pour plus d'informations.

Le programme suivant va allouer un tableau à deux dimensions de manière dynamique et, afficher le temps de création et de destruction du tableau.

#include <stdio.h>
#include <stdlib.h>
 
 
/*========== parttie relative a la mesure du temps ===========*/
#include <sys/times.h>
#include <unistd.h>
typedef struct tms sTms;
typedef struct{
	int debut,fin;
	sTms sdebut, sfin;
}temps_exec;
 
 
void temp(temps_exec *tmps){
    printf("temps réel :\t %d\ntemps utilisateur :\t %ld\ntemps system :\t %ld\n\n",
		tmps->fin - tmps->debut,
		tmps->sfin.tms_utime - tmps->sdebut.tms_utime,
		tmps->sfin.tms_stime - tmps->sdebut.tms_stime);
}
/*========== parttie relative a la mesure du temps ===========*/
 
 
void badInit(int C, int L){
  int **tab;
  temps_exec temps;
 
  temps.debut = times (&temps.sdebut);
  tab = (int **)malloc (sizeof(int*)*L);
  for(int i = 0 ; i < L ; i++){
    tab[i]=(int *)malloc(sizeof(int)*C);
  }
 
  for (int i = 0 ; i < L ; i++){
	free (tab[i]);
  }
  free (tab);
  temps.fin = times (&temps.sfin);
  temp (&temps);
 
 
}
 
void goodInit(int C, int L){
  int **tab;
  int *tab0;
  temps_exec temps;
 
  temps.debut = times (&temps.sdebut);
  tab = (int **)malloc (sizeof(int*)*L);
  tab0 = (int *)malloc (sizeof(int)*(C*L));
 
  for (int i = 0 ; i < L ; i++){
	tab[i] = &tab0[i*C];
  }
 
  free (tab0);
  free (tab);
  temps.fin = times (&temps.sfin);
  temp (&temps);
 
}
 
int main(){
 
  badInit (10, 1000000);
 
  badInit (1000000, 10);
 
  goodInit (10, 1000000);
 
  goodInit (1000000, 10);
 
 
  return 0;
}

Intéressons nous dans un premier temps à la fonction badInit.

Sa compléxité est en o(n) (n la deuxième dimension du tableau), ce qui ne semble pas dramatique.

Dans un premier temps, allons un tableau de 10 colonnes et 1000000 lignes
Soit 1000010 allocation mémoire. Ces allocations sont des appelles systèmes (donc appelle du kernel) qui sont couteux en temps. La première chose à faire est donc placer la plus petite dimension en premier et d'allouer un tableau de 1000000 et de 10 lignes.

Il est néanmoins possible de faire mieux et de réduire à deux allocations mémoire comme le montre la fonction gootInit (la aussi il faut penser au dimensions).

Voici les temps obtenu

$ ./tab
temps réel :     21
temps utilisateur :      12
temps system :   8
 
temps réel :     6
temps utilisateur :      6
temps system :   0
 
temps réel :     4
temps utilisateur :      2
temps system :   1
 
temps réel :     0
temps utilisateur :      0
temps system :   0

L'allocation à deux malloc permet de gagner du temps lors de la création mais pas seulement.

Parcour de tableau

Soit un tableau tab de 1000000 colonnes et 100 lignes alloué avec la fonction badInit.

Nous pouvons l'initialiser de la manière suivante :

  for (int i = 0 ; i < C ; i++){
        for (int j = 0 ; j < L ; j++){
          tab[j][i] = j;
        }
  }

Si nous parcourons le tableau par les lignes (en lisant la première colonne de chaque ligne, puis la deuxième colonne de chaque ligne...), nous obligeons le système à faire des sauts dans la mémoire.

temps réel :     1327
temps utilisateur :      1314
temps system :   11

Si nous parcourions le tableau dans le sens des colonnes

  for (int i = 0 ; i < L ; i++){
        for (int j = 0 ; j < C ; j++){
          tab[i][j] = j;
        }
  }

Nous obtenons :

temps réel :     77
temps utilisateur :      12
temps system :   65

Ce qui est bien mieux, et encore une fois la complexité algorithmique est la même.

En faisant la même chose sur un tableau initialisé avec la fonction goodInit nous obtenons les temps suivant :

temps réel :     207
temps utilisateur :      205
temps system :   2
 
temps réel :     73
temps utilisateur :      12
temps system :   62

Mais nous n'utilisaton pas le fait que le bloc mémoire soit continue, ce qui pourrait améliorer nos performances :

  for (int i = 0 ; i < C*L ; i++){
        tab[0][i] = i;
  }

Nous n'avons plus qu'une boucle, et toujours de la même compléxité algorithmique.

temps réel :     47
temps utilisateur :      46
temps system :   0

Qui dit mieux ?

Et si c'est possible. Dans les exemples précédents, nous obligions le système à recalculer les index de chaque case soit des multiplications en trop.

  tab0 = &tab[0][0];
  for (int i = 0 ; i < C*L ; i++){
        *tab0 = i;
        tab++;
  }

Soit :

temps réel :     0
temps utilisateur :      0
temps system :   0
Fichier attachéTaille
Fichier tab.c2.3 Ko

Outils à la programmation

Autotools pour faire ses Makefiles

Introduction

Vous avez surement installé à la main un paquet de source (sinon vous auriez dû :), avec le fameux ./configure && make && make install

Ou juste que vous en avez marre de faire vos Makefile à la main, pour un projet basique ça passe encore, mais ça atteint vite ses limites.

Autant de raisons pour adopter la suite Autotools

Préparation

Toutes sources seront mises dans un dossier src (tradition oblige)

Automake demande quelques fichiers :

  • AUTHORS
  • ChangeLog
  • NEWS
  • README

Par la suite nous utiliserons deux type de fichier : configure.ac, et Makefile.am
Le configure.ac permet de créer le script qui vérifiera la présence des différents éléments nécessaires (headers, librairies, ...). Les Makefile.am permettront de construire les Makefiles.

Les noms sont assez explicites.

Initialisation

Nous allons utiliser un petit projet comme base d'exemple
autotools

Executer autoscan
Il va parcourir vos fichiers pour créer des fichiers de configurations de base. Celui qui nous intéresse est nommé configure.scan qu'il faut renommer en configure.ac

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
 
AC_PREREQ(2.61)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([src/rs232.c])
AC_CONFIG_HEADER([config.h])
 
# Checks for programs.
AC_PROG_CC
 
# Checks for libraries.
 
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h])
 
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
 
# Checks for library functions.
AC_CHECK_FUNCS([strtol])
 
AC_CONFIG_FILES([src/Makefile])
AC_OUTPUT

Bon pour l'instant il a remarqué nous utilisions la stdlib.h pas de quoi se relever la nuit.

Configuration

Nous allons maintenant configurer tout cela pour que ça fonctionne.

Drapeaux

Il faut configurer variables de drapeaux pour la compilation et pour la liaison :

CFLAGS="-Wall -std=gnu99"
LIBS="-lm"

(Nous n'utiliserons pas la librairie math dans notre exemple)

pkg-config

PKG_CHECK_MODULES(NIX, [gtk+-2.0 libglage-2.0])

Cette ligne va créer les variables NIX_CFLAGS qui correspond aux drapeaux pour gtk et libglade (et respectivement NIX_LDFLAGS avec les drapeaux de liaison). En plus elle les exporte automatiquement vers les Makefile.

Condition

La compilation conditionnelle peut être très intéressante pour ajouter des options de compilations ou drapeaux.

Voici un petit exemple qui permet d'activer un drapeau de debug.

Par défaut mis à l'état bas, pour l'activer il faudra mettre --enable-debug lors du configure.

AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[Debug flags]),[enable_debug=$enableval],[enable_debug="no"])
 
AC_MSG_CHECKING(debug)
AC_MSG_RESULT($enable_debug)
 
if test "x$enable_debug" = "xyes"
then
	DEBUG_CFLAGS="-g -Wall -DDEBUG"
fi
AC_SUBST([DEBUG_CFLAGS])

Mais ce n'est pas tout, cette partie permet uniquement de placer dans la variable DEBUG_CFLAGS les options qui vont bien. Il faudra par la suite utiliser cette variable dans notre Makefile.am

Comment faire une jolie documentation (avec Doxygen)

Ce tutoriel n'a rien de transcendant, mais permettra juste à quelque uns de découvrir cet outil, et vous aider à faire le premier pas.

Introduction

Coder pour soit ça peut être sympa, mais cette pratique atteint assez rapidement ses limites. Mais ouvrir son code demande un minimum de documentation. Alors voici une solution, pas magique, mais presque : Doxygen.

Quelques caractéristiques intéressantes

Petits exemples de documentation doxygen :

Ne soyons pas sectaire il n'y a pas que doxygen qui fasse ce genre de choses

Doxygen est un logiciel qui va analyser votre code pour créer un documentation. Bien évidement, il ne va pas deviner ce que veux fait la fonction la fonction void plop (gchar *msg) il faut donc lui donner un petit coup de main : utiliser des balises. Pas d'affolement c'est tout ce qu'il y a de plus facile.

Ce qui m'a donné envie d'écrire ce tutoriel c'est d'avoir dû documenter le code de notre projet bidon, il y aurait donc pas mal d'exemples basés dessus. Pour pouvoir directement accès aux fichiers se référer à la page du projet.

Pour la documentation officiel : http://www.stack.nl/~dimitri/doxygen/manual.html

Comment commenter son code ?

Quatre manières de commander son code :

/** commentaire
 * blabla
 */
/*!
 *
 */
/*!
...
 */
///
/// ...
///

Quelques balises bien utiles

La liste de la documentation officielle se trouve là : http://www.stack.nl/~dimitri/doxygen/commands.html
Nous ne présenterons ici que les balises vitales pour commencer

Documentation du code

\author trax Givneraud Omar
\version 0.3

Vous l'aurez deviné pour l'auteur et la version. A mettre en entête de de vos fichiers.

\file foobar.c
\class Eugeni
\fn void plop(gchar *msg)

Gné ça sert a quoi ? il peut pas comprendre tout seul que c'est le fichier foobar.c ou la fonction plop ?
Si il pourrait mais ça permet de pouvoir déplacer la documentation un peu on l'on veux et surtout définir la nature d'un bloc : documentation d'une fonction, un fichier ou encore une classe. L'argument est bien évidement optionnel

\brief breve description de la fonction ou du fichier

Pour une documentation longue pas de balise particulière, il suffit juste de sa placer dans un bloc de documentation doxygen.

\param nom_du_parametre sa description
\return ce que retourne la fonction

Créer une page de documentation style howto ou tutoriel

Petit exemple toujours sur le projet bidon :
http://clubnix.esiee.fr/~trax/bidon/doc/html/howto_makeplugin.html

code doxygen de la page :
http://clubnix.esiee.fr/~trax/bidon/doc/howtos/howto_plugin.doc

Pour créer une page, créer un fichier séparé de préférence et créer un bloc de documentation doxygen.
Utiliser la balise

/*!
\page reference_de_la_page Titre de la page
 */

Sections

Pour les sections (titres et sous titres) doxygen utilise une syntaxe proche de celle de LaTex

\section Titre niveau 1
\subsection Titre niveau 2
\subsubsection Titre niveau 3

Inclure du code :

\code 
le code
\endcode

Si doxygen reconnait des éléments de votre projet dans la balise code il créera directement un lien vers vers la documentation en question. Cela peut être très pratique, mais également un inconvénient : vous avez une fonction plop dans votre code, et vous voulez faire un exemple dans votre tutoriel avec une fonction plop qui n'a rien a voir avec celle du projet (ceci est également vrai pour le texte d'une page). Il existe donc la balise verbatim.

\verbatim
plop non reconnu
\endverbatim

Faire une liste

Rien de plus facile !

\li premier element
\li deuxième element

Lancer la moulinette pour obtenir sa doc

Il y a un magnifique fichier de configuration, mais pas question de l'ouvrir à la main pour l'instant : doxywizard est notre ami. Lancer le binaire et suivre les instruction, rien de plus simple. Pour avoir un fichier exemple, comme d'habitude voir dans bidon http://clubnix.esiee.fr/~trax/bidon/doc/Doxyfile2

Faire un Makefile Générique

Note, il est conseillé de savoir faire un Makefile « standard » pour profiter pleinement de la lecture de cet article.

On peut bien sûr utiliser un truc complément inutile :

CFLAGS = -W -Wall -g

Ceci aura pour effet de configurer les CFLAGS, et de compiler tous les fichiers sources du répertoire courant.

En gros ça revient a faire ça :
gcc $CFLAGS *.c
Ce qui ne sert à rien, quand on sait qu'un Makefile sert, entre autres, à compiler séparément ses sources pour ne pas compiler tout à chaque fois.
Je tairai le nom de la personne qui a cru que ça allait me servir…

Sinon, on peut faire des Makefile très simples, avec le nom de chaque règle « en dur ». Ces Makefiles sont en général ceux utilisés pour des petits programmes, dès que le nombre de fichiers sources augmente, il devient très difficile d'écrire toutes les règles à la main.

Pour résoudre ce problème, on peut utiliser des règles génériques qui vont permettre de s'affranchir du nom de chaque règle et de ses dépendances.

CC = gcc
CFLAGS = -W -Wall -g
LDFLAGS = 
 
SRC = $(wildcard *.c)
OBJS = $(SRC:.c=.o)
AOUT = prog
 
all : $(AOUT) 
 
prog : $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $^
%.o : %.c
	$(CC) $(CFLAGS) -o $@ -c $<
clean :
	@rm *.o
cleaner : clean
	@rm $(AOUT)

Quelques explications :
SRC = $(wildcard *.c) : comme son nom l'indique, wildcard agit comme une wildcard, c'est à dire un caractère « joker ». Ici on s'en sert pour récupérer tous les fichiers finissant par .c du répétoire dans lequel est le Makefile.

OBJS = $(SRC:.c=.o) : permet de préciser les nom de chaque fichier .o à partir du fichier .c.

$@ : le nom de la cible

$^ : le nom de chaque dépendance

$developpez.com

Utilisation de GNU Debugger (GDB)

Votre programme crash et vous ne savez pas pourquoi ? Le mieux à faire pour comprendre et d'utiliser un outil de debugage plutôt que se retaper tout votre code... Un outil assez simple est le GNU Debugger, ou GDB. Ce programme va vous permettre de générer un BackTrace de votre programme (c'est à dire la liste de tous vos appels de fonctions etc...) qui vous permettra de savoir où ça plante, si ce n'est pourquoi ça plante.

Pour utiliser le debugger, assurez-vous d'abord que le package gdb est bien installé sur votre machine. Ensuite vous devez vous assurer que votre programme exporte des informations utiles pour gdb. En général on peut obtenir ces informations en ajoutant -ggdb aux instructions de compilations de son programme. Cela permet à gcc de savoir qu'il faut qu'il laisse des informations de debuggage supplémentaires dans le programme pour permettre à gdb de s'y retrouver plus facilement.

Pour créer le BackTrace vous devrez d'abord lancer voter programme sous GDB :

$~ gdb mon_prog

Puis, dans le terminal gdb, tapez :

(gdb) handle SIGPIPE nostop
(gdb) run

L'instruction "run" lancera le programme. Il ne vous reste plus qu'à reproduire le crash si il ne se fait pas de lui-même... Si Votre programme reste bloqué (genre boucle infini, attente d'une entrée, blocage etc...) tapez Ctrl-C pour revenir sous gdb. Puis tapez :

(gdb) bt full

ou bien :

(gdb) backtrace full

Vous verrez alors le BackTrace de votre programme s'afficher dans le terminal. Il se peut que des "??" apparaissent à la place des noms de fonction, c'est simplement que gdb n'a pas pu le lire... Sachez que pour obtenir les meilleures traces possibles, il faut que les librairies que vous utilisez aient été installé avec leur symboles de débugage.

Pour quitter GDB, tapez :

(gdb) quit

Il est aussi possible de se déplacer dans la pile d'appel des fonctions de votre programme. Pour cela, utilisez les commandes up et down. Il est également possible de consulter le contenu des variables en utilisation la commande print (p en abbrégé). L'exemple suivant permet d'afficher le contenue de la structure pointée par struct_p :

(gdb) print *(mon_pointeur_de_struct *)struct_p

Il ne vous reste plus qu'à repérer les erreurs relevées dans le BackTrace et aller les corriger dans votre code...

Pour plus d'informations, vous pouvez aussi consultez les wikis des distributions Ubuntu, Debian et Gentoo.

Tuto Shell Débutant

Introduction

Vous venez d'installer Linux sur votre PC et vous êtes émerveillé par le libre. Mais là vous vous demandez comment copier, renommer, déplacer, supprimer, etc... un fichier. Bien sur vous pouvez ouvrir votre explorateur de fichier et le faire à la main. D'accord ça marche mais comment faire dans un dossier pour supprimer tous les fichiers commençant par c ou p et de taille inférieure à 10ko tout en faisant attention à ne pas supprimer les fichier dont l'extension est .c ?
Pas facile hein ... ;)
Ne vous inquiétez pas avec une console tout cela se fait en une ligne.
Alors commençons.

Qu'est-ce qu'une console ?

Et oui on s'adresse ici aux débutants.
Pour ouvrir une console sous Gnome allez dans Applications->Accessoires->Terminal
Vous obtenez une fenêtre toute blanche (ou noire) avec quelque chose comme cela d'écrit :

user@ordi:~$

Voila vous êtes dans une console !!!!
C'est d'ici que tout ce passe. On va voir comment utiliser des fonctions sur cette console.

Les fonctions en shell

Comment se sert-on d'une fonction ?

Alors on est là devant notre jolie console et que fait-on ?
On va se servir de fonctions. Pour cela il faut savoir comment on appelle une fonction (on verra par la suite les noms de fonctions, pour le moment on fait de la théorie :) ). Pour appeller une fonction on tape juste le nom de la fonction suivie de ses options et arguments (si il y en a). La différence entre les options et les arguments est que les options sont précédées d'un tiret.
Voila un exemple d'appel d'une fonction :

user@ordi:~$ fonction -options argument1 argument2 ...
# ou bien
user@ordi:~$ fonction argument1 argument2 ... -options

Voila c'est tout simple. Comme on le voit l'ordre entre les arguments et les options n'a pas énormément d'importance et les deux appels précédents sont équivalents. Bien entendu ça ne parle pas beaucoup comme ça, mais comme on dit "rien ne vaut l'expérience", alors voyons les fonctions de base.

La fonction pwd

C'est la première fonction que nous verrons : "pwd" (Print Working Directory) soit en français : imprimer le répertoire courant. Testons la :

user@ordi:~$ pwd
/home/user

On est dans le répertoire /home/user. On appelle aussi ce répertoire : le répertoire "~" (prononcez "tilde").

La fonction ls

Fonction très utile "ls". Allez-y tapez ls dans votre console vous devez avoir un résultat du type

user@ordi:~$ ls
at76_usb-0.17         bashrc  Desktop  MEMOVIF.PDF         rapport.tex  tp3
at76_usb-0.17.tar.gz  bluej   latex    rapport_latin1.tex  tp2          WinDLX

Bien sur c'est surement différent chez vous. Vous avez compris ce que faisait cette fonction : elle liste les fichiers du répertoire courant.

Vous me direz : "C'est bien beau tout ça mais comment on fais pour savoir si on a un dossier ou un fichier exécutable ?"
C'est là que les options interviennent. Pour ls une options pratique est -l :

user@ordi:~$ ls -l
drwxr-xr-x 2 aad users  4096 jan  4 18:31 at76_usb-0.17
-rwx------ 1 aad users 55539 jan  2 02:56 at76_usb-0.17.tar.gz
-rw-r--r-- 1 aad users  2379 jan 10 03:20 bashrc
drwx------ 4 aad users  4096 sep 19 17:51 bluej
drwx------ 2 aad users  4096 sep 27 16:13 Desktop
drwxr-xr-x 4 aad users  4096 jan 10 03:20 latex
-rw------- 1 aad users 49309 jan  2 02:32 MEMOVIF.PDF
-rw-r--r-- 1 aad users  7006 déc  6 18:14 rapport_latin1.tex
-rw-r--r-- 1 aad users  7044 déc  6 18:11 rapport.tex
drwx------ 8 aad users  4096 sep 19 18:17 tp2
drwx------ 6 aad users  4096 sep 27 16:13 tp3
drwxr-xr-x 3 aad users  4096 déc  7 16:30 WinDLX

Là plein de choses sont apparues. Voyons ce que l'on apprend. Tout d'abord le début de la ligne (drwxr-xr-x par exemple pour la première ligne) : cela correspond au type de fichier et aux droits des utilisateurs sur ce fichier. le d signifie directory (dossier) -> on a donc un dossier. Si on a un tiret c'est qu'on a un fichier classique.
Le reste sont les droits en lecture(read), écriture(write), exécution (executable) des utilisateurs ; les trois premières lettres correspondent aux droits du propriétaire, les trois suivantes à ceux des utilisateurs appartenant au groupe du fichier, les trois dernier aux autres utilisateurs.
Après cela on a dans l'ordre : le propriétaire, le groupe, la taille en octet du fichier, la date de la dernière modification du fichier (mois, jour, heure), le nom du fichier.

Une autre option intéressante est -a (all) qui permet d'afficher tous les fichiers (même les cachés). Sous Linux les fichiers cachés commencent par un ".". Testons-la :

user@ordi:~$ ls -a
.                     .fontconfig        .povray
..                    .gconf             .qt
.adobe                .gconfd            rapport_latin1.tex
.appletviewer         .gimp-2.2          rapport.tex
at76_usb-0.17         .gnome             .recently-used.xbel
at76_usb-0.17.tar.gz  .gnome2            .ssh
.bash_history         .gnome2_private    .thumbnails
.bash_logout          .gstreamer-0.10    tp2
.bash_profile         .gtkrc-1.2-gnome2  tp3
bashrc                .ICEauthority      .Trash
.bashrc               .icons             .viminfo
.beagle               .java              .wapi
bluej                 .kde               WinDLX
.bluej                latex              .Xauthority
.config               .macromedia        .xchat2
Desktop               MEMOVIF.PDF        .xscreensaver
.dmrc                 .metacity          .xsession-errors
.fbrc                 .mozilla
.fluxbox              .nautilus

On voit plein de nouveaux fichiers. Ce sont les fichiers de configurations Linux. Pas la peine de s'attarder sur eux pour le moment.

Ce que l'on peut faire maintenant c'est combiner les options. Par exemple :

user@ordi:~$ ls -a -l

On a les deux options à la fois. Ce code donnera la même chose que  user@ordi:~$ ls -al .
D'autres options intéressantes sont : -h, -d, -s. Je vous laisse découvrir par vous même leur utilité. Nous verrons plus loin une méthode pour pouvoir connaitre les options d'une fonction.

La fonction cd

Maintenant que l'on peut connaitre les différents fichiers du répertoire courant, voyons comment se balader dans les différents répertoires.
Pour cela on utilise la fonction cd pour "change directory". cette fonction permet de se déplacer dans l'arborescence des dossiers. On se sert de cette fonction comme suit : user@ordi:~$ cd RépertoireCible
Par exemple si je tape ls j'ai :

at76_usb-0.17         bashrc  Desktop  MEMOVIF.PDF         rapport.tex  tp3
at76_usb-0.17.tar.gz  bluej   latex    rapport_latin1.tex  tp2          WinDLX

Desktop est un dossier. Je peux donc entrer dedans par :

user@ordi:~$ cd Desktop
user@ordi:~/Desktop$  #On est dans le répertoire Desktop

Pour revenir en arrière il suffit de faire  cd ..
.. est un dossier spécial représentant le répertoire au dessus du répertoire courant.

user@ordi:~/Desktop$ cd ..      #On remonte dans l`arborescence
user@ordi:~$ 

Si la cible que l'on donne n'est pas un répertoire ou n'existe pas on génère une erreur :

user@ordi:~$ cd MEMOVIF.PDF      #La cible est un fichier
bash: cd: MEMOVIF.PDF: N`est pas un répertoire
user@ordi:~$ cd çanexistepas     #La cible n`existe pas
bash: cd: çanexistepas: Aucun fichier ou répertoire de ce type

La fonction cp

La fonction cp, comme copy, permet de copier un fichier ou un répertoire. Cette fonction est assez simple a utiliser : cp [OPTIONS] SOURCE DESTINATION où SOURCE est le fichier ou répertoire à copier et DESTINATION l'endroit où SOURCE est copiée.
Exemple :

user@ordi:~$ ls
Books   Code       driver_wifi_80211g.zip  goldie.avi     Images      john-1.7.2.tar.gz  Musique  Vidéos
Bureau  Documents  Examples                gtk-cours.pdf  john-1.7.2  Modèles            Public
user@ordi:~$ cp john-1.7.2.tar.gz Documents/
user@ordi:~$ ls Documents/
el201  en201a  in201  john-1.7.2.tar.gz  ma201  ma211_annales.tar.gz  pr201.tar.gz  sh201

Dans cet exemple, john-1.7.2.tar.gz est SOURCE et Document est DESTINATION. On ne s'est pas servi de OPTION car il n'est pas obligatoire d'en utiliser. Cependant certaines options sont assez pratiques :

  • cp -r ou cp -R: permet de copier un répertoire (recursive)
  • cp -i : permet de demander confirmation avant d'écraser un fichier déjà existant (interactive)
  • cp -v : permet d'utiliser le mode verbose : cp devient alors très bavard

Comme pour ls, il n'est pas interdit d'utiliser plusieurs options à la fois ; ainsi cp -rvi Document/en201a ~/cours permet de de copier le répertoire en201a situé dans ./Document vers /home/user/cours.

user@ordi:~$ ls
Books   Code   Documents               Examples    gtk-cours.pdf  john-1.7.2         Modèles  Public
Bureau  cours  driver_wifi_80211g.zip  goldie.avi  Images         john-1.7.2.tar.gz  Musique  Vidéos
user@ordi:~$ cp -rvi Documents/en201a/ ~/cours
`Documents/en201a/` -> '/home/user/cours/en201a'
`Documents/en201a/en201a3_v2.pdf` -> '/home/user/cours/en201a/en201a3_v2.pdf'
`Documents/en201a/en201a4_v2.pdf` -> '/home/user/cours/en201a/en201a4_v2.pdf'
`Documents/en201a/en201a3_v1.pdf` -> '/home/user/cours/en201a/en201a3_v1.pdf'
user@ordi:~$ ls cours/
en201a

Les 3 options citées précédemment ne sont pas inutiles puisque qu'on les retrouve dans beaucoup d'autres commandes pour le même usage.

La fonction rm

La fonction rm, comme remove, permet de supprimer définitivement un fichier. Attention rm ne demande aucune confirmation et une fois que le fichier est supprimé il est impossible de le récupérer. Donc il faut être très prudent lorsqu'on utilise rm. Tip : l'utilisation de rm -i permet d'éviter les accidents aussi je conseille vivement de toujours utiliser rm -i à la place de rm, on peut même aller jusqu'à faire un alias dans son bashrc.
Exemple :

user@ordi:~$ ls Documents/
el201  en201a  in201  john-1.7.2.tar.gz  ma201  ma211_annales.tar.gz  pr201.tar.gz  sh201
user@ordi:~$ rm -i Documents/john-1.7.2.tar.gz 
rm: remove regular file `Documents/john-1.7.2.tar.gz`? oui
user@ordi:~$ ls Documents/
el201  en201a  in201  ma201  ma211_annales.tar.gz  pr201.tar.gz  sh201

NB : rm ne peut pas détruire un répertoire, il faut utiliser rmdir qui permet de supprimer un répertoire vide. Si l'on veut effacer un répertoire non-vide il faut utiliser l'option -R de rm.
Quelques options utiles à savoir :

  • rm -f : force le système à effacer le fichier et passe-outre les vérifications (comme avec l'option i par exemple). Attention soyez prudent !
  • rm -R : permet d'effacer un répertoire.

L'étoile de la mort

Maintenant que l'on sait copier et supprimer des fichiers on va s'intéresser au méta-caractères. "Mais qu'est ce que c'est ?" Ce sont des caractères spéciaux qui représentent plusieurs autres caractères. Pour mieux voir leur utilité je vais les tester sur le dossier suivant :

user@ordi:~$ ls
test1  test2  test3  testA  testF  testAZ

Ces caractères sont les suivants :

  • [] : Les crochets permettent de dire que le caractère à la place des crochet doit être dans la liste des caractères entre les crochets. Exemple :

    user@ordi:~$  ls test[12]
    test1  test2

    Pour désigner tous les caractères entre a et q par exemple on utilise le tiret :

    user@ordi:~$ ls test[A-Q] #équivalent à ls test[a-q]
    testA  testF
  • ? : Le point d'interrogation représente n'importe quel caractère. Il ne représente cependant pas le caractère vide. Exemple :
    user@ordi:~$ ls test?    #On cherche les fichier du nom de test suivi d`un seul caractère
    test1  test2  test3  testA  testF
    user@ordi:~$ ls test??   #Ici suivi de deux caractères
    testAZ
    user@ordi:~$ ls test???  #Ici de trois
    ls: test???: Aucun fichier ou répertoire de ce type
  • * : L'étoile. Le caractère le plus dangereux car il représente toutes les chaînes de caractères, y compris la chaîne vide "". Exemple :
    user@ordi:~$ ls test*    #tous les fichiers dont le nom commence par test.
    test1  test2  test3  testA  testAZ  testF
    user@ordi:~$ ls t*       #tous les fichiers dont le nom commence par t.
    test1  test2  test3  testA  testAZ  testF
    user@ordi:~$ rm *        #Attention : On supprime tous les fichiers sans demande de confirmation
    user@ordi:~$ ls          #On vérifie et le dossier est vide
    user@ordi:~$

    Comme on le voit l'étoile est dangereuse car sans faire attention on peut lancer $ rm -r * qui supprime tous les fichiers du répertoire courant sans confirmation. Alors, on ne le répétera jamais assez, faites attention avec l'étoile.

La fonction mv

mv comme move, permet de déplacer des fichiers et des dossiers. Ce qui veux bien dire que le fichier n'existe qu'en un seul exemplaire à la fin de la commande, par opposition à une copie.

man

Voici une section spéciale car man n'est pas une commande comme cp, cd, ls ou encore rm qui permet de naviguer sur son disque dur ou de toucher aux fichiers. Non man permet de consulter les pages de manuel et c'est très important; car dans 9 cas sur 10 lorque l'on se demande comment marche une commande ou encore quelles options permettent de copier un fichier tout en gardant les anciennes versions en backup, la réponse se touve dans la page man. Bien plus encore man contient également de l'aide précieuse pour le programmeur C ; car de nombreuses pages man sur les librairies standards existent. Essayez donc man printf ou encore man cp. Attention sur certaines distributions Linux, les pages man ne sont pas installées complètement; c'est le cas sur Ubuntu. Pour les installer il faut taper cette ligne de commande dans la console et saisir son mot de passe :

sudo apt-get install manpages manpages-dev manpages-posix manpages-posix-dev

Si vous n'êtes pas sous Ubuntu ou Debian, il faut utiliser le gestionnaire de paquets de votre distribution pour ça renseignez-vous soit sur le site de la distribution Linux en question soit sur google. Après avoir vu ces quelques commandes de base et appris à vous servir des pages man, vous voilà fin prêt à devenir un expert de la console un pur tétard bash ou encore un hardcore g33k qui code sous emacs en console.

Et pour finir commence à te former tout seul : man man !

Tutoriel Subversion

Introduction

C'est bon, vous vous lancez avec quelques amis dans un projet de programation. Enfin, vous allez vous tapez vos quelques milliers de codes, passez vos aprem' les yeux collés sur votre écrans et vos soirées à bouffer des pizzas en débugant ce que vous avez fait dans la journée. C'est beau ! Seul problème : vous n'allez pas bosser tous ensemble sur le même PC ou sur des fichiers entièrement différents... Dans ces cas là, intégrer les modifications de chacun devient vraiment la galère et demande encore plus de travail que le « simple » debugage.
Pour régler cette difficulté, il existe un petit système « magique », Subversion, permettant de garder sur un serveur les différentes versions de votre projet. Grâce à ça, vous pourrez partagez les sources rapidement et facilement (il suffira de se connecter au serveur pour tout récupérer). Mais le principal intérêt de Subversion est de faire des mises à jour rapides et simples de vos sources en fonction des modifications faites par les autres membres de votre groupe. Voilà donc quelques bases pour son utilisation.

Créer un Repository

La première chose à faire est de créer un Repository, c'est à dire le dossier dans lequel vous stockerez les différentes versions de votre projet. Le serveur le plus connu pour le créer est SourceForge. Vous pouvez aussi voir avec le Club*Nix si il y a moyen de s'arranger.
De manière générale, pour créer un repository, la commande est :

$~ svnadmin create svn.mad/projet/repas

Il vous reste maintenant à y importer vos dossiers et fichiers :

$~ svn import bouffe svn.mad/projet/repas -m "Premier commit"
 
 
Adding    bouffe/viande/steak.c
Adding    bouffe/viande/jambon.c
Adding    bouffe/garniture/haricot.c
Adding    bouffe/garniture/frite.c
Adding    bouffe/menu.c
 
Commited revision 1

Cette commande a copié les différents fichiers contenu dans le dossier bouffe sur le serveur SVN dans le repository projet/repas en laissant comme commentaire qu'il s'agit de premier commit.
La commande import ne sert qu'à la création du repository. Nous verrons plus loin comment y rajouter d'autres fichiers.

Pour savoir ce qui se trouve dans le repository, on utilise la commande list :

$~ svn list svn.mad/projet/repas/
 
viande/
garniture/
menu.c

Enfin, pour récupérer les fichiers sur un SVN pour la toute première fois, on utilise la commande checkout :

$~ ls
projet1/ projet2/
 
$~ svn checkout svn.mad/projet/repas/
A    repas/viande/steack.c
A    repas/viande/jambon.c
A    repas/garniture/haricot.c
A    repas/garniture/frite.c
A    repas/menu.c
Checked out revision 42
 
$~ ls
projet1/ projet2/ repas/

Le checkout ne doit être fait qu'une seule fois : la première fois que vous récupérez les fichiers. Par la suite, il faut utiliser le commande update qui sera décrite un peu plus loin.

Passons aux choses sérieuses

Maintenant qu'on a vu comment se créer un repository et comment on le remplit pour la première fois. Maintenant, vous avez bosser sur votre projet, vous y avez ajouté ou supprimé des fichiers, vous y avez apporté des modifications... Mais tout ça seulement de votre côté et vous voulez bien que tout votre groupe puisse en profiter et vous aimeriez profiter des changements qu'ils ont fait.

Etat du repository et de votre copie

Pour connaître l'état du repository comparé à l'état de votre copie de travail vous avez les commandes status et diff, la première indiquant quel est le statut de chaque document de votre copie par rapport au repository et la seconde indique quelles sont les différences entre les documents de votre copie et le reste. Ainsi, en utilisant status :

$~ svn status
 
A    viande/gigot.c
D    viande/saucisse.c
C    garniture/frite.c
M    garniture/haricot.c

Petite explication des items précédents les noms de fichiers :

  • A signifie que le fichier sera ajouté au repository à votre prochain commit
  • D signifie que votre prochain commit supprimera le fichier
  • C signifie qu'il y a un conflit entre l'état de votre copie du fichier et son état dans le repository
  • M signifie que vous avez fait des changements dans le fichier
  • Le conflit signifie que vous avez fait des modifications sur le fichier mais que entre temps, avant que vous l'ayez transmis au serveur SVN, quelqu'un a modifié le même fichier et que ces changements sont en conflits avec ce que vous avez fait.

    Le diff permet de repérer les différences entre la dernière version du repository et votre copie :

    $~ svn diff
     
    Index: menu.c
    =========================
    --- menu.c (revision 21)
    +++ menu.c (working copy)
    @@ -5,15 +5,17 @@
    int main(void){
    -    addHaricot(5);
    +    addFrite(5);
    +    addSteack(5);
        return 0;
    }

    Ici, on voit que le code de la fonction main dans le fichier menu.c a été modifié : on lui a retiré 5 portions de haricot pour lui rajouter 5 portions de frite et 5 steacks. Grace à diff vous pouvez ainsi facilement créer des patchs :

    $~ svn diff > patch

    Se mettre à jour

    Mettre à jour sa copie de travail se fait en une seule commande, update, qui synchronise votre copie avec la dernière version disponible sur le svn :

    $~ svn update
     
    U    menu.c
    U    garniture/frite.c
    Updated to revision 43.

    Modifier la copie locale

    Bon je vais pas vous apprendre à modifier un fichier : vous tapez, vous enregistrez et c'est fini. Les problèmes arrivent quand vous voulez ajouter, supprimer ou déplacer un fichier ou un dossier. Il faut en effet tenir au courant le SVN que vous allez effectuer ce genre de modif'. Pour cela, on utilise les commandes add, delete, mkdir, copy et move.

  • $~ svn add garniture/pates.c va ajouter le fichier au prochain commit
  • $~ svn delete viande/saucisse.c supprimera le fichier au prochain commit
  • $~ svn mkdir dessert créera le dossier dessert au prochain commit
  • Les commandes copy et move ont des noms assez descriptifs et font la même chose que les commandes bash du même nom ;)

    Faire le commit (enfin...!)

    Avant de faire un commit, SVN vérifiera en premier qu'il n'y a pas de conflits entre votre copie et la dernière version présente sur le SVN. Si il y en a vous avez deux possibilités : soit vous annulez tous les changements que vous avez fait dans les fichiers en conflit, soit vous changez les fichiers juste au endroits genants. L'annulation pure et simple des modifications que vous avez faites passe par $~ svn revert file.c

    Une fois que vous avez réglé tous les conflits, il faut le signaler au SVN par $~ svn resolved file.

    Vous pouvez maintenant atteindre le Sacré Graal : transférer vos modifications sur le SVN :

    $~ svn commit -m "Nouveau commit"

    L'option -m permet d'associer un commit au message afin de décrire vite fait vos changements aux autres membres de votre équipe.

    Conclusion

    Vous avez maintenant des bases concernant l'utilisation de SVN. J'ai précisé les différentes actions de base qu'il est possible d'invoquer à partir d'une ligne de commande pour que vous sachiez un peu ce qui se passe. Maintenant, il existe de nombreux clients Subversion (tant sous Windows que sous Linux) comme SmartSVN pour n'en citer qu'un.
    Rappelez-vous : vous êtes nombreux à travailler sur un projet logiciel ? Utilisez SVN pour ne plus perdre du temps à vous transférer les fichiers via une clé USB puis à repérer les différences entre tous les fichiers...

    (Tuto réalisé par MAD[dollm@esiee.fr])

    Web

    Expérience avec le PSR-0 : Drupal, Zend Framework 2, Symfony 2

    Introduction

    Le PSR-0 est une norme du PHP Framework Interop Group basée sur les espaces de noms (namespaces, PHP >= 5.3) pour permettre la création de composants interopérables et chargeables (par autoloading) sans efforts.

    Ceci est une petite expérience permettant de montrer l’intérêt du PSR-0.

    Il faut un niveau un peu avancé en PHP objet pour bien comprendre cet article.

    Le projet

    Dans cette expérience, nous allons créer une petite application la plus robuste possible en utilisant des composants de différents frameworks.

    Le projet choisi est une application pour uploader un fichier sur un serveur en SSH.

    Composants (Packages) et dépendances

    Choix des composants

    Base Silex\Silex Micro-framework basé sur Symfony 2 avec une bonne intégration de Twig
    ServiceManager Zend\ServiceManager ServiceManager simple à utiliser à partir d’un array de configuration
    Formulaires Zend\Form Utile pour le rendu de formulaire et facilite la validation des données
    Transfert de fichiers Drupal\Core\FileTransfer\SSH Implémentation de FileTransfer de Drupal 8 utilisé pour les mises à jour. Facilement remplaçable par FTP ou Local
    Templates Twig\Twig Système de templates pour les vues MVC de plus en plus répandu
    Thème de base Bootstrap Style prêt à être utilisé pour qu’on puisse se concentrer sur le code.

    On va voir plus loin comment le PSR-0 nous simplifie la vie pour utiliser tous ces différents composants.

    Gestion des dépendances

    Pour la gestion des dépendances et la génération de l’autoloader, on utilisera Composer.

    Arborescence du projet

    J’ai choisis d’utiliser 2 fichiers php à la Zend pour la configuration de l’application.
    Le fichier config/global.config.php retourne un array avec la configuration globale à écrire dans le référentiel de code.
    Le fichier config/local.config.php contient la configuration renseignée par l’utilisateur de l’application. Il n’est pas ajouté dans le référentiel de code.
    Les fichiers uploadés seront stockés dans le dossier /upload.
    Le dossier /views contiendra les vues Twig.

    /config/global.config.php
    /config/local.config.php
    /css
    /img
    /js
    /upload
    /vendor
    /views
    /composer.json
    /index.php

    Mise en place du projet

    Création du composer.json

    {
       "name" : "Simple Uploader",
       "description" : "PSR0",
       "type" : "application",
       "authors" : [{
               "name" : "Philippe Lewin",
               "email" : "philippe.lewin @ gmail.com"
           }
       ],
       "keywords" : [
           "demo",
           "psr0"
       ],
       "homepage" : "http://www.clubnix.fr",
       "license" : [
           "GPL-3.0+"
       ],
       "require" : {
           "easyrdf/easyrdf" : "0.8.0-beta.1",
           "twig/twig" : ">=1.8,<2.0-dev",
           "symfony-cmf/routing" : ">=1.0.1",
           "php" : ">=5.3.3",
           "drupal/drupal" : "8.x-dev",
           "kriswallsmith/assetic" : "v1.1.0-alpha1",
           "silex/silex" : "1.0.*@dev",
           "zendframework/zendframework" : ">=2.1.0"
       },
    
       "minimum-stability" : "dev",
       "repositories" : [
               "type" : "vcs",
               "url" : "git://github.com/drupal/drupal.git"
           }, {
               "type" : "vcs",
               "url" : "git://github.com/kriswallsmith/assetic.git"
           }, {
               "type" : "vcs",
               "url" : "git://github.com/symfony-cmf/Routing.git"
           }
       ],
       "config" : {
           "process-timeout" : 3000
       },
       "minimun-stability" : "dev"
    }

    Installation des dépendances

    $ composer install

    Loading composer repositories with package information
     Installing dependencies 
     - Installing symfony/yaml (v2.2.0)
        Loading from cache
     - Installing psr/log (1.0.0)
        Loading from cache
     - Installing twig/twig (v1.12.1)
        Loading from cache
     - Installing doctrine/common (2.3.0)
        Loading from cache
     - Installing phpunit/php-text-template (dev-master 1eeef10)
        Cloning 1eeef106193d2f8c539728e566bb4793071a9e18
     - Installing phpunit/phpunit-mock-objects (1.2.x-dev 8e9d897)
        Cloning 8e9d897b39ca6310ccc2d81b8f29cabd5ce12786
     - Installing phpunit/php-timer (1.0.x-dev ecf7920)
        Cloning ecf7920b27003a9412b07dad79dbb5ad1249e6c3
     - Installing phpunit/php-token-stream (dev-master c25dd88)
        Cloning c25dd88e1592e66dee2553c99ef244203d5a1b98
     - Installing phpunit/php-file-iterator (dev-master 2deb24c)
        Cloning 2deb24c65ea78e126daa8d45b2089ddc29ec1d26
     - Installing phpunit/php-code-coverage (1.2.x-dev b0ec2d0)
        Cloning b0ec2d014fe497315aad876c6289a38fd4c075ff
     - Installing phpunit/phpunit (3.7.15)
        Loading from cache
     - Installing easyrdf/easyrdf (0.8.0-beta.1)
        Loading from cache
     - Installing symfony/http-foundation (v2.2.0)
        Loading from cache
     - Installing symfony/event-dispatcher (v2.2.0)
        Loading from cache
     - Installing symfony/http-kernel (v2.2.0)
        Loading from cache
     - Installing symfony/routing (v2.2.0)
        Loading from cache
     - Installing symfony-cmf/routing (dev-master 1d9cff6)
        Cloning 1d9cff60cf3690831b0555dbc1f4b1b81cd50de3
     - Installing symfony/process (2.1.x-dev 3b1b54a)
        Cloning 3b1b54a6148e505132e397ae05cbf58c9f6b9f29
     - Installing kriswallsmith/assetic (v1.1.0-alpha1)
        Loading from cache
     - Installing guzzle/common (v3.1.0)
        Loading from cache
     - Installing guzzle/stream (v3.1.0)
        Loading from cache
     - Installing guzzle/parser (v3.1.0)
        Loading from cache
     - Installing guzzle/http (v3.1.0)
        Loading from cache
     - Installing symfony/translation (dev-master 4c354b0)
        Cloning 4c354b0f1bb4278c0179a38f8ef850a06f943cc3
     - Installing symfony/validator (v2.2.0)
        Loading from cache
     - Installing symfony/serializer (v2.2.0)
        Loading from cache
     - Installing symfony/dependency-injection (v2.2.0)
        Loading from cache
     - Installing symfony/class-loader (v2.2.0)
        Loading from cache
     - Installing drupal/drupal (8.x-dev ca665f7)
        Cloning ca665f7be315aedc499228b156bd194982d1cd74
     - Installing pimple/pimple (dev-master v1.0.2)
        Cloning v1.0.2
     - Installing silex/silex (1.0.x-dev 7ae0fd8)
        Cloning 7ae0fd8b871eaebf95b856940c47679da40666c6
     - Installing zendframework/zendframework (dev-master 2e22109)
        Cloning 2e22109954ccbc43b9c97e4d47b7b97129e3b5de
    phpunit/php-code-coverage suggests installing ext-xdebug (>=2.0.5)
    phpunit/phpunit suggests installing phpunit/php-invoker (>=1.1.0,<1.2.0)
    symfony/http-kernel suggests installing symfony/browser-kit (2.2.*)
    symfony/http-kernel suggests installing symfony/config (2.2.*)
    symfony/http-kernel suggests installing symfony/console (2.2.*)
    symfony/http-kernel suggests installing symfony/finder (2.2.*)
    symfony/routing suggests installing symfony/config (2.2.*)
    kriswallsmith/assetic suggests installing leafo/lessphp (Assetic provides the integration with the lessphp LESS compiler)
    kriswallsmith/assetic suggests installing leafo/scssphp (Assetic provides the integration with the scssphp SCSS compiler)
    kriswallsmith/assetic suggests installing ptachoire/cssembed (Assetic provides the integration with phpcssembed to embed data uris)
    symfony/translation suggests installing symfony/config (2.2.*)
    symfony/validator suggests installing symfony/locale (2.2.*)
    symfony/validator suggests installing symfony/config (2.2.*)
    symfony/dependency-injection suggests installing symfony/config (2.2.*)
    silex/silex suggests installing symfony/browser-kit (>=2.1,<2.4-dev)
    silex/silex suggests installing symfony/css-selector (>=2.1,<2.4-dev)
    silex/silex suggests installing symfony/dom-crawler (>=2.1,<2.4-dev)
    silex/silex suggests installing symfony/form (>= 2.1.4,<2.4-dev)
    zendframework/zendframework suggests installing zendframework/zendservice-recaptcha (ZendService\ReCaptcha for rendering ReCaptchas in Zend\Captcha and/or Zend\Form)
    zendframework/zendframework suggests installing zendframework/zendpdf (ZendPdf for creating PDF representations of barcodes)
    zendframework/zendframework suggests installing ircmaxell/random-lib (Fallback random byte generator for Zend\Math\Rand if OpenSSL/Mcrypt extensions are unavailable)
    zendframework/zendframework suggests installing ext-intl (ext/intl for i18n features (included in default builds of PHP))
    zendframework/zendframework suggests installing doctrine/annotations (Doctrine Annotations >=1.0 for annotation features)
    zendframework/zendframework suggests installing ocramius/proxy-manager (ProxyManager to handle lazy initialization of services)
    Writing lock file
    Generating autoload files

    Téléchargement de Twitter Bootstrap

    http://twitter.github.io/bootstrap/assets/bootstrap.zip
    Copier les dossiers css, img et js dans le dossier du projet
    Création des fichiers de configuration et d’index.php

    config/global.config.php

    <?php
    return array (
       'upload-form' => array(
       // description du formulaire ici
       ),
       'factories' => array(
       // factories pour le ServiceManager de Zend
       ),
       'invokables' => array (
       // invokables pour le Service Manager de Zend
       ),
    );

    config/local.config.php

    <?php
    return array(
    );

    Fichier index.php

    Dans la première version d’index.php on fait l’inclusion de vendor/autoload.php qui est l’autoloader généré par Composer. Composer a généré ce fichier en se basant sur les déclarations “PSR-0” des composer.json des différents packages du dossier vendor. Grâce à l’autoloader dans vendor/autoload.php, lorsqu’une classe est utilisée, le fichier .php contenant la classe sera automatiquement chargée depuis les sources du bon package.
    Toujours dans ce fichier index.php, la configuration est aussi chargée et le ServiceManager est configuré.
    On en profite pour réaliser un “Hello World” en affichant un message lorsqu’on arrive sur la route “/”.

    <?php
    require_once 'vendor/autoload.php';
     
    use Zend\ServiceManager\Config as ServiceManagerConfig;
    use Zend\ServiceManager\ServiceManager;
     
    $globalConfig = require_once 'config/global.config.php';
    $localConfig  = require_once 'config/local.config.php';
     
    $config = array_merge_recursive($globalConfig, $localConfig);
     
    $sm = new ServiceManager(new ServiceManagerConfig($config));
     
    $app = new Silex\Application();
     
    $app->get('/', function () {
        return "Hello World";
    });
     
    $app->run();

    Premier test de l’application

    On utilise le serveur intégré à php 5.3
    Dans le dossier du projet :
    php -S 127.0.0.1:8080

    Ouvrir le navigateur à l’adresse http://127.0.0.1:8080/ “Hello World” devrait s’afficher.

    Création des vues Twig

    Intégration de Twig dans notre application Silex

    On commence par ajouter le TwigServiceProvider à l’application Silex pour supporter les vues Twig.
    Pour bien faire, on va utiliser une factory du service manager pour contenir l’étape de configuration de notre objet Silex\Application.

    Au passage, on va activer le mode debug de Silex au cas où.

    Dans global.config.php :

    'factories' => array(
        'App' => function($sm) {
            $app = new \Silex\Application();
            $app['debug'] = true;
     
            $app->register($sm->create('TwigServiceProvider'), array('twig.path' => __DIR__.'/../views'));
     
            return $app;
        },
        ),
        'invokables' => array (
            'TwigServiceProvider'        => 'Silex\Provider\TwigServiceProvider',
        ),

    Dans index.php, on remplace
    $app  = new Silex\Application();
    par
    $app  = $sm->create('App');

    Création de notre template

    views/template.twig

    <!DOCTYPE html>
    <html lang="fr">
     <head>
        <meta charset="utf-8">
        <title>Simple Upload Form</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="description" content="Simple Upload Form">
        <meta name="author" content="Philippe Lewin">
        <link href="css/bootstrap.min.css" rel="stylesheet">
        <link href="css/custom.css" rel="stylesheet">
        <link href="css/bootstrap-responsive.min.css" rel="stylesheet">
    </head>
    <body>
       <div class="container">
       {% block content %}{% endblock %}
       </div>
       <script src="js/bootstrap.min.js"></script>
    </body>
    </html>

    css/custom.css

    body {
       padding-top: 40px;
       padding-bottom: 40px;
       background-color: #f5f5f5;
    }
    .form-upload {
       max-width: 300px;
       padding: 19px 29px 29px;
       margin: 0 auto 20px;
       background-color: #fff;
       border: 1px solid #e5e5e5;
       -webkit-border-radius: 5px;
       -moz-border-radius: 5px;
       border-radius: 5px;
       -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
       -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
       box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
    }
    .form-upload .form-upload-heading,
    .form-upload input[type="text"],
    .form-upload input[type="password"] {
       font-size: 16px;
       height: auto;
       margin-bottom: 15px;
       padding: 7px 9px;
    }

    Le template est basé sur l’exemple “sign-in” http://twitter.github.io/bootstrap/examples/signin.html

    Création des blocs index.twig et thanks.twig

    index.twig contient les éléments affichés dans la page d’accueil (le formulaire) et thanks.twig contient un message de remerciement pour informer à l’utilisateur que l’upload c’est bien passé.

    Je ne me casse pas la tête sur l’internationalisation pour ce petit projet.

    index.twig

    Pour l’instant, on n’a pas encore défini le formulaire, ce fichier est pour l’instant assez vide.

    {% extends "template.twig" %}
     
    {% block content %}
       <!-- ... code du formulaire qui va venir … -->
    {% endblock %}

    thanks.twig

    {% extends "template.twig" %}
     
    {% block content %}
       <h2>Merci</h2>
       <p>Le fichier a bien été téléchargé sur le serveur.<p>
    {% endblock %}

    Test avec une vue Twig

    On remplace la route / dans le fichier index.php :

    $app->get('/', function () use ($app) {
       return $app['twig']->render('index.twig', array (
           // modèle à fournir à la vue
       ));
    });

    On remarque que la closure doit déclarer utiliser $app pour pouvoir utiliser twig.

    Lorsqu’on aura notre formulaire de construit, il faudra le passer à la vue via l’array en paramètre de la méthode render.

    Si tout va bien jusque là, une page planche devrait s’afficher et le code HTML doit être généré.

    Mise en place de notre formulaire Zend Form

    Éléments du formulaire

    Notre formulaire va comporter un champ texte pour le login ssh, un champ password pour le mot passe, un champ fichier (pour sélectionner le fichier à uploader) et un bouton valider.

    Nous allons utiliser Zend\Form\Factory pour créer l’objet formulaire à partir d’un array de configuration. Il faudra donc ajouter Zend\Form\Factory au service manager.

    Modification dans global.config.php

    'upload-form' => array(
           'hydrator' => 'Zend\Stdlib\Hydrator\ArraySerializable',
           'attributes' => array('class' => 'form-upload'),
           'elements' => array (
               array (
                   'spec' => array (
                       'name'       => 'username',
                       'attributes' => array(
                           'type'  => 'text',
                           'placeholder' => 'Username',
                           'class'       => 'input-block-level',
                           'required'    => 'required',
                       ),
                   ),
               ),
               array (
                   'spec' => array (
                       'name'       => 'password',
                       'attributes' => array (
                           'type'  => 'password',
                           'placeholder' => 'Password',
                           'class'       => 'input-block-level',
                           'required'    => 'required',
                       ),
                   ),
               ),
               array (
                   'spec' => array (
                       'type' => 'Zend\Form\Element\File',
                       'name' => 'file',
                       'attributes' => array(
                           'class' => 'input-block-level',
                           'required' => 'required',
                       ),
                   ),
               ),
               array (
                   'spec' => array (
                       'name' => 'send',
                       'attributes' => array (
                           'type'  => 'submit',
                           'value' => 'Envoyer',
                           'class' => 'btn btn-large btn-primary',
                       ),
                   ),
               ),
           ),
       ),
     
    // …
     
    'invokables' => array (
           'FormFactory'                => 'Zend\Form\Factory',
           'TwigServiceProvider'        => 'Silex\Provider\TwigServiceProvider',
    ),

    On remarque que j’utilise l’attribut HTML5 placeholder à la place de labels.

    Création du formulaire dans l’index

    On peut maintenant créer notre formulaire à partir de la configuration.

    Dans index.php, juste avant la création de l’application :
    $form = $sm->get('FormFactory')->createForm($config['upload-form']);

    On modifie aussi le contrôleur pour la route “/”, il doit fournir le formulaire à la vue :

    $app->get('/', function () use ($app, $form) {
       $form->prepare();
       return $app['twig']->render('index.twig', array (
           'uploadForm' => $form,
       ));
    });

    Utiliser les aides de vue dans Twig

    Et là c’est la catastrophe. Pour afficher le formulaire Zend, on dispose d’aides de vue (les classes Zend\Form\View\Helper\Form*) mais pour une vue Zend View. Inversement, on dispose d’helpers Twig pour des formulaires Symfony 2. On n’utilise pas Zend View ni de formulaire Symfony 2 actuellement donc comment allons nous faire ?

    La doc de Twig est une grande aide :
    http://twig.sensiolabs.org/doc/advanced.html

    A première vue, la solution la plus simple est de faire de nos View Helper des variables Twig globales. C’est ce que nous allons faire.

    Nous allons utiliser ces 3 ViewHelpers : Zend\Form\View\Helper\{Form, FormElementErrors, FormInput}

    Ajout des invokables :

        'invokables' => array (
           'FormFactory'                => 'Zend\Form\Factory',
           'ViewForm'                   => 'Zend\Form\View\Helper\Form',
           'ViewFormElementErrors'      => 'Zend\Form\View\Helper\FormElementErrors',
           'ViewFormInput'              => 'Zend\Form\View\Helper\FormInput',
           'TwigServiceProvider'        => 'Silex\Provider\TwigServiceProvider',
       ),

    Injection des variables globales depuis la factory App

        'factories' => array(
           'App' => function($sm) {
               $app = new \Silex\Application();
               $app['debug'] = true;
     
               $app->register($sm->create('TwigServiceProvider'), array('twig.path' => __DIR__.'/../views'));
     
               $twigGlobalHelpers = array(
                   'form'               => 'ViewForm',
                   'formInput'          => 'ViewFormInput',
                   'formElementErrors'  => 'ViewFormElementErrors',
               );
     
               foreach($twigGlobalHelpers as $helperName => $helperInvokable) {
                   $app['twig']->addGlobal($helperName, $sm->get($helperInvokable));
               }
     
               return $app;
           },
       ),

    Le block index qui affiche le formulaire

    Maintenant que les aides de vues sont ajoutés et que le contrôleur fourni à la vue l’objet formulaire, nous pouvons finir le code Twig :

    index.twig

    {% extends "template.twig" %}
     
    {% block content %}
       {{ form.openTag(uploadForm)|raw }}
       <h2 class="form-upload-heading">Envoyer un fichier</h2>
       {% for i in ['username', 'password', 'file'] %}
           {% set element = uploadForm.get(i) %}
           {{ formInput.render(element)|raw }}
           {{ formElementErrors.render(element)|raw }}
           <br />
       {% endfor %}
     
       {{ formInput.render(uploadForm.get("send"))|raw }}
     
       {{ form.closeTag(uploadForm)|raw }}
    {% endblock %}

    Twig protège toutes les sorties affichées, comme les View Helpers Zend le font déjà, on doit utiliser le filtre “raw” pour empêcher un deuxième niveau de htmlentities().

    Tester l’affichage du formulaire

    Le formulaire devrait s’afficher lorsqu’on charge la page “/”.

    Traitement du formulaire d’upload

    Ajout d’un nouveau contrôleur pour cette route

    Étant donné que rien n’a été précisé, le formulaire est en méthode POST avec comme target la même page.

    Pour pouvoir répondre à la soumission du formulaire on ajoute un contrôleur pour la route en post dans index.php :

    $app->post('/', function () use ($app, $form, $config) {
       // Code traitement du formulaire ici
       return $app['twig']->render('thanks.twig');
    });

    Validation des du formulaire et réaffichage du formulaire si erreur

    Dans le contrôleur qu’on vient de créer, on injecte les paramètres POST et FILES dans l’objet formulaire et on vérifie si ces données valident le formulaire.

    Si les paramètres de la requête ne valident pas le formulaire, on réaffiche le formulaire en appelant le premier contrôleur.

      $parameters = array_merge_recursive($_POST, $_FILES);
       $form->setData($parameters);
       if (!$form->isValid()) {
           $subRequest = Request::create('/', 'GET');
           return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
       }

    Attention à bien ajouter ces lignes use en haut de index.php.

    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpKernel\HttpKernelInterface;

    Envoi du fichier par SSH

    Pour utiliser les classes FileTransfer de Drupal, je fais appel à la méthode statique factory de la classe que je veux instancier. Cette méthode prend 2 paramètres : un chemin “jail” et un array avec les identifiants de connexion. J’ai pris soin de nommer les noms des champs du formulaire comme l’attend cette méthode pour ne pas passer par une étape de conversion.

    Dans la configuration local.config.php

    return array(
       'file-transfer' => array(
           'class' => 'Drupal\Core\FileTransfer\SSH',
           'jail'  => realpath(__DIR__ . '/../upload'),
       ),
    );

    Code complet du nouveau contrôleur

    $app->post('/', function () use ($app, $form, $config) {
       $parameters = array_merge_recursive($_POST, $_FILES);
       $form->setData($parameters);
       if (!$form->isValid()) {
           $subRequest = Request::create('/', 'GET');
           return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
       }
       $validatedData = $form->getData();
       $fileTransfer = $config['file-transfer']['class']::factory($config['file-transfer']['jail'], $validatedData);
       $fileTransfer->copyFile($validatedData['file']['tmp_name'], $config['file-transfer']['jail'] . '/' . uniqid());
       return $app['twig']->render('thanks.twig');
    });
    Fichier attachéTaille
    Image icon simple-upload-html.png12.41 Ko
    Fichier simple-upload-mockup.svg13.43 Ko

    Utilisations de logiciels libres

    e Libre, sous Linux, BSD ... et même Windows:

    Guide de survie TCP/IP : OpenSSH, Netcat et Socat

    Vous avez probablement déjà été dans une situation plutôt inconfortable où votre environnement joue contre vous. Besoin de transférer un fichier entre deux machines pas accessibles directement ou sans utiliser SCP... SSH sur une machine au ClubNix pour imprimer un rapport depuis le Wi-Fi de l'ESIEE... Accéder à un site web sur port 8443 (la planif!) alors que seul le 80 est ouvert... Connecter entre elles deux machines derrière des NATs différents... Devoir streamer de la vidéo en urgence sur un port bloqué par le hostspot du coin à travers un VPN SSH... Bref, n'importe quelle situation complètement loufoque et improbable d'un jour lambda et parfaitement normal.

    La bonne nouvelle, c'est que la plupart des outils pour résoudre ce genre de problèmes existent déjà sur votre distribution *nix préférée !
    Mieux encore, dans la plupart des cas, un simple accès SSH est plus que suffisant pour faire à peu près n'importe quoi.
    Nous allons voir comment utiliser quelques unes des fonctionnalités de ces outils pour vous simplifier la vie, et pourquoi pas apprendre quelques trucs au passage !

    Les outils

    OpenSSH

    OpenSSH est l'implémentation standard de SSH fournie sur la plupart des distributions Linux. Dans la forme que tout le monde connait, on peut l'utiliser pour simplement ouvrir un shell sur une machine distante par un tunnel chiffré. Ce qui peut être un peu plus intéressant est que ce tunnel chiffré peut aussi servir de base pour beaucoup d'autres choses, par exemple de la redirection de ports, fenêtres, applications, ou même mettre en place un tunnel IP, donc une sorte de VPN.
    Pour une utilisation de base de SSH, il suffit d'indiquer l'utilisateur et hôte distant séparés d'une arobase.

    Netcat

    Le "Couteau suisse TCP/IP", netcat permet de manipuler des flux de données par TCP ou UDP, et peut être très utile pour des scripts ou utilisé en conjonction avec d'autres applications. Il en existe deux implémentations communes, celle de OpenBSD et celle de GNU, qui varient légèrement d'un point de vue de la syntaxe. J'utilise ici la version d'OpenBSD.
    La syntaxe de base est d'indiquer à quel hôte distant et port se connecter, en indiquant si nécessaire des options de connexion en plus.

    Socat

    Une sorte de remake de Netcat avec beaucoup plus de fonctionnalités, mais moins courant. Il permet d'effectuer des opérations plutôt complexes en juste une ligne. Plus d'informations sur la page officielle.
    Socat est beaucoup plus complexe que les deux autres outils, mais fonctionne globalement en spécifiant deux flux (qui peuvent être des fichiers, connexions, sockets, ou autre..), et en transférant des données de l'un à l'autre.

    Les protocoles

    Avant de commencer, faisons un rapide point sur les protocoles couramment utilisés que nous allons manipuler. Il est beaucoup plus simple de comprendre le fonctionnement des outils en sachant comment ils communiquent.

    IP aka. Internet Protocol

    Le protocole le plus utilisé sur Internet, IPv4 (ou v6) permet d'envoyer des données d'une machine à une autre en utilisant leur adresse IP (par exemple, 147.215.81.100 pour le club !). Il suffit d'envoyer un message IP à votre routeur, et il se chargera de l’emmener au bon endroit. Ici, c'est tout ce qui nous intéresse.

    TCP

    La plupart du temps, on ne veut pas envoyer un seul message, mais établir une connexion pour communiquer. C'est ce que fait TCP : il permet de négocier plusieurs connexions avec des machines distantes pour leur envoyer des données.
    Le premier axe important est le multiplexage : plusieurs applications peuvent vouloir communiquer en même temps ! Pour cela on utilise des numéros ports (jusqu'à 65535) : chaque connexion porte un port source aléatoire, et un de destination. Ainsi votre OS peut différencier la connexion au site web du club (vers le port 80 ou 443) de celle au serveur Jabber (port 5222).

    L'autre point important est la négociation de connexion. Ceci est fait en utilisant le three-way handshake (ou triple poignée de main) : le client envoie une demande de connexion au serveur, qui lui répond pour la valider, avant de renvoyer un message pour confirmer qu'elle est établie. C'est sur ce principe que les pare-feu (surtout NAT) reposent pour ne permettre que les connexions sortantes. Le protocole TCP impose aussi d'autres contraintes, par exemple en demandant confirmation de la réception des messages, contrôlant le flot d'envoi des messages, ou vérifiant leur intégrité et ordre de réception, mais ce n'est pas très important pour nous pour l'instant.

    UDP

    TCP fait bien son travail, mais pour certaines applications, par exemple les jeux en réseau, ou la vidéo et la voix, il en fait trop !
    UDP est beaucoup plus simple, et ne permet que le multiplexage (par les numéros de ports) et la vérification des messages (un checksum). C'est un protocole dit sans-état : la connexion n'est pas explicitement ouverte ou fermée, on envoie juste des informations. Les applications peuvent ensuite gérer ces messages comme elles l'entendent.

    Quelques commandes pratiques de base

    Copier des fichiers avec OpenSSH

    Scénario : Vous faites des changements en local dans votre IDE et voulez les envoyer sur un serveur.
    La commande SCP marche plus ou moins comme un simple cp : source, puis destination, avec des options similaires. Il faut juste indiquer l'utilisateur et nom d'hôte en plus, et la copie est faite a partir de la Home.

    Exemples:

    	# Copie le fichier /home/fira/stuff.conf vers /etc/stuff.conf sur le serveur:
    	scp ~/stuff.conf root@serveur:/etc/
    	# Récupère le dossier public_html de votre home sur le serveur distant:
    	scp -r fira@serveur:public_html/ /srv/backup/siteweb/

    Forwarding X11 par SSH

    Scénario : Vous êtes dans un des clubs de l'ESIEE et devez imprimer votre rapport de TP à rendre pour hier. Pas de chance, les 5 salles infos de 50xx sont prises ! Il va falloir aller jusque là-bas et expliquer à Bureau que vous voulez squatter sa salle pour imprimer un rapport comme les 5 autres boulets qui attendent devant l'imprimante.
    Solution : imprimons-le d'ici. En bonus, il sera déjà prêt en arrivant devant l'imprimante.

    Q: Hein ?! COMMENT ?! Quelle est cette sorcellerie ?
    C'est simple : vous avez déjà accès aux postes par SSH.
    OpenSSH possède une option qui permet de faire passer le canal de données de X11, qui gère l'affichage, dans le tunnel. Ainsi l'affichage de l'application sera transporté directement jusqu'à une fenêtre sur votre machine.
    Bien sur, on pourrait imprimer le rapport directement depuis la ligne de commande mais.. Franchement, qui veut lire la doc ?

    	# Utiliser -Y demande le transport du canal X11
    	fira@clubnix$ ssh -fY loyauf@gemini2.esiee.fr firefox

    Q: Hein? C'est tout?
    Oui. Cette commande lancera "firefox" sur gemini2, en nous faisant parvenir l'interface graphique à travers le tunnel.
    Q: Et, si j'ai bien compris, ça marche pour virtuellement n'importe quelle application ?
    Oui.
    Q: Mais c'est génial !
    Oui !

    Attention cependant.
    En utilisant cette option, la connexion graphique est faite directement à travers le tunnel, ce qui est pratique mais pas forcément des plus adaptés. Pour des connexions lentes, ou par Internet de particulier, cela risque d'être très lent, et peut même planter toute la connexion (les paquets envoyés par SSH sont prioritaires en termes de QoS).
    Il existe pour ces cas là d'autres alternatives tels les VNC ou RDP (qui requièrent un serveur spécifique), NoMachine NX (qui requiert une installation globale et un serveur SSH), ou xpra (qui peut s'utiliser à travers SSH, en simple utilisateur, et intègre directement les fenêtres sans bureau virtuel. Magique.)

    Proxy avec OpenSSH

    Scénario : vous avez besoin d'accéder à un site web ou une application qui est bloqué depuis votre point d'accès (par exemple, accéder à un site interne depuis chez soi), mais avez un accès SSH sur une des machines qui peut, elle, lui accéder.

    Rien de plus simple:

     
    	# Crée un proxy SOCKS sur le port 9050
    	fira@laptop$ ssh -NfD 9050 fira@clubnix.fr

    Les options -Nf lancent ssh en arrière plan, ce qui permet de fermer la fenêtre. Pour l’arrêter, il faudrait ensuite le killer, par exemple avec htop ou autre. L'option -D crée un proxy SOCKS4 à travers le tunnel SSH : il faut alors configurer l'application pour utiliser "localhost" comme proxy sur le port 9050.
    Par exemple pour Firefox, en suivant : Editer > Préférences > Avancé > Réseau > Connexion > Préférences - cocher "Configuration manuelle", entrer le nom d'hôte et port sur la ligne SOCKS. Voilà.

    Reverse SSH ou passage de port inversé

    Scénario : vous avez temporairement besoin d’accéder à distance à un serveur derrière pare-feu pour votre projet à rendre demain matin !

    Pas de panique, OpenSSH est là :

    	# Fait un tunnel entre le port 22 de cette machine et le 2222 de l'hôte distant
    	fira@serveur$ ssh -NfR 2222:localhost:22 fira@maison.org
     
    	# A la maison:
    	fira@maison$ ssh -p 2222 localhost
    	Last login: Sat Jun   8 90:01:42 2013
    	fira@serveur$

    Attention: cette méthode n'est pas pratique de façon permanente : si jamais serveur perd la connexion à maison, le tunnel sera coupé et il faudra le relancer. Des outils tels que autossh, en y ajoutant une authentification par clé publique, permettent de se reconnecter automatiquement.

    Passage de ports

    On peut aussi faire l'inverse: demander à ce qu'un port local soit passé à une machine distante.

    	# Redirige notre port 2222 vers le port 22 de traxix en partant de clubnix.fr
    	fira@laptop$ ssh -NfL 2222:traxix:22 fira@clubnix.fr
    	fira@laptop$ ssh -p 2222 localhost
    	Last login: Sun Jun  42 11:12:13 2014
    	fira@traxix$

    Pour les cas plus compliqués

    Les commandes que nous avons vu plus haut sont très pratiques, mais elles ont tous en commun le fait d'utiliser OpenSSH. Certes, ça fonctionne, mais ce n'est pas toujours quelque chose de disponible ou l'outil le plus adapté. Nous allons maintenant voir comment nous débrouiller pour manœuvrer sans.
    Attention: Rappelez vous que si vous utilisez GNU netcat, certaines options peuvent être différentes. Vous n'avez par exemple généralement pas besoin de -p

    Copier un fichier ou transporter un flux avec Netcat

    Netcat permet de transporter des flux de données comme n'importe quelle autre commande, au travers d'une connexion par TCP ou UDP.
    Exemples pratiques :

     # Se préparer à recevoir des données par TCP sur le port 8888 et les stocker dans un fichier
    	fira@serveur$ nc -l -p 8888 > important.conf
    	# On les envoie depuis l'autre côté
    	fira@laptop$ nc serveur 8888 < stuff.txt
     
    	# La même chose avec socat:
    	fira@serveur$ socat TCP-LISTEN:8888 FILE:important.conf,creat
    	fira@laptop$ socat FILE:stuff.conf TCP:serveur:8888
     
    	# Pour visualiser des logs en temps réel en les envoyant aux personnes se connectant sur le port 8888
    	fira@serveur$ tail -f /var/log/messages | grep -i dhcp | nc -kl 8888
    	fira@laptop$ nc serveur 8888
    	May 15 11:55:07 serveur dhcpd[12337]: Server is going haywire!
    	May 15 11:58:08 serveur dhcpd[12337]: Server is giving random leases to everyone!
    	May 15 11:59:42 serveur dhcpd[12337]: We're doomed ! I'll just die now.

    Broadcasteur de logs cheap avec socat

    Si vous avez essayé le dernier exemple, vous aurez peut-être remarqué que si il fonctionne, les données ne sont envoyées qu'à une personne à la fois.
    On pourrait répliquer la fonctionnalité de logging réseau de la plus part des vrais loggueurs simplement avec socat, en les envoyant à tout le monde sur le réseau local par exemple.
    Pour cela on peut utiliser des paquets UDP de broadcast:

    	root@serveur# socat -u OPEN:/var/log/messages,rdonly,ignoreeof UDP-DATAGRAM:192.168.0.255:514,broadcast

    Relai de connexion avec socat

    Scénario : Vous avez besoin d’accéder à un service web mais se connecter directement avec l'application ne fonctionne pas pour une raison X ou Y (par exemple, Firefox n'accepte pas les adresses IPv6 de lien local).
    Solution :

    	fira@laptop$ socat TCP4-LISTEN:8080,fork TPC6:[fe80::a3e:8eff:fe3c:e893%eth0]:80
    	fira@laptop$ wget localhost:8080
    	(...)
    	2013-06-10 19:06:09 (485 KB/s) - ‘index.html’ saved [74817/74817]
     

    Ça fonctionne aussi pour forcer une application à utiliser un proxy de façon transparente, bien que des utilitaires comme Proxychains soient bien sûr plus adaptés.

    	# Se connecter à clubnix.fr:80 à travers proxy:9050
    	fira@laptop$ socat TCP-LISTEN:8080,fork SOCKS4:proxy:clubnix.fr:80,socksport=9050
    	fira@laptop$ wget localhost:8080
    	Connecting to localhost (localhost)|127.0.0.1|:8080... connected.
    	HTTP request sent, awaiting response... 301 Moved Permanently
    	(...)
     

    Connecter deux machines derrière des NAT avec Socat et une troisième box

    Pour cela on peut passer par un point d'échange au milieu accessible aux deux. Il suffit d'indiquer à socat que nous voulons connecter deux sockets d'écoute :

    	fira@middlebox$ socat TCP-LISTEN:9000,fork TCP-LISTEN:9001

    Lorsqu'une connexion arrive sur le port 9000, socat attendra ensuite une connexion sur le port 9001 pour transférer des données entre les deux. Ceci peut permettre de communiquer par exemple par netcat... ou de forwarder vers d'autres ports et serveurs avec les commandes vues plus haut.

    Connecter deux machines derrière des NAT directement par Hole Punching

    Cette méthode est beaucoup plus compliquée et repose sur le fonctionnement inhérent aux firewalls NAT. En tentant d'initier une connexion depuis les deux côtés à la fois et en manipulant les ports sources et destination de façon appropriée, il est possible d'obtenir une connexion directe entre ces deux machines malgré le NAT. Cette technique est utilisée par des clients P2P modernes tels Skype et ne nécessite un serveur central (ou opérateur humain!) que pour passer les connections.
    Des explications plus détaillées sur cette technique ne manquent pas sur internet, voici par exemple un article sur linuxjournal.com.

    Un VPN en 10 minutes avec OpenSSH

    Scénario : Vous avez un accès root et ssh sur une machine chez vous et voulez accéder à son réseau local.
    Ici la machine "laptop" (utilisant le routeur local 192.168.0.254) veut se connecter à la machine "remote", accessible par SSH sur l'IP 88.88.88.88 (elle peut être derrière un NAT, ou non). Nous allons utiliser OpenSSH pour créer un tunnel et préparer une configuration de routage basique.
    Attention : ceci est plus un concept pour apprendre le fonctionnement des outils, une solution avec un vrai client VPN est bien sur plus simple. Ne vous lancez pas dans ces manipulations sans un minimum de compréhension de IP.

    Préparation

    Sur la machine distante, il faut activer les logins root & les tunnels IP dans la configuration de SSH (/etc/ssh/sshd_config) avec "PermitRootLogin yes" et "PermitTunnel yes". Attention: il faut ensuite redémarrer SSH.

    Sur la machine locale, il peut être utile de désactiver les utilitaires de gestion du réseau tel NetworkManager car il risque de modifier les routes.
    Nous configurons ensuite les interfaces manuellement :

    	root@laptop# ip link set dev wlan0 up
    	# Dans le cas du Wi-Fi, il faut s'associer avec le point d'accès
    	root@laptop# wpa_supplicant -B -Dwext -iwlan0 -c/etc/wpa_supplicant/wpa_supplicant.conf
    	# On démarre le client DHCP avec -G pour qu'il ne modifie pas les routes
    	root@laptop# dhcpcd -B -G wlan0
    	# Mais on ajoute quand meme une route par défaut pour l'instant:
    	root@laptop# ip route add default via 192.168.0.254 dev wlan0

    Mise en place du tunnel

    	# Crée des interfaces tunnel tun3 des deux côtés de la connexion
    	root@laptop# ssh -Nf -w 3:3 root@serveur
    	# On doit activer et configurer ces interfaces, des deux côtés:
    	root@laptop# ip link set dev tun3 up
    	root@laptop# ip addr add dev tun3 scope host 192.168.254.2 peer 192.168.254.1
    	root@remote# ip link set dev tun3 up
    	root@remote# ip addr add dev tun3 scope host 192.168.254.1 peer 192.168.254.2
     
    	# Par précaution, on place une route explicite pour acceder au serveur, et éviter que le tunnel essaie de se connecter à travers lui même
    	root@laptop# ip route add 88.88.88.88/32 via 192.168.0.254 dev wlan0
     
    	# Les deux machines devraient maintenant pouvoir se joindre a travers le tunnel SSH
    	root@laptop# ping 192.168.254.1
    	PING 192.168.254.1 (192.168.254.1) 56(84) bytes of data.
    	64 bytes from (...)
     

    Configuration du routage

    Cette partie est plus embettante car elle dépend de la configuration de votre machine distante. Pour l'exemple je vais admettre un simple PC de bureau sans règles de firewall ou routage particulières.
    Nous allons donc configurer un NAT sur la machine distante pour relayer les connexions. Il serait possible de plutôt envoyer des paquets Ethernet par une interface tap (avec une option dans SSH ou en utilisant socat, pour être de façon complétement transparente sur le même réseau) mais cela veut dire changer les paramètres de bridge de la connexion actuelle (ce que personne ne veut faire a distance).

    	root@remote# iptables -t nat -A POSTROUTING -j MASQUERADE
    	root@remote# sysctl net.ipv4.ip_forward=1
     
    	# Il n'y a plus qu'à configurer les routes sur notre PC local pour que le traffic passe par le VPN !
    	root@laptop# ip route replace default via 192.168.254.1
     

    Limitations

    Ce type de configuration n'est évidemment pas optimale pour beaucoup de raisons (configuration manuelle, insécurité, inefficacité des programmes, utilisation de TCP, un VPN traditionnel utilise généralement UDP, fragmentation des paquets...). Pour un vrai VPN, vous voudrez sans doute utiliser une alternative telle OpenVPN ou tinc (à noter que tinc et ssh peuvent être multiplexés avec sslh pour être tous les deux accessibles sur le même port).

    Conclusion

    Avec un accès sur quelques machines Linux et des outils disponibles sur presque n'importe quelle distribution, on peut facilement se débrouiller pour acceder aux services dans des situations autrement impossibles.
    Il est possible d'effectuer des fonctions complexes en utilisant socat, et un bon nombre en sont détaillées dans sa page de manuel.
    L'utilisation de ces commandes est aussi très instructif concernant le fonctionnement et les possibilités offertes par les protocoles utilisés les plus couramment.

    Ressources supplémentaires

    1. "SSH Trickery @ Nick Moore's Blog"
    2. Chainer des proxys avec Proxychains
    3. Introduction aux NATs dans le contexte de netfilter
    4. Un article complet sur la technique du "Hole Punching"
    5. Page d'accueil du projet Tor pour l'anonimité sur Internet
    6. Le manuel de Socat donne beaucoup d'exemples d'utilisation
    Domaine: 

    Configuration de Mozilla à l'ESIEE

    Les petits trucs et astuces qui aident lorsqu'on travaille sur les PC et stations gérées par le SMIG.

    Accès Web avec Mozilla (proxy)

    Le proxy est un point essentiel du réseau de l'ESIEE. Cet élément se place entre internet et le réseau local de l'ESIEE. Il sert à économiser la bande passante en gardant en mémoire les sites les plus souvent visités. C'est grâce à lui que vous pouvez accéder à Internet. Par défaut, Mozilla essaye de se connecter à Internet sans passer par le proxy. Il faut donc le configurer afin d'avoir accés à toutes les pages du Web.

    http://cache.esiee.fr/scripts/proxy.pac

    Annuaire des adresses mail dans Mozilla

    Cette page va te permettre de configurer Thunderbird ou Mozilla Mail pour qu'il accède à l'annuaire centralisé de l'ESIEE (LDAP). Comme le serveur n'est pas accessible depuis internet, cette configuration ne fonctionnera que si ta machine est sur le réseau de l'ESIEE.

    Tout d'abord, affiche les préférences et choisis ''Composition'' puis ''addressing'' (ou les équivalents dans la langue de ton logiciel de messagerie) :

    [[image:Thunderbird_pref_ldap-avant.png]]

    Puis clique sur le bouton ''Edit Directories...''. Une fenêtre s'ouvre, clique alors sur ''Add''. Tu obtiens alors la fenêtre suivante:

    [[image:Config_ldap_ESIEE.png]]

    Rentre les options suivantes et clique sur OK :

    * '''Name''' : ''config esiee''. C'est le nom qui sera visible depuis d'autres réglages
    * '''Hostname''' : ''ldap.esiee.fr''. C'est l'addresse IP du serveur
    * '''Base DN''' : ''ou=Personnes,dc=esiee,dc=fr''. C'est la formule magique
    * '''Port number''' : ''389''. C'est le port qui sert en général pour du LDAP
    * '''Bind DN''' : ne rien mettre

    Maintenant, le fenêtre précédente devrais afficher la configuration que tu viens juste de créer:

    [[image:Thunderbird_liste_ldap.png]]

    Tu peux cliquer sur OK et tu te retrouveras dans les préférences, ou le serveur sera selectionné:

    [[image:Thunderbird_pref_ldap-apres.png]]

    Maintenant, il te faut vérifier que les comptes sont bien configurés pour utiliser ce serveur. Dans la configuration des comptes, sélectionne ''Composition & Addressing'' pour ton compte mail ESIEE. Puis sélectionne ''Use a different LDAP server'' comme indiqué sur la capture suivante:

    [[image:Thunderbird_account_settings.png]]

    Normalement, ca devrais marcher aussi avec l'autre case mais au moment ou j'écris ces lignes, ca ne marche pas sur ma machine.

    Et voila, si tout s'est bien passé, ton logciel de messagerie préféré devrais rechercher dans l'annuaire central de l'esiee les destinataires de ton prochain mail. Clique donc sur ''nouveau message'' et écris les trois premières lettres du nom ou du prénom de la personne que tu veux contacter. Par exemple si tu écrire à Thierry Simonnet pour lui dire que tu apprécies les services du SMIG, il te suffit de tapper ''sim'' dans la case des destinataires, comme le montre la capture suivante:

    [[image:Thunderbird_ldap_marche.png]]

    Vous n'avez plus d'excuse pour ne pas écrire a votre binôme!

    Tutoriel informatique décisionnelle avec BIRT

    Introduction

    L'informatique décisionnelle désigne les moyens, outils et méthodes pour fournir une aide à la décision.

    Voici un tutoriel pour se lancer dans l'informatique décisionnelle avec une génération de rapports par BIRT.

    Cas étudié

    Ce tutoriel décrit comment un étudiant d'ESIEE Paris peut faire usage d'informatique décisionnelle pour aider à la décision d'un lieu pour l'organisation d'un événement lors de la semaine d’élection du BDE ESIEE Paris.

    Les outils

    Dans ce tutoriel, nous allons utiliser BIRT Report Designer, l'outil graphique basé sur eclipse pour concevoir les rapports.
    Nous allons aussi utiliser BIRT Report Engine, qui fournit un script pour générer les rapports.

    Téléchargement des outils

    Les outils à télécharger se trouvent sur cette page :
    http://download.eclipse.org/birt/downloads/

    Téléchargez :

    • la All-in-One ou le RCP Designer, l'outil pour créer les rapports BIRT (fichiers .rptdesign) ;
    • le Report Engine pour générer les fichiers PDF sans l'outil graphique ;
    • le connecteur JDBC MySQL http://dev.mysql.com/downloads/connector/j/ (ou équivalent pour votre base de données)

    Lancement et configuration du projet

    Le lancement d'eclipse produit cet écran :

    BIRT lancement

    Ouvrez la perspective Report Design :
    Window > Open Perspective > Report Design

    Eclipse Workbench vide

    Créez un nouveau Report Project :

    New Project Wizard

    New Report Project

    Vous devez voir ça :

    Workbench après ajout d'un report project

    Il faut créer un rapport vide (un fichier rptdesign) File > New... > Report

    Creation rapport

    Creation rapport vide

    Ajout de la data source et des data sets

    Maintenant que le rapport est créé, on peut explorer la data avec la vue Data Explorer (vide évidemment).

    Vue data explorer vide

    Ajout de la data source

    Pour pouvoir récupérer des données d'une base de données, on doit ajouter une data source (choisir JDBC Data Source pour MySQL), dans mon cas, je nomme la Data Source "Dimension" :

    Fenetre ajout Data Source Type BIRT

    La page suivante me demande les informations JDBC.
    Fenetre ajout Data Source vide BIRT

    On ne réussira pas à se connecter à MySQL sans le connecteur renseigné, on va donc configurer le connecteur en allant sur manage connectors.

    Fenetre gestion connecteurs JDBC

    Le connecteur est configuré, je peux remplir tous les champs et tester la connexion :

    Création datasource rempli

    On doit pouvoir voir la nouvelle datasource dans le data explorer :

    Nouvelle Data Source

    Ajout des data sets

    On peut ajouter des data sets depuis le data explorer :

    BIRT ajout d'un Data Set

    Il faut préciser la requête SQL pour chaque DataSet :
    BIRT ajout d'un Data Set - query

    Dans mon cas, je vais ajouter deux data sets avec les requêtes suivantes.

    Récupération des noms des salles des épis 2 et 5.

    SELECT group_concat(r.resourceName ORDER BY r.resourceName ASC) AS rooms_list
    FROM resources r
    WHERE r.resourceCategory = 'classroom'
    	AND r.resourceIsGroup=0
    	AND (
    		r.resourceName LIKE "2_0%"
    		OR r.resourceName LIKE "5_0%"
    	)

    Récupération de tous les événements dans les salles de l'épi 2 pour la semaine 33 (semaine d’élection)

    SELECT
    	a.activityName,
    	r.resourceName,
    	e.eventDay,
    	e.eventSlot,
    	e.eventDuration
    FROM 
    	events e
    LEFT JOIN events_resources er
    	ON er.eventId = e.eventId
    LEFT JOIN resources r
    	ON r.resourceId = er.resourceId
    LEFT JOIN activities a
    	ON a.activityId = e.eventActivityId
    WHERE
    	r.resourceCategory='classroom'
    	AND r.resourceIsGroup=0
    	AND r.resourceName LIKE "2_0%"
    AND e.eventWeek = 33
    ORDER BY e.eventDay ASC, e.eventSlot ASC

    Création du rapport

    Dans mon cas, après la configuration des data sets, j'ajoute un chart Gantt pour chaque jour. Je ne détaille pas cette partie, à vous de concevoir un rapport pertinent pour vos besoins.

    BIRT rapport occupation

    Génération du rapport

    Pour générer le rapport avec le Report Engine (sans le faire depuis le Report Designer qui demande une configuration pénible), consultez la cheatsheet :
    CheatSheet BIRT Report Engine du Club*Nix

    BIRT Report Engine Cheatsheet

    English version : BIRT Report Engine command-line cheatsheet

    Téléchargement et configuration

    http://download.eclipse.org/birt/downloads/

    La génération d'un rapport en ligne de commande se fait avec le script genReport.sh ou genReport.bat sous Windows.

    La variable d'environnement BIRT_HOME doit être configuré et doit contenir le chemin du dossier parent de ReportEngine.
    Exemple d'appel :

    BIRT_HOME=.. ./genReport.sh --format PDF --output report.pdf ~/workspaces/demo/reporting/Reporting\ préélectoral/occupation-epis.rptdesign

    Les commandes genReport.sh les plus utiles

    Générer le rapport en PDF

    ./genReport.sh --format PDF --output /chemin/vers/sortie/rapport.pdf /chemin/vers/fichier.rptdesign

    Générer le rapport en HTML

    Générer le rapport sous forme de page HTML

    ./genReport.sh --format HTML --output /chemin/vers/sortie/rapport.html /chemin/vers/fichier.rptdesign

    Générer le rapport sous forme de Reportlet (pas de contenant HTML, utile pour dashboard)

    ./genReport.sh --format HTML --htmlType ReportletNoCSS --output /chemin/vers/sortie/rapport.html /chemin/vers/fichier.rptdesign

    Passage des paramètres du rapport

    Par argument à genReport

    ./genReport.sh --format PDF --parameter ANNEE=2013 --parameter MOIS=8 --output /chemin/vers/sortie/rapport.pdf /chemin/vers/fichier.rptdesign
    ./genReport.sh --format PDF -p ANNEE=2013 -p MOIS=8 --output /chemin/vers/sortie/rapport.pdf /chemin/vers/fichier.rptdesign

    Par fichier properties

    Fichier mes_params.properties

    ANNEE=2013
    MOIS=8
    ./genReport.sh --format PDF -F mes_params.properties --output /chemin/vers/sortie/rapport.pdf /chemin/vers/fichier.rptdesign

    X-Chat 2 sous Windows

    Qu'est-ce que l'IRC ?

    Présentation rapide

    L'IRC, "Internet Relay Chat", est techniquement un protocole de communication sur Internet utilisé pour converser avec des personnes. Pour le néophyte, ça ressemble au chat de Caramail (blah...), sauf que c'est beaucoup mieux.

    Un réseau IRC est constitué de plusieurs serveurs reliés entre eux, sur lesquels se connectent les clients. Comme les serveurs sont reliés entre eux, deux clients connectés à deux serveurs différents pourront quand même communiquer.

    Dans la pratique, sur un réseau IRC les discussions prennent place dans des salons (channels) que l'on nomme par un dièse # suivi du nom proprement dit, comme #clubnix.

    Comment se connecter à un réseau IRC

    Il faut utiliser un client IRC, un logiciel adapté, comme un navigateur internet permet de visiter des sites web. Ce tutorial va décrire l'installation et la configuration du logiciel X-Chat 2 sous Windows

    Installation de X-Chat 2

    Il faut d'abord aller télécharger le logiciel directement ici ou encore .

    L'installation ne devrait pas poser de problèmes, une fois l'installeur téléchargé et lancé, il suffit de cliquer sur suivant. A l'écran dont suit la capture d'écran, vous pouvez laisser les options par défaut. (N'installez pas les plugins supplémentaires sauf si vous savez ce que vous faites)
    Configuration X-Chat 2

    Lorsque vous lancerez X-Chat pour la première fois après l'avoir installé, vous tomberez sur l'écran suivant:

    Cliquez alors sur "Mode d'édition". Le dialogue se modifie de sorte que vous puissiez rajouter des réseaux et serveurs.

    Cliquez alors sur Ajouter (1). En bas de la liste des réseaux, sur la gauche, "Nouveau réseau" apparaît. Cliquez dessus une première fois pour le sélectionner, une seconde fois pour renommer (2). L'appeler rezirc serait une bonne idée.

    Réglez ensuite les paramètres comme suit.


    # Choisissez comme Pseudonyme le nom que vous aurez sur IRC. Choisissez un nom composé uniquement de caractères alphanumériques ([aA-zZ]/[0-9]) et sans espaces. Les deux cases suivantes sont pour choisir des pseudonymes secondaires, si jamais celui que vous choisissez est déjà utilisé. Laissez le nom d'utilisateur par défaut. Vous pouvez également renseigner votre Nom réel.
    # Comme nom de serveur, choisissez celui correspond à l'endroit où vous êtes en vous aidant de ce tableau.
    [tablemanager:2]
    # Dans joindre les canaux rentrez le salon #clubnix. Lorsque vous vous connecterez au réseau, vous rejoindrez automatiquement ce canal.
    # Comme jeu de caractères sélectionnez ISO-8859-15 (Western Europe). Ceci est important et nécessaire pour que tout le monde puisse voir les caractères accentués correctement.
    # Cochez la case connexion automatique au démarrage afin de vous connecter automatiquement lorsque vous lancez X-Chat. Décochez utiliser un serveur Proxy. Cochez enfin Pas de liste de serveurs au démarrage pour que cette boîte de dialogue n'apparaisse pas la prochaine fois que vous relancerez X-Chat.

    Vous pouvez vous connecter en utilisant le bouton Connexion et fermer la fenêtre de dialogue avec le bouton Close

    Utilisation de X-Chat 2

    # Sur la droite il y a la liste des personnes présentes dans le salon. Le petit point vert signifie OP = Channel Operator. Un OP est là pour modérer et éventuellement éjecter les personnes qui pollueraient le canal. Dans le cas présent, |}o{| est un bot, ce n'est pas un humain mais un programme.
    # Ici c'est la fenêtre principale des discussions. Lorsque qu'un pseudonyme apparaît en jaune gras, cela signifie que quelqu'un s'adresse à vous ou parle de vous, car il a écrit une ligne contenant votre pseudonyme.
    # Ici, c'est le sujet (aka topic) de discussion. N'a souvent aucun rapport avec le nom du canal ou les discussions elles-mêmes ;-)
    # Le champ où vous tapez vos messages.
    # Les onglets des serveurs auxquels vous êtes connecté et les salons dans lesquels vous êtes présent.

    Il est possible de dialoguer en privé avec une personne, sur la liste de droite faites un clic droit sur son pseudonyme.

    Dans le menu contextuel, sélectionnez Ouvrir la fenêtre de dialogue. Il est désormais possible de dialoguer avec cette personne en toute tranquillité.

    Aller plus loin

    Je vous laisse maintenant découvrir par vous-même toutes les possibilités d'IRC et les options de X-Chat 2 (transfert de fichiers, scripts, horodatage, coloration des pseudonymes pour rendre plus facile le suivi des discussions). Si vous êtes courageux, vous pouvez tenter d'utiliser ''irssi'', qui par son fonctionnement en console est à bien des égards extrêmement pratique

    ''Rédaction originale: Ferréol de Soras - e-mail: desoraf at esiee dot fr''

    Contribuer au site

    Ce site est basé sur Drupal. Tous les membres du Club*Nix peuvent y contribuer librement, en respectant bien entendu les règles de bienséance et de lisibilité (Koi T'M pa le SMS ?). Pour ce faire, il faut déjà se connecter, en utilisant son login et mot de passe enregistrés dans l'annuaire LDAP du club. Ensuite, dirigeons-nous vers l'item du menu intitulé "Créer du contenu", titre on ne peut plus explicite.

    Les différents types de contenu

    Une multitude de choix s'offre à nous, mais lequel prendre ?

    • Les brèves sont les contenus les plus simples. Un titre et du texte que l'on peut mettre en forme, comme on le verra plus tard. Ces contenus apparaissent ensuite sur la page d'accueil, et on peut y soumettre des commentaires.
    • Les pages sont destinées à du contenu fixe. Par défaut elles n'apparaîtront nulle part, il faut inclure un lien vers cette page dans une autre, ou demander aux admins du site d'ajouter un lien vers celle-ci dans le menu, si cette page présente un intérêt remarquable.
    • La page de livre permet de créer un contenu organisé. Un livre contient plusieurs pages qui sont organisées par chapitre, comme un livre ( on ne s'en serait pas douté ). Lorsqu'on crée une page de livre, on peut la rattacher à un livre déjà existant, ou créer un nouveau livre, en sélectionnant une page parente à l'aidre du menu "Parent". La section tutoriels du site est sous la forme d'un livre, pour y ajouter un contenu il suffit de créer une page de livre et de la rattacher à une page du livre "Tutoriels".
    • Le type "table" permet de créer un tableau qui pourra ensuite être inséré dans un autre contenu.

    Mise en forme

    Maintenant nous allons nous attacher à la mise en forme de nos écrits.
    Heureusement pour moi, Drupal fournit une aide pour la mise en forme, donc RTFM. Un petit résumé rapide quand même : on peut choisir le type de format du document dans "Format d'entrée". Le type "filtered HTML" permet d'utiliser quelques balises HTML listées dans la description du filtre, d'ajouter un tableau créé précédement à l'aide du type de contenu "table" et de colorer du code à l'aide la balise .

    Documentation

    Ou trouver de la bonne documentation ?

    Accèder à la doc écrite par nos très vénérés anciens

    Il suffit de se rendre sur http://clubnix.esiee.fr/doc simple non ? encore fallait-il le savoir.

    Documentation Club*Nix

    Cette section a pour but de regrouper tous les documents décrivant le fonctionnement du club.

    Serveur web

    Le serveur web se nomme anigros. On peut le trouver à l'adresse 147.215.81.102.
    L'installation est une Debian stable (lenny).

    Accès SVN

    Le club met à disposition de ses membres un dépôt Subversion. Subversion (SVN) est un logiciel de gestion de versions, il est donc très pratique pour réaliser un projet de programmation.
    Ce document explique comment créer un dépôt SVN sur le serveur de club et comment régler ses permissions d'accès.

    Création d'un dépôt

    Pour créer un dépôt svn :

    cd /var/svn
    svnadmin create nom

    L'accès se fait via DAV et le serveur web, pour qu'il puisse écrire dedans les fichiers du dépôt doivent appartenir au serveur web.

    chown -R www-data:www-data aints

    Configuration du serveur

    L'accès au svn via DAV nécessite le module dav_svn. Le paquet qui le contient sous Debian est libapache2-svn. La configuration du module se fait dans le fichier /etc/apache2/mods-available/dav_svn.conf. Après l'avoir configuré il faut activer le module avec la commande a2enmod dav_svn.

    Voici la partie de la configuration qui nous intéresse :

    <Location /svn>
      DAV svn
      SVNParentPath /var/svn/repos
      AuthzSVNAccessFile /etc/apache2/dav_svn.authz
     
      Satisfy Any
      Require valid-user
     
      AuthType Basic
      AuthBasicProvider ldap
      AuthName "Subversion repository"
      AuthLDAPURL ldap://ldapix/ou=People,dc=clubnix,dc=org?uid?one
    </Location>

    Cette configuration permet d'utiliser l'authentification LDAP et d'avoir un fichier dav_svn.authz permettant de contrôler finement les permissions.

    Contrôle fin des permissions

    Le fichier dav_svn.authz permet donc de configurer les permissions par dépôt.
    Par exemple si je veux que l'on puisse accéder anonymement aux fichiers du dépôt aints, voici la ligne de ce fichier qui correspond.

    # Tout le monde peut lire le dépôt aints
    [aints:/]
    * = r

    Cette page contient des informations plus précise sur le contrôle des permissions.

    Livres en libre accès

    Bien que très riches et souvent assez récents, les différents moyens d'information purement informatiques qu'il est possible de trouver sur le net ont quelques inconvénients :

    • Incomplets
    • Pas de relecture
    • Et surtout n'importe qui peut mettre n'importe quoi

    C'est pour cela que beaucoup d'entre nous aiment pouvoir se tourner vers des versions « papier » dites plus fiables.

    Pauvre étudiants que nous sommes, cette solution nous apparaît souvent très onéreuse. Prier pour que le livre soit dans la bibliothèque la plus proche...

    Fort heureusement, dans leur grande bonté, certains éditeurs mettent à disposition certains de leur livres gratuitement, ou à des prix réduits au format électronique :

    Système

    Les documents de cette catégorie traitent du fonctionnement d'un système GNU/Linux.

    Mettre en place un serveur DHCP

    Ce petit article décrit la configuration minimale nécessaire pour mettre en place un serveur DHCP. Pour rappel un DHCP permet d'attribuer dynamiquement des adresses ip des ordinateurs ou toute machine se connectant au réseau et envoyant des demandes (imprimantes, ordinateurs,... ) en tout genre.

    Un DHCP peut être très pratique sur des réseaux de toutes tailles. Mais cela peut être néanmoins dangereux, surtout avec les options routers, dns : un individu se connectant pourra alors sans problème profiter de votre connection internet si vous avez pas fait des règles de routagei assez sécurisées. Pour un petit réseau où il y a souvent des ordinateurs portables qui viennent s'y greffer, cela peut faciliter la vie de leurs utilisateurs.

    Prérequis

    Pour ce qui est des connaissances : un minimum de connaissances systèmes et réseaux sont nécessaires, sans être indispensables. Si vous pouviez comprendre ce que vous faites serait un plus.

    Pour ce qui est des logiciels : dhcpd évidement, disponible en général via le gestionnaire de package de votre unix flavor libre préféré.

    Base de fichier

    Le fichier de configuration du serveur DHCP est le fichier dhcp.conf, généralement situé à la racine
    du répertoire /etc. Mais il arrive qu'il soit dans un sous-répertoire dhcp/ de celui ci.
    Pour commencer il faut spécifier au serveur DHCP un réseau sur lequel il va opérer pour cela il suffit d'utiliser subnet :

    subnet <reseau> netmask <masque-de-sous-reseau> {}

    <reseau> est un réseau ip du type 192.168.1.0 ou
    192.168.0.0 et <masque-de-sous-reseau> un masque de sous réseau de la
    forme : 255.255.255.0 ou 255.255.0.0. De cette façon vous avez défini le réseau
    sur lequel opérera votre serveur DHCP et par là même l'interface réseau concernée.

    Prenons mon cas en exemple : mon réseau est du type : 192.168.1.0 et mon masque du type : 255.255.255.0.
    Ce qui nous donne :

    subnet 192.168.1.0 netmask 255.255.255.0 {}

    Configuration d'un serveur DHCP : range

    La façon la plus simple de faire un dhcp.conf est de définir une plage (en anglais range) d'adresses attribuables par le serveur. Pour celà on va utiliser la commande range dans la commande subnet vue précédement :

    subnet 192.168.1.0 netmask 255.255.255.0 {
    	range 192.168.1.50 192.168.1.150;
    }

    Ainsi nous avons défini une plage d'adresse dans laquelle le serveur DHCP va piocher. Évidemment vous êtes limité à 254 adresses (de 1 à 254) maximum.
    Enfin tout dépend de la classe de réseau que vous avez.

    Vous pouvez spécifier plusieurs plages évidemment, il suffit d'ajouter des lignes range, une pour chaque plage.

    Configuration d'un serveur DHCP : host

    Une autre façon est de spécifier hôte par hôte l'adresse ip et diverses options. Pour cela on utilise la commande host.

    subnet 192.168.1.0 netmask 255.255.255.0 {
     	range 192.168.1.50 192.168.1.150;
    }
     
    host <nom> {
     	hardware ethernet <macadress>;
    	fixed-address <adresse_ip>;
    	option host-name "<nom>";
     }

    L'hôte <nom> dont l'adresse mac (de la forme : CC:CC:CC:CC:CC:CC) est <macadress>aura pour adresse ip
    <adresse_ip>; et se verra passer le nom <nom> (optionnel). C'est surtout utilisé avec un bootp.

    Récuperer l'adresse mac d'une carte réseau

    Si elle n'est pas indiquée sur la carte, ou sur la machine, il existe plusieurs manières d'obtenir l'adresse mac d'une carte réseau.
    La plus simple, si vous avez un shell sur la machine en question, est de taper ifconfig device
    device est le nom de l'interface réseau qui vous interesse.
    Une autre méthode consiste à pinguer la machine voulue et ensuite d'utiliser la commande arp <adresse_ip>

    ce qui vous donnera l'adresse mac de la machine distante.
    Enfin sur certaines machines (notament les sun) l'open boot affiche l'adresse mac au démarrage.

    dhcp.conf : options utiles

    Vous pouvez rajouter des options particulièrement utiles : temps de libération, adresse du dns, de la passerelle ...

    Lease time

    Il peut être utile de spécifier le temps (en secondes) au bout duquel le ou les clients devront libérer l'adresse attribuée. Deux
    options vous le permette : default-lease-time et max-lease-time. Dans notre exemple cela
    pourrait donner :

    subnet 192.168.1.0 netmask 255.255.255.0 {
     	range 192.168.1.50 192.168.1.150;
    	default-lease-time 600;
    	max-lease-time 7200;
    }

    Domain name, domain name servers

    Deux autres options peuvent être très utiles : domain-name et domain-name-servers

    grâce à elles vous pouvez spécifier aux clients le domaine et les serveurs de noms de celui ci. Dans notre exemple ça nous donnera :

    subnet 192.168.1.0 netmask 255.255.255.0 {
    	range 192.168.1.50 192.168.1.150;
    	default-lease-time 600;
    	max-lease-time 7200;
    	option domain-name-servers 192.168.1.42;
    	option domain-name "domain.net";
    }

    Passerelle

    Une dernière option peut être très utile : routers qui vous permet de spécifier aux clients l'adresse ip de la passerelle.
    Dans notre exemple cela nous donnera :

     subnet 192.168.1.0 netmask 255.255.255.0 {
    	range 192.168.1.50 192.168.1.150;
    	default-lease-time 600;
    	max-lease-time 7200;
    	option domain-name-servers 192.168.1.42;
    	option domain-name "domain.net";
    	option routers 192.168.1.42;
    }
     

    Conclusion

    Avec ça il y a de quoi mettre en place un serveur DHCP minimal et efficace. Pour plus de détails je vous renvoie vers le man de dhcpd et surtout celui, très complet, de dhcpd.conf (5).

    N'hésitez pas à nous envoyer (à moi ou au club) pour toute remarque, question, suggestion, sur cette documentation.

    Licence

    Cet article est publié sous la licence Creative Commons by-sa : http://creativecommons.org/licenses/by-sa/2.0/fr/ . Pour toute question merci de contacter
    l'auteur : ange(at)librium.org.

    Serveur personnel complet

    Ce petit howto est pensé pour suivre pas à pas la mise en place d'un serveur personnel complet en utilisant NetBSD 2. La première partie présente rapidement les enjeux d'un tel serveur, si vous estimez que vous connaissez ces enjeux, passez à la section suivante.

    Le présent document est publié sous la licence CC-bysa.

    Copyright © 2004 Thomas Riboulet

    Document originel.

    Principes et choix

    Enjeux, utilités

    Avec la généralisation des accés haut débit de type xDSL et la baisse des prix des micro ordinateurs il devient souvent utile de partager sa connection internet entre les différents micro ordinateur d'un foyer, d'un étage d'immeuble, ... Certains FAI proposent des solutions dites "clés en mains" mais celles ci sont souvent incomplètes, peu performantes voir peu sécurisées. L'arrivée des accés haut débit sous entendent plusieurs choses : un accés permanent, un débit utilisé de façon limitée, l'accés à des nouveaux services.

    L'accés permanent est le point principal des accés xDSL. Avec de tels accés vous avez la possibilité d'avoir un ordinateur connecté 24/24h et 7/7j sur Internet. De là découle des points intéressants et des points moins intéressants.

    Etre connécté en permanence représente généralement un accroissement des risques d'attaques sur l'ordinateur connecté et, parfois, les ordinateurs connectés sur internet via ce même ordinateur. C'est la que le premier besoin se fait donc sentir : protéger la connection internet et les ordinateurs qui l'utilise. Le serveur devra donc faire office de pare-feu (firewall).

    D'un autre coté, être connecté en permanence permet d'assurer un certain nombre de services qui peuvent vous être utiles : serveur web pour partager des documents, des albums photos, ... Si vous êtes étudiant vous pouvez tirer parti d'un serveur subversion ou cvs.

    Le débit proposé est de plus en plus important, du moins dans le sens Internet -> utilisateur (déscendant), dans l'autre sens (montant) les FAI commencent à faire des progrés. La plupart du temps la bande passante disponible n'est pas utilisée pleinement, et bien des choses sont faisables. Si vous disposez d'un accés xDSL correct (1024/256) et d'une adresse IP fixe alors vous pouvez peut être trouver une utilité à avoir certains services chez vous : mini serveur web, serveur subversion/cvs si vous êtes développeur, ou étudiant, et enfin serveur mail. Utilité d'avoir son propre serveur mail ? Ne pas dépendre d'un fournisseur de services X ou Y. Le problème c'est que là vous dépendrez de la stabilité de votre connection. Mais si vous avez un bon camarade, disposant lui aussi d'un tel serveur il peut surement faire relais et ainsi palier des problèmes de connection.

    Si vous avez plusieurs ordinateurs utilisés pour surfer sur le web il peut être utile d'utiliser un serveur mandataire aka proxy, ainsi qu'un serveur de noms (DNS).

    Enfin, pour faciliter les échanges de fichiers il peut être utile de faire un serveur de fichiers accessible via SMB (windows) ou NFS (unices). De même on peut envisager un serveur d'impression.

    Pour résumer le serveur fera donc office de : firewall, passerelle, serveur mail, serveur subversion, serveur web et bdd, proxy, dns, file-server, et serveur d'impression.

    Choix matériels

    Ce sont là les choix matériels de l'auteur

    Deux objectifs ont guidé mon choix : faible encombrement, prix et consommation éléctrique. Il est important pour moi d'avoir une machine relativement puissante mais ni trop encombrante, ni trop cher, ni trop gourmande. Plusieurs machines collent à peu prés dans ces besoins : les soekris (www.soekris.com) et les epia (via). Les soekris sont de sympathiques petites betes dotés en général de deux cartes réseaux minimum, voir plus et même parfois de ports pour des cartes au format pcmcia, minipci. Mais les soekris ont 2 problèmes : le prix et la puissance. Un soekris est trés bien pour faire firewall, pas plus. Si vous avez les moyens je vous conseille d'ailleurs d'investir dans un soekris pour s'occuper du firewall et déléguer les autres tâches précédement listées à une autre machine. Les Epia sont donc la solution : un format pas trés grand : 17x17cm, un faible consommation éléctrique, un prix raisonnable et une puissance plus que correcte (800MHz voir 1GHz pour les premiers modèles).

    Mon choix s'est donc porté sur une Epia achetée sur ldlc.fr, l'alimentation que j'utiliserai sera l'alimentation d'une SparcStation 4 (format ATX) le temps de trouver un boitier pas trop cher pour la remplacer. Vous pouvez trouver des boitiers sur internet : mini-itx.com en vend, mais les frais de ports sont élevés. Cependant les instructions qui suivent sont valables pour toutes les machines sauf peut être pour les médiums d'install.

    Il est important d'avoir un minimum de puissance car le nombre de services hébergés sur la machine vont être important et risquent de bouffer pas mal de ressources. Pour mon cas j'ai pris une Epia M10000, le processeur Nehemiah à 1GHz devrait pouvoir tenir la charge. Pour la RAM, je commence avec 256Mo de DDR 2100.

    Choix logiciels

    Maintenant que vous avez votre matériel prêt vous pouvez passer à la phase suivante : la prépration de l'install logicielle. Pour l'OS le choix est NetBSD 2. NetBSD présente plusieurs points importants selon moi : stabilité, propreté du code, de la documentation, licence libre. Bien sur OpenBSD peut aussi être une bonne solution. Néanmoins dans cet article je décris l'installation d'un serveur personnel avec NetBSD, les principes sont applicables à tout autre unice libre (GNU/Linux ou les autres BSD) mais vous trouverez certaines différences à plusieurs endroits. Dans ce cas allez voir les docs du système que vous utilisez, généralement vous trouverez ce qu'il faut.

    Firewall, passerelle

    Nous utiliserons Packet Filter (pf) et non le classique ipf de NetBSD (qui n'est pas libre). Porté récement sur NetBSD je le trouve bien plus puissant qu'iptables et nous pourrons normalement utiliser les fonctions de queuing et de limitation de débit (QoS).

    Serveur web

    Pour le serveur web nous utiliserons apache 2 et les modules mod_php, mod_perl. Nous verrons l'installation de Postgresql, pour ceux qui préfèrent MySQL il n'y a pas beaucoup de choses à faire pour le remplacer.

    Serveur mail

    Le serveur mail : nous verrons l'installation du critiqué sendmail mais aussi de postfix. Le but pour le serveur mail est d'avoir aussi courier-imaps et un serveur LDAP pour gérer les comptes mails.

    Autres services

    Pour le proxy j'utiliserai l'habituel squid, et Bind pour le DNS. Nous verrons aussi l'installation d'OpenSSH et d'un serveur subversion.

    Installation

    Il faut obligatoirement avoir : une machine prête, une connexion internet permanente utilisable, une galette bootable de NetBSD 2, du thé ou du café et du courage.

    Nous verrons d'abord les pré-requis pour pouvoir mener à bien l'installation, puis nous passerons à l'installation du système.

    Méthode de boot

    Nous utiliserons un cdrom pour démarrer l'install, sur certaines machines (sparc notament) vous pouvez utiliser des images de boot via le réseau et lancer l'install directement. C'est d'ailleurs cette dernière méthode que je préfère personnellement : il n'y a pas besoin de cdrom, c'est plus rapide etc ... C'est faisable en théorie sur x86 en utilisant PXE, malheureusement par manque de temps cette méthode n'est pas couverte dans la présente version de cette documentation.

    Pour mener à bien cette installation nous allons avoir besoin de :

    • un cd bootable de NetBSD 2.0
    • un serveur dhcp
    • un serveur nfs

    Je vous recommande le téléchargement des paquets suivant afin de mener à bien l'installation simplement :

    • BSDSUM
    • CKSUM
    • MD5
    • SYSVSUM
    • base.tgz
    • comp.tgz
    • etc.tgz
    • kern-GENERIC.MP.tgz
    • kern-GENERIC.tgz
    • kern-GENERIC_DIAGNOSTIC.tgz
    • man.tgz
    • misc.tgz
    • text.tgz
    • gnu.tar.gz

    Vous pouvez les récuperer sur n'importe quel mirroir netbsd, par exemple : ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-2.0/i386/binary/sets/. Vous remarquerez que tous les sets ne sont pas présents ici. En effet comme c'est un serveur nous considérons ne pas avoir besoin des sets games et ceux relatifs à X.

    Installation

    Le principe est simple, et pour ceux habitués à des installs de debian, ou d'une autre distro sérieuse de GNU/Linux, l'install paraîtra aisée et rapide.Nous commencerons pas démarrer sur le CD bootable gravé à cet effet. Nous ferons l'install de NetBSD (partitionnement, choix des sets, config réseau, install, reboot). Puis nous récupèrerons les sources du noyau, et les ports (pkgsrc). Enfin, dans les chapitres suivants nous aborderons l'install des différents services.

    NetBSD 2

    Lecture conseillée

    Le NetBSD guide a un chapitre consacré à une installation d'exemple : http://netbsd.org/guide/en/chap-exinst.html .
    L'installation n'est pas bien compliquée. Il suffit de se laisser guider. Pour les habitués de GNU/Linux quelques différences notables sont visibles mais nous les aborderons en temps voulu.Un petit menu vous invite à choisir la langue utilisée pendant l'installation (voir Fig 2-1). Par habitude je prends toujours anglais, mais rien ne vous empeche de prendre français, Néanmoins je vous recommande la version anglaise, il n'y a pas de problème de traduction, vous êtes sur de ce qui est dit, et vous être tranquille si un jour vous avez besoin de faire une install avec un media ou est seulement présent l'anglais.
    Figure 2.1. Choix de la langue

    Comme dit dans le NetBSD guide il ne faut pas être décu par l'aspect sommaire de l'installateur, si la quantité n'est pas la la qualité par contre ... Sur chaque écran vous avez en général une rapide présentation de l'action concernée dans la partie supérieure. Dans la partie inférieur vous avez l'espace de travail.

    Une fois le langage choisi (je présume que vous avez pris anglais) vous arrivez au menu principal de l'installateur (fig 2-2).
    Figure 2.2. Menu principal de l'installateur
    Vous allez évidement choisir le premier item du menu : Install NetBSD to hard disk. Sélectionnez et validez.

    L'installateur vous affiche alors un résumé rapide de ce qui va se passer durant l'install et vous demande confirmation.Figure 2.3. Demande de confirmation

    Si vous êtes d'accord, validez.

    Si vous avez plusieurs disques dur il va vous demander de selectionner le disque à utiliser pour l'install. Pour les habitués de GNU/Linux voila une première différence : le nommage des disques. Sous GNU/Linux ils sont désignés par hdX (avec X une lettre), sous NetBSD (et les autres BSD d'ailleurs) ils sont désignés par wdY (avec Y un chiffre). Sélectionnez votre disque et validez.

    Vous passez alors au choix du type d'installation : complet (full) ou spécial (custom) (fig 2-4) évidement dans notre cas nous allons prendre custom afin de ne pas installer certains composants inutiles pour notre serveur.Figure 2.4. Demande du type d'installation Si vous choisissez bien custom vous allez vous trouver devant un écran vous permettant de sélectionner les sets que vous voulez installer (fig 2-5).Figure 2.5. Sélection des sets

    Avec les flèches haut et bas vous vous déplacez dans la liste et avec la touche Entrée vous changez le status d'install des sets. Changez en No pour Games, et déselectionnez tous les sets concernant X (en tapant Entrée sur la ligne X11 sets puis Unselect all sets.
    Les sets dont nous parlons ici ne constituent qu'une install de base, nous verrons par la suite comment installer des packages supplémentaires via pkgsrc (ports).
    Nous arrivons à la deuxième grosse différence avec GNU/Linux : le partitionnement. NetBSD a une façon particulière de gérer les partitions. En effet vous n'allez pas vraiment créez des partitions. Vous allez en créez une pour NetBSD et dans celle ci vous allez découper en slice l'espace pour faire les partitions habituelles. Vous allez donc arriver à un écran vous demandant de choisir entre éditer la table des partitions ou utiliser tout le disque (fig 2-6).Figure 2.6. Partitionnement

    Comme nous avons un serveur avec un seul OS : NetBSD nous allons prendre le deuxième choix : utiliser tout le disque (Use the entire disk).

    L'installateur va alors demander l'unité de mesure à utiliser, il y a trois choix possibles : Megabytes, Cylinders, et Sectors (fig 2-7). Comme je ne parle pas trop en Cylindres et Secteurs j'ai pris Megabytes (MegaOctets), et je vous invite à faire de même.Figure 2.7. Choix de l'unité de mesure

    Arrive alors le choix de spécifier la taille des partitions de NetBSD (slices) ou d'utiliser celles qui existent déja (fig 2-8).Figure 2.8. Partitions NetBSD
    Comme précédement nous considérons avoir un disque vierge, une install seule etc ... Donc on va les spécifier nous même.

    Les ports : pkgsrc

    pkgsrc ou Package source est la collection de packages de NetBSD. Elle permet d'installer, et désinstaller facilement
    des logiciels. Ce sont les sources qui sont directement utilisées, il y a donc compilation du logiciel voulu. Il existe évidement des packages binaires mais je préfère, personnellement,
    la première solution. De plus c'est une façon efficace de maintenir son système à jour. Nous verrons comment utiliser Sushi pour facilement installer,
    et tenir à jour le système.

    Nous allons installer plusieurs logiciels importants à commencer par packet filter, puis apache (2), ses différents modules dont nous allons avoir besoin,
    puis postfix, openldap, courier, et nous traiterons ensuite de la configuration de tout ce beau monde.
    img

    Tutoriel Linux pour débutants

    Débutant, on est tous passés par là.

    Pour faciliter la vie des amateurs Linux, je vous livre un pdf que j'ai trouvé sur internet et qui m'a beaucoup servi pour la suite en ce qui concerne le système Linux. Les 4 premières pages font peur, mais ne vous inquiétez pas, les pré-requis sont juste connaître les quelques commandes de base (cd, ls, mv, cp, man, sudo...).

    Ce n'est pas essentiel de tout lire d'une traite en espérant comprendre du premier coup, mais ne vous inquiétez pas les membres du club seront ravis de vous expliquer les points sombres.

    Le pdf est en pièce jointe, le nom de l'auteur y est inscrit dessus.

    Domaine: 
    Fichier attachéTaille
    PDF icon Tutoriel Linux pour débutants897.73 Ko