aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.c14
-rw-r--r--src/tree.c142
-rw-r--r--src/tree.h6
3 files changed, 150 insertions, 12 deletions
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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#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