char *rm_xattr_read_hash(RmSession *session, RmFile *file) { g_assert(file); g_assert(session); #if HAVE_XATTR if(session->cfg->read_cksum_from_xattr == false) { return NULL; } char cksum_key[64] = {0}, mtime_key[64] = {0}, mtime_buf[64] = {0}, cksum_hex_str[512] = {0}; memset(cksum_hex_str, '0', sizeof(cksum_hex_str)); cksum_hex_str[sizeof(cksum_hex_str) - 1] = 0; if(0 || rm_xattr_build_key(session, "cksum", cksum_key, sizeof(cksum_key)) || rm_xattr_get(file, cksum_key, cksum_hex_str, sizeof(cksum_hex_str) - 1) || rm_xattr_build_key(session, "mtime", mtime_key, sizeof(mtime_key)) || rm_xattr_get(file, mtime_key, mtime_buf, sizeof(mtime_buf) - 1)) { return NULL; } if(g_ascii_strtoll(mtime_buf, NULL, 10) < file->mtime) { /* Data is too old and not useful, autoclean it */ rm_xattr_clear_hash(session, file); return NULL; } /* remember, this file is special. A unicorn amongst files. */ file->has_ext_cksum = true; return g_strdup(cksum_hex_str); #else return NULL; #endif }
static void rm_traverse_file(RmTravSession *trav_session, RmStat *statp, char *path, bool is_prefd, unsigned long path_index, RmLintType file_type, bool is_symlink, bool is_hidden, bool is_on_subvol_fs, short depth) { RmSession *session = trav_session->session; RmCfg *cfg = session->cfg; if(rm_fmt_is_a_output(session->formats, path)) { /* ignore files which are rmlint outputs */ return; } /* Try to autodetect the type of the lint */ if(file_type == RM_LINT_TYPE_UNKNOWN) { RmLintType gid_check; /* see if we can find a lint type */ if(statp->st_size == 0) { if(!cfg->find_emptyfiles) { return; } else { file_type = RM_LINT_TYPE_EMPTY_FILE; } } else if(cfg->permissions && access(path, cfg->permissions) == -1) { /* bad permissions; ignore file */ trav_session->session->ignored_files++; return; } else if(cfg->find_badids && (gid_check = rm_util_uid_gid_check(statp, trav_session->userlist))) { file_type = gid_check; } else if(cfg->find_nonstripped && rm_util_is_nonstripped(path, statp)) { file_type = RM_LINT_TYPE_NONSTRIPPED; } else { RmOff file_size = statp->st_size; if(!cfg->limits_specified || ((cfg->minsize == (RmOff)-1 || cfg->minsize <= file_size) && (cfg->maxsize == (RmOff)-1 || file_size <= cfg->maxsize))) { if(rm_mounts_is_evil(trav_session->session->mounts, statp->st_dev) == false) { file_type = RM_LINT_TYPE_DUPE_CANDIDATE; } else { /* A file in an evil fs. Ignore. */ trav_session->session->ignored_files++; return; } } else { return; } } } RmFile *file = rm_file_new(session, path, statp, file_type, is_prefd, path_index, depth); if(file != NULL) { file->is_symlink = is_symlink; file->is_hidden = is_hidden; file->is_on_subvol_fs = is_on_subvol_fs; file->link_count = statp->st_nlink; rm_file_list_insert_file(file, session); g_atomic_int_add(&trav_session->session->total_files, 1); rm_fmt_set_state(session->formats, RM_PROGRESS_STATE_TRAVERSE); if(trav_session->session->cfg->clear_xattr_fields && file->lint_type == RM_LINT_TYPE_DUPE_CANDIDATE) { rm_xattr_clear_hash(session, file); } } }