diff options
| author | scratko <m@scratko.xyz> | 2024-05-12 18:58:18 +0300 | 
|---|---|---|
| committer | scratko <m@scratko.xyz> | 2024-05-12 18:58:18 +0300 | 
| commit | 42ed538a599be39e2a180408d0cdb5ec4e98ce99 (patch) | |
| tree | 90277b1f97ad636171549517e271c0d38537fa9e /file_finder.c | |
| download | file-finder-42ed538a599be39e2a180408d0cdb5ec4e98ce99.tar.gz file-finder-42ed538a599be39e2a180408d0cdb5ec4e98ce99.tar.bz2 file-finder-42ed538a599be39e2a180408d0cdb5ec4e98ce99.zip  | |
Initial commit
Diffstat (limited to 'file_finder.c')
| -rw-r--r-- | file_finder.c | 107 | 
1 files changed, 107 insertions, 0 deletions
diff --git a/file_finder.c b/file_finder.c new file mode 100644 index 0000000..9746a5f --- /dev/null +++ b/file_finder.c @@ -0,0 +1,107 @@ +#include <sys/types.h> +#include <dirent.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +enum { buf_size = 10 }; + +struct path_type { +    char *buffer; +    int size; +    int pos; +}; + +static void init_path(struct path_type *path) +{ +    path->buffer = malloc(buf_size); +    path->size = buf_size; +    path->pos = 0; +} + +static void copy_str(char *first, char *second, int pos) +{ +    int i; +    for(i = 0; i <= pos; ++i) +        first[i] = second[i]; +} + +static void allocate_memory(struct path_type *path) +{ +    char *tmp = malloc(path->size * 2); +    copy_str(tmp, path->buffer, path->pos); +    free(path->buffer); +    path->buffer = tmp; +    path->size *= 2; +} + +static void add_dir_into_path(char *directory_name, int length, +                              struct path_type *path) +{ +    int i; +    for(i = 0; i < length; ++i, ++path->pos) +        path->buffer[path->pos] = directory_name[i]; +    path->buffer[path->pos] = '/'; +    ++path->pos; +    path->buffer[path->pos] = '\0'; +} + +static void edit_path(struct path_type *path) +{ +    if(path->pos == 2) +        return; +    path->pos -= 2;       /* skip '/' and '\0' */ +    for( ; path->buffer[path->pos] != '/'; --path->pos) +        path->buffer[path->pos] = '\0'; +    ++path->pos; +} + +static void recursive_step(char *target_name, struct path_type *path) +{ +    int name_length; +    char *directory_name; +    DIR *current_directory; +    struct dirent *data; +    directory_name = path->buffer; +    current_directory = opendir(directory_name); +    while((data = readdir(current_directory))) { +        if(data->d_type == DT_DIR) { +            if(!strcmp(data->d_name, target_name)) +                printf("%s%s\n", path->buffer, data->d_name); +            if(!strcmp(data->d_name, ".") || !strcmp(data->d_name, "..")) +                continue; +            name_length = strlen(data->d_name); +            name_length += 2; /* slash and null character */ +            while(name_length + path->pos > path->size) +                allocate_memory(path); +            add_dir_into_path(data->d_name, strlen(data->d_name), path); +            recursive_step(target_name, path); +            edit_path(path); +        } else if(!strcmp(data->d_name, target_name)) +            printf("%s%s\n", path->buffer, data->d_name); +    } +    closedir(current_directory); +} + +static void set_start_path(struct path_type *path) +{ +    path->buffer[path->pos] = '.'; +    ++path->pos; +    path->buffer[path->pos] = '/'; +    ++path->pos; +    path->buffer[path->pos] = '\0'; +} + +int main(int argc, char **argv) +{ +    struct path_type path; +    if(argc != 2) { +        perror("enter only two params"); +        return 1; +    } +    init_path(&path); +    set_start_path(&path); +    recursive_step(argv[1], &path); +    free(path.buffer); +    return 0; +}  | 
