char * hash_result(struct hash *hash) { unsigned char sum[16]; hash_result_as_bytes(hash, sum); return format_hash_as_string(sum, hash_input_size(hash)); }
static int verify_object(struct conf *conf, struct manifest *mf, struct object *obj, struct hashtable *stated_files, struct hashtable *hashed_files) { for (uint32_t i = 0; i < obj->n_file_info_indexes; i++) { struct file_info *fi = &mf->file_infos[obj->file_info_indexes[i]]; char *path = mf->files[fi->index]; struct file_stats *st = hashtable_search(stated_files, path); if (!st) { struct stat file_stat; if (x_stat(path, &file_stat) != 0) { return 0; } st = x_malloc(sizeof(*st)); st->size = file_stat.st_size; st->mtime = file_stat.st_mtime; st->ctime = file_stat.st_ctime; hashtable_insert(stated_files, x_strdup(path), st); } if (fi->size != st->size) { return 0; } // Clang stores the mtime of the included files in the precompiled header, // and will error out if that header is later used without rebuilding. if ((guessed_compiler == GUESSED_CLANG || guessed_compiler == GUESSED_UNKNOWN) && output_is_precompiled_header && fi->mtime != st->mtime) { cc_log("Precompiled header includes %s, which has a new mtime", path); return 0; } if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) { if (!(conf->sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME)) { if (fi->mtime == st->mtime && fi->ctime == st->ctime) { cc_log("mtime/ctime hit for %s", path); continue; } else { cc_log("mtime/ctime miss for %s", path); } } else { if (fi->mtime == st->mtime) { cc_log("mtime hit for %s", path); continue; } else { cc_log("mtime miss for %s", path); } } } struct file_hash *actual = hashtable_search(hashed_files, path); if (!actual) { struct hash *hash = hash_init(); int result = hash_source_code_file(conf, hash, path); if (result & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", path); hash_free(hash); return 0; } if (result & HASH_SOURCE_CODE_FOUND_TIME) { hash_free(hash); return 0; } actual = x_malloc(sizeof(*actual)); hash_result_as_bytes(hash, actual->hash); actual->size = hash_input_size(hash); hashtable_insert(hashed_files, x_strdup(path), actual); hash_free(hash); } if (memcmp(fi->hash, actual->hash, mf->hash_size) != 0 || fi->size != actual->size) { return 0; } } return 1; }