Example #1
0
int
ftw(const char *path, int (*fn)(const char *, const struct stat *, int),
    int nfds)
{
	char * const paths[2] = { (char *)path, NULL };
	FTSENT *cur;
	FTS *ftsp;
	int error = 0, fnflag, sverrno;

	/* XXX - nfds is currently unused */
	if (nfds < 1 || nfds > OPEN_MAX) {
		errno = EINVAL;
		return (-1);
	}

	ftsp = fts_open(paths, FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
	if (ftsp == NULL)
		return (-1);
	while ((cur = fts_read(ftsp)) != NULL) {
		switch (cur->fts_info) {
		case FTS_D:
			fnflag = FTW_D;
			break;
		case FTS_DNR:
			fnflag = FTW_DNR;
			break;
		case FTS_DP:
			/* we only visit in preorder */
			continue;
		case FTS_F:
		case FTS_DEFAULT:
			fnflag = FTW_F;
			break;
		case FTS_NS:
		case FTS_NSOK:
		case FTS_SLNONE:
			fnflag = FTW_NS;
			break;
		case FTS_SL:
			fnflag = FTW_SL;
			break;
		case FTS_DC:
			errno = ELOOP;
			/* FALLTHROUGH */
		default:
			error = -1;
			goto done;
		}
		error = fn(cur->fts_path, cur->fts_statp, fnflag);
		if (error != 0)
			break;
	}
done:
	sverrno = errno;
	if (fts_close(ftsp) != 0 && error == 0)
		error = -1;
	else
		errno = sverrno;
	return (error);
}
static int remove_path(const char *path)
{
	FTS *fts;
	FTSENT *ent;
	const char *argv[2] = { path, NULL };
	int err;

	fts = fts_open((char *const *)argv, FTS_NOSTAT | FTS_PHYSICAL, NULL);
	if (!fts)
		return errno;

	for (;;) {
		ent = fts_read(fts);
		if (!ent) {
			err = errno;
			break;
		}

		err = remove_ent(ent);
		if (err)
			break;
	}
	fts_close(fts);
	return err;
}
Example #3
0
static int
recurse(const char * path)
{
  FTS *fts;
  FTSENT *ftsent;
  char * const apath[] = { strdup(path), NULL };
  fts = fts_open(apath,FTS_NOCHDIR|FTS_NOSTAT|FTS_COMFOLLOW, NULL);
  if ( NULL == fts)
    {
      ERROR("fts_open(%s) failed", path);
      return EXIT_FAILURE;
    }
  while ((ftsent = fts_read(fts)))
    switch (ftsent->fts_info)
      {
      case FTS_F:
	if ( is_video(ftsent) )
	  if ( convert_video(ftsent) )
	    ERROR("conversion failed: %s", ftsent->fts_path);
	break;
      case FTS_SLNONE:
      case FTS_NS:
      case FTS_ERR:
	ERROR("fts_read: %s (%s)", ftsent->fts_path, strerror(errno));
      default:(void)0;
      }
  fts_close(fts);
  free(apath[0]);
  return EXIT_SUCCESS;
}
Example #4
0
fs_entry* fsc_read(fscrawl_t f) {

    FTSENT *ent;

    if (!f)
        return NULL;

    for(;;) {
        ent = fts_read(f->fts);

        if (ent == NULL) {
            if (errno) {
                logerrno(LOG_DEBUG, "fsc_read", errno);
                continue;
            }
            break;
        }

        if (ent->fts_namelen > 0 && FTSENT_VALID_TYPE(ent))
            return ftsentcpy(&f->ent, ent);

        if (ent->fts_info == FTS_ERR)
            logerrno(LOG_DEBUG, "fsc_read", ent->fts_errno);
    }

    return NULL;
}
Example #5
0
int
onlp_file_find(char* root, char* fname, char** rpath)
{
    FTS *fs;
    FTSENT *ent;
    char* argv[] = { NULL, NULL };
    argv[0] = root;

    if ((fs = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_COMFOLLOW,
                       NULL)) == NULL) {
        AIM_LOG_ERROR("fts_open(%s): %{errno}", argv[0], errno);
        return ONLP_STATUS_E_INTERNAL;
    }

    while ((ent = fts_read(fs)) != NULL) {
        switch (ent->fts_info)
            {
            case FTS_F:
                {
                    if(!strcmp(fname, ent->fts_name)) {
                        *rpath = realpath(ent->fts_path, NULL);
                        fts_close(fs);
                        return ONLP_STATUS_OK;
                    }
                }
                break;
            }
    }
    fts_close(fs);
    return ONLP_STATUS_E_MISSING;
}
Example #6
0
S triefort_iter_next(ITER * const iter) {
  FTSENT * ent;

  while((ent = fts_read(iter->fts))) {
    switch(ent->fts_info) {
    case FTS_NS: case FTS_DNR: case FTS_ERR:
      fprintf(stderr, "%s: fts_read error: %s\n",
          ent->fts_accpath, strerror(ent->fts_errno));
      break;
    case FTS_F:  case FTS_DC: case FTS_DOT:    case FTS_NSOK:
    case FTS_DP: case FTS_SL: case FTS_SLNONE: case FTS_DEFAULT:
      break;
    case FTS_D:
      // We've found a directory at our level.
      // TODO: probably more validation. Maybe?
      if (ent->fts_level == iter->fort->cfg.depth + 1) {
        iter->ent = ent;
        mk_hash_from_hex_str(
            iter->ent->fts_name,
            iter->hash,
            iter->fort->cfg.hash_len);
        return triefort_ok;
      }
      break;
    }
  }

  iter->ent = NULL;
  iter->done = true;

  return triefort_err_iterator_done;
}
Example #7
0
static int recursive_remove(const char * const path) {
  if (NULL == path) { return 0; }

  int e = 0;

  if (dir_exists(path)) {
    FTSENT * ent;
    const char * const ptrs[] = { path, 0 };
    const int fts_options = FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV;
    FTS * fts = fts_open((char * const *)ptrs, fts_options, NULL);

    while((ent = fts_read(fts)) && 0 == e) {
      switch(ent->fts_info) {
      case FTS_NS: case FTS_DNR: case FTS_ERR:
        fprintf(stderr, "%s: fts_read error: %s\n",
            ent->fts_accpath, strerror(ent->fts_errno));
        e = ent->fts_errno;
        break;
      case FTS_D: case FTS_DC: case FTS_DOT: case FTS_NSOK:
        break;
      case FTS_DP: case FTS_F: case FTS_SL: case FTS_SLNONE: case FTS_DEFAULT:
        if (0 != remove(ent->fts_accpath)) {
          fprintf(stderr, "Unable to remove %s. %s\n",
              ent->fts_accpath,
              strerror(ent->fts_errno));
          e = ent->fts_errno;
        }
        break;
      }
    }
    fts_close(fts);
  }

  return e;
}
Example #8
0
int traverse(char* const argv[], void (*process_file)(const char *path))
{
	FTS *ftsp = NULL;
	FTSENT *child = NULL;

	if ((ftsp = fts_open(argv, FTS_COMFOLLOW | FTS_NOCHDIR | FTS_XDEV, NULL)) == NULL) {
		warn("fts_open");
		return -1;
	}

	while ((child = fts_read(ftsp)) != NULL) {
		if (errno != 0) {
			perror("fts_read");
		}
		switch(child->fts_info) {
			case FTS_F :
			//	printf("%d     %s\t\t\t", child->fts_level, child->fts_name);
				process_file(child->fts_path);
				break;
			//case FTS_D :
			//	printf("%d %s\n", child->fts_level, child->fts_path);
			//	break;
			default :
				break;
		}
	}
	fts_close(ftsp);
	return 0;
}
Example #9
0
/////////////////////////////////////////////////////////////
// Count the number of files for header length calculation
/////////////////////////////////////////////////////////////
static int countFiles(char **source)
{
  FTS *ftsp;
  FTSENT *p, *chp;
  int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;

  if ((ftsp = fts_open(source, fts_options, NULL)) == NULL) {
    warn("fts_open");
    return -1;
  }

  /* Initialize ftsp with as many argv[] parts as possible. */
  chp = fts_children(ftsp, 0);
  if (chp == NULL) {
    return 0;               /* no files to traverse */
  }

  while ((p = fts_read(ftsp)) != NULL)
    {
      switch (p->fts_info) {
      case FTS_F:

        if(strstr(p->fts_path, "DS_Store") == NULL) //wasn't a DS_Store file.
          {
            //increment the file count
            fileCountForHeader++;
          }
        break;
      default:
        break;
      }
    }
  fts_close(ftsp);
  return 0;
}
Example #10
0
static int remove_dir_recursively(char *dirname) {
        FTS *ftsp;
        FTSENT *p, *chp;
        int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
        
        if ((ftsp = fts_open(&dirname, fts_options, NULL)) == NULL) {
                perror("fts_open");
                return -1;
        }
        chp = fts_children(ftsp, 0);
        if (chp == NULL) {
                fts_close(ftsp);
                rmdir(dirname);
                return 0;
        }
        while ((p = fts_read(ftsp)) != NULL) {
                switch (p->fts_info) {
                case FTS_D:
                        if (strcmp(dirname, p->fts_path)) {
                                remove_dir_recursively(p->fts_path);
                                rmdir(p->fts_path);
                        }
                        break;
                case FTS_F:
                        unlink(p->fts_path);
                        break;
                default:
                        break;
                }
        }
        fts_close(ftsp);
        rmdir(dirname);
        return 0;
}
Example #11
0
int list_deleted_files(const char *path, size_t root_path_len, bool verbose) { // This WORKS with files and itself is listed. However, prefixs are WRONG!
    if (!verbose) {
        printf("Removed: %s/\n", &path[root_path_len]);
        return 0;
    }
    FTSENT *cur;
    char *paths[2] = {(char *) path, NULL };
    FTS *ftsp = fts_open(paths, FTS_NOCHDIR | FTS_PHYSICAL, NULL);
    if (ftsp == NULL) { return -1; }
    int return_val = 0;
    while (((cur = fts_read(ftsp)) != NULL) && (return_val == 0)) {
        switch (cur->fts_info) {
            case FTS_D:
                break; // do nothing
            case FTS_DP:
                printf("Removed: %s/\n", &cur->fts_path[root_path_len]);
                break;
            case FTS_F:
            case FTS_SL:
                printf("Removed: %s\n", &cur->fts_path[root_path_len]);
                break;
            case FTS_DEFAULT:
                fprintf(stderr, "File %s is a special file (device or pipe). We cannot handle that.\n", cur->fts_path);
                return_val = -1;
                break;
            default:
                fprintf(stderr, "Error occured when opening %s.\n", cur->fts_path);
                return_val = -1;
        }
    }
    if (errno) { return_val = -1; } // if no error happened, fts_read will "sets the external variable errno to 0" according to the documentation
    return fts_close(ftsp) || return_val;
}
Example #12
0
/* this is used with -r to recursively descend directories */
static void
handle_dir(char *dir)
{
	char *path_argv[2];
	FTS *fts;
	FTSENT *entry;

	path_argv[0] = dir;
	path_argv[1] = 0;
	fts = fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
	if (fts == NULL) {
		// warn("couldn't fts_open %s", dir);
        fprintf(stderr, "gzip: couldn't fts_open %s: %s\n", dir, strerror(errno));
		return;
	}

	while ((entry = fts_read(fts))) {
		switch(entry->fts_info) {
		case FTS_D:
		case FTS_DP:
			continue;

		case FTS_DNR:
		case FTS_ERR:
		case FTS_NS:
			maybe_warn("%s", entry->fts_path);
			continue;
		case FTS_F:
			handle_file(entry->fts_path, entry->fts_statp);
		}
	}
	(void)fts_close(fts);
}
Example #13
0
int
grep_tree(char **argv)
{
	FTS	*fts;
	FTSENT	*p;
	int	c, fts_flags;

	c = 0;

	fts_flags = FTS_PHYSICAL | FTS_NOSTAT | FTS_NOCHDIR;

	if (!(fts = fts_open(argv, fts_flags, NULL)))
		err(2, NULL);
	while ((p = fts_read(fts)) != NULL) {
		switch (p->fts_info) {
		case FTS_DNR:
			break;
		case FTS_ERR:
			file_err = 1;
			if(!sflag)
				warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
			break;
		case FTS_DP:
			break;
		default:
			c += procfile(p->fts_path);
			break;
		}
	}
	if (errno)
		err(2, "fts_read");

	return c;
}
Example #14
0
void parse_summary_recursive(struct rmDsummary_set *dest, char *dirname, struct hash_table *categories)
{

	FTS *hierarchy;
	FTSENT *entry;
	char *argv[] = {dirname, NULL};

	hierarchy = fts_open(argv, FTS_PHYSICAL, NULL);

	if(!hierarchy)
		fatal("fts_open error: %s\n", strerror(errno));

	struct rmDsummary *s;
	while( (entry = fts_read(hierarchy)) )
		if( S_ISREG(entry->fts_statp->st_mode) && strstr(entry->fts_name, RULE_SUFFIX) ) //bug: no links
		{
			FILE *stream;
			stream = fopen(entry->fts_accpath, "r");
			if(!stream)
				fatal("Cannot open resources summary file: %s : %s\n", entry->fts_accpath, strerror(errno));

			while((s = parse_summary(stream, entry->fts_path, categories)))
				list_push_tail(dest->summaries, s);

			fclose(stream);
		}

	fts_close(hierarchy);
}
Example #15
0
static void
notice_cgroups_in_hierarchy (CockpitSamples *samples,
                             const gchar *prefix,
                             void (* collect) (CockpitSamples *, const gchar *, const gchar *))
{
  const gchar *paths[] = { prefix, NULL };
  gsize prefix_len;
  FTSENT *ent;
  FTS *fs;

  prefix_len = strlen (prefix);

  fs = fts_open ((gchar **)paths, FTS_NOCHDIR | FTS_COMFOLLOW, NULL);
  if (fs)
    {
      while((ent = fts_read (fs)) != NULL)
        {
          if (ent->fts_info == FTS_D)
            {
              const char *f = ent->fts_path + prefix_len;
              if (*f == '/')
                f++;
              collect (samples, ent->fts_path, f);
            }
        }
      fts_close (fs);
    }
}
Example #16
0
int16_t chown_recursive(char * const path, uid_t uid, uid_t gid) {
	// See man fts(3) for these.  Modify these to do what you want:
	int fts_options =  FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV | FTS_SEEDOT ;
	
	// fts_open requires a null-terminated array of paths.
	// We only have one path.
	char* paths[2] ;
	paths[0] = path ;
	paths[1] = NULL ;
	
	FTS* ftsp = fts_open(paths, fts_options, NULL) ;
	if (ftsp == NULL) {
		return -2 ;
	}
	
	FTSENT* ftsPointer = 0 ;
	while ((ftsPointer = fts_read(ftsp)) != NULL) {
		/*
		 This will execute once for each item in the tree.
		 According to the man page fts(3):
		 "directories are visited two distinguishable times; in pre-order
		 (before any of their descendants are visited) and in post-order
		 (after all of their descendants have been visited)"
		 But if I replace chown() below with a printf(), it only logs once for
		 each directory, in pre-order.  Example:
		 Doing /Users/jk/Desktop/OW5/.
		 Doing /Users/jk/Desktop/OW5/..
		 Doing /Users/jk/Desktop/OW5/BkmxTemp/.
		 Doing /Users/jk/Desktop/OW5/BkmxTemp/..
		 Doing /Users/jk/Desktop/OW5/BkmxTemp/placesNo1Dump.txt
		 Doing /Users/jk/Desktop/OW5/BkmxTemp/placesOk1Dump.txt
		 Apparently a "visit" does not mean "returned by ftsPointer->fts_info"
		 */
		int result ;
		switch (ftsPointer->fts_info) { 
			// List here the file types you want to be chown-ed.
			// We want all types.
			case FTS_F:     // regular file
			case FTS_D:     // directory
			case FTS_DOT:   // system dot file, i.e. '.' or '..' 
			case FTS_SL:    // symbolic link
				result = chown(ftsPointer->fts_path, uid, gid) ;
				if (result != 0) {
					// chown only returns either 0 or -1.
					// Must be -1 here.
					return result ;
				}
				break ;
				
			default:
				printf("Internal Error 524-0192 unknown type %d\n", ftsPointer->fts_info) ;
				break; 
		}
	}
	
	fts_close(ftsp) ;
	
	return 0 ;
	
}
/* this is used with -r to recursively descend directories */
static void
handle_dir(char *dir)
{
	char *path_argv[2];
	FTS *fts;
	FTSENT *entry;

	path_argv[0] = dir;
	path_argv[1] = 0;
	fts = fts_open(path_argv, FTS_PHYSICAL, NULL);
	if (fts == NULL) {
		warn("couldn't fts_open %s", dir);
		return;
	}

	while ((entry = fts_read(fts))) {
		switch(entry->fts_info) {
		case FTS_D:
		case FTS_DP:
			continue;

		case FTS_DNR:
		case FTS_ERR:
		case FTS_NS:
			maybe_warn("%s", entry->fts_path);
			continue;
		case FTS_F:
			handle_file(entry->fts_name, entry->fts_statp);
		}
	}
	(void)fts_close(fts);
}
Example #18
0
int traverse(const char *lower_root, const char *upper_root, bool verbose, FILE* script_stream, TRAVERSE_CALLBACK callback_d, TRAVERSE_CALLBACK callback_dp, TRAVERSE_CALLBACK callback_f, TRAVERSE_CALLBACK callback_sl, TRAVERSE_CALLBACK callback_whiteout,void *extra) { // returns 0 on success
    FTSENT *cur;
    char *paths[2] = {(char *) upper_root, NULL };
    char lower_path[PATH_MAX];
    strcpy(lower_path, lower_root);
    size_t upper_root_len = strlen(upper_root);
    size_t lower_root_len = strlen(lower_root);
    FTS *ftsp = fts_open(paths, FTS_NOCHDIR | FTS_PHYSICAL, NULL);
    if (ftsp == NULL) { return -1; }
    int return_val = 0;
    while (((cur = fts_read(ftsp)) != NULL) && (return_val == 0)) {
        TRAVERSE_CALLBACK callback = NULL;
        switch (cur->fts_info) {
            case FTS_D:
                callback = callback_d;
                break;
            case FTS_DP:
                callback = callback_dp;
                break;
            case FTS_F:
                callback = callback_f;
                break;
            case FTS_SL:
                callback = callback_sl;
                break;
            case FTS_DEFAULT:
                if (is_whiteout(cur->fts_statp)) {
                    callback = callback_whiteout;
                } else {
                    return_val = -1;
                    fprintf(stderr, "File %s is a special file (device or pipe). We cannot handle that.\n", cur->fts_path);
                }
                break;
            default:
                return_val = -1;
                fprintf(stderr, "Error occured when opening %s.\n", cur->fts_path);
        }
        if (callback != NULL) {
            int fts_instr = 0;
            struct stat lower_status;
            bool lower_exist = true;
            strcpy(&lower_path[lower_root_len], &(cur->fts_path[upper_root_len]));
            if (lstat(lower_path, &lower_status) != 0) {
                if (errno == ENOENT || errno == ENOTDIR) { // the corresponding lower file (or its ancestor) does not exist at all
                    lower_exist = false;
                } else { // stat failed for some unknown reason
                    fprintf(stderr, "Failed to stat %s.\n", lower_path);
                    return_val = -1;
                    break; // do not call callback in this case
                }
            }
            return_val = callback(lower_path, cur->fts_path, lower_root_len, lower_exist ? &lower_status : NULL, cur->fts_statp, verbose, script_stream, &fts_instr,extra); // return_val must previously be 0
            if (fts_instr) {
                fts_set(ftsp, cur, fts_instr);
            }
        }
    }
    if (errno) { return_val = -1; } // if no error happened, fts_read will "sets the external variable errno to 0" according to the documentation
    return fts_close(ftsp) || return_val;
}
Example #19
0
struct list *parse_summary_recursive(char *dirname)
{

	FTS *hierarchy;
	FTSENT *entry;
	char *argv[] = {dirname, NULL};

	struct list *summaries = list_create(0);

	hierarchy = fts_open(argv, FTS_PHYSICAL, NULL);

	if(!hierarchy)
		fatal("fts_open error: %s\n", strerror(errno));

	struct summary *s;
	while( (entry = fts_read(hierarchy)) )
		if( strstr(entry->fts_name, RULE_SUFFIX) )
		{
			s = parse_summary_file(entry->fts_accpath);
			list_push_head(summaries, (void *) s);
		}

	fts_close(hierarchy);

	return summaries;
}
Example #20
0
/* Tell fts not to traverse into the hierarchy at ENT.  */
static void
fts_skip_tree (FTS *fts, FTSENT *ent)
{
  fts_set (fts, ent, FTS_SKIP);
  /* Ensure that we do not process ENT a second time.  */
  ignore_value (fts_read (fts));
}
Example #21
0
int
rm_dir(char *path)
{
	FTS		*fts;
	FTSENT		*p;
	static char	*fpath[] = { NULL, NULL };

	fpath[0] = path;
	if ((fts = fts_open(fpath, FTS_PHYSICAL, NULL)) == NULL) {
		warn("fts_open %s", path);
		return (1);
	}

	while ((p = fts_read(fts)) != NULL) {
		switch (p->fts_info) {
		case FTS_DP:
		case FTS_DNR:
			if (rmdir(p->fts_accpath) == -1)
				warn("rmdir %s", p->fts_accpath);
			break;
		case FTS_F:
			if (unlink(p->fts_accpath) == -1)
				warn("unlink %s", p->fts_accpath);
			break;
		case FTS_D:
		case FTS_DOT:
		default:
			continue;
		}
	}
	fts_close(fts);

	return (0);
}
Example #22
0
bool Path::rmdir(const Path& dir)
{
    if (!dir.isDir())
        return false;
    // hva slags drittapi er dette?
    char* const dirs[2] = { const_cast<char*>(dir.constData()), 0 };
    FTS* fdir = fts_open(dirs, FTS_NOCHDIR, 0);
    if (!fdir)
        return false;
    FTSENT *node;
    while ((node = fts_read(fdir))) {
        if (node->fts_level > 0 && node->fts_name[0] == '.') {
            fts_set(fdir, node, FTS_SKIP);
        } else {
            switch (ftsType(node->fts_info)) {
            case File:
                unlink(node->fts_path);
                break;
            case Directory:
                ::rmdir(node->fts_path);
                break;
            default:
                break;
            }
        }
    }
    fts_close(fdir);
    return true;
}
Example #23
0
FTSENT *__sf_fts_read(FTS *ftsp)
{
    if (tt_rand_u32() % 2) {
        return NULL;
    } else {
        return fts_read(ftsp);
    }
}
Example #24
0
int FDirectory::AddDirectory(const char *dirpath)
{
	char *argv [2] = { NULL, NULL };
	argv[0] = new char[strlen(dirpath)+1];
	strcpy(argv[0], dirpath);
	FTS *fts;
	FTSENT *ent;
	int count = 0;

	fts = fts_open(argv, FTS_LOGICAL, NULL);
	if (fts == NULL)
	{
		Printf("Failed to start directory traversal: %s\n", strerror(errno));
		return 0;
	}

	const size_t namepos = strlen(Filename);
	FString pathfix;

	while ((ent = fts_read(fts)) != NULL)
	{
		if (ent->fts_info == FTS_D && ent->fts_name[0] == '.')
		{
			// Skip hidden directories. (Prevents SVN bookkeeping
			// info from being included.)
			fts_set(fts, ent, FTS_SKIP);
		}
		if (ent->fts_info == FTS_D && ent->fts_level == 0)
		{
			continue;
		}
		if (ent->fts_info != FTS_F)
		{
			// We're only interested in remembering files.
			continue;
		}

		// Some implementations add an extra separator between
		// root of the hierarchy and entity's path.
		// It needs to be removed in order to resolve
		// lumps' relative paths properly.
		const char* path = ent->fts_path;

		if ('/' == path[namepos])
		{
			pathfix = FString(path, namepos);
			pathfix.AppendCStrPart(&path[namepos + 1], ent->fts_pathlen - namepos - 1);

			path = pathfix.GetChars();
		}

		AddEntry(path, ent->fts_statp->st_size);
		count++;
	}
	fts_close(fts);
	delete[] argv[0];
	return count;
}
Example #25
0
bool hardened_shadow_remove_dir_contents(const char *path) {
  bool result = true;

  /* Note: nftw-based code would be possibly simpler,
   * but it wouldn't be possible to have as detailed error messages. */
  FTS *fts_handle = NULL;
  char *fts_argv[] = { strdup(path), NULL };

  /* Make sure strdup above succeeded. */
  if (!fts_argv[0]) {
    result = false;
    goto out;
  }

  fts_handle = fts_open(fts_argv, FTS_PHYSICAL | FTS_NOSTAT, NULL);
  if (!fts_handle) {
    warn("fts_open");
    result = false;
    goto out;
  }

  FTSENT *fts_entry;
  while ((fts_entry = fts_read(fts_handle))) {
    switch (fts_entry->fts_info) {
      case FTS_DNR:
      case FTS_NS:
        /* Warn about the problem, but continue deleting files. */
        warnx("%s: %s", fts_entry->fts_path, strerror(fts_entry->fts_errno));
        result = false;
        break;
      case FTS_ERR:
        /* We consider this a fatal error, i.e. abort processing now. */
        warnx("%s: %s", fts_entry->fts_path, strerror(fts_entry->fts_errno));
        result = false;
        goto out;
      case FTS_D:
        break;
      case FTS_DP:
        if (fts_entry->fts_level > 0 && rmdir(fts_entry->fts_accpath) != 0) {
          warn("%s", fts_entry->fts_accpath);
          result = false;
        }
        break;
      default:
        if (fts_entry->fts_level > 0 && unlink(fts_entry->fts_accpath) != 0) {
          warn("%s", fts_entry->fts_accpath);
          result = false;
        }
        break;
    }
  }

out:
  if (fts_handle)
    fts_close(fts_handle);
  free(fts_argv[0]);
  return result;
}
Example #26
0
  Error PathMan::read_dir(const char * path) {
    uint32_t len = strlen(path);
    char word[len+1];
    memcpy(word, path, len);
    word[len ] = 0;
    char * ppath[] = {word, 0};

    LookUp lu = lookup("/"), flu;

    if (lu.err)
      return lu.err;

    FTSENT *node;
    FTS *tree = fts_open(ppath, FTS_NOCHDIR, 0);

    if (!tree)
      return FAILURE;

    {
      size_t len;
      while ((node = fts_read(tree))) {
        char word[node->fts_pathlen + 3];

        if (node->fts_info & FTS_F) {
          mkword(node, word, len);
          flu = add_file(word, 0);

          if (flu.err)
            goto fout;

          flu.file->offset = 0;
          flu.file->size = node->fts_statp->st_size;
        } else if (node->fts_info & FTS_D) {
          mkword(node, word, len);
          if (len > 1) {
            if (word[len - 1] != '/') {
              word[len++] = '/';
            }
            word[len] = 0;

            lu = add_dir(word, 0);

            if (lu.err)
              goto dout;
          }
        }
      }
      fts_close(tree);
    }

    return SUCCESS;
  fout:
    fts_close(tree);
    return flu.err;
  dout:
    fts_close(tree);
    return lu.err;
  }
Example #27
0
/*
 * Traverse() walks the logical directory structure specified by the argv list
 * in the order specified by the mastercmp() comparison function.  During the
 * traversal it passes linked lists of structures to display() which represent
 * a superset (may be exact set) of the files to be displayed.
 */
static void
traverse(int argc, char *argv[], int options)
{
    FTS *ftsp;
    FTSENT *p, *chp;
    int ch_options;

    if ((ftsp =
                fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
        err(EXIT_FAILURE, NULL);

    display(NULL, fts_children(ftsp, 0));
    if (f_listdir)
        return;

    /*
     * If not recursing down this tree and don't need stat info, just get
     * the names.
     */
    ch_options = !f_recursive && options & FTS_NOSTAT ? FTS_NAMEONLY : 0;

    while ((p = fts_read(ftsp)) != NULL)
        switch (p->fts_info) {
        case FTS_DC:
            warnx("%s: directory causes a cycle", p->fts_name);
            break;
        case FTS_DNR:
        case FTS_ERR:
            warnx("%s: %s", p->fts_name, strerror(p->fts_errno));
            rval = EXIT_FAILURE;
            break;
        case FTS_D:
            if (p->fts_level != FTS_ROOTLEVEL &&
                    p->fts_name[0] == '.' && !f_listdot)
                break;

            /*
             * If already output something, put out a newline as
             * a separator.  If multiple arguments, precede each
             * directory with its name.
             */
            if (output)
                (void)printf("\n%s:\n", p->fts_path);
            else if (argc > 1) {
                (void)printf("%s:\n", p->fts_path);
                output = 1;
            }

            chp = fts_children(ftsp, ch_options);
            display(p, chp);

            if (!f_recursive && chp != NULL)
                (void)fts_set(ftsp, p, FTS_SKIP);
            break;
        }
    if (errno)
        err(EXIT_FAILURE, "fts_read");
}
/*
 * Print all files in the directory tree that match the glob pattern.
 * Example: pmatch("/usr/src", "*.c");
 */
void
pmatch(char *dir, const char *pattern)
{
	FTS *tree;
	FTSENT *f;
	char *argv[] = { dir, NULL };

	/*
	 * FTS_LOGICAL follows symbolic links, including links to other
	 * directories. It detects cycles, so we never have an infinite
	 * loop. FTS_NOSTAT is because we never use f->statp. It uses
	 * our entcmp() to sort files by name.
	 */
	tree = fts_open(argv, FTS_LOGICAL | FTS_NOSTAT, entcmp);
	if (tree == NULL)
		err(1, "fts_open");

	/*
	 * Iterate files in tree. This iteration always skips
	 * "." and ".." because we never use FTS_SEEDOT.
	 */
	while ((f = fts_read(tree))) {
		switch (f->fts_info) {
		case FTS_DNR:	/* Cannot read directory */
		case FTS_ERR:	/* Miscellaneous error */
		case FTS_NS:	/* stat() error */
			/* Show error, then continue to next files. */
			warn("%s", f->fts_path);
			continue;
		case FTS_DP:
			/* Ignore post-order visit to directory. */
			continue;
		}

		/*
		 * Check if name matches pattern. If so, then print
		 * path. This check uses FNM_PERIOD, so "*.c" will not
		 * match ".invisible.c".
		 */
		if (fnmatch(pattern, f->fts_name, FNM_PERIOD) == 0)
			puts(f->fts_path);

		/*
		 * A cycle happens when a symbolic link (or perhaps a
		 * hard link) puts a directory inside itself. Tell user
		 * when this happens.
		 */
		if (f->fts_info == FTS_DC)
			warnx("%s: cycle in directory tree", f->fts_path);
	}

	/* fts_read() sets errno = 0 unless it has error. */
	if (errno != 0)
		err(1, "fts_read");

	if (fts_close(tree) < 0)
		err(1, "fts_close");
}
Example #29
0
/*
  This function takes three parameters:

  PATH of an existing file system object.

  A RECURSE boolean which if the file system object is a directory, will
  call restorecon_private on every file system object in the directory.

  A LOCAL boolean that indicates whether the function should set object labels
  to the default for the local process, or use system wide settings.

  Returns false on failure.  errno will be set appropriately.
*/
bool
restorecon (char const *path, bool recurse, bool local)
{
  char *newpath = NULL;
  FTS *fts;
  bool ok = true;

  if (! IS_ABSOLUTE_FILE_NAME (path) && ! local)
    {
      /* Generate absolute path as required by subsequent matchpathcon(),
         with libselinux < 2.1.5 2011-0826.  Also generating the absolute
         path before the fts walk, will generate absolute paths in the
         fts entries, which may be quicker to process in any case.  */
      newpath = canonicalize_filename_mode (path, CAN_MISSING);
      if (! newpath)
        error (EXIT_FAILURE, errno, _("error canonicalizing %s"),
               quote (path));
    }

  const char *ftspath[2] = { newpath ? newpath : path, NULL };

  if (! recurse)
    {
      ok = restorecon_private (*ftspath, local) != -1;
      free (newpath);
      return ok;
    }

  fts = xfts_open ((char *const *) ftspath, FTS_PHYSICAL, NULL);
  while (1)
    {
      FTSENT *ent;

      ent = fts_read (fts);
      if (ent == NULL)
        {
          if (errno != 0)
            {
              error (0, errno, _("fts_read failed"));
              ok = false;
            }
          break;
        }

      ok &= restorecon_private (fts->fts_path, local) != -1;
    }

  if (fts_close (fts) != 0)
    {
      error (0, errno, _("fts_close failed"));
      ok = false;
    }

  free (newpath);
  return ok;
}
Example #30
0
int
_rm(char const* path)
{
    FTS* tree;
    FTSENT* cur = NULL;
    char* paths[2];
    paths[0] = (char*)path;
    paths[1] = NULL;

    tree = fts_open(paths, FTS_COMFOLLOW | FTS_NOCHDIR, NULL);
    if (tree != NULL)
    {
        while ((cur = fts_read(tree)) != NULL)
        {
            switch (cur->fts_info)
            {
                case FTS_NS:
                case FTS_DNR:
                case FTS_ERR:
                    fprintf(stderr, "Error: %s: fts_read error: %s\n",
                            cur->fts_accpath, strerror(cur->fts_errno));
                    return 1;

                case FTS_DC:
                case FTS_DOT:
                case FTS_NSOK:
                    /* Not reached unless FTS_LOGICAL, FTS_SEEDOT, or FTS_NOSTAT were */
                    /* passed to fts_open() */
                    break;

                case FTS_D:
                    /* Do nothing. Need depth-first search, so directories are deleted */
                    /* in FTS_DP */
                    break;

                case FTS_DP:
                case FTS_F:
                case FTS_SL:
                case FTS_SLNONE:
                case FTS_DEFAULT:
                    if (remove(cur->fts_accpath) < 0)
                    {
                        fprintf(stderr, "Error: %s: Failed to remove: %s\n",
                                strerror(errno), cur->fts_path);
                        return 1;
                    }
                    break;
            }
        }

        fts_close(tree);
        return 0;
    }

    return 1;
}