Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**********************************
- * finder.c
- *
- * CS50 AP
- * Finder
- *
- * Searches for a target string in
- * all files in a directory
- *
- **********************************/
- #define _BSD_SOURCE
- #define _GNU_SOURCE
- #include <cs50.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dirent.h>
- // struct to hold the file name and type
- typedef struct
- {
- string name;
- string type;
- }
- path;
- // struct to hold the directory info
- typedef struct
- {
- string name;
- int npaths;
- path* paths;
- }
- directory;
- // string to hold the word to seek
- string key;
- // the function to search for files in a directory and populate the struct
- directory populate(directory dir);
- // the function to recursively iterate through directories and handle files
- int seek(directory dir);
- // main - sets arguments and calls the seek function
- int main(int argc, char* argv[])
- {
- // create initial directory
- directory dir;
- // Ensure propper amount of command line arguments
- // Set "dir"s name based on command line arguments entered
- if (argc == 2)
- {
- dir.name = "./";
- }
- else if (argc == 3)
- {
- if (argv[2][(strlen(argv[2])-1)] == '/')
- {
- dir.name = argv[2];
- }
- else
- {
- printf("Error: Directory does not end with '/' \n");
- return 2;
- }
- }
- else
- {
- printf("Usage: ./<program> <search term> [directory]\n");
- return 1;
- }
- // assign search term to key.
- key = argv[1];
- // call the seek function to search files for key
- return seek(dir);
- }
- // for a given directory, searches for files and fills array in the struct
- directory populate(directory dir)
- {
- // initialize all pointers and values in the given struct
- dir.npaths = 0;
- dir.paths = NULL;
- DIR* dirp;
- struct dirent* entry;
- // opendir is a system call that opens a "directory stream" containing
- // information about all files in the given directory (represented here
- // by dir.name)
- dirp = opendir(dir.name);
- if (dirp == NULL)
- {
- printf("Opening directory failed. Check your input filepath!\n");
- return dir;
- }
- // while directory stream still contains files, seek through them
- while((entry = readdir(dirp)) != NULL)
- {
- // if entry is a directory and not '.' or '..',
- // increase file count and populate the struct
- if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
- {
- // allocate zeroed-out memory for the construction of the file name
- string name = calloc(1, strlen(dir.name) + strlen(entry->d_name) + 2);
- strcat(name, dir.name);
- strcat(name, entry->d_name);
- strcat(name, "/");
- // reallocate memory to expand the array
- dir.paths = realloc(dir.paths, (dir.npaths + 1) * sizeof(path));
- // add a new element to the array containing names and types
- path newPath = {.name = name, .type = "directory"};
- dir.paths[dir.npaths] = newPath;
- // increase file count for the directory
- dir.npaths++;
- }
- // else if entry is a file, increase file count and populate the struct
- else if (entry->d_type == DT_REG)
- {
- // allocate zeroed-out memory for the construction of the file name
- string name = calloc(1, strlen(dir.name) + strlen(entry->d_name) + 1);
- strcat(name, dir.name);
- strcat(name, entry->d_name);
- // reallocate memory to expand the array
- dir.paths = realloc(dir.paths, (dir.npaths + 1) * sizeof(path));
- // add a new element to the array containing names and types
- path newPath = {.name = name, .type = "file"};
- dir.paths[dir.npaths] = newPath;
- // increase file count for the directory
- dir.npaths++;
- }
- }
- // close directory stream using system call closedir and return struct
- closedir(dirp);
- return dir;
- }
- // recursive function to iterate through directories and search files
- int seek(directory dir)
- {
- // Segmentation fault cause is in here. Probably due to recursion.
- populate(dir);
- printf("Sanity Check. Should = 0\n");
- printf("%i\n", strncmp(dir.paths[dir.npaths].type, "file", 4));
- // Check file type
- if (strncmp(dir.paths[dir.npaths].type, "file", 4) == 0)
- {
- // Open current file.
- FILE* fp = fopen(dir.paths[dir.npaths].name, "r");
- if (fp == NULL)
- {
- printf("Critical Failure. No file found.\n");
- return 4;
- }
- printf("Sanity Check2\n");
- int i = 2;
- do
- {
- // Checks string by string for key in opened file.
- char str[50];
- fgets(str, 50, fp);
- if (strstr(str, key) != NULL)
- {
- printf("Sanity Check3\n");
- // If key is found, open new file and write file name where key was found.
- FILE* fr = fopen("found.txt", "a");
- if (fr != NULL)
- {
- fprintf(fr, "%s", dir.paths[dir.npaths].name);
- }
- fclose(fr);
- break;
- }
- // Notify user if key wasn't found.
- if (strstr(str,key) == NULL)
- {
- printf("Nothing found.\n");
- break;
- }
- fgets(str, 50, fp);
- i--;
- }
- while (i != 0); // Just needed termination
- fclose(fp);
- }
- // If type equals directory call self recursively.
- if (strncmp(dir.paths[dir.npaths].type, "directory", 9) == 0)
- {
- directory changing_name;// recursive needs to create a new struct each time.
- seek(changing_name);
- }
- else
- {
- printf("Unknown type.\n");
- return 3;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement