diff options
| author | Sadeep Madurange <sadeep@asciimx.com> | 2026-03-10 17:40:58 +0800 |
|---|---|---|
| committer | Sadeep Madurange <sadeep@asciimx.com> | 2026-03-10 17:40:58 +0800 |
| commit | e0500692be6a8775c0a3c83984fc48d445a5f1d8 (patch) | |
| tree | b669a7072d375acd72905edc2520f4fe87dfa364 /main.c | |
| parent | 0afd55f721a878ad1104f4343114355778eaa058 (diff) | |
| download | cvn-e0500692be6a8775c0a3c83984fc48d445a5f1d8.tar.gz | |
Move memory and stack to own files and sort before hash.
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 98 |
1 files changed, 55 insertions, 43 deletions
@@ -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; -} - |
