Last active
August 29, 2015 13:56
-
-
Save jtpaasch/9007775 to your computer and use it in GitHub Desktop.
Walk a directory up or down, looking for a file or folder.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <unistd.h> | |
| #include <stdlib.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <dirent.h> | |
| #include <string.h> | |
| /* | |
| * A NON-CONSTANT VARIABLE | |
| * THAT CAN BE SET BY THE FIND_UP() FUNCTION | |
| */ | |
| char found_path[1024]; | |
| /* | |
| * Function PROTOTYPES. | |
| */ | |
| int find_up(char *path, char *target); | |
| int find_down(char *path, char *target); | |
| /* | |
| * The MAIN entry point into the program. | |
| * That is to say, this function runs first. | |
| * | |
| * @return int Status code | |
| */ | |
| int main(void) { | |
| // What is the path? | |
| char path[100]; | |
| path[0] = '\0'; | |
| strcat(path, "./test"); | |
| // What are we looking for? | |
| char target[100]; | |
| target[0] = '\0'; | |
| strcat(target, "foo.txt"); | |
| // Can we find it? | |
| int success = find_up(path, target); | |
| if (success) { | |
| puts("We found it: "); | |
| puts(found_path); | |
| } else { | |
| puts("Not found"); | |
| } | |
| // Exit cleanly. | |
| return 0; | |
| } | |
| /* | |
| * Walk a directory tree up, looking for | |
| * a file/directory that matches the specified path. | |
| * | |
| * @return int | |
| */ | |
| int find_up(char *path, char *target) { | |
| DIR *stream; | |
| struct dirent *item; | |
| // Open the directory. | |
| stream = opendir(path); | |
| if (stream != NULL) { | |
| // Check each item in the directory. | |
| while ((item = readdir(stream))) { | |
| // Ignore "." and ".." items. | |
| if (strcmp(item->d_name, ".") == 0 || strcmp(item->d_name, "..") == 0) { | |
| continue; | |
| } | |
| // Is this the item we're looking for? | |
| if (strcmp(item->d_name, target) == 0) { | |
| // Store the path as "found_path". | |
| found_path[0] = '\0'; | |
| strcat(found_path, path); | |
| strcat(found_path, "/"); | |
| strcat(found_path, target); | |
| return 1; | |
| } | |
| } | |
| // What's the path to the parent directory? | |
| char parent_directory[strlen(path) + 4]; | |
| char full_path[1024]; | |
| parent_directory[0] = '\0'; | |
| strcat(parent_directory, path); | |
| strcat(parent_directory, "/../"); | |
| // If there is a parent directory, check it. | |
| int success; | |
| realpath(parent_directory, full_path); | |
| if (strcmp(full_path, "/") == 0) { | |
| success = 0; | |
| } else { | |
| success = find_up(full_path, target); | |
| } | |
| // Close the stream and return the results. | |
| (void) closedir(stream); | |
| return success; | |
| } | |
| // If we couldn't open the directory, let's print an error. | |
| else { | |
| return 0; | |
| } | |
| } | |
| /* | |
| * Walk a directory tree down, looking for | |
| * a file/directory that matches the specified path. | |
| * | |
| * @return int | |
| */ | |
| int find_down(char *path, char *target) { | |
| // We need to store our directory stream in a DIR object. | |
| DIR *stream; | |
| // We need to store items in the directory in a "dirent" struct. | |
| struct dirent *item; | |
| // We need to store info about files in a "stat" struct. | |
| struct stat info; | |
| // Open the current directory. | |
| stream = opendir(path); | |
| // Did we get a valid stream? Let's make sure the stream isn't NULL. | |
| if (stream != NULL) { | |
| // Read the stream, one item at a time. | |
| while ((item = readdir(stream))) { | |
| // Ignore "." and ".." items. | |
| if (strcmp(item->d_name, ".") == 0 || strcmp(item->d_name, "..") == 0) { | |
| continue; | |
| } | |
| // Is it the item we're looking for? | |
| if (strcmp(item->d_name, target) == 0) { | |
| return 1; | |
| } | |
| // If not, keep searching. | |
| else { | |
| // Generate a path for this file. | |
| char full_path[1024]; | |
| full_path[0] = '\0'; | |
| strcat(full_path, path); | |
| strcat(full_path, "/"); | |
| strcat(full_path, item->d_name); | |
| // Can we get some info about the item? | |
| if (stat(full_path, &info) == 0) { | |
| // Is it a directory? If so, look in it. | |
| if (info.st_mode & S_IFDIR) { | |
| int success = find_down(full_path, target); | |
| // Did we find what we're looking for? | |
| if (success) { | |
| return 1; | |
| } | |
| } | |
| } | |
| // if we got no info, report the error. | |
| else { | |
| printf("Could not stat the file: %s", full_path); | |
| } | |
| } | |
| } | |
| // Be sure to close our stream. | |
| (void) closedir(stream); | |
| return 0; | |
| } | |
| // If we couldn't open the directory, let's print an error. | |
| else { | |
| printf("Could not open the directory: %s", path); | |
| return 0; | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment