diff options
| -rw-r--r-- | main.c | 77 |
1 files changed, 68 insertions, 9 deletions
@@ -1,6 +1,9 @@ +#include <dirent.h> +#include <err.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> @@ -10,16 +13,23 @@ #define REPO ".cvn" #define INDEX "index" +#define MAX_SUBDIRS 256 + static inline void init(int argc, char *argv[]); +static inline void status(int argc, char *argv[]); + +/* helpers */ +static inline void traverse(void); struct command { - char *name; - void (*func)(int argc, char *argv[]); + char *name; + void (*func)(int argc, char *argv[]); }; struct command cmd[] = { - {"init", init}, - {NULL, NULL} + {"init", init}, + {"status", status}, + {NULL, NULL} }; int main(int argc, char *argv[]) @@ -29,7 +39,7 @@ int main(int argc, char *argv[]) if (argc < 2) { fprintf(stderr, "Usage: %s <command> [<args>]\n", argv[0]); return 1; - } + } for (i = 0; cmd[i].name != NULL; i++) { if (strcmp(argv[1], cmd[i].name) == 0) { @@ -56,8 +66,8 @@ static inline void init(int argc, char *argv[]) break; default: break; - } - } + } + } if (mkdir(REPO, 0755) == -1) { if (errno != EEXIST) { @@ -77,10 +87,59 @@ static inline void init(int argc, char *argv[]) perror("Failed to create index"); return; } - } + } else + close(idx_fd); - close(idx_fd); close(repo_fd); printf("Initialized repository in %s\n", REPO); } +static inline void status(int argc, char *argv[]) +{ + traverse(); +} + +static inline void traverse(void) +{ + DIR *dir; + char *path, *rel_path; + struct stat st; + struct dirent *entry; + int subdirs_len; + char *subdirs[MAX_SUBDIRS]; + + subdirs_len = 0; + subdirs[subdirs_len++] = strdup("."); + + while (subdirs_len) { + path = subdirs[--subdirs_len]; + if (!(dir = opendir(path))) { + warn("Failed to open directory %s", path); + free(path); + continue; + } + + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; + if (asprintf(&rel_path, "%s/%s", path, entry->d_name) == -1) + err(1, "asprintf() failed"); + if (lstat(rel_path, &st) == -1) { + warn("lstat() failed: %s", rel_path); + free(rel_path); + continue; + } + if (S_ISDIR(st.st_mode)) { + if (subdirs_len >= MAX_SUBDIRS) + errx(1, "Repository too large: directory tree too deep/wide"); + subdirs[subdirs_len++] = rel_path; + } else { + printf("File: %s\n", rel_path); + free(rel_path); + } + } + + free(path); + closedir(dir); + } +} |
