Thread: Directory crawler problems

  1. #16
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Well, this:
    >>struct dirent **check_dirent
    says check_dirent is a pointer to a pointer to a struct dirent, which makes this incorrect:
    >>check_dirent->d_name

    You have an extra level of indirection to think about. If you had declared it like so:
    >>struct dirent *check_dirent
    then this would have been OK:
    >>check_dirent->d_name
    ... I'm not saying you should change it to that, more using it to help highlight your error.

    As for this:
    >>check_stat.st_mode
    check_stat is a pointer, so you need to use the -> syntax rather than dot.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  2. #17
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    >>check_dirent->d_name
    ... I'm not saying you should change it to that, more using it to help highlight your error.
    You got me, I have no idea.

    Code:
    int isdir(struct dirent **check_dirent) {
        struct stat     check_stat;
        
        if( stat(*check_dirent->d_name, &check_stat) == 0 ) {
            if( S_ISDIR(check_stat.st_mode) != 0 ) {
                //
            }
        }
    
        return 1;
    }

  3. #18
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Maybe:
    Code:
    if( stat((*check_dirent)->d_name, &check_stat) == 0 ) {
    or, just pass a pointer to the function, rather than the address of a pointer.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  4. #19
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    Im not sure how i can enter a 2nd level directory.

    Ive tried "./dirname", but that doesnt seem to work.

    I started thinking of chdir(im really starting to like the posix book), but then how could i do the opendir call?

    I can hard code this if i have to, but is there away around this?

  5. #20
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Somehow, either hard or dynamically, put the directory name into the call to opendir(). Post what you've tried if it ain't working.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #21
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    I screwed up something, Im still not getting a 3rd level.

    It does compile now.

    Code:
    #define PORTAGE_DIR     "I:\\tmp"
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <dirent.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    int isdir(struct dirent **check_dirent) {
        struct stat     check_stat;
        
        if( stat((*check_dirent)->d_name, &check_stat) == 0 ) {
            if( S_ISDIR(check_stat.st_mode) != 0 ) {
                if( strcmp( (*check_dirent)->d_name , "." ) != 0 ) {
                    if( strcmp( (*check_dirent)->d_name , ".." ) != 0 ) {
                        return 0;
                    }
                }
            }
        }
    
        return 1;
    }
    
    int main() {
        DIR             *master = opendir(PORTAGE_DIR);
        struct  dirent  *master_dirent;
        DIR             *crawl;
        struct  dirent  *crawl_dirent;
        
        char *open = NULL;
        
        if(master != NULL) {
            while( (master_dirent = readdir(master)) != 0 ) {
                if( isdir(&master_dirent) == 0 ) {
                    open = malloc( strlen(PORTAGE_DIR) + strlen(master_dirent->d_name) + 3 );
                    sprintf(open, "%s\\\\%s", PORTAGE_DIR, master_dirent->d_name);
                    
                    crawl = opendir(open);
                    
                    while( (crawl_dirent = readdir(crawl)) != 0 ) {
                        if( isdir(&crawl_dirent) == 0 ) {
                            printf("%s\n", crawl_dirent->d_name);
                        }
                    }
                    
                    closedir(crawl);
                }
            }
            
            closedir(master);
        } else {
            perror("Error: ");
        }
    
        return 0;
    }

  7. #22
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I've wandered through this thread, an FAQ, and another recent post, and slammed something together that looks for .mp3 files up to MAXLEVEL directories deep from the starting directory. It's done in Borland on a Windows box; it seems to find such files on my system.

    Could this be anything similar to what you are trying to do? (Some of my guesses are off the mark, however.)
    Code:
    #include <stdio.h> 
    #include <dir.h> 
    #include <string.h>
    #include <dos.h> /* for FA_DIREC and FA_ARCH */
    
    #define MAXLEVEL 3
    
    #define ALL_ATTS  (FA_DIREC | FA_ARCH)
    
    int strend(const char *s, const char *t)
    {
       size_t slen = strlen(s);
       size_t tlen = strlen(t);
       int    rc;
    
       if ( slen < tlen )
          rc = 0;
       else if ( strcmp(s + (slen - tlen), t) == 0 )
          rc = 1;
       else
          rc = 0;
    
       return rc;
    }
    
    #ifdef MAXLEVEL
    int maxlevel = 0;
    #endif
    
    void walker(const char *path, const char *findme)
    {
       struct ffblk  finder;
       unsigned int  res;
    #ifdef MAXLEVEL
       if(++maxlevel > MAXLEVEL)
       {
          return;
       }
    #endif
       chdir(path);
    
       for ( res = findfirst("*.*", &finder, ALL_ATTS); res == 0; res = findnext(&finder) )
       {
          if ( strcmp(finder.ff_name, "." ) == 0 ) continue;  /* current dir */
          if ( strcmp(finder.ff_name, "..") == 0 ) continue;  /* parent dir  */
          /* 
           * If its a directory, examine it
           * else compare the filename with the one we're looking for
           */
          if ( finder.ff_attrib & FA_DIREC )
          {
             char newpath[MAXPATH];
             strcpy(newpath, path);
             strcat(newpath, "\\");
             strcat(newpath, finder.ff_name);
             chdir(finder.ff_name);
             walker(newpath, findme);
             chdir("..");
             --maxlevel;
          }
          else
          {
             if ( strend(finder.ff_name, findme) )
             {
                printf("%s\\%s\n", path, finder.ff_name);
                fflush(stdout);
             }
          }
       }
    }
    
    int main(void)
    {
       walker("c:\\Program Files", ".mp3");
       return(0);
    }
    [EDIT]Salem, vVv and Hammer (FAQ), Prelude, me.
    Last edited by Dave_Sinkula; 08-15-2003 at 09:21 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #23
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by mart_man00
    I screwed up something, Im still not getting a 3rd level.

    It does compile now.
    Well, you never enter the second level. This is the flow of your code:
    Code:
    int main() 
    {
        if(master != NULL) 
        {
            while(reading master directory) 
           {
                while(reading subdirectory)
                {
                        printf(subsubdirectory);
                }
            }
        }
    
        return 0;
    }
    You never open the second subdirectory, you simply list it.

    Also, you really should use C's false & true definitions of 0 and 1 in isdir(). You return them backwards. Don't switch them around unless you have a very good reason.

    Also, make the isdir() routine more readable:
    Code:
    int isdir(struct dirent **check_dirent) {
        struct stat     check_stat;
        
        if (stat(*check_dirent)->d_name, &check_stat) return 0;     
        if (!S_ISDIR(check_stat.st_mode))         return 0;
        if (!strcmp((*check_dirent)->d_name , "." ))  return 0;
        if (!strcmp((*check_dirent)->d_name , ".." )) return 0;
    
        return 1;
    }
    Some will complain about multiple returns, that's a personal choice.
    Last edited by WaltP; 08-16-2003 at 01:53 AM.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  9. #24
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    [QUOTE]Well, you never enter the second level. [QUOTE]
    crawl = opendir(open); /* This doesnt open??? */

    Also, make the isdir() routine more readable:
    Um, I dont get yours. Yours will only return 1 if every if fails, one fail means its not a directory.

    Thanks Dave_Sinkula, but id like it to also work in Linux, so no dos.h.

  10. #25
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by mart_man00
    Um, I dont get yours. Yours will only return 1 if every if fails, one fail means its not a directory.
    Yes, what's not to understand.
    If it's a file, it's not a directory, return FALSE
    If it's a "." consider it not a directory, return FALSE
    If it's a ".." consider it not a directory, return FALSE
    Here it must be a valid directory, return TRUE

    In the calling routine,
    Code:
    if (isdir(xxx))
    {
        printf("xxx is a directory to use");
    }
    else
    {
        printf("Don't use xxx, it's not considered a directory");
    }
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  11. #26
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    Man, this simple task is becoming an epic saga
    Lol, yeah. I think my record is like 4 pages, 1 to go
    ----------

    What about me not opening the directory? Whats wrong with my version now?

    isdir seems to work now, Im wondering why im getting nothing back.

    Thanks guys

  12. #27
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    I just noticed that in windows it wont print the dir if its name is 'Test' something screwy is going on...

    <edit>
    tried a IRC room, this is screwy. Need guru help.
    Last edited by mart_man00; 08-17-2003 at 12:02 AM.

  13. #28
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    Shameless bumb.

  14. #29
    Registered User
    Join Date
    Jul 2002
    Posts
    913
    sorry to bump again.

    It varies from windows to linux, im going to try to keep it linux.

    This line seems to cause some problem
    [code]if( stat(&check_dirent->d_name, &check_stat) == 0 ) {[/code[

    If i remove it works, but then im not checking for errors. Confused.

  15. #30
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    I'm sure I don't need to remind you not to bump threads, not matter how shamelessly

    Anyway, I guess you've had your fingers in the programming pie again, so better post your code (again) and we'll see where you're at. And try include some form of decent error message or problem description.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Finding files in a directory
    By smarta_982002 in forum C Programming
    Replies: 1
    Last Post: 01-25-2008, 10:10 AM
  2. Building a tree from a directory structure
    By geekoftheweek in forum C Programming
    Replies: 2
    Last Post: 11-26-2007, 03:15 AM
  3. About current working directory
    By George2 in forum Linux Programming
    Replies: 3
    Last Post: 05-02-2007, 10:34 PM
  4. fprintf in directory
    By rkooij in forum C Programming
    Replies: 9
    Last Post: 03-09-2006, 04:23 AM
  5. problems with my first attempt at a Qt application...
    By Captain Penguin in forum C++ Programming
    Replies: 0
    Last Post: 10-01-2002, 09:14 PM