csearchmallocminixdirent.h

Search function in minix 3.1


I've been trying to implement a search function in minix that will look for a file in the current or subdirectories and print the path. So far my code compiles without fail but it returns only a couple weird ascii characters for some reason, any idea of what I'm doing wrong?

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

_PROTOTYPE(int main, (int argc, char **argv));
_PROTOTYPE(char *find_file, (char *name, char *directory));

int main(argc, argv)
int argc;
char **argv;
{
    char *path = find_file(argv[0], "./");
    if (strcmp(path, "") == 0) {
        printf("file could not be found.");
    } else {
        printf("File found in: %s\n", path);
    }
    return(0);
}

char *find_file(name, directory)
char *name;
char *directory;
{
    DIR *d;
    struct dirent *e;
    struct stat s;

    char *dr;
    char *res;
    char *result;

    d = opendir(directory);
    if (d != NULL) {
        while (e = readdir(d)) {
            if (e->d_name == name)
                return name;
        }
    }
    closedir(d);

    d = opendir(directory);
    if (d != NULL) {
        while (e = readdir(d)) {
            stat(e->d_name, &s);
            if (s.st_mode & S_IFDIR) {
                dr = malloc(strlen(directory) + strlen(e->d_name) + 2);
                strcpy(dr, directory);
                strcat(dr, e->d_name);
                strcat(dr, "/");
                res = find_file(name, dr));
                if (strcmp(res, "") != 0) {
                    strcpy(result, e->d_name);
                    strcat(result, "/");
                    strcat(result, res);
                    return result;
                }
            }
        }
    }
    closedir(d);
    return "";
}

So I first check if the file is in the current directory before going into the child folders that's why I open and close the directory twice. The only thing I suspect may be unorthodox is using malloc straight off the bat and declaring a set amount, is that a no no? Thanks for the help <3

EDIT: so I tried to use malloc with the size of the string instead of the set amount but no change, here's a screenshot:

enter image description here

EDIT2: Updated my code thanks to the suggestions, still not working 100% as it's going parent folders or something weird like that, will post the solution if I manage to get it working perfectly (y)

EDIT3: I've managed to get it working (to some degree) it can work perfectly but in some cases it doesn't find the existing file, don't know the reasons for this and too tired to determine why ^_^ here's the final working code for anyone else who will look for a similar solution in the future:

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

_PROTOTYPE(int main, (int argc, char **argv));
_PROTOTYPE(char *find_file, (char *name, char *directory));

int main(argc, argv)
int argc;
char **argv;
{
    char *path = find_file(argv[1], "./");
    if (strcmp(path, "") == 0) {
        printf("file could not be found.\n");
    } else {
        printf("File found in: %s\n", path);
    }
    return(0);
}

char *find_file(name, directory)
char *name;
char *directory;
{
    DIR *d;
    struct dirent *e;
    struct stat s;

    char *dr;
    char *res;
    char *result;

    d = opendir(directory);
    if (d != NULL) {
        while (e = readdir(d)) {
            if (strcmp(e->d_name, name) == 0)
                return e->d_name;
        }
    }
    closedir(d);

    d = opendir(directory);
    if (d != NULL) {
        while (e = readdir(d)) {
            stat(e->d_name, &s);
            if (strcmp(e->d_name, ".") != 0 && strcmp(e->d_name, "..") != 0) {    
                if (s.st_mode & S_IFDIR) != 0) {
                    dr = malloc(strlen(directory) + strlen(e->d_name) + 2);
                    strcpy(dr, directory);
                    strcat(dr, e->d_name);
                    strcat(dr, "/");
                    res = find_file(name, dr));
                    if (strcmp(res, "") != 0) {
                        result = malloc(strlen(e->d_name) + strlen(res) + 2);
                        strcpy(result, e->d_name);
                        strcat(result, "/");
                        strcat(result, res);
                        return result;
                    }
                }
            }
        }
    }
    closedir(d);
    return "";
}

For some reason the file name was passed in argv1 not argv[0] which is weird since I've implemented another function that passed the file name through argv[0]... Minix ¯|(ツ)


Solution

  • You are giving an unintialized pointer to stat.

    struct stat *s
    ....
    stat(e->d_name, s);
    

    What you should do instead is:

    struct stat s
    ....
    stat(e->d_name, &s);
    

    Another problem (among other things) is this part:

    strcpy(res, find_file(name, dr));
    if (res != "") {
    

    You can not compare string like this in C, you have to use strcmp(res, "") == 0, because you are comparing pointers here. It may even work in this case (if static strings are reused by your compiler), but in the general case it will not.