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 :

Parcours récursif d'une arborescence


Sujet :

C

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut Parcours récursif d'une arborescence
    Bonjour,

    Je ne suis pas très familier de ce contexte, j'aimerais avoir vos retours sur cette fonction.
    L'objectif est de rechercher la présence d'un fichier f.ext dans un sous-dossier a/b/c et sous-dossiers sans utiliser de bibliothèques tierces avec un code aussi portable que possible (a minima Windows et Linux).
    La fonction retourne 0 si le fichier a été trouvé, une autre valeur selon ce qui a pu se passer.

    path est le répertoire initial,
    name est le fichier recherché
    out sera le chemin complet du fichier, si trouvé

    SIZESIGN est un define, SEP est une macro qui donne le séparateur selon l'OS

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    int lib_string_scan_dir_file (char *path, const char *name, char **out)
    {
        DIR *d, *sd;
        struct dirent *entry;
        char dir[SIZESIGN][SIZESIGN];
        char buffer[SIZESIGN];
        int i, k, ndir = 0;
     
        strncpy (dir[ndir++], path, SIZESIGN-1);
        d = opendir (dir[0]);
        if (d == NULL)
            return 1;
     
        while ((entry = readdir (d)))
        {
            if ((!strcmp (entry->d_name, ".")) || (!strcmp (entry->d_name, "..")))
            {
     
            }
            else
            {
                snprintf (buffer, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
                sd = opendir (buffer);
                if (sd != NULL)
                {
                    k = snprintf (dir[ndir++], SIZESIGN-1, "%s", buffer);
                    if ((k < 0) && (k >= SIZESIGN))
                    {
                        dir[ndir][0] = '\0';
                        ndir--;
                    }
                }
                else
                {
                    if (!strcmp (entry->d_name, name))
                    {
                        k = snprintf (*out, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
                        if ((k < 0) && (k >= SIZESIGN))
                            return 2;
                        else
                            return 0;
                    }
                }
            }
        }
        for (i = 1; i < ndir; i++)
        {
            k = lib_string_scan_dir_file (dir[i], name, out);
            if (k == 0)
                return k;
        }
        return 1;
    }
    Avez-vous des commentaires, des suggestions ?
    Mon code est-il mauvais ou correct ?

  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 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par _iri_ Voir le message
    Bonjour,

    Je ne suis pas très familier de ce contexte, j'aimerais avoir vos retours sur cette fonction.
    L'objectif est de rechercher la présence d'un fichier f.ext dans un sous-dossier a/b/c et sous-dossiers sans utiliser de bibliothèques tierces avec un code aussi portable que possible (a minima Windows et Linux).
    La fonction retourne 0 si le fichier a été trouvé, une autre valeur selon ce qui a pu se passer.

    path est le répertoire initial,
    name est le fichier recherché
    out sera le chemin complet du fichier, si trouvé

    SIZESIGN est un define, SEP est une macro qui donne le séparateur selon l'OS

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    int lib_string_scan_dir_file (char *path, const char *name, char **out)
    {
        DIR *d, *sd;
        struct dirent *entry;
        char dir[SIZESIGN][SIZESIGN];
        char buffer[SIZESIGN];
        int i, k, ndir = 0;
     
        strncpy (dir[ndir++], path, SIZESIGN-1);
        d = opendir (dir[0]);
        if (d == NULL)
            return 1;
     
        while ((entry = readdir (d)))
        {
            if ((!strcmp (entry->d_name, ".")) || (!strcmp (entry->d_name, "..")))
            {
     
            }
            else
            {
                snprintf (buffer, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
                sd = opendir (buffer);
                if (sd != NULL)
                {
                    k = snprintf (dir[ndir++], SIZESIGN-1, "%s", buffer);
                    if ((k < 0) && (k >= SIZESIGN))
                    {
                        dir[ndir][0] = '\0';
                        ndir--;
                    }
                }
                else
                {
                    if (!strcmp (entry->d_name, name))
                    {
                        k = snprintf (*out, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
                        if ((k < 0) && (k >= SIZESIGN))
                            return 2;
                        else
                            return 0;
                    }
                }
            }
        }
        for (i = 1; i < ndir; i++)
        {
            k = lib_string_scan_dir_file (dir[i], name, out);
            if (k == 0)
                return k;
        }
        return 1;
    }
    Avez-vous des commentaires, des suggestions ?
    Mon code est-il mauvais ou correct ?
    Salut
    J'ai des commentaires
    1) Que fait ton code quand d_name vaut "." ou ".." ? Tu as mis un if mais vide
    2) je ne comprends pas le if ((k < 0) && (k > SIZESIGN)). Une variable peut-elle être à la fois plus petite que 0 et plus grande qu'un entier positif ?
    3) A quoi te sert la variable k dans le dernier for ?
    4) ton code ne gère pas les liens symboliques (boucle infinie possible)

    J'ai aussi des suggestions : Tu peux simplifier if (machin) return 2 else return 0 par return machin ?2 :0
    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
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Salut
    J'ai des commentaires
    1) Que fait ton code quand d_name vaut "." ou ".." ? Tu as mis un if mais vide
    2) je ne comprends pas le if ((k < 0) && (k > SIZESIGN)). Une variable peut-elle être à la fois plus petite que 0 et plus grande qu'un entier positif ?
    3) A quoi te sert la variable k dans le dernier for ?
    4) ton code ne gère pas les liens symboliques (boucle infinie possible)

    J'ai aussi des suggestions : Tu peux simplifier if (machin) return 2 else return 0 par return machin ?2 :0
    1/ Rien
    J'ai laissé pour une possibilité d'action ultérieure.

    2/ Boulette et grand merci ! Et comme j'ai bêtement recopié le premier pour le second ...
    Il s'agit d'un || et non d'un &&
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ((k < 0) || (k > SIZESIGN))
    /* erreur */
    3/ Le k est le retour du scan du sous-dossier en cours. S'il vaut 0, c.à.d. le fichier a été trouvé, on sort de la fonction courante et, par ricochet, des fonctions récursives supérieurs.
    Impropre ? Non fiable ?

    4/ Les liens symboliques. Effectivement ... Comment faire ?
    Sans passer par des API spécifiques. As-tu une piste, une idée ?

    Suggestion : merci, j'avais des printf de retour au milieu mais le code sera bien plus lisble sans cette lourdeur.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par _iri_ Voir le message
    3/ Le k est le retour du scan du sous-dossier en cours. S'il vaut 0, c.à.d. le fichier a été trouvé, on sort de la fonction courante et, par ricochet, des fonctions récursives supérieurs.
    Impropre ? Non fiable ?
    Inutile
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    if (lib_string_scan_dir_file (dir[i], name, out) == 0) return 0:

    Citation Envoyé par _iri_ Voir le message
    4/ Les liens symboliques. Effectivement ... Comment faire ?
    Sans passer par des API spécifiques. As-tu une piste, une idée ?
    Utiliser stat() sur le répertoire supposé. Cette fonction te remplit une structure (que tu auras déclarée) avec les caractéristiques du fichier. Ensuite te suffit de vérifier le champ st_mode de cette structure. Et comme c'est un champ mélangeant plusieurs infos (type et droit), il y a des macros toutes faites pour extraire l'info comme S_IFDIR() et S_IFLNK()

    Citation Envoyé par _iri_ Voir le message
    Suggestion : merci, j'avais des printf de retour au milieu mais le code sera bien plus lisble sans cette lourdeur.
    C'est pratique pour vérifier...
    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]

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Inutile
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    if (lib_string_scan_dir_file (dir[i], name, out) == 0) return 0:
    C'est exact, la même chose en plus condensé.
    C'était dans le cas ultérieur où la possibilité de retourner tous les fichiers satisfaisant à la demande. Mais même dans ce cas, c'était inutile.

    Citation Envoyé par Sve@r Voir le message
    Utiliser stat() sur le répertoire supposé. Cette fonction te remplit une structure (que tu auras déclarée) avec les caractéristiques du fichier. Ensuite te suffit de vérifier le champ st_mode de cette structure. Et comme c'est un champ mélangeant plusieurs infos (type et droit), il y a des macros toutes faites pour extraire l'info comme S_IFDIR() et S_IFLNK()
    Je n'ai jamais eu de problème avec stat() sous Linux mais sous Windows, tout n'est pas implémenté (en tout cas dans les header fournis avec MingW). Je testerai.

    Citation Envoyé par Sve@r Voir le message
    C'est pratique pour vérifier...
    C'est le but

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par _iri_ Voir le message
    Je n'ai jamais eu de problème avec stat() sous Linux mais sous Windows, tout n'est pas implémenté (en tout cas dans les header fournis avec MingW). Je testerai.
    Le pb c'est que tu veux un outil utilisable sous Linux et sous Windows. Donc même si Windows ne sait pas ce qu'est un lien symbolique, il te faut gérer ça dans le cas où ton pg sera exécuté dans Linux.

    Et en réfléchissant un peu plus à cette problématique, on en arrive à la conclusion que tu risques de devoir passer par de la compilation conditionnelle style
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #if TARGET=LINUX
        ... (le code qui gère la particularité Linux)...
    #elif TARGET=ZINDOW
        ... (le code qui gère la particularité Windows)...
    #else
        ... (le code qui gère la particularité de cet OS particulier)...
    #endif
    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]

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Le pb c'est que tu veux un outil utilisable sous Linux et sous Windows. Donc même si Windows ne sait pas ce qu'est un lien symbolique, il te faut gérer ça dans le cas où ton pg sera exécuté dans Linux.
    Je travaille sur le même projet mais sur des bibliothèques différentes avec des développeurs honnêtement plus compétents que moi. Mais ils codent essentiellement avec les APIs Windows quand bien même leurs équivalents standards existent, en utilisant toutes sortes de macros et de routines MS. Or il y a la version Linux derrière !
    Certes, ils codent dans un contexte de demandes clients (au niveau fonctionnalités) alors que je code dans un cadre purement opensource. Il n'empêche que je ne peux pas compiler leurs bibliothèques avec MingW/GCC (il faut VC++) et que pour fournir une compatibilité avec la version Linux, ça va être tendre ...

    Je n'ai aucune obligation à développer ce code de façon portable, je me l'impose tout seul et je m'y tiens. C'est intellectuellement mieux et en pratique bien plus efficace puisque ma version Linux est à jour avec celle Windows.
    Encore une fois, je n'ai pas les mêmes contraintes qu'eux.


    Citation Envoyé par Sve@r Voir le message
    Et en réfléchissant un peu plus à cette problématique, on en arrive à la conclusion que tu risques de devoir passer par de la compilation conditionnelle
    Oui, je m'y suis déjà résolu pour quelques cas et encore souvent parce qu'il y a une différence au niveau des prototypes (dernier cas, mkdir). Mais j'essaie de trouver les solutions

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut
    Les liens symboliques existent sous Vista et 7 me semble t-il. Est-ce identique à ce qu'on connaît sous unix/linux (de mon point de vue, ici) ?
    À ma connaissance, stat() ne permet pas de les distinguer (sous Windows). Me faut-il donc passer par une api windows ?

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut
    Au sujet des liens symboliques, j'ai fait ainsi, n'ayant rien trouvé de standard sous Windows :
    (http://msdn.microsoft.com/en-us/libr...=VS.85%29.aspx)

    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
    #if !(defined WIN)
    struct stat *s = NULL;
    #endif
    ...
    while ((entry = readdir (d)))
    {
        snprintf (buffer, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
    #if (defined WIN)
        k = GetFileAttributes (buffer);
        if (k == INVALID_FILE_ATTRIBUTES)
            /* message et gestion erreur */
        else if (!(k & FILE_ATTRIBUTE_REPARSE_POINT))
    #else
        k = stat (buffer, s);
        if (k == -1)
            /* message et gestion erreur */
        else if (!(s->st_mode & S_IFLNK))
    #endif
       {
            sd = opendir (buffer);
            ...
    Si vous avez une meilleure solution, n'hésitez pas !
    En attendant, merci à Sve@r pour ses commentaires.

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par _iri_ Voir le message
    Les liens symboliques existent sous Vista et 7 me semble t-il. Est-ce identique à ce qu'on connaît sous unix/linux (de mon point de vue, ici) ?
    Les liens symboliques existent depuis 1988 sous Unix. 6 ans plus tard, en 1994, NT est arrivé en annonçant fièrement qu'ils avaient inventé un objet révolutionnaire: le raccourci !!!
    Et en plus les liens symboliques Unix (et ipso facto Linux) peuvent pointer vers des noms relatifs (vers ../truc par exemple) ou vers des noms absolus (vers /machin/truc) alors que les raccourcis zindow ne peuvent pointer que sur des noms absolus (C:\truc\chose)

    Citation Envoyé par _iri_ Voir le message
    À ma connaissance, stat() ne permet pas de les distinguer (sous Windows). Me faut-il donc passer par une api windows ?
    Là je ne sais pas.

    Citation Envoyé par _iri_ Voir le message
    Au sujet des liens symboliques, j'ai fait ainsi, n'ayant rien trouvé de standard sous Windows :
    (http://msdn.microsoft.com/en-us/libr...=VS.85%29.aspx)

    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
    #if !(defined WIN)
    struct stat *s = NULL;
    #endif
    ...
    while ((entry = readdir (d)))
    {
        snprintf (buffer, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
    #if (defined WIN)
        k = GetFileAttributes (buffer);
        if (k == INVALID_FILE_ATTRIBUTES)
            /* message et gestion erreur */
        else if (!(k & FILE_ATTRIBUTE_REPARSE_POINT))
    #else
        k = stat (buffer, s);
        if (k == -1)
            /* message et gestion erreur */
        else if (!(s->st_mode & S_IFLNK))
    #endif
       {
            sd = opendir (buffer);
            ...
    Si vous avez une meilleure solution, n'hésitez pas !
    Pas bon. Tu définis un pointeur s que tu remplis sans avoir alloué de mémoire pour lui !!! Te faut maintenant lui faire un malloc().

    Ou alors tu définis une variable "s" de type "struct stat" puis tu remplis en passant "&s" à stat() et tu remplaces tous tes "s->" par "s."...

    Citation Envoyé par _iri_ Voir le message
    En attendant, merci à Sve@r pour ses commentaires.
    Avec plaisir
    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]

  11. #11
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Pas bon. Tu définis un pointeur s que tu remplis sans avoir alloué de mémoire pour lui !!! Te faut maintenant lui faire un malloc().

    Ou alors tu définis une variable "s" de type "struct stat" puis tu remplis en passant "&s" à stat() et tu remplaces tous tes "s->" par "s."...
    Tout à fait ! Ça a d'ailleurs rapidement planté à l'exécution !

    Je passe en résolu et merci encore !

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

Discussions similaires

  1. Parcours récursif d'une arborescence
    Par Michel Deriaz dans le forum Codes sources à télécharger
    Réponses: 1
    Dernier message: 13/09/2017, 17h30
  2. [XSLT] Parcours récursif d'une liste
    Par Tueur_a_gage dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 15/06/2007, 14h05
  3. Parcours en largeur d'une arborescence->Vector
    Par Paniez dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 07/12/2006, 22h21
  4. [VBA-A]Parcours d'une arborescence dossiers et fichiers
    Par sidneyvba dans le forum VBA Access
    Réponses: 2
    Dernier message: 20/03/2006, 16h58
  5. Parcours très rapide d'une arborescence ?
    Par Invité dans le forum C++Builder
    Réponses: 7
    Dernier message: 06/05/2005, 09h24

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