Пример #1
0
static void test_get_files_in_directory(void) {
        _cleanup_strv_free_ char **l = NULL, **t = NULL;

        assert_se(get_files_in_directory("/tmp", &l) >= 0);
        assert_se(get_files_in_directory(".", &t) >= 0);
        assert_se(get_files_in_directory(".", NULL) >= 0);
}
Пример #2
0
static int found_directory(struct asfd *asfd, FF_PKT *ff_pkt, struct conf *conf,
	char *fname, dev_t parent_device, bool top_level)
{
	int rtn_stat;
	DIR *directory;
	char *link=NULL;
	size_t link_len;
	size_t len;
	int nbret=0;
	int count=0;
	bool recurse;
	dev_t our_device;
	struct dirent **nl=NULL;

	recurse=true;
	our_device=ff_pkt->statp.st_dev;

	/*
	* Ignore this directory and everything below if one of the files defined
	* by the 'nobackup' option exists.
	*/
	if((nbret=nobackup_directory(conf->nobackup, ff_pkt->fname)))
	{
		if(nbret<0) return -1; // error
		return 0; // do not back it up.
	}

	/* Build a canonical directory name with a trailing slash in link var */
	len=strlen(fname);
	link_len=len+200;
	if(!(link=(char *)malloc_w(link_len+2, __func__)))
		return -1;
	snprintf(link, link_len, "%s", fname);

	/* Strip all trailing slashes */
	while(len >= 1 && IsPathSeparator(link[len - 1])) len--;
	/* add back one */
	link[len++]='/';
	link[len]=0;

	ff_pkt->link=link;
	ff_pkt->type=FT_DIR;

#if defined(HAVE_WIN32)
	windows_reparse_point_fiddling(ff_pkt);
#endif

	rtn_stat=send_file(asfd, ff_pkt, top_level, conf);
	if(rtn_stat || ff_pkt->type==FT_REPARSE || ff_pkt->type==FT_JUNCTION)
	{
		/* ignore or error status */
		free_w(&link);
		return rtn_stat;
	}

	/*
	* Do not descend into subdirectories (recurse) if the
	* user has turned it off for this directory.
	*
	* If we are crossing file systems, we are either not allowed
	* to cross, or we may be restricted by a list of permitted
	* file systems.
	*/
	if(!top_level
	  && (parent_device!=ff_pkt->statp.st_dev
#if defined(HAVE_WIN32)
		|| ff_pkt->statp.st_rdev==WIN32_MOUNT_POINT
#endif
		))
	{
		if(fstype_excluded(asfd, conf, ff_pkt->fname))
		{
			free_w(&link);
			return send_file(asfd, ff_pkt, top_level, conf);
		}
		if(!fs_change_is_allowed(conf, ff_pkt->fname))
		{
			ff_pkt->type=FT_NOFSCHG;
			recurse=false;
		}
	}
	/* If not recursing, just backup dir and return */
	if(!recurse)
	{
		free_w(&link);
		return send_file(asfd, ff_pkt, top_level, conf);
	}

	/* reset "link" */
	ff_pkt->link=ff_pkt->fname;

	/*
	* Descend into or "recurse" into the directory to read
	*   all the files in it.
	*/
	errno = 0;
#if defined(O_DIRECTORY) && defined(O_NOATIME)
	int dfd=-1;
	if((dfd=open(fname, O_RDONLY|O_DIRECTORY|conf->atime?0:O_NOATIME))<0
	  || !(directory=fdopendir(dfd)))
#else
// Mac OS X appears to have no O_NOATIME and no fdopendir(), so it should
// end up using opendir() here.
	if(!(directory=opendir(fname)))
#endif
	{
#if defined(O_DIRECTORY) && defined(O_NOATIME)
		if(dfd>=0) close(dfd);
#endif
		ff_pkt->type=FT_NOOPEN;
		rtn_stat=send_file(asfd, ff_pkt, top_level, conf);
		free_w(&link);
		return rtn_stat;
	}

	/*
	* Process all files in this directory entry (recursing).
	*    This would possibly run faster if we chdir to the directory
	*    before traversing it.
	*/
	if(get_files_in_directory(directory, &nl, &count))
	{
		closedir(directory);
		free_w(&link);
		return -1;
	}
	closedir(directory);

	rtn_stat=0;
	if(nl)
	{
		if(process_files_in_directory(asfd, nl, count,
			&rtn_stat, &link, len, &link_len, conf,
			ff_pkt, our_device))
		{
			free_w(&link);
			free(nl);
			return -1;
		}
	}
	free_w(&link);
	if(nl) free(nl);

	return rtn_stat;
}
Пример #3
0
static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *toppath, const char *drop) {
        _cleanup_free_ char *unit = NULL;
        _cleanup_free_ char *path = NULL;
        _cleanup_strv_free_ char **list = NULL;
        char **file;
        char *c;
        int r;

        assert(!endswith(drop, "/"));

        path = strjoin(toppath, "/", drop);
        if (!path)
                return -ENOMEM;

        log_debug("Looking at %s", path);

        unit = strdup(drop);
        if (!unit)
                return -ENOMEM;

        c = strrchr(unit, '.');
        if (!c)
                return -EINVAL;
        *c = 0;

        r = get_files_in_directory(path, &list);
        if (r < 0)
                return log_error_errno(r, "Failed to enumerate %s: %m", path);

        STRV_FOREACH(file, list) {
                Hashmap *h;
                int k;
                char *p;
                char *d;

                if (!endswith(*file, ".conf"))
                        continue;

                p = strjoin(path, "/", *file);
                if (!p)
                        return -ENOMEM;
                d = p + strlen(toppath) + 1;

                log_debug("Adding at top: %s %s %s", d, special_glyph(ARROW), p);
                k = hashmap_put(top, d, p);
                if (k >= 0) {
                        p = strdup(p);
                        if (!p)
                                return -ENOMEM;
                        d = p + strlen(toppath) + 1;
                } else if (k != -EEXIST) {
                        free(p);
                        return k;
                }

                log_debug("Adding at bottom: %s %s %s", d, special_glyph(ARROW), p);
                free(hashmap_remove(bottom, d));
                k = hashmap_put(bottom, d, p);
                if (k < 0) {
                        free(p);
                        return k;
                }

                h = hashmap_get(drops, unit);
                if (!h) {
                        h = hashmap_new(&string_hash_ops);
                        if (!h)
                                return -ENOMEM;
                        hashmap_put(drops, unit, h);
                        unit = strdup(unit);
                        if (!unit)
                                return -ENOMEM;
                }

                p = strdup(p);
                if (!p)
                        return -ENOMEM;

                log_debug("Adding to drops: %s %s %s %s %s",
                          unit, special_glyph(ARROW), basename(p), special_glyph(ARROW), p);
                k = hashmap_put(h, basename(p), p);
                if (k < 0) {
                        free(p);
                        if (k != -EEXIST)
                                return k;
                }
        }