From e6f8a3570b63724091c4cec78db609ad65963d65 Mon Sep 17 00:00:00 2001 From: Joursoir Date: Fri, 26 Feb 2021 13:07:57 +0000 Subject: create own function: tree --- src/main.c | 14 +----- src/tree.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tree.h | 6 +++ 3 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 src/tree.c create mode 100644 src/tree.h (limited to 'src') diff --git a/src/main.c b/src/main.c index 6f27dbc..4ac64a2 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ #include "handerror.h" #include "implementation.h" #include "exec-cmd.h" +#include "tree.h" enum constants { maxlen_texteditor = 16, @@ -35,7 +36,6 @@ enum constants { #define LOCKPASS_DIR ".lock-password/" #define GPGKEY_FILE ".gpg-key" -#define TREE_OUTPUT_FILE ".tree" #define TEXTEDITOR_FILE ".text-editor" #define usageprint(...) \ @@ -500,19 +500,9 @@ int cmd_showtree(int argc, char *argv[]) if(flag_copy) errprint("You must type a passname, not a directory\n"); - char *arg1[] = {"tree", "-C", "--noreport", path, "-o", TREE_OUTPUT_FILE, NULL}; - easyFork("tree", arg1); - - char *arg2[] = {"sed", "-i", "-E", "s/\\.gpg(\\x1B\\[[0-9]+m)?( ->|$)/\\1\\2/g", TREE_OUTPUT_FILE, NULL}; - easyFork("sed", arg2); // remove .gpg at the pass name - if(strcmp(path, ".") == 0) printf("Password Manager\n"); else printf("Password Manager/%s\n", path); - - char *arg3[] = {"tail", "-n", "+2", TREE_OUTPUT_FILE, NULL}; - easyFork("tail", arg3); // remove working directory from output - - remove(TREE_OUTPUT_FILE); + tree(path, ""); } else { diff --git a/src/tree.c b/src/tree.c new file mode 100644 index 0000000..658b6cf --- /dev/null +++ b/src/tree.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include + +#include "tree.h" + +#define ANSIC_RST "\x1B[0m" +#define ANSIC_BBLU "\x1B[34;1m" +#define ANSIC_BGRN "\x1B[32;1m" + +static void entries_sort(char **entries, const int size) +{ + int i, j; + char *temp; + for(i = 0; i < size; i++) { + for(j = i + 1; j < size; j++) { + if(strcmp(entries[i], entries[j]) > 0) + { + temp = entries[i]; + entries[i] = entries[j]; + entries[j] = temp; + } + } + } +} + +static int is_dir(const char *path) +{ + struct stat buffer; + if(stat(path, &buffer)) + return 0; + return S_ISDIR(buffer.st_mode); +} + +static int count_dir_entries(const char *path) +{ + int counter = 0; + DIR *dir; + struct dirent *dir_entry; + + dir = opendir(path); + if(dir == NULL) { + fprintf(stderr, "opendir() failed\n"); + return -1; + } + + errno = 0; + while((dir_entry = readdir(dir))) { + if(dir_entry->d_name[0] == '.') + continue; + counter++; + } + if(errno) { + fprintf(stderr, "readdir() failed\n"); + return -1; + } + closedir(dir); + return counter; +} + +static char *xstrcat(const char *first, const char *second, + const char *delimiter) +{ + size_t size = sizeof(char) * (strlen(first) + strlen(second) + 1); + if(delimiter) + size += sizeof(char) * strlen(delimiter); + char *res = malloc(size); + strcpy(res, first); + if(delimiter) + strcat(res, delimiter); + strcat(res, second); + return res; +} + +int tree(const char *path, const char *prefix) +{ + DIR *main_dir; + struct dirent *temp_dirent; + char **entries; + char *pointer, *prefix_depth; + int cnt_ent, i; + + cnt_ent = count_dir_entries(path); + if(cnt_ent == -1) + return 1; + entries = malloc(sizeof(char *) * cnt_ent); + + main_dir = opendir(path); + if(main_dir == NULL) { + perror("opendir"); + return 1; + } + + i = 0; + while((temp_dirent = readdir(main_dir))) { + char *file_name = temp_dirent->d_name; + if(file_name[0] == '.') + continue; + entries[i] = malloc(sizeof(char) * (strlen(file_name) + 1)); + strcpy(entries[i], file_name); + i++; + } + closedir(main_dir); + if(errno) { + perror("opendir"); + return 1; + } + + entries_sort(entries, cnt_ent); + for(i = 0; i < cnt_ent; i++) { + char *full_path; + if(i == cnt_ent - 1) { + pointer = "└── "; + prefix_depth = " "; + } + else { + pointer = "├── "; + prefix_depth = "│ "; + } + + full_path = xstrcat(path, entries[i], "/"); + if(is_dir(full_path)) { + printf("%s%s%s%s%s\n", prefix, pointer, ANSIC_BBLU, + entries[i], ANSIC_RST); + + prefix_depth = xstrcat(prefix, prefix_depth, NULL); + tree(full_path, prefix_depth); + free(prefix_depth); + } + else + printf("%s%s%s\n", prefix, pointer, entries[i]); + + free(entries[i]); + free(full_path); + } + + free(entries); + return 0; +} diff --git a/src/tree.h b/src/tree.h new file mode 100644 index 0000000..548d254 --- /dev/null +++ b/src/tree.h @@ -0,0 +1,6 @@ +#ifndef LPASS_TREE_H +#define LPASS_TREE_H + +int tree(const char *path, const char *prefix); + +#endif /* LPASS_TREE_H */ \ No newline at end of file -- cgit v1.2.3-18-g5258