summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2026-03-10 17:40:58 +0800
committerSadeep Madurange <sadeep@asciimx.com>2026-03-10 17:40:58 +0800
commite0500692be6a8775c0a3c83984fc48d445a5f1d8 (patch)
treeb669a7072d375acd72905edc2520f4fe87dfa364 /main.c
parent0afd55f721a878ad1104f4343114355778eaa058 (diff)
downloadcvn-e0500692be6a8775c0a3c83984fc48d445a5f1d8.tar.gz
Move memory and stack to own files and sort before hash.
Diffstat (limited to 'main.c')
-rw-r--r--main.c98
1 files changed, 55 insertions, 43 deletions
diff --git a/main.c b/main.c
index f6eff2f..d639f07 100644
--- a/main.c
+++ b/main.c
@@ -8,6 +8,9 @@
#include <string.h>
#include <unistd.h>
+#include "mem.h"
+#include "stack.h"
+
#define MAX_DEPTH 256
#define CVN_DIR ".cvn"
@@ -16,18 +19,12 @@
#define HASH_LEN SHA1_DIGEST_LENGTH
#define HASH_INPUT_LEN 4096
-#define MALLOC(s) _xmalloc((s), __FILE__, __LINE__)
-#define REALLOC(p, s) _xrealloc((p), (s), __FILE__, __LINE__)
-
static inline void init(int argc, char *argv[]);
static inline void status(int argc, char *argv[]);
static inline void update_index(void);
static inline int ignore(const char *path);
-static inline void *_xmalloc(size_t s, const char *file, int line);
-static inline void *_xrealloc(void *ptr, size_t s, const char *file, int line);
-
struct command {
char *name;
void (*func)(int argc, char *argv[]);
@@ -98,8 +95,13 @@ static inline void status(int argc, char *argv[])
update_index();
}
+struct hashed_file {
+ char *name;
+ uint8_t hash[HASH_LEN];
+};
+
static char hash_input[HASH_INPUT_LEN];
-static uint8_t *hash_at_level[MAX_DEPTH] = {0};
+static struct stack *hash_at_level[MAX_DEPTH] = {0};
static inline void print_hash(const uint8_t hash[HASH_LEN],
const char *path)
@@ -110,19 +112,24 @@ static inline void print_hash(const uint8_t hash[HASH_LEN],
printf(": %s\n", path);
}
-void update_hash_at(size_t level, const uint8_t *hash)
+static inline void insert_hash(size_t level, const char *filename,
+ const uint8_t *hash)
{
- SHA1_CTX ctx;
+ struct stack *st;
+ struct hashed_file *hf;
if (level >= 0) {
- if (hash_at_level[level]) {
- SHA1Init(&ctx);
- SHA1Update(&ctx, hash_at_level[level], HASH_LEN);
- SHA1Update(&ctx, hash, HASH_LEN);
- SHA1Final(hash_at_level[level], &ctx);
- } else {
- hash_at_level[level] = MALLOC(sizeof(uint8_t) * HASH_LEN);
- memcpy(hash_at_level[level], hash, HASH_LEN);
+ hf = MALLOC(sizeof(struct hashed_file));
+ hf->name = strdup(filename);
+ memcpy(hf->hash, hash, HASH_LEN);
+ st = hash_at_level[level];
+ if (st)
+ push(st, (void *)hf);
+ else {
+ st = MALLOC(sizeof(struct stack));
+ stack_alloc(st);
+ push(st, (void *)hf);
+ hash_at_level[level] = st;
}
}
}
@@ -161,11 +168,36 @@ void hash_path(const char *path, uint8_t *hash)
SHA1Final(hash, &ctx);
}
+int compare_items(const void *a, const void *b) {
+ const void *pa = *(const void **)a;
+ const void *pb = *(const void **)b;
+
+ const struct hashed_file *hfa = (const struct hashed_file *)pa;
+ const struct hashed_file *hfb = (const struct hashed_file *)pb;
+
+ return strcmp(hfb->name, hfa->name);
+}
+
static inline void hash_dir(size_t level, uint8_t *hash)
{
- memcpy(hash, hash_at_level[level], HASH_LEN);
- free(hash_at_level[level]);
- hash_at_level[level] = NULL;
+ SHA1_CTX ctx;
+ struct stack *st;
+ struct hashed_file *hf;
+
+ st = hash_at_level[level];
+ if (st && st->len > 0) {
+ SHA1Init(&ctx);
+ qsort(st->items, st->len, sizeof(st->items[0]), compare_items);
+ while (st->len > 0) {
+ hf = pop(st);
+ SHA1Update(&ctx, hf->hash, HASH_LEN);
+ free(hf->name);
+ free(hf);
+ }
+ SHA1Final(hash, &ctx);
+ stack_free(st);
+ hash_at_level[level] = NULL;
+ }
}
int compute_hash(const char * path, const struct stat *st,
@@ -175,8 +207,8 @@ int compute_hash(const char * path, const struct stat *st,
mode_t mode;
unsigned char hash[HASH_LEN];
- const char *file_name = path + ftwbuf->base;
- if (ignore(file_name))
+ const char *filename = path + ftwbuf->base;
+ if (ignore(filename))
return 0;
mode = st->st_mode;
@@ -187,12 +219,11 @@ int compute_hash(const char * path, const struct stat *st,
hash_file(path, hash);
else if (S_ISLNK(mode))
hash_path(path, hash);
- update_hash_at(level - 1, hash);
} else if (tflag == FTW_DP) {
hash_dir(level, hash);
- update_hash_at(level - 1, hash);
}
+ insert_hash(level - 1, filename, hash);
print_hash(hash, path);
return 0;
}
@@ -208,22 +239,3 @@ static inline int ignore(const char *path)
return strcmp(path, CVN_DIR) == 0;
}
-static inline void *_xmalloc(size_t s, const char *file, int line)
-{
- void *p;
-
- if (!(p = malloc(s)))
- err(1, "%s:%d: malloc", file, line);
- return p;
-}
-
-static inline void *_xrealloc(void *ptr, size_t s,
- const char *file, int line)
-{
- void *p;
-
- if (!(p = realloc(ptr, s)))
- err(1, "%s:%d: realloc", file, line);
- return p;
-}
-