예제 #1
0
파일: dir.c 프로젝트: BlueZenith/git
/*
 * Read a directory tree. We currently ignore anything but
 * directories, regular files and symlinks. That's because git
 * doesn't handle them at all yet. Maybe that will change some
 * day.
 *
 * Also, we ignore the name ".git" (even if it is not a directory).
 * That likely will not change.
 */
static int read_directory_recursive(struct dir_struct *dir,
				    const char *base, int baselen,
				    int check_only,
				    const struct path_simplify *simplify)
{
	DIR *fdir;
	int contents = 0;
	struct dirent *de;
	struct strbuf path = STRBUF_INIT;

	strbuf_add(&path, base, baselen);

	fdir = opendir(path.len ? path.buf : ".");
	if (!fdir)
		goto out;

	while ((de = readdir(fdir)) != NULL) {
		switch (treat_path(dir, de, &path, baselen, simplify)) {
		case path_recurse:
			contents += read_directory_recursive(dir, path.buf,
							     path.len, 0,
							     simplify);
			continue;
		case path_ignored:
			continue;
		case path_handled:
			break;
		}
		contents++;
		if (check_only)
			break;
		dir_add_name(dir, path.buf, path.len);
	}
	closedir(fdir);
 out:
	strbuf_release(&path);

	return contents;
}
예제 #2
0
파일: dir.c 프로젝트: CCorreia/git
/*
 * Read a directory tree. We currently ignore anything but
 * directories, regular files and symlinks. That's because git
 * doesn't handle them at all yet. Maybe that will change some
 * day.
 *
 * Also, we ignore the name ".git" (even if it is not a directory).
 * That likely will not change.
 */
static int read_directory_recursive(struct dir_struct *dir,
				    const char *base, int baselen,
				    int check_only,
				    const struct path_simplify *simplify)
{
	DIR *fdir = opendir(*base ? base : ".");
	int contents = 0;
	struct dirent *de;
	char path[PATH_MAX + 1];

	if (!fdir)
		return 0;

	memcpy(path, base, baselen);

	while ((de = readdir(fdir)) != NULL) {
		int len;
		switch (treat_path(dir, de, path, sizeof(path),
				   baselen, simplify, &len)) {
		case path_recurse:
			contents += read_directory_recursive(dir, path, len, 0, simplify);
			continue;
		case path_ignored:
			continue;
		case path_handled:
			break;
		}
		contents++;
		if (check_only)
			goto exit_early;
		else
			dir_add_name(dir, path, len);
	}
exit_early:
	closedir(fdir);

	return contents;
}
예제 #3
0
static int 
read_directory_recursive(struct dir_struct *dir,
                         const char *base, int baselen,
                         int check_only,
                         struct index_state *index,
                         const char *worktree,
                         IgnoreFunc ignore_func,
                         void *data)
{
    char *realpath = g_build_path (PATH_SEPERATOR, worktree, base, NULL);
    GDir *fdir = g_dir_open (realpath, 0, NULL);
    const char *dname;
    char *nfc_dname;
    int contents = 0;
    int dtype;

    if (fdir) {
        char path[SEAF_PATH_MAX + 1];
        memcpy(path, base, baselen);
        while ((dname = g_dir_read_name(fdir)) != NULL) {
            int len = 0;

#ifdef __APPLE__
            nfc_dname = g_utf8_normalize (dname, -1, G_NORMALIZE_NFC);
#else
            nfc_dname = g_strdup(dname);
#endif

            if (is_dot_or_dotdot(nfc_dname)) {
                g_free (nfc_dname);
                continue;
            }

            if (ignore_func (realpath, nfc_dname, data)) {
                g_free (nfc_dname);
                continue;
            }

            dtype = get_dtype(nfc_dname, realpath);
            switch (dtype) {
            case DT_REG:
                len = strlen(nfc_dname);
                memcpy(path + baselen, nfc_dname, len + 1);
                len = strlen(path);
                break;
            case DT_DIR:
                len = strlen(nfc_dname);
                memcpy(path + baselen, nfc_dname, len + 1);
                memcpy(path + baselen + len, "/", 2);
                len = strlen(path);
                read_directory_recursive(dir, path, len, 0,
                                         index, worktree, ignore_func, data);
                g_free (nfc_dname);
                continue;
            default: /* DT_UNKNOWN */
                len = 0;
                break;
            }
            if(len > 0)
                dir_add_name(dir, path, len, index);
            g_free (nfc_dname);
        }
        g_dir_close(fdir);
    }

    g_free(realpath);
    return contents;
}
예제 #4
0
파일: dir.c 프로젝트: B-Rich/git
/*
 * Read a directory tree. We currently ignore anything but
 * directories, regular files and symlinks. That's because git
 * doesn't handle them at all yet. Maybe that will change some
 * day.
 *
 * Also, we ignore the name ".git" (even if it is not a directory).
 * That likely will not change.
 *
 * Returns the most significant path_treatment value encountered in the scan.
 */
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
				    const char *base, int baselen,
				    int check_only,
				    const struct path_simplify *simplify)
{
	DIR *fdir;
	enum path_treatment state, subdir_state, dir_state = path_none;
	struct dirent *de;
	struct strbuf path = STRBUF_INIT;

	strbuf_add(&path, base, baselen);

	fdir = opendir(path.len ? path.buf : ".");
	if (!fdir)
		goto out;

	while ((de = readdir(fdir)) != NULL) {
		/* check how the file or directory should be treated */
		state = treat_path(dir, de, &path, baselen, simplify);
		if (state > dir_state)
			dir_state = state;

		/* recurse into subdir if instructed by treat_path */
		if (state == path_recurse) {
			subdir_state = read_directory_recursive(dir, path.buf,
				path.len, check_only, simplify);
			if (subdir_state > dir_state)
				dir_state = subdir_state;
		}

		if (check_only) {
			/* abort early if maximum state has been reached */
			if (dir_state == path_untracked)
				break;
			/* skip the dir_add_* part */
			continue;
		}

		/* add the path to the appropriate result list */
		switch (state) {
		case path_excluded:
			if (dir->flags & DIR_SHOW_IGNORED)
				dir_add_name(dir, path.buf, path.len);
			else if ((dir->flags & DIR_SHOW_IGNORED_TOO) ||
				((dir->flags & DIR_COLLECT_IGNORED) &&
				exclude_matches_pathspec(path.buf, path.len,
					simplify)))
				dir_add_ignored(dir, path.buf, path.len);
			break;

		case path_untracked:
			if (!(dir->flags & DIR_SHOW_IGNORED))
				dir_add_name(dir, path.buf, path.len);
			break;

		default:
			break;
		}
	}
	closedir(fdir);
 out:
	strbuf_release(&path);

	return dir_state;
}
예제 #5
0
파일: dir.c 프로젝트: sirnot/git
/*
 * Read a directory tree. We currently ignore anything but
 * directories, regular files and symlinks. That's because git
 * doesn't handle them at all yet. Maybe that will change some
 * day.
 *
 * Also, we ignore the name ".git" (even if it is not a directory).
 * That likely will not change.
 */
static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
{
	DIR *fdir = opendir(path);
	int contents = 0;

	if (fdir) {
		struct dirent *de;
		char fullname[PATH_MAX + 1];
		memcpy(fullname, base, baselen);

		while ((de = readdir(fdir)) != NULL) {
			int len, dtype;
			int exclude;

			if (is_dot_or_dotdot(de->d_name) ||
			     !strcmp(de->d_name, ".git"))
				continue;
			len = strlen(de->d_name);
			/* Ignore overly long pathnames! */
			if (len + baselen + 8 > sizeof(fullname))
				continue;
			memcpy(fullname + baselen, de->d_name, len+1);
			if (simplify_away(fullname, baselen + len, simplify))
				continue;

			dtype = DTYPE(de);
			exclude = excluded(dir, fullname, &dtype);
			if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
			    && in_pathspec(fullname, baselen + len, simplify))
				dir_add_ignored(dir, fullname, baselen + len);

			/*
			 * Excluded? If we don't explicitly want to show
			 * ignored files, ignore it
			 */
			if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
				continue;

			if (dtype == DT_UNKNOWN)
				dtype = get_dtype(de, fullname);

			/*
			 * Do we want to see just the ignored files?
			 * We still need to recurse into directories,
			 * even if we don't ignore them, since the
			 * directory may contain files that we do..
			 */
			if (!exclude && (dir->flags & DIR_SHOW_IGNORED)) {
				if (dtype != DT_DIR)
					continue;
			}

			switch (dtype) {
			default:
				continue;
			case DT_DIR:
				memcpy(fullname + baselen + len, "/", 2);
				len++;
				switch (treat_directory(dir, fullname, baselen + len, simplify)) {
				case show_directory:
					if (exclude != !!(dir->flags
							& DIR_SHOW_IGNORED))
						continue;
					break;
				case recurse_into_directory:
					contents += read_directory_recursive(dir,
						fullname, fullname, baselen + len, 0, simplify);
					continue;
				case ignore_directory:
					continue;
				}
				break;
			case DT_REG:
			case DT_LNK:
				break;
			}
			contents++;
			if (check_only)
				goto exit_early;
			else
				dir_add_name(dir, fullname, baselen + len);
		}
exit_early:
		closedir(fdir);
	}

	return contents;
}