how can I get this readdir code sample to search other directories

10,680

Solution 1

opendir doesn't handle wildcards. It expects a real directory path. I'm not sure what you mean when you say

wildcard search works in the current directory

If you mean it works in your shell, that's to be expected. The shell will first expand the wildcard and then perform the command you typed.

So how to solve this? Expand the wildcard yourself using glob before calling opendir.


Edit: sorry, I thought you were trying to match the wildcard in the directory name. It looks like you want to match directory contents using the wildcard. In that case simply replace

if (strcmp(dp->d_name, arg) != 0)

with

if (fnmatch(arg, dp->d_name, 0) != 0)

You could also use glob for this. It will actually replace the call to opendir and the loop. Here is an example for using glob:

#include <glob.h>
#include <stdio.h>


static void lookup(const char *root, const char *arg)
{
    size_t n;
    glob_t res;
    char **p;

    chdir(root);
    glob(arg, 0, 0, &res);

    n = res.gl_pathc;
    if (n < 1) {
        printf("failed to find %s\n", arg);
    } else {
        for (p = res.gl_pathv; n; p++, n--) {
            printf("found %s\n", *p);
        }
    }
    globfree(&res);
}


int main(int argc, char *argv[])
{
    int i;
    for (i = 2; i < argc; i++)
        lookup(argv[1], argv[i]);
    return (0);
}

Solution 2

I'm not sure what you are expecting. If your program is called lookup then if you call it in the 'current directory', where that directory holds files something.1, something.2 and something.3 like this:

lookup something*

the shell will expand it to

lookup  something.1 something.2 something.3

and your program will see three command line args and will be able to find a match in the readdir loop.

If you change the opendir call to "/dev/shm" and call it from the original directory (the one that has something.[1-3]) then the shell will again expand the wildcard in the current directory. But unless the files something.1, something.2 and something.3 are also present in /dev/shm, the readdir loop will not see them.

Note that your lookup function is a bit odd. I would expect it to be more like this:

    static int lookup(const char * dir, const char *arg)
    {
        DIR *dirp;
        struct dirent *dp;

        if ((dirp = opendir(dir)) == NULL) {
            perror(dir);
            return -1;
        }

        while ((dp = readdir(dirp)) != NULL) {
            if (!strcmp(dp->d_name, arg)) {
                break;
            }
        }
        (void) closedir(dirp);

        printf("%s %s\n", dp ? "found" : "failed to find", arg);
        return 0;
    }
Share:
10,680
lacrosse1991
Author by

lacrosse1991

Updated on June 17, 2022

Comments

  • lacrosse1991
    lacrosse1991 almost 2 years

    I am currently working with a code example that initially is designed to take an argument, then search for that argument in the current directory, I've tried to make it search another directory (/dev/shm to exact) by replacing the "." with "/dev/shm" but the code turns up nothing when i search for something* (notice the wildcard). The wild card search works fine in the current directory so I do not think it is the wild card that is the problem, If someone could help me out though I would really appreciate it, thanks!

    #include <dirent.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    
    
    static void lookup(const char *arg)
    {
        DIR *dirp;
        struct dirent *dp;
    
    
        if ((dirp = opendir(".")) == NULL) {
            perror("couldn't open '.'");
            return;
        }
    
    
        do {
            errno = 0;
            if ((dp = readdir(dirp)) != NULL) {
                if (strcmp(dp->d_name, arg) != 0)
                    continue;
    
    
                (void) printf("found %s\n", arg);
                (void) closedir(dirp);
                    return;
    
    
            }
        } while (dp != NULL);
    
    
        if (errno != 0)
            perror("error reading directory");
        else
            (void) printf("failed to find %s\n", arg);
        (void) closedir(dirp);
        return;
    }
    
    
    int main(int argc, char *argv[])
    {
        int i;
        for (i = 1; i < argc; i++)
            lookup(argv[i]);
        return (0);
    }