• STATISTIQUES
  • Il y a eu un total de 2 membres et 6022 visiteurs sur le site dans les dernières 24h pour un total de 6 024 personnes!


    1 membre s'est inscrit dans les dernières 24h!


    Membres: 2 608
    Discussions: 3 580
    Messages: 32 820
    Tutoriels: 78
    Téléchargements: 38
    Sites dans l'annuaire: 58


  • ANNUAIRE
  • [EN] xda-developers
    Très bon site pour les gros bidouilleurs de smartphone de windows à androïd et de Apple jusqu'...
    Phreaking
    [EN] This is legal
    Basic: 10, Realistic: 5, Programming: 1, Bonus: 11, SQL: 2, Encryption: 6, Application: 4, User Contributed: 3
    Challenges
    [EN] Astalavista
    JavaScript: 1, Exploit: 2, Crypto: 34, CrackIt: 15, Stegano: 8, Programming: 12, Logic: 36, Special: 6, Science: 4, Info...
    Challenges
    [EN] Listbrain Version 3
    Site proposant 66 challenges présentés dans une liste mélangée.
    Challenges
    [EN] Big-Daddy
    Big-Daddy est site internet communautaire avec un effectif diversifié, y compris des artistes, des programmeur...
    Hacking
    [EN] hax.tor
    50 level de challenges mélangés
    Challenges
    [FR] Comment ca marche
     Gratuit et accessible à tous, ce site de communauté permet de se dépanner, se faire aider ...
    Webmaster

  • DONATION
  • Si vous avez trouvé ce site internet utile, nous vous invitons à nous faire un don du montant de votre choix via Paypal. Ce don servira à financer notre hébergement.

    MERCI!




Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
[C] Parcours récursif des dossiers
20-04-2013, 22h52 (Modification du message : 20-04-2013, 22h57 par InstinctHack.)
Message : #1
InstinctHack Hors ligne
Posting Freak
*



Messages : 1,366
Sujets : 184
Points: 299
Inscription : Dec 2011
[C] Parcours récursif des dossiers
io,

j'essaye de démarrer en C, mais c'est dur :')
Je voudras afficher la totalité de mes fichiers et répertoires et ça à partir de la racine.
Le problème c'est que ça compile pas et que j'ignore comment corriger les erreurs.
Quelqu'un pour m'aider à avancer ?

Code C :

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main()
{
        parcours_rep("/");
}

int parcours_rep(path)
{
        struct dirent *lecture;
        DIR *rep;
        rep = opendir(path);
        while (lecture = readdir(rep))//parcours des elements du repertoire
        {
                if(lecture->d_name!='.' && lecture->d_name!='..')//on ignore les "." et les ".."
                {
                        printf("%s\n", lecture->d_name);//petit affichage
                        if ( opendir(path.'/'.lecture->d_name) == ENOTDIR)//si l'ouverture échoue parce que c'est pas un dossier
                        {}
                        else
                        {
                        parcours_rep(path.'/'.lecture->d_name);//si on est encore là, c'est que c'est un repertoire (ou qu'une erreur est survenue, mais tampis...), donc on le parcours
                        }
                }
        }
        closedir(rep);
}

 


Et voilà le message d'erreurs lors de la compilation :
Code BASH :

khaled@loopinfinity:~/LIFE/Informatique/Programmation/C/malware$ gcc file.c
file.c: In function ‘parcours_rep’:
file.c:14:2: warning: passing argument 1 of ‘opendir’ makes pointer from integer without a cast [enabled by default]
In file included from file.c:3:0:
/usr/include/dirent.h:136:13: note: expected ‘const char *’ but argument is of type ‘int’
file.c:18:45: error: ‘ENOTDIR’ undeclared (first use in this function)
file.c:18:45: note: each undeclared identifier is reported only once for each function it appears in
 
Citation :un jour en cours de java j'ai attrapé les seins d'une fille mais elle m'a frappé en disant "c'est privé !!"
j'ai pas compris pourquoi, je croyais qu'on était dans la même classe
+1 (0) -1 (0) Répondre
20-04-2013, 23h16 (Modification du message : 20-04-2013, 23h23 par Kiwazaru.)
Message : #2
Kiwazaru Hors ligne
Padawan d'un super escargot
*



Messages : 284
Sujets : 26
Points: 139
Inscription : Mar 2012
RE: [C] Parcours récursif des dossiers
Déjà, je crois qu'on ne peut pas faire : if (opendir(arg) == ENOTDIR) puisque opendir attend de renvoyer quelque chose dans une déclaration DIR* .
On devrais donc faire DIR* new; -> new = opendir(new_path); + if ( new != ENOTDIR )..
Ensuite pour l'histoire de récursivité, je pense pas qu'on puisse fonctionner avec une seule fonction, j'avais pensé à deux fonction qui auraient une interaction continuelle entre elles, et ces deux fonctions serait dynamique entre elle aussi, cet à dire qu'elles se complèterait et donc permettrais de parcourir un nouveau dossier sans devoir déclarer une infinité de DIR* ce qui serais totalement bête et de toute façon impossible puisqu'on ne peut prédire le nombre de dossier présent dans un dossier de dossier à l'avance...
Pour finir une fonction "int" qui ne renvoi rien ça sert à rien donc fait une fonction "void" :p.

Bref on aurais un schéma : int main(); void dParcours(char* path); void dParcours_bis(char *path);
Avec dans chacune des fonctions une déclaration de DIR* qui parcourrait le nouveau "path" et qui se renverrais à la fonction dParcours (si la fonction courante est dParcours_bis et vice versa) avec le nouveau dossier trouvé Smile

Je ne sais pas si c'est la solution la plus simple, mais c'est là seule qui m'est venu à l'esprit à la vue de ce post pour éviter une infinité de déclaration DIR* :p
Sinon pour l'indentation de ton code, -> if() sans instruction dedans tu peux faire
Code C :
if( x == y ){
}
 

Ou encore,
Code C :
if( x == y ) { }

Je sais pas si des compilateurs acceptent
Code C :
if( x == y )
else{
...
}
 
Toucher au Kernel, c'est un peut comme se shooter au LSD, on pense pouvoir tout faire mais ça finit souvent mal.
+1 (0) -1 (0) Répondre
21-04-2013, 03h16 (Modification du message : 21-04-2013, 03h28 par b0fh.)
Message : #3
b0fh Hors ligne
Membre actif
*



Messages : 210
Sujets : 17
Points: 309
Inscription : Jul 2012
RE: [C] Parcours récursif des dossiers
Plop,

opendir() retourne NULL en cas d'erreur. ENOTDIR sera dans errno si il y a lieu. Par contre il n'y a aucun problème pour faire l'affectation directement dans le if, à part peut-être un souci de lisibilité

Plutôt que d'avoir une branche if vide, c'est un meilleur style d'inverser la condition.

Attention, tu ne peux pas comparer des strings avec == et != en C. Ici j'ai triché comme un porc en me contentant d'ignorer tout ce qui commence par un point.

Tu ne peux pas non plus concaténer des strings avec .

Il manquait la déclaration de type dans l'argument de ta fonction.

Si tu n'utilises pas de prototypes, tu dois déclarer les fonctions avant leur utilisation (donc bouger le main à la fin)

Comme ta fonction récursive ne retourne rien, j'ai changé son type de retour en void. J'ai aussi ajouté un return au main.

Tu peux aussi utiliser continue pour sauter au début d'une boucle (certains disent que c'est du mauvais style. Je les emmerde.)

J'utilise 4096 comme taille maximum pour un path, c'est ce qui est défini dans linux (mais ça n'est pas forcément portable). Plutôt que d'accumuler les allocations mémoire, j'utilise un seul buffer qui contient le chemin complet. La fonction récursive garde deux pointeurs, un vers le début du buffer (qui est utilisée pour le printf du chemin complet), et un vers la fin qui sert a ajouter le / et le nom de la dentry)

Je fais le print au début de la fonction récursive, et je ne teste pas si une dentry est un répertoire avant de descendre, parce que si ce n'est pas le cas, le opendir() va rater plus loin (philosophie "let it fail").

Il faut quand même tester si un répertoire est un symlink avant de descendre plus loin, sous peine de se retrouver coincé dans des boucles infinies.

Au final ça donne ça:

Code :
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>

#define PATH_MAX 4096


void parcours_rep(char *path, char *end)
{
        struct dirent *lecture;
        struct stat statbuf;
        DIR *rep;

        printf("%s\n", path);

        if (lstat(path, &statbuf))  // on saute si lstat échoue
                return;

        if (S_ISLNK(statbuf.st_mode))  // on saute les symlinks;
                return;

        if (!(rep = opendir(path)))
                return;  // opendir échoue, on se contente de retourner
        
        *end++ = '/';   // on ajoute un / a la fin du path

        while ((lecture = readdir(rep)))//parcours des elements du repertoire
        {
                if (lecture->d_name[0] == '.')
                        continue;
                strcpy(end, lecture->d_name);
                parcours_rep(path, end + strlen(lecture->d_name));
        }

        closedir(rep);
}

int main()
{
        char path[4096] = "/";
        parcours_rep(path, path + strlen(path));
        return 0;
}

Il y a encore plusieurs améliorations possibles. Par exemple un meilleur traitement d'erreur, l'utilisation de qqch de moins dangereux que strcat(), et surtout un mécanisme d'ouverture du répertoire cible en temps constant (ici, on fait à chaque fois un opendir() sur le path complet, ce qui force le kernel a tout retraverser depuis la racine. Il serait beaucoup mieux de faire des chdir() et de ne faire des opendir() que sur les chemins relatifs trouvés dans les dentry. L'amélioration est laissée comme exercice au lecteur Smile
+1 (1) -1 (0) Répondre
21-04-2013, 11h38
Message : #4
Kiwazaru Hors ligne
Padawan d'un super escargot
*



Messages : 284
Sujets : 26
Points: 139
Inscription : Mar 2012
RE: [C] Parcours récursif des dossiers
Le problème dans ton code B0fh c'est que ça va opendir(); sur le premier dossier venu et ça ne va pas lister les fichiers qui pourraient être présent à la suite de ce dossier :/
Toucher au Kernel, c'est un peut comme se shooter au LSD, on pense pouvoir tout faire mais ça finit souvent mal.
+1 (0) -1 (0) Répondre
21-04-2013, 11h44
Message : #5
supersnail Hors ligne
Éleveur d'ornithorynques
*******



Messages : 1,610
Sujets : 72
Points: 466
Inscription : Jan 2012
RE: [C] Parcours récursif des dossiers
@ReVeRse: ben si... si t'arrives à ouvrir le dossier, tu parcours les fichiers, t'appelles la fonction récursive qui va afficher le nom du fichier et retourner à la fonction appelante si c'est pas un dossier (vu que opendir() va fail); la fonction appelante qui va continuer tranquillement à parcourir les fichiers et s'appeler elle-même...
Mon blog

Code :
push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp

"VIM est merveilleux" © supersnail
+1 (0) -1 (0) Répondre
21-04-2013, 11h48
Message : #6
Kiwazaru Hors ligne
Padawan d'un super escargot
*



Messages : 284
Sujets : 26
Points: 139
Inscription : Mar 2012
RE: [C] Parcours récursif des dossiers
Le truc là c'est qu'on veut faire par exemple:

fichier
fichier
fichier
dossier -> fichier, fichier, dossier, fichier, fichier -> (dans dossier) fichier, fichier
fichier

On parcourt donc 3 fois la fonction qui va afficher : "Fichier + Fichier + Fichier" et là il va detecter dossier, du coup avec votre code on va rentrer dans dossier qui va nous lister "Fichier + Fichier" qui va detecter le dossier et rentrer dedans et lister "Fichier + Fichier", sauf qu'il aura zappé 3 fichiers, donc il faudra faire une genre de sauvegarde du dossier précédent à chaque dossier parcouru pour aller parcourir la fin de chaque dossier etc...
Toucher au Kernel, c'est un peut comme se shooter au LSD, on pense pouvoir tout faire mais ça finit souvent mal.
+1 (0) -1 (0) Répondre
21-04-2013, 13h05
Message : #7
supersnail Hors ligne
Éleveur d'ornithorynques
*******



Messages : 1,610
Sujets : 72
Points: 466
Inscription : Jan 2012
RE: [C] Parcours récursif des dossiers
Ben c'est le principe de la récursivité ça.... Quand tu sors d'une fonction, tu reviens dans la fonction parente juste après l'appel de la fonction (la magie des stack frames & tout le bordel), so jvois pas pourquoi ça zapperait des fichiers.

La récursivité, learn how 2 use it Wink
Mon blog

Code :
push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp

"VIM est merveilleux" © supersnail
+1 (0) -1 (0) Répondre
21-04-2013, 13h18
Message : #8
Kiwazaru Hors ligne
Padawan d'un super escargot
*



Messages : 284
Sujets : 26
Points: 139
Inscription : Mar 2012
RE: [C] Parcours récursif des dossiers
Yep mais là, la fonction qui s'appelle elle même (je savais pas qu'on pouvais faire ça btw :p d'où mes deux fonctions x) ) elle fait toujours la même chose cet à dire check si on a un dossier et si on a un dossier on rentre dedans et on appelle la même fonction et ainsi de suite, je vois pas le moment où on check si il y a d'autre(s) fichier derrière...
Toucher au Kernel, c'est un peut comme se shooter au LSD, on pense pouvoir tout faire mais ça finit souvent mal.
+1 (0) -1 (0) Répondre
21-04-2013, 13h24 (Modification du message : 21-04-2013, 13h25 par supersnail.)
Message : #9
supersnail Hors ligne
Éleveur d'ornithorynques
*******



Messages : 1,610
Sujets : 72
Points: 466
Inscription : Jan 2012
RE: [C] Parcours récursif des dossiers
Ben quand tu fais un "return;" ? (ou simplement à la fin de la fonction)

Pour simplifier, il se passe ceci:
Code :
print du dossier1
opendir du "dossier1"
readdir du dossier1 et appel de la fonction avec le path du fichier1
  | print du fichier1
  | opendir du "fichier1" => FAIL, return
readdir du dossier1 et appel de la fonction avec le path du sousdossier1
  | print du sousdossier1
  | opendir du "sousdossier1"
  | readdir du fichier2 et appel de la fonction avec le path du fichier1 (qui affiche le fichier2 et retourne)
  | [...]
  | La boucle est terminée, on sort de la fonction
readdir du dossier1 et appel de la fonction avec le path du fichier3
[...]
sortie de la fonction

J'espère que mon schéma pourri t'aidera à mieux comprendre ce qui se passe Wink
Mon blog

Code :
push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp

"VIM est merveilleux" © supersnail
+1 (0) -1 (0) Répondre
21-04-2013, 13h26
Message : #10
Kiwazaru Hors ligne
Padawan d'un super escargot
*



Messages : 284
Sujets : 26
Points: 139
Inscription : Mar 2012
RE: [C] Parcours récursif des dossiers
Ahhh ! Return peut s'utiliser donc comme ça aussi? Big GrinD
Intéréssant ça :>

Au temps pour moi je savais pas Smile On en apprend des choses :p
Toucher au Kernel, c'est un peut comme se shooter au LSD, on pense pouvoir tout faire mais ça finit souvent mal.
+1 (0) -1 (0) Répondre
21-04-2013, 17h23
Message : #11
InstinctHack Hors ligne
Posting Freak
*



Messages : 1,366
Sujets : 184
Points: 299
Inscription : Dec 2011
RE: [C] Parcours récursif des dossiers
Merci encore bofh pour ton aide ici et sur irc.
L'objectif est désormais de ne lister QUE les répertoires et de lancer une fonction à chaque fois :
Code :
on compte les fichiers qui match à un motif dans ce répertoire
on tente de remontrer d'un niveau puis on refait l'opération précédante
on tente de remontrer d'un niveau puis on refait l'opération précédante
En gros, je compte les fichiers .flv dans le répertoire, dans ../ et dans ../../
voilà le code en php
Code PHP :

<?php
$data=array();
function parcourir_repertoire($repertoire)
{
        global $data;
        $le_repertoire = @opendir($repertoire);
                if($le_repertoire==false)return;//en cas d'erreur (403 par exemple) on return
        while($fichier = @readdir($le_repertoire))// parcours des fichiers
        {
                $element=$repertoire.'/'.$fichier;
                if(in_array($element,array('//proc','//sys')))continue;//on évite certains répertoires
                if ($fichier == "." || $fichier == "..") continue;

                if(is_dir($element))
                {
                        $data[$element]=nombre_reps($element,2,array('flv'));// on stocke le nombre de fichier qui possède les extensions dans l'array et cela sur x niveaux (3 == . ../ ../../ )
                        parcourir_repertoire($element);//on parcours le répertoire
                }
        }
        closedir($le_repertoire);
}

function nombre_reps($repertoire,$nombre,$ext)
{
        $a=0;
        $a+=nombre_rep($repertoire,$ext);//on ajoute le nombre de fichier correspondants dans le repertoire

        for($b=0;$b<$nombre;$b++)//on fait autant de boucles que nécessaire
        {
                $repertoire=dirname($repertoire);//on remonte dans l'arbo
                $a+=nombre_rep($repertoire,$ext);//on refait la meme
        }
        return $a;
}

function nombre_rep($repertoire,$ext)
{
        $a=0;
        if(is_dir($repertoire))//si c'est bien un répertoire
        {
                $b=@scandir($repertoire);// comment ça c'est mal ? :')
                if($b!=false)//si pas d'erreur
                {
                        foreach($b as $key=>$value)//on parcours les elements
                        {
                                $c=pathinfo($repertoire.'/'.$value);//on récupère les données sur lui
                                if(isset($c['extension']) && in_array($c['extension'],$ext))//si il as une extension et qu'elles nous intéresse
                                        $a++;
                        }
                }
        }
        return $a;
}

$temps_debut = microtime(true);
parcourir_repertoire('/home');
$temps_fin = microtime(true);
echo "Temps d'exécution : ".round($temps_fin - $temps_debut, 3).PHP_EOL;

arsort($data,SORT_NATURAL);
$a=0;
foreach($data as $key=>$value)
{
        $a++;
        if($a==10)break;
        echo $key." > ".$value.PHP_EOL;
}
 


Si le challenge intéresse quelqu'un de le transcoder en C Wink
Citation :un jour en cours de java j'ai attrapé les seins d'une fille mais elle m'a frappé en disant "c'est privé !!"
j'ai pas compris pourquoi, je croyais qu'on était dans la même classe
+1 (0) -1 (0) Répondre
22-04-2013, 06h54
Message : #12
Sh4dows Hors ligne
Tweetos
*



Messages : 293
Sujets : 5
Points: 49
Inscription : Dec 2012
RE: [C] Parcours récursif des dossiers
Sinon dans ma présentation il y avait mon myls avec l'option -R (ls -R) Tongue
Ce n'était pas une fonction récursive par contre il fonctionnait malgré un code dégueulasse..

https://github.com/Sh4dows/myls/blob/master/main.c <-- fonctions spider
Faites ce que je dis et non ce que je fais !
+1 (0) -1 (0) Répondre
22-04-2013, 11h20
Message : #13
sakiir Hors ligne
[sakiir@Ubuntu]:~$ ./ExploitMe ShellC0de
*



Messages : 411
Sujets : 51
Points: 34
Inscription : Sep 2012
RE: [C] Parcours récursif des dossiers
j'ai deja essayé de faire ca sous Win , et ca été tres difficile .. ^^
Bonne chance
+1 (0) -1 (0) Répondre


Sujets apparemment similaires…
Sujet Auteur Réponses Affichages Dernier message
  [C TOTW 2] Parcours de tableau ark 5 313 29-09-2014, 17h44
Dernier message: crown
  [C++] Parcours de dossier récursif Dobry 2 129 04-03-2012, 11h13
Dernier message: Dobry
  [C] Need help pour free en recursif... ark 3 174 27-11-2011, 00h57
Dernier message: walafc0

Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)
N-PN
Accueil | Challenges | Tutoriels | Téléchargements | Forum | Retourner en haut