summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2026-03-01 21:13:36 +0800
committerSadeep Madurange <sadeep@asciimx.com>2026-03-01 21:27:50 +0800
commit5a9973f55d239fc92a17daea9a1e89beac827670 (patch)
treeda9933b2f5eeed3b0a5385a95c93d47f7e8173c7
parent999a97899d67924dd66c5a632a12f8fe4201a9a7 (diff)
downloadcvn-master.tar.gz
Define traverse()HEADmaster
-rw-r--r--main.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/main.c b/main.c
index d9c3c53..f709768 100644
--- a/main.c
+++ b/main.c
@@ -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);
+ }
+}