Problème avec certains fichiers [C] !

Résolu
StayCrunchy Messages postés 43 Date d'inscription mercredi 24 novembre 2010 Statut Membre Dernière intervention 26 février 2014 - 6 avril 2012 à 13:37
StayCrunchy Messages postés 43 Date d'inscription mercredi 24 novembre 2010 Statut Membre Dernière intervention 26 février 2014 - 6 avril 2012 à 18:39
Bonjour,

Pardonnez le titre de mon sujet qui est assez peu explicite, mais je peinais à trouver mieux.
Je viens donc ici (une nouvelle fois) pour demander votre aide. En effet j'ai un problème. Je rédige un petit programme qui parcours tous les dossiers de mon ordinateur dans le but de lister tous les fichiers présents dans un fichier. Cependant je rencontre un problème lorsque je fais tourner mon prog sous Ubuntu (que je ne retrouve pas sous Windows).
Mon programme ne fait pas la différence entre les dossiers et les liens vers dossier et les liens vers fichiers. Ce qui me pose le problème suivant :

Vendredi 06/04/2012 a 13:02:20  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/dev/fd/4/". // >> "4" n’étant pas un dossier
Vendredi 06/04/2012 a 13:02:36  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:02:39  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:02:43  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:02:46  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:02:49  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:02:52  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:02:55  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:02:58  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:03:00  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".
Vendredi 06/04/2012 a 13:03:03  start_scan.c (135):
> Erreur lors de l'ouverture du dossier "/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/proc/1688/cwd/dev/fd/4/".


Après verification dans dossier concerné,
"/dev/fd/4/" >> "fd" est un "Lien vers dossier (inode/directory)" et "4" est un "Lien vers tube (inode/fifo)".

Ensuite, autre problème :
"/proc/1688/cwd/" qui se répète en boucle. "cwd" est un "Lien vers dossier (inode/directory)" et visiblement mon programme l'ouvre comme un dossier normal et continue son travail, provoquant une boucle infinie.

Enfin pour finir, le bout de code de mon programme qui verifie si un fichier est un fichier ou un dossier :
	
if( ( d_dossier=opendir(d_name) ) != NULL)
{
closedir(d_dossier);
nb_dossier++;
liste_dossier = (char**)ajouter_ligne( liste_dossier , d_name, nb_dossier);
}
else
{	nb_fichier++;
liste_fichier = (char**)ajouter_ligne(liste_fichier, (*inf).d_name, nb_fichier);
}

je ne connais pas d'autres moyens de le faire...
Comment ignorer les fichiers "lien" ? Comment les reconnaître dans un premier temps ?

d'avance merci ;)

6 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
6 avril 2012 à 17:55
Remplace stat par lstat :)

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
6 avril 2012 à 14:39
Bonjour.

C'est normal, sous Unix, il existe différents type de fichier, et il te faut les gérer (notamment les liens).
Pour cela tu peux utiliser la macro IS_REG pour savoir si le fichier est un fichier "normal" ou non.
if(S_ISREG(stat_info.st_mode))
{
    //file is regular
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
StayCrunchy Messages postés 43 Date d'inscription mercredi 24 novembre 2010 Statut Membre Dernière intervention 26 février 2014
6 avril 2012 à 15:47
Merci,

J'ai essayé avec stat() et la macro.

alors j'ai modifié mon code en :
if(stat(d_name, &stat_file) != 0)
{
debug("Erreur retournee par "stat()".");
return -1;
}

if( S_ISFIFO(stat_file.st_mode)) exit(-1);
if( S_ISLNK(stat_file.st_mode)) exit(-1);
if( S_ISDIR(stat_file.st_mode))
{
printf("dir : %s\n", d_name);
nb_dossier++;
liste_dossier = (char**)ajouter_ligne( liste_dossier , d_name, nb_dossier);
}
if(S_ISREG(stat_file.st_mode))
{
printf("reg : %s\n", d_name);
nb_fichier++;
liste_fichier = (char**)ajouter_ligne(liste_fichier, (*inf).d_name,nb_fichier);
}


mais toujours le même problème :
dir : /dev/fd       // >> Lien vers dossier (inode/directory)
reg : /dev/core
dir : /dev/pts
dir : /dev/mapper
dir : /dev/input
dir : /dev/bus
dir : /dev/net
dir : /dev/pktcdvd
dir : /dev/bus/usb
dir : /dev/bus/usb/002
dir : /dev/bus/usb/001
dir : /dev/disk/by-label
dir : /dev/disk/by-uuid
dir : /dev/disk/by-path
dir : /dev/disk/by-id
reg : /dev/fd/3    // >> Lien vers connecteur réseau (inode/socket)
dir : /dev/fd/4   // >> Lien vers tube (inode/fifo)


Je pense avoir mal fait quelque chose, mais je ne vois pas quoi.
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
6 avril 2012 à 15:58
Tu peux me donner un code minimaliste complet (qui compile) qui met en avant ton problème ?
Je vais le tester sur ma machine.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
StayCrunchy Messages postés 43 Date d'inscription mercredi 24 novembre 2010 Statut Membre Dernière intervention 26 février 2014
6 avril 2012 à 17:12
main.c
int main()
{
      start_scan("/"); 
      return 0;
}


start_scan.c
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include 
#include <stdio.h>
#define MAX 512

int start_scan(char *chemin_complet)
{
DIR *d_racine NULL, *d_dossier NULL;
struct dirent *inf;
FILE *f_fichier NULL, *f_dossier NULL;;
char message[255];
char d_name[MAX];
char **liste_dossier NULL, **liste_fichier NULL;
int nb_dossier 0, nb_fichier 0, i;
struct stat stat_file;
char *pSeek = NULL;

if( (d_racine = opendir(chemin_complet)) != NULL )
{
while(inf = readdir(d_racine))
{
if( (strcmp((*inf).d_name, ".") != 0) && (strcmp((*inf).d_name, "..") != 0) )
{
strcpy(d_name, chemin_complet);
strcat(d_name, "/");
strcat(d_name, (*inf).d_name);
while( (pSeek =strstr(d_name, "//")) != NULL) // supprime les doubles "//"
{
strcpy(message, pSeek+2);
*(pSeek+1) = '\0';
strcat(d_name, message);
}

if(stat(d_name, &stat_file) != 0)
{
printf("Erreur retournee par "stat(%s)".\n", d_name);
//debug("Erreur retournee par "stat(%s)".", d_name);
//return -1;
}

if( S_ISFIFO(stat_file.st_mode)) exit(-1);
if( S_ISLNK(stat_file.st_mode)) exit(-1);
if( S_ISDIR(stat_file.st_mode))
{
printf("dir : %s\n", d_name);
if(start_scan(d_name) != 0)
{	sprintf(message, "%s (%d):\n> Erreur retournee par Start_scan(%s).", __FILE__, __LINE__, d_name);
puts(message);//erreur(message);
return -1;
}
//nb_dossier++;
//liste_dossier = (char**)ajouter_ligne( liste_dossier , d_name, nb_dossier);
}
if(S_ISREG(stat_file.st_mode))
{
printf("reg : %s\n", d_name);
//nb_fichier++;
//liste_fichier = (char**)ajouter_ligne(liste_fichier, (*inf).d_name, nb_fichier);
}
}
}
closedir(d_racine);

}
else
{	sprintf(message, "%s (%d):\n> Erreur lors de l'ouverture du dossier "%s".", __FILE__, __LINE__, chemin_complet);
puts(message);
//erreur(message);
exit(-1);
//return -1;
}

return 0;
}


Voila, j'ai testé ça compile, mais toujours le même problème.
0
StayCrunchy Messages postés 43 Date d'inscription mercredi 24 novembre 2010 Statut Membre Dernière intervention 26 février 2014
6 avril 2012 à 18:39
Merci merci ^^
tu viens de sauver un clavier ;)
0
Rejoignez-nous