25 #define ZP_RH_SUBDIR "zpmod"
26 #define ZP_RH_FILE "rehash_path_v1.snapshot"
29 const char *xdg =
getsparam(
"XDG_CACHE_HOME");
31 const char *base = (xdg && *xdg) ? xdg : NULL;
32 if (!base && home && *home) {
33 size_t len = strlen(home) +
sizeof(
"/.cache");
34 char *p = (
char *)
zalloc(len);
51 zwarnnam(nam,
"%srehash-diff: cannot resolve cache directory",
55 size_t len = strlen(base) + 1 + strlen(
ZP_RH_SUBDIR) + 1;
56 char *full = (
char *)
zalloc(len);
64 if (stat(full, &st) != 0) {
65 if (mkdir(full, 0700) != 0) {
66 zwarnnam(nam,
"%srehash-diff: cannot create %s: %s",
zp_icon(
"❌ "), full,
80 size_t len = strlen(dir) + 1 + strlen(
ZP_RH_FILE) + 1;
81 char *p = (
char *)
zalloc(len);
109 size_t nc = v->
cap ? v->
cap * 2 : 16;
124 for (
size_t i = 0; i < v->
size; i++) {
139 FILE *fp = fopen(file,
"r");
144 if (!fgets(line,
sizeof(line), fp)) {
148 if (strncmp(line,
"version:1", 9) != 0) {
152 while (fgets(line,
sizeof(line), fp)) {
153 if (line[0] ==
'\n' || line[0] ==
'#') {
156 char *nl = strchr(line,
'\n');
161 char *p = strtok_r(line,
"\t", &save);
165 char *ino_s = strtok_r(NULL,
"\t", &save);
166 char *mt_s = strtok_r(NULL,
"\t", &save);
167 if (!ino_s || !mt_s) {
170 unsigned long ino = strtoul(ino_s, NULL, 10);
171 long mt = strtol(mt_s, NULL, 10);
172 size_t l = strlen(p) + 1;
173 char *dup = (
char *)
zalloc(l);
181 e.
mtime = (time_t)mt;
195 FILE *fp = fopen(file,
"w");
197 zwarnnam(nam,
"%srehash-diff: cannot write %s: %s",
zp_icon(
"❌ "), file,
201 fprintf(fp,
"version:1\n");
202 for (
size_t i = 0; i < paths->
size; i++) {
204 if (stat(paths->
items[i].
path, &st) != 0) {
207 fprintf(fp,
"%s\t%lu\t%ld\n", paths->
items[i].
path,
208 (
unsigned long)st.st_ino, (
long)st.st_mtime);
219 for (
char **path_it = arr; *path_it; ++path_it) {
223 size_t len = strlen(*path_it) + 1;
224 char *dup = (
char *)
zalloc(len);
228 memcpy(dup, *path_it, len);
249 int have_prev = (
rh_load(nam, file, &prev) == 0);
258 for (
size_t i = 0; i < now.
size; i++) {
261 if (stat(cur->
path, &st) != 0) {
264 cur->
ino = st.st_ino;
265 cur->
mtime = st.st_mtime;
268 for (
size_t j = 0; j < prev.
size; j++) {
287 for (
size_t j = 0; j < prev.
size; j++) {
295 if (
rh_write(nam, file, &now) != 0) {
299 "%srehash-diff: added=%d removed=%d changed=%d unchanged=%d\n",
300 zp_icon(
"🔄 "), added, removed, changed, unchanged);
302 fprintf(stdout,
" + dirs: ");
303 for (
size_t i = 0, printed = 0; i < now.
size; i++) {
308 for (
size_t j = 0; j < prev.
size; j++) {
326 fprintf(stdout,
" - dirs: ");
327 for (
size_t j = 0, printed = 0; j < prev.
size; j++) {
338 fprintf(stdout,
" * dirs: ");
339 for (
size_t i = 0, printed = 0; i < now.
size; i++) {
340 for (
size_t j = 0; j < prev.
size; j++) {
const char * zp_icon(const char *s)
Return icon string if enabled, empty string otherwise.
static char * zp_rh_dir(char *nam)
static char * zp_rh_base_cache_dir(void)
static void rh_collect_current(struct rh_vec *out)
static int rh_write(char *nam, const char *file, struct rh_vec *paths)
static void rh_vec_init(struct rh_vec *v)
int zp_rehash_diff_core(char *nam)
static int rh_vec_push(struct rh_vec *v, struct rh_entry *e)
static char * zp_rh_file(char *nam)
static void rh_vec_free(struct rh_vec *v)
static int rh_load(const char *nam, const char *file, struct rh_vec *out)
Module declaration header (mdh) for zpmod.
Prototype stub for zpmod when building out-of-tree.
Optional terminal/locale detection for emoji support in messages.
void * zalloc(size_t size)
void zfree(void *ptr, size_t size)
char ** getaparam(const char *name)
void * zrealloc(void *ptr, size_t size)
char * getsparam(const char *name)
void zwarnnam(const char *, const char *,...)
char * ztrdup(const char *)
Incremental PATH diff rehash entrypoint.
Local, non-invasive shims to suppress benign vendor header warnings.