Ejemplo n.º 1
0
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 ());
}
Ejemplo n.º 2
0
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);
    }
}
Ejemplo n.º 3
0
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;
}