Forum Programmation.c Un probleme sur mon code

Posté par  .
Étiquettes : aucune
0
29
nov.
2006
Bonjour,
Je suis en train de recoder la fonction ls, mais javou avoir quelque problemes.
La fonction marche plutot bien mais lorsque je fais ./exec /etc par exemple
il ne me donne pas le reel utilisateur et met mon login comme utilisateur. je me demande pourquoi. si vous avez une idee je suis preneur

Lorsque je le lance ./exec MP3 par exemple il m'affiche bien tout ce qu'il y a dans le dossier mp3 avec la bonne personne (moi en occurence)

mais si je le lance avec ./exec /etc ou ./exec /home etc ... des fichier appartenant au root sont mis a mon nom. (sur le programme biensur).


#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <grp.h>
#include <pwd.h>
#include <sys/dir.h>
#include <dirent.h>

void read_folder(DIR *dir)
{
struct dirent *d;
struct stat stats;
struct group *g;
struct passwd *pwd;

while (d = readdir(dir))
{
stat(d->d_name, &stats);
g = getgrgid(stats.st_gid);
pwd = getpwuid(stats.st_uid);
printf("~~ Variables de stat sur %s ~~ \n\n", d->d_name);
printf("-Peripherique: %d\n", stats.st_dev);
printf("-Numero I-Noeud: %d\n", stats.st_ino);
printf("-Modes: %o\n", stats.st_mode);
printf("-Nb Liens materiels: %d\n", stats.st_nlink);
printf("-UID: %s\n", pwd->pw_name);
printf("-GID: %s\n\n", g->gr_name);
}
}

int main(int argc, char **argv)
{
DIR *dir;

if (argc != 2)
{
printf("Comment on m'utilise ?\n%s dossier", argv[0]);
exit(1);
}
if ((dir = opendir(argv[1])) == NULL)
{
printf("Probleme avec Opendir.");
exit(1);
}
read_folder(dir);
closedir(dir);
}
  • # Et sans getgr[ug]id ?

    Posté par  . Évalué à 2.

    Et si tu affiches directement stats.st_gid, et stats.st_uid, avant l'appel de getgr[ug]id, ce sont bien les bonnes valeurs ?

    Ca ne corrigera probablement pas ce problème précis, mais il faut aussi rajouter des tests d'erreur pour stat, getgrid, etc.
    • [^] # Re: Et sans getgr[ug]id ?

      Posté par  . Évalué à 2.

      et la réponse est "non !" :-)

      indice : ton prog fonctionnera toujours bien si tu l'appelles dans le répertoire courant. (genre tu te déplaces dans /etc, et tu appelles ton prog à partir de là).
      ça te met sur la voie ?

      sinon, c'est une assez mauvaise idée d'appeler ton prog 'exec', puisqu'il y a déjà une commande qui porte ce nom. Essaie de trouver mieux ...
      • [^] # Re: Et sans getgr[ug]id ?

        Posté par  (site web personnel) . Évalué à 3.

        yep, autant l'appeler test (et oublier le ./ devant :p )
        • [^] # Re: Et sans getgr[ug]id ?

          Posté par  . Évalué à 2.

          mouhahaha !
          oui, ben on l'a tous fait je crois ... en tout cas, moi, je l'ai fait ;-)
          • [^] # Re: Et sans getgr[ug]id ?

            Posté par  . Évalué à 1.

            Non ba ca a pas l'air de marcher, puis maintenant que je verifie le retour de stats il me lache une jolie erreur apres avoir lu dans le dossier le fichier . .. Donc il me dit bien a qui appartient . (Quoi que jsuis pas sur qu'il m'appartienne) et .. mais apres les autres fichiers nada ya une erreur. Apres verification, si ils m'appartiennent drwxr-xr-x 3 mon_login rendu 512 Nov 30 03:22 . drwx------ 4 mon_login rendu 512 Nov 30 11:32 .. -rw-r--r-- 1 mon_login rendu 4 Nov 29 17:07 c -rw-r--r-- 1 mon_login rendu 5 Nov 29 17:07 d -rw-r--r-- 1 mon_login rendu 3 Nov 29 17:07 l drwxr-xr-x 2 mon_login rendu 512 Nov 29 11:48 tmp #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <grp.h> #include <pwd.h> #include <sys/dir.h> #include <dirent.h> void read_folder(DIR *dir) { #define S_ISUID 0004000 /* set user id on execution */ #define S_ISGID 0002000 /* set group id on execution */ struct dirent *d; struct stat stats; struct group *g; struct passwd *pwd; while (d = readdir(dir)) { if (stat(d->d_name, &stats) != 0) { printf("%d", stat(d->d_name, &stats)); printf ("erreur\n"); exit (-1); } g = getgrgid(stats.st_gid); pwd = getpwuid(stats.st_uid); printf("~~ Variables de stat sur %s ~~ \n\n", d->d_name); printf("-Peripherique: %d\n", stats.st_dev); printf("-Numero I-Noeud: %d\n", stats.st_ino); printf("-Modes: %o\n", stats.st_mode); printf("-Nb Liens materiels: %d\n", stats.st_nlink); printf("-UID: %s\n", pwd->pw_name); printf("-GID: %s\n\n", g->gr_name); } } int main(int argc, char **argv) { static DIR *dir; if (argc != 2) { printf("Comment on m'utilise ?\n%s dossier", argv[0]); exit(1); } if ((dir = opendir(argv[1])) == NULL) { printf("Probleme avec Opendir."); exit(1); } read_folder(dir); closedir(dir); }
            • [^] # Re: Et sans getgr[ug]id ?

              Posté par  . Évalué à 2.

              ouaip, t'es sur la bonne voie. Y a plus qu'à comprendre pourquoi stat renvoie une erreur. Relis attentivement le man et le prototype de stat.
              Pour rappel, . désigne le répertoire courant, et .. le répertoire parent et sont donc présent dans tous les répertoires.

              ps: chez moi, ton prog fonctionne très bien s'il est lancé sur le répertoire courant (./<prog> .). C'est quand on le lance sur un autre répertoire que ça ne fonctionne pas.
              • [^] # Re: Et sans getgr[ug]id ?

                Posté par  . Évalué à 1.

                exact :) je vais relire le man (En esperant trouver la perle rare)
                • [^] # Re: Et sans getgr[ug]id ?

                  Posté par  . Évalué à 1.


                  stat() and lstat() will fail if:

                  [ENOTDIR] A component of the path prefix is not a directory.

                  [ENAMETOOLONG] A component of a pathname exceeded {NAME_MAX} charac-
                  ters, or an entire path name exceeded {PATH_MAX} char-
                  acters.

                  [ENOENT] The named file does not exist.

                  [EACCES] Search permission is denied for a component of the
                  path prefix.

                  [ELOOP] Too many symbolic links were encountered in translat-
                  ing the pathname.

                  [EFAULT] sb or name points to an invalid address.

                  [ENXIO] The named file is a character special or block special
                  file, and the device associated with this special file
                  does not exist.

                  [EIO] An I/O error occurred while reading from or writing to
                  the file system.

                  [EBADF] A badly formed v-node was encountered. This can hap-
                  pen if a file system information node is incorrect.



                  Je pense pas que mon script soit sujet a une de ses erreurs, mais j'avou ne pas tres bien comprendre le man en sa totalite ^^

                  Maintenant que je verfie stat j'ai toujours ce probleme d'erreur, seulement chose bizard, si j'inhibe le exit(-1) il maffiche bien le printf("Erreur"); mais me donne bien le nom des fichiers donc j'avou ne pas bien comprendre.

                  Une question:

                  Est ce que a chaque fois que j'qppel stat la structure se vide bien et peut etre remplacer par les nouvelles donnees ? peut-etre devraige faire un malloc ou un truc du genre et le free a chaque fois ? ou bien je m'egare ?
                  • [^] # Re: Et sans getgr[ug]id ?

                    Posté par  . Évalué à 2.

                    "je pense pas que mon script soit sujet a une de ses erreurs"

                    es-tu bien sur ? que vaut le errno en retour de stat ?
                    (cf man errno, strerror, ...)

                    autre indice, si tu fais un cd /etc et que tu appeles ton prog sur . ensuite, ça fonctionne bien.

                    stat() stats the file pointed to by path and fills in buf.

                    attention, c'est ton dernier essai, la réponse au prochain commentaire hein ! :-)
                    • [^] # Re: Et sans getgr[ug]id ?

                      Posté par  . Évalué à 1.

                      2 ENOENT No such file or directory. A component of a specified pathname
                      did not exist, or the pathname was an empty string.


                      Retour de ma fonction :

                      Erreur : 2 (errno)

                      Je ne comprend pas pourtant les fichiers existent bien ? faut-il le pathname en entier depuis la racine ?

                      Bon je suis sur que je suis a l'ouest ! la reponse :D ^^
                      • [^] # Re: Et sans getgr[ug]id ?

                        Posté par  . Évalué à 1.

                        Voila ou en est mon code


                        #include <stdio.h>
                        #include <unistd.h>
                        #include <dirent.h>
                        #include <stdio.h>
                        #include <unistd.h>
                        #include <errno.h>
                        #include <pwd.h>
                        #include <grp.h>
                        #include <time.h>
                        #include <string.h>
                        #include <sys/stat.h>
                        #include <sys/types.h>

                        void aff_info(char *file, struct stat buf)
                        {
                        struct group *g;
                        struct passwd *pwd;

                        if (stat(file, &buf) != 0)
                        {
                        printf("%d", stat(file, &buf));
                        printf ("erreur %s\n", strerror(errno));
                        exit(-1);
                        }
                        g = getgrgid(buf.st_gid);
                        pwd = getpwuid(buf.st_uid);
                        printf("~~ Variables de stat sur %s ~~ \n\n", file);
                        printf("-Peripherique: %d\n", buf.st_dev);
                        printf("-Numero I-Noeud: %d\n", buf.st_ino);
                        printf("-Modes: %o\n", buf.st_mode);
                        printf("-Nb Liens materiels: %d\n", buf.st_nlink);
                        printf("-UID: %s\n", pwd->pw_name);
                        printf("-GID: %s\n\n", g->gr_name);
                        return ;
                        }

                        void read_folder(DIR *dir)
                        {
                        struct dirent *d;
                        struct stat buf;

                        while (d = readdir(dir))
                        {
                        aff_info(d->d_name, buf);
                        }
                        }

                        int main(int argc, char **argv)
                        {
                        DIR *dir;

                        if (argc != 2)
                        {
                        printf("Comment on m'utilise ?\n%s dossier", argv[0]);
                        exit(1);
                        }
                        if ((dir = opendir(argv[1])) == NULL)
                        {
                        printf("Probleme avec Opendir.");
                        exit(1);
                        }
                        read_folder(dir);
                        closedir(dir);
                        }

                      • [^] # Re: Et sans getgr[ug]id ?

                        Posté par  . Évalué à 2.

                        "faut-il le pathname en entier depuis la racine ?"

                        on y vient ! on y vient !
                        Effectivement, ton souci vient de l'appel à stat.
                        prenons l'exemple ou tu appelles ton prog sur /etc à partir d'un autre répertoire

                        Du début à la fin, readdir travaille sur /etc
                        par contre, stat fonctionne avec des chemins relatifs ou absolus.

                        Du coup, pour les entrées . et .., chance (façon de parler, c'est pas vraiment de la chance en fait), stat arrive à les trouver dans le répertoire local et te renvoie les droits de . et de .. du répertoire courant => ce qui explique tes problèmes de users faux sur . et ..

                        à partir de là, readdir va continuer à te lister les fichiers de /etc, mais comme tu appelles stat directement avec leur nom, stat les cherche dans le répertoire local, et, ne les trouvant pas, te crache une erreur ENOENT.

                        il suffit de corriger ton appel à stat pour "stater" les fichiers dans leur répertoire et ça devrait être bon.

                        ouala :-)
                        • [^] # Re: Et sans getgr[ug]id ?

                          Posté par  . Évalué à 1.

                          trop fort tu es !

                          MERCI BEAUCOUP :D
                          • [^] # Re: Et sans getgr[ug]id ?

                            Posté par  . Évalué à 2.

                            c'était avec plaisir. Ca rappelle des souvenirs :-)
                            je me souviens d'être resté longtemps coicé sur select, dans genre appel système imbittable tant que t'as pas lu 97 fois le man ;-)

                            en tout cas, je veux plus voir de questions sur stat !
  • # J'ai peut etre trouver

    Posté par  . Évalué à 2.

    Cela vient il pas du fait que je n'utilise pas:

    Le bit Set-GID (S_ISGID) a plusieurs utilisations particulières : pour un répertoire, il indique que la sémantique BSD doit être appliquée en son sein, c'est-à-dire que les fichiers qui y sont créés héritent leur GID du répertoire et non pas du GID effectif du processus créateur, et les sous-répertoires auront automatiquement le bit S_ISGID actif. Pour les fichiers qui n'ont pas d'autorisation d'exécution pour le groupe (S_IXGRP non actif), ce bit indique qu'un verrouillage strict est en vigueur sur ce fichier.

    ??

    sinon je vois pas trop c'est la premiere fois pour moi que j'utilise ces fonctions, je dois recoder un ls disons que pour l'instant ca va a peu pres mais que ce ptit bug au niveau des repertoires me fait un peu **** ^^ :)
    • [^] # Re: J'ai peut etre trouver

      Posté par  . Évalué à 2.

      C'est beaucoup plus simple que ça.
      Suis le conseil d'alveric et test le retour de ton appel à stat (parfois, il échoue).

      Si tu es joueur, je te laisse creuser dans cette direction tout seul (c'est toujours plus gratifiant de comprendre par soi même), à moins que tu en aies super marre de chercher et que tu aies besoin d'une réponse urgente. (A ce moment là, dis-le, et je te proposerais une explication)
      • [^] # Re: J'ai peut etre trouver

        Posté par  . Évalué à 2.

        Nop sa m'nrv de chercher mais je veux aussi trouver par moi meme ! je sais c'est assez complexe c'est toujours plus sympas de se dire qu'on a pas eu tout macher dans la bouche mais quelque fois je suis perdu je veux etre sur d'etre dans la bonne direction, voila tout :D

        En tout cas merci de ton aide :)

        Je viendrai souvent ici vous dire si sa avance ... ou pas Je vais me pencher sur stat qui a en effet beaucoup de probleme apres verification .

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.