back to scratko.xyz
summaryrefslogtreecommitdiff
path: root/file_finder.c
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-05-12 18:58:18 +0300
committerscratko <m@scratko.xyz>2024-05-12 18:58:18 +0300
commit42ed538a599be39e2a180408d0cdb5ec4e98ce99 (patch)
tree90277b1f97ad636171549517e271c0d38537fa9e /file_finder.c
downloadfile-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.c107
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;
+}