/*
 * Utilities for paths and pathnames
 */

#include "git-compat-util.h"
#include "abspath.h"
#include "gettext.h"
#include "repository.h"
#include "strbuf.h"
#include "string-list.h"
#include "dir.h"
#include "worktree.h"
#include "setup.h"
#include "submodule-config.h"
#include "path.h"
#include "packfile.h"
#include "odb.h"
#include "lockfile.h"
#include "exec-cmd.h"

static int get_st_mode_bits(const char *path, int *mode)
{
	struct stat st;
	if (lstat(path, &st) < 0)
		return -1;
	*mode = st.st_mode;
	return 0;
}

static struct strbuf *get_pathname(void)
{
	static struct strbuf pathname_array[4] = {
		STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
	};
	static int index;
	struct strbuf *sb = &pathname_array[index];
	index = (index + 1) % ARRAY_SIZE(pathname_array);
	strbuf_reset(sb);
	return sb;
}

static const char *cleanup_path(const char *path)
{
	/* Clean it up */
	if (skip_prefix(path, "./", &path)) {
		while (*path == '/')
			path++;
	}
	return path;
}

static void strbuf_cleanup_path(struct strbuf *sb)
{
	const char *path = cleanup_path(sb->buf);
	if (path > sb->buf)
		strbuf_remove(sb, 0, path - sb->buf);
}

int dir_prefix(const char *buf, const char *dir)
{
	size_t len = strlen(dir);
	return !strncmp(buf, dir, len) &&
		(is_dir_sep(buf[len]) || buf[len] == '\0');
}

/* $buf =~ m|$dir/+$file| but without regex */
static int is_dir_file(const char *buf, const char *dir, const char *file)
{
	int len = strlen(dir);
	if (strncmp(buf, dir, len) || !is_dir_sep(buf[len]))
		return 0;
	while (is_dir_sep(buf[len]))
		len++;
	return !strcmp(buf + len, file);
}

static void replace_dir(struct strbuf *buf, int len, const char *newdir)
{
	int newlen = strlen(newdir);
	int need_sep = (buf->buf[len] && !is_dir_sep(buf->buf[len])) &&
		!is_dir_sep(newdir[newlen - 1]);
	if (need_sep)
		len--;	 /* keep one char, to be replaced with '/'  */
	strbuf_splice(buf, 0, len, newdir, newlen);
	if (need_sep)
		buf->buf[newlen] = '/';
}

struct common_dir {
	/* Not considered garbage for report_linked_checkout_garbage */
	unsigned ignore_garbage:1;
	unsigned is_dir:1;
	/* Belongs to the common dir, though it may contain paths that don't */
	unsigned is_common:1;
	const char *path;
};

static struct common_dir common_list[] = {
	{ 0, 1, 1, "branches" },
	{ 0, 1, 1, "common" },
	{ 0, 1, 1, "hooks" },
	{ 0, 1, 1, "info" },
	{ 0, 0, 0, "info/sparse-checkout" },
	{ 1, 1, 1, "logs" },
	{ 1, 0, 0, "logs/HEAD" },
	{ 0, 1, 0, "logs/refs/bisect" },
	{ 0, 1, 0, "logs/refs/rewritten" },
	{ 0, 1, 0, "logs/refs/worktree" },
	{ 0, 1, 1, "lost-found" },
	{ 0, 1, 1, "objects" },
	{ 0, 1, 1, "refs" },
	{ 0, 1, 0, "refs/bisect" },
	{ 0, 1, 0, "refs/rewritten" },
	{ 0, 1, 0, "refs/worktree" },
	{ 0, 1, 1, "remotes" },
	{ 0, 1, 1, "worktrees" },
	{ 0, 1, 1, "rr-cache" },
	{ 0, 1, 1, "svn" },
	{ 0, 0, 1, "config" },
	{ 1, 0, 1, "gc.pid" },
	{ 0, 0, 1, "packed-refs" },
	{ 0, 0, 1, "shallow" },
	{ 0, 0, 0, NULL }
};

/*
 * A compressed trie.  A trie node consists of zero or more characters that
 * are common to all elements with this prefix, optionally followed by some
 * children.  If value is not NULL, the trie node is a terminal node.
 *
 * For example, consider the following set of strings:
 * abc
 * def
 * definite
 * definition
 *
 * The trie would look like:
 * root: len = 0, children a and d non-NULL, value = NULL.
 *    a: len = 2, contents = bc, value = (data for "abc")
 *    d: len = 2, contents = ef, children i non-NULL, value = (data for "def")
 *       i: len = 3, contents = nit, children e and i non-NULL, value = NULL
 *           e: len = 0, children all NULL, value = (data for "definite")
 *           i: len = 2, contents = on, children all NULL,
 *              value = (data for "definition")
 */
struct trie {
	struct trie *children[256];
	int len;
	char *contents;
	void *value;
};

static struct trie *make_trie_node(const char *key, void *value)
{
	struct trie *new_node = xcalloc(1, sizeof(*new_node));
	new_node->len = strlen(key);
	if (new_node->len) {
		new_node->contents = xmalloc(new_node->len);
		memcpy(new_node->contents, key, new_node->len);
	}
	new_node->value = value;
	return new_node;
}

/*
 * Add a key/value pair to a trie.  The key is assumed to be \0-terminated.
 * If there was an existing value for this key, return it.
 */
static void *add_to_trie(struct trie *root, const char *key, void *value)
{
	struct trie *child;
	void *old;
	int i;

	if (!*key) {
		/* we have reached the end of the key */
		old = root->value;
		root->value = value;
		return old;
	}

	for (i = 0; i < root->len; i++) {
		if (root->contents[i] == key[i])
			continue;

		/*
		 * Split this node: child will contain this node's
		 * existing children.
		 */
		child = xmalloc(sizeof(*child));
		memcpy(child->children, root->children, sizeof(root->children));

		child->len = root->len - i - 1;
		if (child->len) {
			child->contents = xstrndup(root->contents + i + 1,
						   child->len);
		}
		child->value = root->value;
		root->value = NULL;
		root->len = i;

		memset(root->children, 0, sizeof(root->children));
		root->children[(unsigned char)root->contents[i]] = child;

		/* This is the newly-added child. */
		root->children[(unsigned char)key[i]] =
			make_trie_node(key + i + 1, value);
		return NULL;
	}

	/* We have matched the entire compressed section */
	if (key[i]) {
		child = root->children[(unsigned char)key[root->len]];
		if (child) {
			return add_to_trie(child, key + root->len + 1, value);
		} else {
			child = make_trie_node(key + root->len + 1, value);
			root->children[(unsigned char)key[root->len]] = child;
			return NULL;
		}
	}

	old = root->value;
	root->value = value;
	return old;
}

typedef int (*match_fn)(const char *unmatched, void *value, void *baton);

/*
 * Search a trie for some key.  Find the longest /-or-\0-terminated
 * prefix of the key for which the trie contains a value.  If there is
 * no such prefix, return -1.  Otherwise call fn with the unmatched
 * portion of the key and the found value.  If fn returns 0 or
 * positive, then return its return value.  If fn returns negative,
 * then call fn with the next-longest /-terminated prefix of the key
 * (i.e. a parent directory) for which the trie contains a value, and
 * handle its return value the same way.  If there is no shorter
 * /-terminated prefix with a value left, then return the negative
 * return value of the most recent fn invocation.
 *
 * The key is partially normalized: consecutive slashes are skipped.
 *
 * For example, consider the trie containing only [logs,
 * logs/refs/bisect], both with values, but not logs/refs.
 *
 * | key                | unmatched      | prefix to node   | return value |
 * |--------------------|----------------|------------------|--------------|
 * | a                  | not called     | n/a              | -1           |
 * | logstore           | not called     | n/a              | -1           |
 * | logs               | \0             | logs             | as per fn    |
 * | logs/              | /              | logs             | as per fn    |
 * | logs/refs          | /refs          | logs             | as per fn    |
 * | logs/refs/         | /refs/         | logs             | as per fn    |
 * | logs/refs/b        | /refs/b        | logs             | as per fn    |
 * | logs/refs/bisected | /refs/bisected | logs             | as per fn    |
 * | logs/refs/bisect   | \0             | logs/refs/bisect | as per fn    |
 * | logs/refs/bisect/  | /              | logs/refs/bisect | as per fn    |
 * | logs/refs/bisect/a | /a             | logs/refs/bisect | as per fn    |
 * | (If fn in the previous line returns -1, then fn is called once more:) |
 * | logs/refs/bisect/a | /refs/bisect/a | logs             | as per fn    |
 * |--------------------|----------------|------------------|--------------|
 */
static int trie_find(struct trie *root, const char *key, match_fn fn,
		     void *baton)
{
	int i;
	int result;
	struct trie *child;

	if (!*key) {
		/* we have reached the end of the key */
		if (root->value && !root->len)
			return fn(key, root->value, baton);
		else
			return -1;
	}

	for (i = 0; i < root->len; i++) {
		/* Partial path normalization: skip consecutive slashes. */
		if (key[i] == '/' && key[i+1] == '/') {
			key++;
			continue;
		}
		if (root->contents[i] != key[i])
			return -1;
	}

	/* Matched the entire compressed section */
	key += i;
	if (!*key) {
		/* End of key */
		if (root->value)
			return fn(key, root->value, baton);
		else
			return -1;
	}

	/* Partial path normalization: skip consecutive slashes */
	while (key[0] == '/' && key[1] == '/')
		key++;

	child = root->children[(unsigned char)*key];
	if (child)
		result = trie_find(child, key + 1, fn, baton);
	else
		result = -1;

	if (result >= 0 || (*key != '/' && *key != 0))
		return result;
	if (root->value)
		return fn(key, root->value, baton);
	else
		return -1;
}

static struct trie common_trie;
static int common_trie_done_setup;

static void init_common_trie(void)
{
	struct common_dir *p;

	if (common_trie_done_setup)
		return;

	for (p = common_list; p->path; p++)
		add_to_trie(&common_trie, p->path, p);

	common_trie_done_setup = 1;
}

/*
 * Helper function for update_common_dir: returns 1 if the dir
 * prefix is common.
 */
static int check_common(const char *unmatched, void *value,
			void *baton UNUSED)
{
	struct common_dir *dir = value;

	if (dir->is_dir && (unmatched[0] == 0 || unmatched[0] == '/'))
		return dir->is_common;

	if (!dir->is_dir && unmatched[0] == 0)
		return dir->is_common;

	return 0;
}

static void update_common_dir(struct strbuf *buf, int git_dir_len,
			      const char *common_dir)
{
	char *base = buf->buf + git_dir_len;
	int has_lock_suffix = strbuf_strip_suffix(buf, LOCK_SUFFIX);

	init_common_trie();
	if (trie_find(&common_trie, base, check_common, NULL) > 0)
		replace_dir(buf, git_dir_len, common_dir);

	if (has_lock_suffix)
		strbuf_addstr(buf, LOCK_SUFFIX);
}

void report_linked_checkout_garbage(struct repository *r)
{
	struct strbuf sb = STRBUF_INIT;
	const struct common_dir *p;
	int len;

	if (!r->different_commondir)
		return;
	strbuf_addf(&sb, "%s/", r->gitdir);
	len = sb.len;
	for (p = common_list; p->path; p++) {
		const char *path = p->path;
		if (p->ignore_garbage)
			continue;
		strbuf_setlen(&sb, len);
		strbuf_addstr(&sb, path);
		if (file_exists(sb.buf))
			report_garbage(PACKDIR_FILE_GARBAGE, sb.buf);
	}
	strbuf_release(&sb);
}

static void adjust_git_path(struct repository *repo,
			    struct strbuf *buf, int git_dir_len)
{
	const char *base = buf->buf + git_dir_len;

	if (is_dir_file(base, "info", "grafts"))
		strbuf_splice(buf, 0, buf->len,
			      repo->graft_file, strlen(repo->graft_file));
	else if (!strcmp(base, "index"))
		strbuf_splice(buf, 0, buf->len,
			      repo->index_file, strlen(repo->index_file));
	else if (dir_prefix(base, "objects"))
		replace_dir(buf, git_dir_len + 7, repo->objects->sources->path);
	else if (repo_settings_get_hooks_path(repo) && dir_prefix(base, "hooks"))
		replace_dir(buf, git_dir_len + 5, repo_settings_get_hooks_path(repo));
	else if (repo->different_commondir)
		update_common_dir(buf, git_dir_len, repo->commondir);
}

static void strbuf_worktree_gitdir(struct strbuf *buf,
				   const struct repository *repo,
				   const struct worktree *wt)
{
	if (!wt)
		strbuf_addstr(buf, repo->gitdir);
	else if (!wt->id)
		strbuf_addstr(buf, repo->commondir);
	else
		repo_common_path_append(repo, buf, "worktrees/%s", wt->id);
}

static void repo_git_pathv(struct repository *repo,
			   const struct worktree *wt, struct strbuf *buf,
			   const char *fmt, va_list args)
{
	int gitdir_len;
	strbuf_worktree_gitdir(buf, repo, wt);
	if (buf->len && !is_dir_sep(buf->buf[buf->len - 1]))
		strbuf_addch(buf, '/');
	gitdir_len = buf->len;
	strbuf_vaddf(buf, fmt, args);
	if (!wt)
		adjust_git_path(repo, buf, gitdir_len);
	strbuf_cleanup_path(buf);
}

char *repo_git_path(struct repository *repo,
		    const char *fmt, ...)
{
	struct strbuf path = STRBUF_INIT;
	va_list args;
	va_start(args, fmt);
	repo_git_pathv(repo, NULL, &path, fmt, args);
	va_end(args);
	return strbuf_detach(&path, NULL);
}

const char *repo_git_path_append(struct repository *repo,
				 struct strbuf *sb,
				 const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	repo_git_pathv(repo, NULL, sb, fmt, args);
	va_end(args);
	return sb->buf;
}

const char *repo_git_path_replace(struct repository *repo,
				  struct strbuf *sb,
				  const char *fmt, ...)
{
	va_list args;
	strbuf_reset(sb);
	va_start(args, fmt);
	repo_git_pathv(repo, NULL, sb, fmt, args);
	va_end(args);
	return sb->buf;
}

char *mkpathdup(const char *fmt, ...)
{
	struct strbuf sb = STRBUF_INIT;
	va_list args;
	va_start(args, fmt);
	strbuf_vaddf(&sb, fmt, args);
	va_end(args);
	strbuf_cleanup_path(&sb);
	return strbuf_detach(&sb, NULL);
}

const char *mkpath(const char *fmt, ...)
{
	va_list args;
	struct strbuf *pathname = get_pathname();
	va_start(args, fmt);
	strbuf_vaddf(pathname, fmt, args);
	va_end(args);
	return cleanup_path(pathname->buf);
}

const char *worktree_git_path(const struct worktree *wt, const char *fmt, ...)
{
	struct strbuf *pathname = get_pathname();
	va_list args;

	if (!wt)
		BUG("%s() called with NULL worktree", __func__);

	va_start(args, fmt);
	repo_git_pathv(wt->repo, wt, pathname, fmt, args);
	va_end(args);
	return pathname->buf;
}

static void do_worktree_path(const struct repository *repo,
			     struct strbuf *buf,
			     const char *fmt, va_list args)
{
	strbuf_addstr(buf, repo->worktree);
	if(buf->len && !is_dir_sep(buf->buf[buf->len - 1]))
		strbuf_addch(buf, '/');

	strbuf_vaddf(buf, fmt, args);
	strbuf_cleanup_path(buf);
}

char *repo_worktree_path(const struct repository *repo, const char *fmt, ...)
{
	struct strbuf path = STRBUF_INIT;
	va_list args;

	va_start(args, fmt);
	do_worktree_path(repo, &path, fmt, args);
	va_end(args);

	return strbuf_detach(&path, NULL);
}

const char *repo_worktree_path_append(const struct repository *repo,
				      struct strbuf *sb,
				      const char *fmt, ...)
{
	va_list args;

	if (!repo->worktree)
		return NULL;

	va_start(args, fmt);
	do_worktree_path(repo, sb, fmt, args);
	va_end(args);

	return sb->buf;
}

const char *repo_worktree_path_replace(const struct repository *repo,
				       struct strbuf *sb,
				       const char *fmt, ...)
{
	va_list args;

	strbuf_reset(sb);
	if (!repo->worktree)
		return NULL;

	va_start(args, fmt);
	do_worktree_path(repo, sb, fmt, args);
	va_end(args);

	return sb->buf;
}

/* Returns 0 on success, negative on failure. */
static int do_submodule_path(struct repository *repo,
			     struct strbuf *buf, const char *path,
			     const char *fmt, va_list args)
{
	struct strbuf git_submodule_common_dir = STRBUF_INIT;
	struct strbuf git_submodule_dir = STRBUF_INIT;
	int ret;

	ret = submodule_to_gitdir(repo, &git_submodule_dir, path);
	if (ret)
		goto cleanup;

	strbuf_complete(&git_submodule_dir, '/');
	strbuf_addbuf(buf, &git_submodule_dir);
	strbuf_vaddf(buf, fmt, args);

	if (get_common_dir_noenv(&git_submodule_common_dir, git_submodule_dir.buf))
		update_common_dir(buf, git_submodule_dir.len, git_submodule_common_dir.buf);

	strbuf_cleanup_path(buf);

cleanup:
	strbuf_release(&git_submodule_dir);
	strbuf_release(&git_submodule_common_dir);
	return ret;
}

char *repo_submodule_path(struct repository *repo,
			  const char *path, const char *fmt, ...)
{
	int err;
	va_list args;
	struct strbuf buf = STRBUF_INIT;
	va_start(args, fmt);
	err = do_submodule_path(repo, &buf, path, fmt, args);
	va_end(args);
	if (err) {
		strbuf_release(&buf);
		return NULL;
	}
	return strbuf_detach(&buf, NULL);
}

const char *repo_submodule_path_append(struct repository *repo,
				       struct strbuf *buf,
				       const char *path,
				       const char *fmt, ...)
{
	int err;
	va_list args;
	va_start(args, fmt);
	err = do_submodule_path(repo, buf, path, fmt, args);
	va_end(args);
	if (err)
		return NULL;
	return buf->buf;
}

const char *repo_submodule_path_replace(struct repository *repo,
					struct strbuf *buf,
					const char *path,
					const char *fmt, ...)
{
	int err;
	va_list args;
	strbuf_reset(buf);
	va_start(args, fmt);
	err = do_submodule_path(repo, buf, path, fmt, args);
	va_end(args);
	if (err)
		return NULL;
	return buf->buf;
}

static void repo_common_pathv(const struct repository *repo,
			      struct strbuf *sb,
			      const char *fmt,
			      va_list args)
{
	strbuf_addstr(sb, repo->commondir);
	if (sb->len && !is_dir_sep(sb->buf[sb->len - 1]))
		strbuf_addch(sb, '/');
	strbuf_vaddf(sb, fmt, args);
	strbuf_cleanup_path(sb);
}

char *repo_common_path(const struct repository *repo,
		       const char *fmt, ...)
{
	struct strbuf sb = STRBUF_INIT;
	va_list args;
	va_start(args, fmt);
	repo_common_pathv(repo, &sb, fmt, args);
	va_end(args);
	return strbuf_detach(&sb, NULL);
}

const char *repo_common_path_append(const struct repository *repo,
				    struct strbuf *sb,
				    const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	repo_common_pathv(repo, sb, fmt, args);
	va_end(args);
	return sb->buf;
}

const char *repo_common_path_replace(const struct repository *repo,
				     struct strbuf *sb,
				     const char *fmt, ...)
{
	va_list args;
	strbuf_reset(sb);
	va_start(args, fmt);
	repo_common_pathv(repo, sb, fmt, args);
	va_end(args);
	return sb->buf;
}

static struct passwd *getpw_str(const char *username, size_t len)
{
	struct passwd *pw;
	char *username_z = xmemdupz(username, len);
	pw = getpwnam(username_z);
	free(username_z);
	return pw;
}

/*
 * Return a string with ~ and ~user expanded via getpw*. Returns NULL on getpw
 * failure or if path is NULL.
 *
 * If real_home is true, strbuf_realpath($HOME) is used in the `~/` expansion.
 *
 * If the path starts with `%(prefix)/`, the remainder is interpreted as
 * relative to where Git is installed, and expanded to the absolute path.
 */
char *interpolate_path(const char *path, int real_home)
{
	struct strbuf user_path = STRBUF_INIT;
	const char *to_copy = path;

	if (!path)
		goto return_null;

	if (skip_prefix(path, "%(prefix)/", &path))
		return system_path(path);

	if (path[0] == '~') {
		const char *first_slash = strchrnul(path, '/');
		const char *username = path + 1;
		size_t username_len = first_slash - username;
		if (username_len == 0) {
			const char *home = getenv("HOME");
			if (!home)
				goto return_null;
			if (real_home)
				strbuf_add_real_path(&user_path, home);
			else
				strbuf_addstr(&user_path, home);
#ifdef GIT_WINDOWS_NATIVE
			convert_slashes(user_path.buf);
#endif
		} else {
			struct passwd *pw = getpw_str(username, username_len);
			if (!pw)
				goto return_null;
			strbuf_addstr(&user_path, pw->pw_dir);
		}
		to_copy = first_slash;
	}
	strbuf_addstr(&user_path, to_copy);
	return strbuf_detach(&user_path, NULL);
return_null:
	strbuf_release(&user_path);
	return NULL;
}

int calc_shared_perm(struct repository *repo,
		     int mode)
{
	int tweak;
	int shared_repo = repo_settings_get_shared_repository(repo);
	if (shared_repo < 0)
		tweak = -shared_repo;
	else
		tweak = shared_repo;

	if (!(mode & S_IWUSR))
		tweak &= ~0222;
	if (mode & S_IXUSR)
		/* Copy read bits to execute bits */
		tweak |= (tweak & 0444) >> 2;
	if (shared_repo < 0)
		mode = (mode & ~0777) | tweak;
	else
		mode |= tweak;

	return mode;
}

int adjust_shared_perm(struct repository *repo,
		       const char *path)
{
	int old_mode, new_mode;

	if (!repo_settings_get_shared_repository(repo))
		return 0;
	if (get_st_mode_bits(path, &old_mode) < 0)
		return -1;

	new_mode = calc_shared_perm(repo, old_mode);
	if (S_ISDIR(old_mode)) {
		/* Copy read bits to execute bits */
		new_mode |= (new_mode & 0444) >> 2;

		/*
		 * g+s matters only if any extra access is granted
		 * based on group membership.
		 */
		if (FORCE_DIR_SET_GID && (new_mode & 060))
			new_mode |= FORCE_DIR_SET_GID;
	}

	if (((old_mode ^ new_mode) & ~S_IFMT) &&
			chmod(path, (new_mode & ~S_IFMT)) < 0)
		return -2;
	return 0;
}

void safe_create_dir(struct repository *repo, const char *dir, int share)
{
	if (mkdir(dir, 0777) < 0) {
		if (errno != EEXIST) {
			perror(dir);
			exit(1);
		}
	}
	else if (share && adjust_shared_perm(repo, dir))
		die(_("Could not make %s writable by group"), dir);
}

int safe_create_dir_in_gitdir(struct repository *repo, const char *path)
{
	if (mkdir(path, 0777)) {
		int saved_errno = errno;
		struct stat st;
		struct strbuf sb = STRBUF_INIT;

		if (errno != EEXIST)
			return -1;
		/*
		 * Are we looking at a path in a symlinked worktree
		 * whose original repository does not yet have it?
		 * e.g. .git/rr-cache pointing at its original
		 * repository in which the user hasn't performed any
		 * conflict resolution yet?
		 */
		if (lstat(path, &st) || !S_ISLNK(st.st_mode) ||
		    strbuf_readlink(&sb, path, st.st_size) ||
		    !is_absolute_path(sb.buf) ||
		    mkdir(sb.buf, 0777)) {
			strbuf_release(&sb);
			errno = saved_errno;
			return -1;
		}
		strbuf_release(&sb);
	}
	return adjust_shared_perm(repo, path);
}

static enum scld_error safe_create_leading_directories_1(struct repository *repo,
							 char *path)
{
	char *next_component = path + offset_1st_component(path);
	enum scld_error ret = SCLD_OK;

	while (ret == SCLD_OK && next_component) {
		struct stat st;
		char *slash = next_component, slash_character;

		while (*slash && !is_dir_sep(*slash))
			slash++;

		if (!*slash)
			break;

		next_component = slash + 1;
		while (is_dir_sep(*next_component))
			next_component++;
		if (!*next_component)
			break;

		slash_character = *slash;
		*slash = '\0';
		if (!stat(path, &st)) {
			/* path exists */
			if (!S_ISDIR(st.st_mode)) {
				errno = ENOTDIR;
				ret = SCLD_EXISTS;
			}
		} else if (mkdir(path, 0777)) {
			if (errno == EEXIST &&
			    !stat(path, &st) && S_ISDIR(st.st_mode))
				; /* somebody created it since we checked */
			else if (errno == ENOENT)
				/*
				 * Either mkdir() failed because
				 * somebody just pruned the containing
				 * directory, or stat() failed because
				 * the file that was in our way was
				 * just removed.  Either way, inform
				 * the caller that it might be worth
				 * trying again:
				 */
				ret = SCLD_VANISHED;
			else
				ret = SCLD_FAILED;
		} else if (repo && adjust_shared_perm(repo, path)) {
			ret = SCLD_PERMS;
		}
		*slash = slash_character;
	}
	return ret;
}

enum scld_error safe_create_leading_directories(struct repository *repo,
						char *path)
{
	return safe_create_leading_directories_1(repo, path);
}

enum scld_error safe_create_leading_directories_no_share(char *path)
{
	return safe_create_leading_directories_1(NULL, path);
}

enum scld_error safe_create_leading_directories_const(struct repository *repo,
						      const char *path)
{
	int save_errno;
	/* path points to cache entries, so xstrdup before messing with it */
	char *buf = xstrdup(path);
	enum scld_error result = safe_create_leading_directories(repo, buf);

	save_errno = errno;
	free(buf);
	errno = save_errno;
	return result;
}

int safe_create_file_with_leading_directories(struct repository *repo,
					      const char *path)
{
	int fd;

	fd = open(path, O_RDWR|O_CREAT|O_EXCL, 0600);
	if (0 <= fd)
		return fd;

	/* slow path */
	safe_create_leading_directories_const(repo, path);
	return open(path, O_RDWR|O_CREAT|O_EXCL, 0600);
}

static int have_same_root(const char *path1, const char *path2)
{
	int is_abs1, is_abs2;

	is_abs1 = is_absolute_path(path1);
	is_abs2 = is_absolute_path(path2);
	return (is_abs1 && is_abs2 && tolower(path1[0]) == tolower(path2[0])) ||
	       (!is_abs1 && !is_abs2);
}

/*
 * Give path as relative to prefix.
 *
 * The strbuf may or may not be used, so do not assume it contains the
 * returned path.
 */
const char *relative_path(const char *in, const char *prefix,
			  struct strbuf *sb)
{
	int in_len = in ? strlen(in) : 0;
	int prefix_len = prefix ? strlen(prefix) : 0;
	int in_off = 0;
	int prefix_off = 0;
	int i = 0, j = 0;

	if (!in_len)
		return "./";
	else if (!prefix_len)
		return in;

	if (have_same_root(in, prefix))
		/* bypass dos_drive, for "c:" is identical to "C:" */
		i = j = has_dos_drive_prefix(in);
	else {
		return in;
	}

	while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
		if (is_dir_sep(prefix[i])) {
			while (is_dir_sep(prefix[i]))
				i++;
			while (is_dir_sep(in[j]))
				j++;
			prefix_off = i;
			in_off = j;
		} else {
			i++;
			j++;
		}
	}

	if (
	    /* "prefix" seems like prefix of "in" */
	    i >= prefix_len &&
	    /*
	     * but "/foo" is not a prefix of "/foobar"
	     * (i.e. prefix not end with '/')
	     */
	    prefix_off < prefix_len) {
		if (j >= in_len) {
			/* in="/a/b", prefix="/a/b" */
			in_off = in_len;
		} else if (is_dir_sep(in[j])) {
			/* in="/a/b/c", prefix="/a/b" */
			while (is_dir_sep(in[j]))
				j++;
			in_off = j;
		} else {
			/* in="/a/bbb/c", prefix="/a/b" */
			i = prefix_off;
		}
	} else if (
		   /* "in" is short than "prefix" */
		   j >= in_len &&
		   /* "in" not end with '/' */
		   in_off < in_len) {
		if (is_dir_sep(prefix[i])) {
			/* in="/a/b", prefix="/a/b/c/" */
			while (is_dir_sep(prefix[i]))
				i++;
			in_off = in_len;
		}
	}
	in += in_off;
	in_len -= in_off;

	if (i >= prefix_len) {
		if (!in_len)
			return "./";
		else
			return in;
	}

	strbuf_reset(sb);
	strbuf_grow(sb, in_len);

	while (i < prefix_len) {
		if (is_dir_sep(prefix[i])) {
			strbuf_addstr(sb, "../");
			while (is_dir_sep(prefix[i]))
				i++;
			continue;
		}
		i++;
	}
	if (!is_dir_sep(prefix[prefix_len - 1]))
		strbuf_addstr(sb, "../");

	strbuf_addstr(sb, in);

	return sb->buf;
}

/*
 * A simpler implementation of relative_path
 *
 * Get relative path by removing "prefix" from "in". This function
 * first appears in v1.5.6-1-g044bbbc, and makes git_dir shorter
 * to increase performance when traversing the path to work_tree.
 */
const char *remove_leading_path(const char *in, const char *prefix)
{
	static struct strbuf buf = STRBUF_INIT;
	int i = 0, j = 0;

	if (!prefix || !prefix[0])
		return in;
	while (prefix[i]) {
		if (is_dir_sep(prefix[i])) {
			if (!is_dir_sep(in[j]))
				return in;
			while (is_dir_sep(prefix[i]))
				i++;
			while (is_dir_sep(in[j]))
				j++;
			continue;
		} else if (in[j] != prefix[i]) {
			return in;
		}
		i++;
		j++;
	}
	if (
	    /* "/foo" is a prefix of "/foo" */
	    in[j] &&
	    /* "/foo" is not a prefix of "/foobar" */
	    !is_dir_sep(prefix[i-1]) && !is_dir_sep(in[j])
	   )
		return in;
	while (is_dir_sep(in[j]))
		j++;

	strbuf_reset(&buf);
	if (!in[j])
		strbuf_addstr(&buf, ".");
	else
		strbuf_addstr(&buf, in + j);
	return buf.buf;
}

/*
 * It is okay if dst == src, but they should not overlap otherwise.
 * The "dst" buffer must be at least as long as "src"; normalizing may shrink
 * the size of the path, but will never grow it.
 *
 * Performs the following normalizations on src, storing the result in dst:
 * - Ensures that components are separated by '/' (Windows only)
 * - Squashes sequences of '/' except "//server/share" on Windows
 * - Removes "." components.
 * - Removes ".." components, and the components the precede them.
 * Returns failure (non-zero) if a ".." component appears as first path
 * component anytime during the normalization. Otherwise, returns success (0).
 *
 * Note that this function is purely textual.  It does not follow symlinks,
 * verify the existence of the path, or make any system calls.
 *
 * prefix_len != NULL is for a specific case of prefix_pathspec():
 * assume that src == dst and src[0..prefix_len-1] is already
 * normalized, any time "../" eats up to the prefix_len part,
 * prefix_len is reduced. In the end prefix_len is the remaining
 * prefix that has not been overridden by user pathspec.
 *
 * NEEDSWORK: This function doesn't perform normalization w.r.t. trailing '/'.
 * For everything but the root folder itself, the normalized path should not
 * end with a '/', then the callers need to be fixed up accordingly.
 *
 */

static const char *skip_slashes(const char *p)
{
	while (is_dir_sep(*p))
		p++;
	return p;
}

int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
{
	char *dst0;
	const char *end;

	/*
	 * Copy initial part of absolute path: "/", "C:/", "//server/share/".
	 */
	end = src + offset_1st_component(src);
	while (src < end) {
		char c = *src++;
		if (is_dir_sep(c))
			c = '/';
		*dst++ = c;
	}
	dst0 = dst;

	src = skip_slashes(src);

	for (;;) {
		char c = *src;

		/*
		 * A path component that begins with . could be
		 * special:
		 * (1) "." and ends   -- ignore and terminate.
		 * (2) "./"           -- ignore them, eat slash and continue.
		 * (3) ".." and ends  -- strip one and terminate.
		 * (4) "../"          -- strip one, eat slash and continue.
		 */
		if (c == '.') {
			if (!src[1]) {
				/* (1) */
				src++;
			} else if (is_dir_sep(src[1])) {
				/* (2) */
				src += 2;
				src = skip_slashes(src);
				continue;
			} else if (src[1] == '.') {
				if (!src[2]) {
					/* (3) */
					src += 2;
					goto up_one;
				} else if (is_dir_sep(src[2])) {
					/* (4) */
					src += 3;
					src = skip_slashes(src);
					goto up_one;
				}
			}
		}

		/* copy up to the next '/', and eat all '/' */
		while ((c = *src++) != '\0' && !is_dir_sep(c))
			*dst++ = c;
		if (is_dir_sep(c)) {
			*dst++ = '/';
			while (is_dir_sep(c))
				c = *src++;
			src--;
		} else if (!c)
			break;
		continue;

	up_one:
		/*
		 * strip the last component
		 *
		 * dst0..dst is prefix portion, and dst[-1] is '/';
		 * go up one level.
		 */
		dst--;	/* go to trailing '/' */
		if (dst <= dst0)
			return -1;
		/* Windows: dst[-1] cannot be backslash anymore */
		while (dst0 < dst && dst[-1] != '/')
			dst--;
		if (prefix_len && *prefix_len > dst - dst0)
			*prefix_len = dst - dst0;
	}
	*dst = '\0';
	return 0;
}

int normalize_path_copy(char *dst, const char *src)
{
	return normalize_path_copy_len(dst, src, NULL);
}

int strbuf_normalize_path(struct strbuf *src)
{
	struct strbuf dst = STRBUF_INIT;

	strbuf_grow(&dst, src->len);
	if (normalize_path_copy(dst.buf, src->buf) < 0) {
		strbuf_release(&dst);
		return -1;
	}

	/*
	 * normalize_path does not tell us the new length, so we have to
	 * compute it by looking for the new NUL it placed
	 */
	strbuf_setlen(&dst, strlen(dst.buf));
	strbuf_swap(src, &dst);
	strbuf_release(&dst);
	return 0;
}

/*
 * path = Canonical absolute path
 * prefixes = string_list containing normalized, absolute paths without
 * trailing slashes (except for the root directory, which is denoted by "/").
 *
 * Determines, for each path in prefixes, whether the "prefix"
 * is an ancestor directory of path.  Returns the length of the longest
 * ancestor directory, excluding any trailing slashes, or -1 if no prefix
 * is an ancestor.  (Note that this means 0 is returned if prefixes is
 * ["/"].) "/foo" is not considered an ancestor of "/foobar".  Directories
 * are not considered to be their own ancestors.  path must be in a
 * canonical form: empty components, or "." or ".." components are not
 * allowed.
 */
int longest_ancestor_length(const char *path, struct string_list *prefixes)
{
	int max_len = -1;

	if (!strcmp(path, "/"))
		return -1;

	for (size_t i = 0; i < prefixes->nr; i++) {
		const char *ceil = prefixes->items[i].string;
		int len = strlen(ceil);

		/*
		 * For root directories (`/`, `C:/`, `//server/share/`)
		 * adjust the length to exclude the trailing slash.
		 */
		if (len > 0 && ceil[len - 1] == '/')
			len--;

		if (strncmp(path, ceil, len) ||
		    path[len] != '/' || !path[len + 1])
			continue; /* no match */

		if (len > max_len)
			max_len = len;
	}

	return max_len;
}

/* strip arbitrary amount of directory separators at end of path */
static inline int chomp_trailing_dir_sep(const char *path, int len)
{
	while (len && is_dir_sep(path[len - 1]))
		len--;
	return len;
}

/*
 * If path ends with suffix (complete path components), returns the offset of
 * the last character in the path before the suffix (sans trailing directory
 * separators), and -1 otherwise.
 */
static ssize_t stripped_path_suffix_offset(const char *path, const char *suffix)
{
	int path_len = strlen(path), suffix_len = strlen(suffix);

	while (suffix_len) {
		if (!path_len)
			return -1;

		if (is_dir_sep(path[path_len - 1])) {
			if (!is_dir_sep(suffix[suffix_len - 1]))
				return -1;
			path_len = chomp_trailing_dir_sep(path, path_len);
			suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
		}
		else if (path[--path_len] != suffix[--suffix_len])
			return -1;
	}

	if (path_len && !is_dir_sep(path[path_len - 1]))
		return -1;
	return chomp_trailing_dir_sep(path, path_len);
}

/*
 * Returns true if the path ends with components, considering only complete path
 * components, and false otherwise.
 */
int ends_with_path_components(const char *path, const char *components)
{
	return stripped_path_suffix_offset(path, components) != -1;
}

/*
 * If path ends with suffix (complete path components), returns the
 * part before suffix (sans trailing directory separators).
 * Otherwise returns NULL.
 */
char *strip_path_suffix(const char *path, const char *suffix)
{
	ssize_t offset = stripped_path_suffix_offset(path, suffix);

	return offset == -1 ? NULL : xstrndup(path, offset);
}

int daemon_avoid_alias(const char *p)
{
	int sl, ndot;

	/*
	 * This resurrects the belts and suspenders paranoia check by HPA
	 * done in <435560F7.4080006@zytor.com> thread, now enter_repo()
	 * does not do getcwd() based path canonicalization.
	 *
	 * sl becomes true immediately after seeing '/' and continues to
	 * be true as long as dots continue after that without intervening
	 * non-dot character.
	 */
	if (!p || (*p != '/' && *p != '~'))
		return -1;
	sl = 1; ndot = 0;
	p++;

	while (1) {
		char ch = *p++;
		if (sl) {
			if (ch == '.')
				ndot++;
			else if (ch == '/') {
				if (ndot < 3)
					/* reject //, /./ and /../ */
					return -1;
				ndot = 0;
			}
			else if (ch == 0) {
				if (0 < ndot && ndot < 3)
					/* reject /.$ and /..$ */
					return -1;
				return 0;
			}
			else
				sl = ndot = 0;
		}
		else if (ch == 0)
			return 0;
		else if (ch == '/') {
			sl = 1;
			ndot = 0;
		}
	}
}

/*
 * On NTFS, we need to be careful to disallow certain synonyms of the `.git/`
 * directory:
 *
 * - For historical reasons, file names that end in spaces or periods are
 *   automatically trimmed. Therefore, `.git . . ./` is a valid way to refer
 *   to `.git/`.
 *
 * - For other historical reasons, file names that do not conform to the 8.3
 *   format (up to eight characters for the basename, three for the file
 *   extension, certain characters not allowed such as `+`, etc) are associated
 *   with a so-called "short name", at least on the `C:` drive by default.
 *   Which means that `git~1/` is a valid way to refer to `.git/`.
 *
 *   Note: Technically, `.git/` could receive the short name `git~2` if the
 *   short name `git~1` were already used. In Git, however, we guarantee that
 *   `.git` is the first item in a directory, therefore it will be associated
 *   with the short name `git~1` (unless short names are disabled).
 *
 * - For yet other historical reasons, NTFS supports so-called "Alternate Data
 *   Streams", i.e. metadata associated with a given file, referred to via
 *   `<filename>:<stream-name>:<stream-type>`. There exists a default stream
 *   type for directories, allowing `.git/` to be accessed via
 *   `.git::$INDEX_ALLOCATION/`.
 *
 * When this function returns 1, it indicates that the specified file/directory
 * name refers to a `.git` file or directory, or to any of these synonyms, and
 * Git should therefore not track it.
 *
 * For performance reasons, _all_ Alternate Data Streams of `.git/` are
 * forbidden, not just `::$INDEX_ALLOCATION`.
 *
 * This function is intended to be used by `git fsck` even on platforms where
 * the backslash is a regular filename character, therefore it needs to handle
 * backlash characters in the provided `name` specially: they are interpreted
 * as directory separators.
 */
int is_ntfs_dotgit(const char *name)
{
	char c;

	/*
	 * Note that when we don't find `.git` or `git~1` we end up with `name`
	 * advanced partway through the string. That's okay, though, as we
	 * return immediately in those cases, without looking at `name` any
	 * further.
	 */
	c = *(name++);
	if (c == '.') {
		/* .git */
		if (((c = *(name++)) != 'g' && c != 'G') ||
		    ((c = *(name++)) != 'i' && c != 'I') ||
		    ((c = *(name++)) != 't' && c != 'T'))
			return 0;
	} else if (c == 'g' || c == 'G') {
		/* git ~1 */
		if (((c = *(name++)) != 'i' && c != 'I') ||
		    ((c = *(name++)) != 't' && c != 'T') ||
		    *(name++) != '~' ||
		    *(name++) != '1')
			return 0;
	} else
		return 0;

	for (;;) {
		c = *(name++);
		if (!c || is_xplatform_dir_sep(c) || c == ':')
			return 1;
		if (c != '.' && c != ' ')
			return 0;
	}
}

static int is_ntfs_dot_generic(const char *name,
			       const char *dotgit_name,
			       size_t len,
			       const char *dotgit_ntfs_shortname_prefix)
{
	int saw_tilde;
	size_t i;

	if ((name[0] == '.' && !strncasecmp(name + 1, dotgit_name, len))) {
		i = len + 1;
only_spaces_and_periods:
		for (;;) {
			char c = name[i++];
			if (!c || c == ':')
				return 1;
			if (c != ' ' && c != '.')
				return 0;
		}
	}

	/*
	 * Is it a regular NTFS short name, i.e. shortened to 6 characters,
	 * followed by ~1, ... ~4?
	 */
	if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' &&
	    name[7] >= '1' && name[7] <= '4') {
		i = 8;
		goto only_spaces_and_periods;
	}

	/*
	 * Is it a fall-back NTFS short name (for details, see
	 * https://en.wikipedia.org/wiki/8.3_filename?
	 */
	for (i = 0, saw_tilde = 0; i < 8; i++)
		if (name[i] == '\0')
			return 0;
		else if (saw_tilde) {
			if (name[i] < '0' || name[i] > '9')
				return 0;
		} else if (name[i] == '~') {
			if (name[++i] < '1' || name[i] > '9')
				return 0;
			saw_tilde = 1;
		} else if (i >= 6)
			return 0;
		else if (name[i] & 0x80) {
			/*
			 * We know our needles contain only ASCII, so we clamp
			 * here to make the results of tolower() sane.
			 */
			return 0;
		} else if (tolower(name[i]) != dotgit_ntfs_shortname_prefix[i])
			return 0;

	goto only_spaces_and_periods;
}

/*
 * Inline helper to make sure compiler resolves strlen() on literals at
 * compile time.
 */
static inline int is_ntfs_dot_str(const char *name, const char *dotgit_name,
				  const char *dotgit_ntfs_shortname_prefix)
{
	return is_ntfs_dot_generic(name, dotgit_name, strlen(dotgit_name),
				   dotgit_ntfs_shortname_prefix);
}

int is_ntfs_dotgitmodules(const char *name)
{
	return is_ntfs_dot_str(name, "gitmodules", "gi7eba");
}

int is_ntfs_dotgitignore(const char *name)
{
	return is_ntfs_dot_str(name, "gitignore", "gi250a");
}

int is_ntfs_dotgitattributes(const char *name)
{
	return is_ntfs_dot_str(name, "gitattributes", "gi7d29");
}

int is_ntfs_dotmailmap(const char *name)
{
	return is_ntfs_dot_str(name, "mailmap", "maba30");
}

int looks_like_command_line_option(const char *str)
{
	return str && str[0] == '-';
}

char *xdg_config_home_for(const char *subdir, const char *filename)
{
	const char *home, *config_home;

	assert(subdir);
	assert(filename);
	config_home = getenv("XDG_CONFIG_HOME");
	if (config_home && *config_home)
		return mkpathdup("%s/%s/%s", config_home, subdir, filename);

	home = getenv("HOME");
	if (home)
		return mkpathdup("%s/.config/%s/%s", home, subdir, filename);

	return NULL;
}

char *xdg_config_home(const char *filename)
{
	return xdg_config_home_for("git", filename);
}

char *xdg_cache_home(const char *filename)
{
	const char *home, *cache_home;

	assert(filename);
	cache_home = getenv("XDG_CACHE_HOME");
	if (cache_home && *cache_home)
		return mkpathdup("%s/git/%s", cache_home, filename);

	home = getenv("HOME");
	if (home)
		return mkpathdup("%s/.cache/git/%s", home, filename);
	return NULL;
}

REPO_GIT_PATH_FUNC(squash_msg, "SQUASH_MSG")
REPO_GIT_PATH_FUNC(merge_msg, "MERGE_MSG")
REPO_GIT_PATH_FUNC(merge_rr, "MERGE_RR")
REPO_GIT_PATH_FUNC(merge_mode, "MERGE_MODE")
REPO_GIT_PATH_FUNC(merge_head, "MERGE_HEAD")
REPO_GIT_PATH_FUNC(fetch_head, "FETCH_HEAD")
REPO_GIT_PATH_FUNC(shallow, "shallow")
