IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

valeur inode "d_fileno" différente de la valeur dans "ls -i"


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 17
    Points : 26
    Points
    26
    Par défaut valeur inode "d_fileno" différente de la valeur dans "ls -i"
    Petit problème lorsque je désire afficher l'inode d'un fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    int			main(int argc, char *argv[])
    {
    	DIR			*dp;
    	struct dirent	*dirp;
     
    	if (argc != 2)
    	{
    		ft_error("USAGE");
    	}
    	if ((dp = opendir(argv[1])) == NULL)
    		ft_error("Can't open");
    	while ((dirp = readdir(dp)) != NULL)
    	{
    		printf("%llu    %s\n", dirp->d_fileno, dirp->d_name);
    	}
    	closedir(dp);
    	exit (0);
    }
    j'essaye de reproduire un basique ls -i, mais la valeur retournée par mon petit programme ne correspond pas toujours à la valeur renvoyé par ls -i. Notamment pour les dossiers /net, /home et /dev.
    J'ai essayé, à titre de comparaison, d'utiliser la valeur de l'inode contenu dans la structure stat de chaque fichier mais les valeurs ne correspondent pas.

    résultat ls -i :
    848433 cores
    301 dev
    848435 etc
    5 home

    résultat a.out :
    848433 cores
    848434 dev
    848435 etc
    869200 home


    Certaines valeurs (comme /cores) correspondent mais d'autres non. En observant ls -l pour comprendre, j'ai remarqué que la date de modification correspondait à aujourd'hui pour les dossiers avec des valeurs différentes, ce qui voudrait dire que l'inode que je trouve avec mon programme correspond à la dernière date de modification (qui serait la date de création du dossier) mais que le ls -i m'afficherait l'inode correspondant à la création du fichier lors de la "création du système".
    Je ne sais pas si je suis assez clair, mais j'aimerais bien comprendre d'ou provient la différence.


    Merci

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 675
    Points : 30 963
    Points
    30 963
    Billets dans le blog
    1
    Par défaut
    Bonjour

    J'ai peut-être ton explication. Cela concerne les dossiers qui sont des "points de montages" (comme par exemple "/home" chez-moi).
    Si je regarde "ls -lid /home" je vois "2" comme n° d'inode (puisque, pour le FS qui y est monté, sa racine "/" porte le n° 2). Si je lance ton programme en demandant de traiter "/", je vois "56" (parce que, dans le dossier "/", le point de montage "/home" porte le n° 56). Et si je le relance en lui demandant de traiter "/home", alors je vois que "." porte le n° 2.
    Même principe pour "/dev" qui est un point de montage sur "udev"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 17
    Points : 26
    Points
    26
    Par défaut
    Merci pour ta réponse. Je ne connaissais pas les points de montages mais je me doutais que ça avait une explication étrange un rapport avec l'endroit de départ.

    Pour reprendre ton exemple, mes résultats sont identiques aux tiens (je suis sous macOS pour information) sauf pour la racine ou j'obtiens :
    2 .
    1 ..
    alors que je devrais avoir 2 et 2.

    Du coup avec tes explications et ton exemple, je me suis dit que je pourrais obtenir le numéro d'inode du dossier en me déplaçant dans les dossiers chaque fois que j'en rencontre un, de lire et donc de récupérer le numéro d'inode de la structure nouvellement crée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	while ((dirp = readdir(dp)) != NULL)
    		{
    			if (strcmp(dirp->d_name, ".") != 0 && strcmp(dirp->d_name, "..") != 0 && dirp->d_type == DT_DIR)
    			{
    				dp2 = opendir(dirp->d_name);
    				dirp2 = readdir(dp2);
    				printf("%llu\t", dirp2->d_fileno);
    				closedir(dp2);
    			}
    			else
    				printf("%llu\t", dirp->d_fileno);
    }
    En dehors du fait que j'obtiens une erreur pour essayer de lire deux dossiers à la suite, c'est une solution qui me parait pas très optimale...
    Je vais chercher du côté des points de montage pour voir si j'obtiens des réponses. J'ai encore un peu de mal à saisir le fait que l'inode puisse être différente en fonction du dossier dans lequel on se trouve, alors que c'est censé être (pour moi) une valeur invariable.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ça risque d'être la même chose pour les liens symboliques vers répertoire, vu que si j'ai bien compris, le lien symbolique est lui-même un fichier contenant un chemin (il y aura donc l'inode du lien, et l'inode du dossier lié).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 675
    Points : 30 963
    Points
    30 963
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Personne.c Voir le message
    Merci pour ta réponse. Je ne connaissais pas les points de montages
    Un montage est une opération permettant d'associer un périphérique IO (disque dur, clef USB, cdrom) à ton ordinateur par le biais d'un dossier (qu'on nomme alors "point de montage"). Si par exemple tu associes ta clef USB au dossier "/toto", tout ce que tu vois apparaître sous "/toto" est le contenu de ta clef. Si tu y copies un fichier le fichier ira physiquement sur ta clef et inversement si tu veux récupérer un fichier de ta clef il suffit de le copier depuis "/toto".
    Remarque: le dossier "/toto" n'est pas obligé d'être vide pour être associé à un périphérique. Mais s'il ne l'est pas, tout son contenu "avant association" (qui se trouve sur le périphérique dans lequel "/toto" a été créé) est alors masqué par l'association. Et si on défait l'association, alors on retrouve le contenu précédent.

    Citation Envoyé par Personne.c Voir le message
    Pour reprendre ton exemple, mes résultats sont identiques aux tiens (je suis sous macOS pour information) sauf pour la racine ou j'obtiens :
    2 .
    1 ..
    alors que je devrais avoir 2 et 2.
    Mouais. C'est apparement une petite différence entre Mac et Unix pour lequel l'inode n° 1 sert aux "bad blocks" et où le ".." de "/" porte le même numéro "2" que "." ce qui permet de taper "cd /../../../../../.." sans se préoccuper d'"aller trop haut"...

    Citation Envoyé par Personne.c Voir le message
    Du coup avec tes explications et ton exemple, je me suis dit que je pourrais obtenir le numéro d'inode du dossier en me déplaçant dans les dossiers chaque fois que j'en rencontre un, de lire et donc de récupérer le numéro d'inode de la structure nouvellement crée...
    ...
    En dehors du fait que j'obtiens une erreur pour essayer de lire deux dossiers à la suite, c'est une solution qui me parait pas très optimale...
    Ben déjà tu pourrais tester si le dossier est réellement utilisé comme point de montage (je crois que stat() permet de le voir) mais surtout tu ne dois afficher dirp2->d_fileno que si dirp2->d_name est égal à "."...

    Citation Envoyé par Personne.c Voir le message
    J'ai encore un peu de mal à saisir le fait que l'inode puisse être différente en fonction du dossier dans lequel on se trouve, alors que c'est censé être (pour moi) une valeur invariable.
    C'est pas qu'elle est différente, c'est que tu ne vois pas la même selon l'endroit où tu te trouves !!!

    Prenons un exemple simple: deux disques sda et sdb.
    Le disque "sda" contient les fichiers suivants (avec leurs n° d'inode): / (2), /home (55), /etc (18)
    Le disque "sdb" contient d'autres fichiers (avec là aussi des numéros qui n'ont de sens que dans "sdb" et qui, donc, peuvent être les mêmes que ceux de "sda"): / (2), /paul (29), /pierre (18), /jean (23)
    Les deux disques ayant la même structure interne de manipulation de fichiers (on nomme cela "FS" pour "FileSystem"), ils ont tous deux une arborescence qui commence à "/ (2)". C'est d'ailleurs grâce à cette "convention" qu'un système Unix, quand il démarre de zéro, sait quelle inode il doit récupérer de son disque de boot pour commencer à travailler.

    Si maintenant on monte le disque "sdb" dans "/home", alors quand on est dans "/" et qu'on regarde "/home" (de façon très bas niveau, avec des outils d'analyse de FS), on est dans "sda" donc on verra le dossier "/home" de sda donc avec l'inode 55. Mais si on descend dans "/home", on se retrouvera (par le biais de la liaison) dans le disque sdb et on verra alors l'arborescence de "sdb" avec le dossier "." qui aura 2. Mais ce "2" qu'on voit, ce n'est pas le numéro d'inode de "/home" (qui est toujours 55), c'est le numéro d'inode de la racine "/" du disque sdb !!!

    Reste effectivement un dilemne: quoi afficher si on demande le numéro d'inode de "/home" ? Doit-on afficher le numéro du dossier "/home" qui est dans "sda" ou bien la racine "/" de "sdb" qui y est associée ? Les programmeurs de "ls" ont tranché pour cette seconde solution et c'est probablement pour ça que quand on tape "ls -lid /home" on voit "2" donc la commande doit probablement faire un "positionnement" comme tu y as pensé toi aussi...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 17
    Points : 26
    Points
    26
    Par défaut
    Si maintenant on monte le disque "sdb" dans "/home", alors quand on est dans "/" et qu'on regarde "/home" (de façon très bas niveau, avec des outils d'analyse de FS), on est dans "sda" donc on verra le dossier "/home" de sda donc avec l'inode 55. Mais si on descend dans "/home", on se retrouvera (par le biais de la liaison) dans le disque sdb et on verra alors l'arborescence de "sdb" avec le dossier "." qui aura 2. Mais ce "2" qu'on voit, ce n'est pas le numéro d'inode de "/home" (qui est toujours 55), c'est le numéro d'inode de la racine "/" du disque sdb !!!

    Reste effectivement un dilemne: quoi afficher si on demande le numéro d'inode de "/home" ? Doit-on afficher le numéro du dossier "/home" qui est dans "sda" ou bien la racine "/" de "sdb" qui y est associée ? Les programmeurs de "ls" ont tranché pour cette seconde solution et c'est probablement pour ça que quand on tape "ls -lid /home" on voit "2" donc la commande doit probablement faire un "positionnement" comme tu y as pensé toi aussi...
    Merci pour ton explication, je comprends mieux cette histoire d'endroit et de "device".


    Effectivement, en affichant successivement les valeurs de st_dev contenue dans la structure stat(), j'obtiens des valeurs différentes dans les dossiers que j'ai cité plus haut. D'ailleurs, même en utilisant la commande stat du terminal 'stat -x /*' (je pensais que tu parlais de ça au début), on remarque que la valeur du champs 'Device' est différente pour ces dossiers. En effectuant mes recherches suite à tes remarques sur les points de montage, j'ai même découvert la commande df qui m'indique directement quels dossiers sont des points de montages, c'est pratique !

    Donc, au lieu de vérifier dans chaque dossier si c'est différent, je me contente de comparer le numéro de dev de base (devnum) au numéro des autres dossiers :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    		while ((dirp = readdir(dp)) != NULL)
    		{
    				stat(dirp->d_name, &buf);
    				printf("%d\t", buf.st_dev);
    				if (strcmp(dirp->d_name, ".") == 0)
    				{
    					devnum = buf.st_dev;
    				}
    				if (buf.st_dev != devnum)
    				{
    					dp2 = opendir(dirp->d_name);
    					dirp2 = readdir(dp2);
    					if (strcmp(dirp2->d_name, ".") == 0)              /* condition surement inutile */
    						printf("%llu\t", dirp2->d_fileno);
    					closedir(dp2);
    				}
    				else
    					printf("%llu\t", dirp->d_fileno);		
     
    		}
    Même problème, le numéro st_dev ne change que si mon exécutable se trouve à la racine....
    Dans mes recherches, je suis tombé sur la fonction chdir(), qui règle tous les problèmes mais je n'aime pas les solutions trop simples.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 675
    Points : 30 963
    Points
    30 963
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Personne.c Voir le message
    Dans mes recherches, je suis tombé sur la fonction chdir(), qui règle tous les problèmes mais je n'aime pas les solutions trop simples.
    Bien entendu et c'est un très bon réflexe. Un chdir ne se fait que s'il se justifie et ici, rien ne le justifie !!!

    Bon déjà grosse erreur sur stat: quand on fait un stat() sur un fichier, il faut bien penser à donner le nom complet du fichier et pas simplement son nom final !!! (mais je t'avoue que j'ai fait la même )

    Sinon quand je te dis de comparer (dans ta sous-recherche), d_name avec ".", c'était sous-entendu "avec une exploration du sous-dossier" donc une boucle sur dp2 !!!!!!

    Ceci dit tout ça nous amène maintenant à un truc assez complexe, avec dp, dp2, dirp, dirp2. Et là, quand on arrive à un truc de ce genre, il faut savoir dire "stop" et penser à déporter des tâches.

    Mais surtout il faut aussi savoir reposer la base de la réflexion, ça améliore le codage.

    Donc je pose clairement ton principe comme tu aurais dû le faire: examiner tous les fichiers d'un répertoire et comparer leur st_dev avec le st_dev du répertoire en question. Si ça diffère, c'est que le fichier est monté sur un autre device. On peut en plus rajouter "si ça diffère et que le fichier est un dossier" ce qui limitera quelques recherches (c'est toujours bon de pouvoir trouver des éléments de vérification supplémentaires).
    Et si le fichier est un dossier monté sur un autre device, alors descendre dans ledit dossier et rechercher le d_fileno de "point". A ce niveau, celui qui a bien lu ce que j'ai expliqué avant peut se dire "c'est idiot, on connait déjà numéro puisque c'est une racine de FS donc c'est 2" mais bon, admettons que ça puisse être autre chose (moi aussi j'aime pas les soluces trop simples). Et puis sous Linux on a aussi des FS virtuels (en mémoire) comme tmpfs et dont le n° n'est plus "2" donc finalement cette étape n'est pas inutile.
    Mais c'est un travail complexe donc là, autant déléguer la charge de récupérer ce d_fileno de "point" à une autre fonction spécialement faite pour ça. Comme ça on sera plus à l'aise pour coder le principal.

    Ce qui donne alors le code suivant...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <stdio.h>
    #include <dirent.h>
    #include <sys/stat.h>
     
    // Fonction qui renvoie l'inum de "." dans un sous-dossier
    ino_t findInum(char *name) {
    	DIR *dp;
    	struct dirent *dirp;
    	off_t inum=0;
     
    	dp=opendir(name);
    	while ((dirp = readdir(dp)) != NULL) {
    		if (strcmp(dirp->d_name, ".") == 0) {
    			inum=dirp->d_fileno;
    			break;
    		}
    	}
    	closedir(dp);
    	return inum;
    }
     
    int main(int argc, char *argv[])
    {
    	DIR *dp;
    	struct stat buf;
    	struct dirent *dirp;
    	int devnum;
    	char name[1024];
     
     	// Recherche du device du dossier initial
    	stat(argv[1], &buf);
    	devnum=buf.st_dev;
     
    	// Traitement du dossier
    	dp = opendir(argv[1]);
    	while ((dirp = readdir(dp)) != NULL) {
    		sprintf(name, "%s/%s", argv[1], dirp->d_name);
    		lstat(name, &buf);
    		printf("%llu\t%s\n", ((buf.st_mode & S_IFMT) != S_IFDIR || buf.st_dev == devnum) ?dirp->d_fileno :findInum(name), dirp->d_name);
    	}
    	closedir(dp);
    }

    Bon j'avoue que le printf() final est un peu difficile mais pas vraiment compliqué. Si le fichier en cours n'est pas un dossier, ou bien si son device est égal au device initial alors pas de soucis sinon alors c'est que c'est un dossier monté donc il faut afficher le inum interne dudit dossier, inum interne que me récupère ma fonction dédiée.

    Et dernier détail: j'utilise lstat() plutôt que stat() car dans le cas d'un lien symbolique, stat() va regarder ce qu'il y a au bout du lien alors que moi je veux vraiment les infos du lien lui-même.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 17
    Points : 26
    Points
    26
    Par défaut
    Bon déjà grosse erreur sur stat: quand on fait un stat() sur un fichier, il faut bien penser à donner le nom complet du fichier et pas simplement son nom final !!! (mais je t'avoue que j'ai fait la même )

    Sinon quand je te dis de comparer (dans ta sous-recherche), d_name avec ".", c'était sous-entendu "avec une exploration du sous-dossier" donc une boucle sur dp2 !!!!!!
    Merci pour l'info, je ne le savais pas.

    Concernant l'exploration du sous-dossier, j'avoue que j'ai eu "la flemme" de penser que le premier appel à readdir lirait forcément le dossier "." d'ou mon commentaire dans le code "condition surement inutile". J'en déduis que c'est aléatoire, même si je le fais 1000 fois et qu'il m'affiche toujours "." en premier.

    Bien entendu, j'avais déporté l'ensemble de la boucle dans un autre fonction, je n'avais laissé que l'appel à la fonction dans mon main.
    Concernant le printf, je n'utilise pas souvent les ternaires mais c'est très pratique. Je comptais y rajouter le cas des dossiers/fichiers cachés (tout ce qui commence par un point) qui, je suppose, ne peuvent être des points de montage mais dans le doute, je laisse tes conditions.

    Le problème c'est que je n'ai pas accès à certains dossiers pour lire le numéro d'inode quand il est différent (permission denied). Pourtant, je suis quand même censé afficher un inode. Du coup j'ai donné à inum la valeur par défaut de stat.st_ino.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ino_t		inode(char *pathname)
    {
    	DIR		*dp;
    	struct dirent	*dirp;
    	struct stat	buf;
    	ino_t		inum;
     
    	stat(pathname, &buf);
    	inum = buf.st_ino;
    	if ((dp = opendir(pathname)) == NULL)
    		return(inum);
    	while ((dirp = readdir(dp)) != NULL)
    	{
    		if (strcmp(dirp->d_name, ".") == 0)
    		{
    			inum = dirp->d_fileno;
    			break;
    		}
    	}
    	closedir(dp);
    	return (inum);
    }

    Tout semble bien fonctionner en dehors du dossier /dev/fd pour lequel ma boucle (readdir) n'arrive pas à trouver ni le dossier "." ni ".." une fois dans le sous-dossier. Mais j'ai l'impression que ce dossier mérite un cours à lui tout seul.
    Merci encore pour ton aide et tes explications Sve@r.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 17/03/2007, 20h32
  2. Réponses: 3
    Dernier message: 11/07/2005, 15h20
  3. Réponses: 5
    Dernier message: 15/04/2005, 14h22
  4. Réponses: 8
    Dernier message: 09/03/2005, 10h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo