diff options
| author | Sadeep Madurange <sadeep@asciimx.com> | 2026-03-23 23:30:18 +0800 |
|---|---|---|
| committer | Sadeep Madurange <sadeep@asciimx.com> | 2026-03-23 23:31:55 +0800 |
| commit | c54970aed7e1ecbec194863dc42484075a77bcbe (patch) | |
| tree | 21dd3e959bda79a21b67115b8088c8c3d7aa98f1 | |
| parent | e8f2f497caffed1daa9c2e5125216d7f6d0430ce (diff) | |
| download | cvn-c54970aed7e1ecbec194863dc42484075a77bcbe.tar.gz | |
Remove concat function and use snprintf wrapper.
| -rw-r--r-- | main.c | 144 |
1 files changed, 59 insertions, 85 deletions
@@ -3,6 +3,7 @@ #include <fcntl.h> #include <fnmatch.h> #include <ftw.h> +#include <limits.h> #include <sha1.h> #include <stdarg.h> #include <stdio.h> @@ -18,10 +19,10 @@ #define EXCLUDE_PATHS ".vcxignore" -#define BUF_LEN 8192 -#define MAX_DEPTH 256 -#define MAX_PATH_LEN 4096 -#define HASH_LEN SHA1_DIGEST_STRING_LENGTH +#define MAX_DEPTH 256 +#define BUF_LEN 8192 +#define PATH_LEN PATH_MAX +#define HASH_LEN SHA1_DIGEST_STRING_LENGTH #define KIND_DEL 'D' #define KIND_MOD 'M' @@ -44,15 +45,15 @@ static inline void print_status(const char *file, char kind, int islnk); static inline int scan_head(const char * path, const struct stat *st, int flag, struct FTW *ftwbuf); static inline int scan_tree(const char * path, const struct stat *st, int flag, struct FTW *ftwbuf); -static inline void mkcopy(const char *path, char dst[HASH_LEN]); -static inline void mklink(const char *src, const char obj[HASH_LEN]); +static inline void mkcopy(const char *path, char *dst); +static inline void mklink(const char *src, const char *obj); static inline void mkdirs(const char *path); static inline void copy_link(const char *src); static inline void copy_file(const char *src, const char *dst); static inline int lnklen(const char *lnk); -static inline void concat(char *dst, size_t n, const char *arg1, ...); +static inline char *format_path(const char *fmt, ...); 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); @@ -120,7 +121,7 @@ static inline void add(int argc, char *argv[]) { size_t i; struct stat st; - char *wt_path; + char *wt_path, *hd_path; if (argc < 2) errx(1, "Usage: %s [<files>]", argv[0]); @@ -133,14 +134,8 @@ static inline void add(int argc, char *argv[]) if (lstat(wt_path, &st) == -1) err(1, "%s", wt_path); - size_t hd_sz = strlen(HEAD) + strlen(wt_path) + 2; - char hd_path[hd_sz]; - concat(hd_path, hd_sz, HEAD, "/", wt_path, NULL); + hd_path = format_path("%s/%s", HEAD, wt_path); - size_t tmp_sz = strlen(TMP_DIR) + strlen(wt_path) + 2; - char tmp_path[tmp_sz]; - concat(tmp_path, tmp_sz, TMP_DIR, "/", wt_path, NULL); - if (nftw(hd_path, scan_head, MAX_DEPTH, FTW_PHYS) == -1) err(1, "Failed to scan head"); @@ -152,14 +147,12 @@ static inline void add(int argc, char *argv[]) int scan_head(const char * path, const struct stat *sb, int flag, struct FTW *ftwbuf) { + char *wt_path; struct stat wt_stat; if (flag == FTW_F) { const char *filename = path + ftwbuf->base; - - size_t wt_sz = strlen(filename) + 3; - char wt_path[wt_sz]; - concat(wt_path, wt_sz, ".", "/", filename, NULL); + wt_path = format_path("./%s", filename); if (lstat(wt_path, &wt_stat) == -1) { if (errno == ENOENT) { @@ -190,16 +183,14 @@ int scan_head(const char * path, const struct stat *sb, int flag, static inline int scan_tree(const char * path, const struct stat *st, int flag, struct FTW *ftwbuf) { + char *hd_path; + if (fnmatch("./.vcx/*", path, 0) == 0) return 0; if (flag == FTW_F) { const char *filename = path + ftwbuf->base; - - size_t hd_sz = strlen(HEAD) + strlen(filename) + 2; - char hd_path[hd_sz]; - concat(hd_path, hd_sz, HEAD, "/", filename, NULL); - + hd_path = format_path("%s/%s", HEAD, filename); if (access(hd_path, F_OK) != 0) scan_res_cb(path, KIND_NEW, S_ISLNK(st->st_mode) != 0); } @@ -304,36 +295,31 @@ static inline void stage_entry(const char *path, char kind, int islnk) } } -static inline void mkcopy(const char *path, char dst[HASH_LEN]) +static inline void mkcopy(const char *path, char *dst) { - int len, obj_len; - char obj_name[HASH_LEN]; + int len; + char *obj_path; len = strlen(path); - obj_len = HASH_LEN - 1; - if (SHA1Data((const uint8_t *)path, len, obj_name) == NULL) + + if (SHA1Data((const uint8_t *)path, len, dst) == NULL) err(1, "Failed to compute hash for %s", path); - size_t obj_sz = strlen(OBJ_DIR) + obj_len + 6; - char obj_path[obj_sz]; - concat(obj_path, obj_sz, OBJ_DIR, "/", obj_name, ".tmp", NULL); + obj_path = format_path("%s/%s.tmp", OBJ_DIR, dst); copy_file(path, obj_path); } -static inline void mklink(const char *src, const char obj[HASH_LEN]) +static inline void mklink(const char *src, const char *obj) { - // HASH_LEN includes null byte - size_t lnkt_sz = strlen("../obj/") + HASH_LEN + 4; - char lnk_target[lnkt_sz]; - concat(lnk_target, lnkt_sz, "../obj/", obj, ".tmp", NULL); - - size_t lnkp_sz = strlen(TMP_DIR) + strlen(src) + 2; - char lnk_path[lnkp_sz]; - concat(lnk_path, lnkp_sz, TMP_DIR, "/", src, NULL); - - mkdirs(lnk_path); - if (symlink(lnk_target, lnk_path) != 0) - err(1, "symlink error on %s", src); + char *lnk, *dst; + + lnk = format_path("../obj/%s.tmp", obj); + dst = format_path("%s/%s", TMP_DIR, src); + + mkdirs(dst); + + if (symlink(lnk, dst) != 0) + err(1, "symlink %s", src); } static inline void print_status(const char *file, char kind, int islnk) @@ -350,46 +336,12 @@ static inline int lnklen(const char *lnk) err(1, "lstat %s", lnk); len = st.st_size + 1; - if (MAX_PATH_LEN < len) + if (PATH_LEN < len) errx(1, "Link too long: %s", lnk); return len; } -static inline void concat(char *dst, size_t n, const char *arg1, ...) -{ - va_list ap; - const char *part; - int curlen, partlen; - - if (!dst || n == 0) - return; - - dst[0] = '\0'; - curlen = 0; - - if (!arg1) - return; - - va_start(ap, arg1); - part = arg1; - - while (part) { - partlen = strlen(part); - if (curlen + partlen + 1 > n) { - dst[curlen] = '\0'; - va_end(ap); - errx(1, "Path too long: %s%s", dst, part); - } - memcpy(dst + curlen, part, partlen); - curlen += partlen; - part = va_arg(ap, const char *); - } - - dst[curlen] = '\0'; - va_end(ap); -} - static inline int diff(const char *file1, const char *file2) { pid_t pid; @@ -469,7 +421,9 @@ static inline void copy_link(const char *src) { int len; ssize_t n; + char *dst; + // todo: use path_buf len = lnklen(src); char target[len]; n = readlink(src, target, len); @@ -478,9 +432,7 @@ static inline void copy_link(const char *src) target[n] = '\0'; - size_t dst_sz = strlen(TMP_DIR) + strlen(src) + 2; - char dst[dst_sz]; - concat(dst, dst_sz, TMP_DIR, src, NULL); + dst = format_path("%s/%s", TMP_DIR, src); mkdirs(dst); if (symlink(target, dst) != 0) @@ -492,10 +444,10 @@ static inline void mkdirs(const char *path) char *p; int pathlen; - static char buf[MAX_PATH_LEN]; + static char buf[PATH_LEN]; pathlen = strlen(path); - if (MAX_PATH_LEN < pathlen + 1) + if (PATH_LEN < pathlen + 1) errx(1, "Path too long: %s", path); buf[0] = '\0'; @@ -513,6 +465,28 @@ static inline void mkdirs(const char *path) } } +static char *path_buf[2][PATH_LEN]; + +static inline char *format_path(const char *fmt, ...) +{ + int rc; + va_list args; + static uint8_t i = 1; + + i ^= 1; + va_start(args, fmt); + rc = vsnprintf((char *)path_buf[i], PATH_LEN, fmt, args); + va_end(args); + + if (rc < 0) + err(1, "vsnprintf"); + + if (rc >= PATH_LEN) + errx(1, "Path too long"); + + return (char *)path_buf[i]; +} + static inline void *_xmalloc(size_t s, const char *file, int line) { void *p; |
