#include #include #include #include #include #include #include #include #include "hash.h" #include "helpers.h" #ifdef GITHASH static uint64_t murmur64(uint64_t k) { PS(); k ^= k >> 33; k *= 0xff51afd7ed558ccdLLU; k ^= k >> 33; k *= 0xc4ceb9fe1a85ec53LLU; k ^= k >> 33; PE(); return k; } uint64_t generate_hash(git_repository *repo) { PS(); struct stat dir, index; char path[PATH_MAX] = { 0 }; const char *gitpath = git_repository_path(repo); if (strlen(gitpath) + strlen("/..") > PATH_MAX - 1) { L("strlen: %s", strerror(errno)); PE(); return -1; } strcat(path, gitpath); if (stat(path, &index) < 0) { PE(); return -1; } strcat(path, "/.."); if (stat(path, &dir) < 0) { PE(); return -1; } PE(); return murmur64(dir.st_mtim.tv_nsec ^ index.st_mtim.tv_nsec); } repohash *read_hash(git_repository *repo) { PS(); FILE *f; uint64_t data; uint8_t changes; repohash *hash = malloc(sizeof(repohash)); char path[PATH_MAX] = { 0 }; const char *gitpath = git_repository_path(repo); if (strlen(gitpath) + strlen(XD_HASH_PATH) > PATH_MAX - 1) { L("strlen: %s", strerror(errno)); PE(); return NULL; } strcat(path, gitpath); strcat(path, XD_HASH_PATH); f = fopen(path, "r"); if (!f) { L("fopen: %s", strerror(errno)); PE(); return NULL; } if (fread(&data, sizeof(uint64_t), 1, f) != 1) { L("fread: %s", strerror(errno)); PE(); return NULL; } if (fseek(f, sizeof(uint64_t), SEEK_SET) < 0) { L("fseek: %s", strerror(errno)); PE(); return NULL; } if (fread(&changes, sizeof(uint8_t), 1, f) != 1) { L("fread: %s", strerror(errno)); PE(); return NULL; } fclose(f); hash->hash = data; hash->changes = changes; PE(); return hash; } int write_hash(git_repository *repo, repohash hash) { PS(); FILE *f; char path[PATH_MAX] = { 0 }; const char *gitpath = git_repository_path(repo); if (strlen(gitpath) + strlen(XD_HASH_PATH) > PATH_MAX - 1) { L("strlen: %s", strerror(errno)); PE(); return 1; } strcat(path, gitpath); strcat(path, XD_HASH_PATH); f = fopen(path, "wb"); if (!f) { L("fopen: %s", strerror(errno)); PE(); return 1; } if (fwrite(&hash.hash, sizeof(uint64_t), 1, f) != 1) { L("fwrite: %s", strerror(errno)); PE(); return 1; } if (fseek(f, sizeof(uint64_t), SEEK_SET) < 0) { L("fseek: %s", strerror(errno)); PE(); return 1; } if (fwrite(&hash.changes, sizeof(uint8_t), 1, f) != 1) { L("fwrite: %s", strerror(errno)); PE(); return 1; } fclose(f); PE(); return 0; } #endif