#include "../../include/error.h" #include "../../include/util.h" #include "../../include/ctx.h" #include #include #include #include bool lm_ctx_check(lm_ctx_t *ctx, lm_entry_t *entry, lm_ctx_check_callback_t callback, void *data){ if(NULL == ctx || NULL == entry){ lm_error_set(LM_ERR_ArgNULL); return false; } if(NULL == ctx->root){ lm_error_set(LM_ERR_CtxRootNULL); return false; } if(!lm_ctx_database_init(ctx)) return false; // error set by function size_t rootlen = strlen(ctx->root), current = 0, total = 0; char *path = NULL, *hash = NULL, *fhash = NULL; bool keep = false, ret = false, success = false; struct stat st; total = lm_database_files_count(ctx->db, entry); while(lm_database_files_next(ctx->db, entry, &path, &hash, &keep)){ char fp[rootlen+strlen(path)+10]; join(fp, ctx->root, path); bzero(&st, sizeof(st)); success = false; current++; pdebug(__func__, "(%d/%d) checking %s", current, total, fp); if(!exists(fp, &st)){ pdebug(__func__, "%s does not exist, check will fail", fp); lm_error_set(LM_ERR_FileNotExist, fp); goto next; } if(S_ISLNK(st.st_mode)){ pdebug(__func__, "%s seems to be a link, no hash verification to do", fp); if(hash[0] != '\0'){ lm_error_set(LM_ERR_FileNotLink, fp); goto end; } success = true; goto next; } if((fhash = get_md5(fp)) == NULL){ char *suberr = lm_strerror_dup(); pdebug(__func__, "failed to get hash of %s: %s", fp, suberr); lm_error_set(LM_ERR_FileHashFail, fp, suberr); free(suberr); goto next; } if(!eq(fhash, hash)){ lm_error_set(LM_ERR_FileHashNoMatch, fp); goto next; } success = true; next: free(fhash); fhash = NULL; if(NULL != callback) if(!callback(ctx, entry, fp, success, current, total, data)) goto end; if(!success) goto end; } ret = true; end: lm_database_files_next_free(ctx->db, entry, &path, &hash, &keep); free(fhash); return ret; }