static void do_process_predicate (char *pathname, char *base, int mode, ino_t inum, struct stat *pstat) { (void) mode; (void) inum; state.rel_pathname = base; /* cwd_dir_fd was already set by safely_chdir */ apply_predicate (pathname, pstat, get_eval_tree ()); }
static void visit (FTS *p, FTSENT *ent, struct stat *pstat) { struct predicate *eval_tree; state.have_stat = (ent->fts_info != FTS_NS) && (ent->fts_info != FTS_NSOK); state.rel_pathname = ent->fts_accpath; state.cwd_dir_fd = p->fts_cwd_fd; /* Apply the predicates to this path. */ eval_tree = get_eval_tree (); apply_predicate (ent->fts_path, pstat, eval_tree); /* Deal with any side effects of applying the predicates. */ if (state.stop_at_current_level) { fts_set (p, ent, FTS_SKIP); } }
static int process_path (char *pathname, char *name, bool leaf, char *parent, mode_t mode, ino_t inum) { struct stat stat_buf; static dev_t root_dev; /* Device ID of current argument pathname. */ int i; struct predicate *eval_tree; eval_tree = get_eval_tree (); /* Assume it is a non-directory initially. */ stat_buf.st_mode = 0; /* The caller usually knows the inode number, either from readdir or * a *stat call. We use that value (the caller passes 0 to indicate * ignorance of the inode number). */ stat_buf.st_ino = inum; state.rel_pathname = name; state.type = 0; state.have_stat = false; state.have_type = false; state.already_issued_stat_error_msg = false; if (!digest_mode (&mode, pathname, name, &stat_buf, leaf)) return 0; if (!S_ISDIR (state.type)) { if (state.curdepth >= options.mindepth) apply_predicate (pathname, &stat_buf, eval_tree); return 0; } /* From here on, we're working on a directory. */ /* Now we really need to stat the directory, even if we know the * type, because we need information like struct stat.st_rdev. */ if (get_statinfo (pathname, name, &stat_buf) != 0) return 0; state.have_stat = true; mode = state.type = stat_buf.st_mode; /* use full info now that we have it. */ state.stop_at_current_level = options.maxdepth >= 0 && state.curdepth >= options.maxdepth; /* If we've already seen this directory on this branch, don't descend it again. */ for (i = 0; i <= dir_curr; i++) if (stat_buf.st_ino == dir_ids[i].ino && stat_buf.st_dev == dir_ids[i].dev) { state.stop_at_current_level = true; issue_loop_warning (name, pathname, i); } if (dir_alloc <= ++dir_curr) { dir_alloc += DIR_ALLOC_STEP; dir_ids = (struct dir_id *) xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id)); } dir_ids[dir_curr].ino = stat_buf.st_ino; dir_ids[dir_curr].dev = stat_buf.st_dev; if (options.stay_on_filesystem) { if (state.curdepth == 0) root_dev = stat_buf.st_dev; else if (stat_buf.st_dev != root_dev) state.stop_at_current_level = true; } if (options.do_dir_first && state.curdepth >= options.mindepth) apply_predicate (pathname, &stat_buf, eval_tree); if (options.debug_options & DebugSearch) fprintf (stderr, "pathname = %s, stop_at_current_level = %d\n", pathname, state.stop_at_current_level); if (state.stop_at_current_level == false) { /* Scan directory on disk. */ process_dir (pathname, name, strlen (pathname), &stat_buf, parent); } if (options.do_dir_first == false && state.curdepth >= options.mindepth) { /* The fields in 'state' are now out of date. Correct them. */ if (!digest_mode (&mode, pathname, name, &stat_buf, leaf)) return 0; if (0 == dir_curr) { at_top (pathname, mode, stat_buf.st_ino, &stat_buf, do_process_predicate); } else { do_process_predicate (pathname, name, mode, stat_buf.st_ino, &stat_buf); } } dir_curr--; return 1; }