/*
 * Utilities for paths and pathnames
 */

#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "abspath.h"
#include "environment.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 "object-store-ll.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;
}

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);
}

static int dir_prefix(const char *buf, const char *dir)
{
	int 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(const 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->odb->path);
	else if (git_hooks_path && dir_prefix(base, "hooks"))
		replace_dir(buf, git_dir_len + 5, git_hooks_path);
	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
		strbuf_git_common_path(buf, repo, "worktrees/%s", wt->id);
}

void repo_git_pathv(const 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(const 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);
}

void strbuf_repo_git_path(struct strbuf *sb,
			  const struct repository *repo,
			  const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	repo_git_pathv(repo, NULL, sb, fmt, args);
	va_end(args);
}

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(struct repository *r,
			      const struct worktree *wt, const char *fmt, ...)
{
	struct strbuf *pathname = get_pathname();
	va_list args;

	if (wt && wt->repo != r)
		BUG("worktree not connected to expected repository");

	va_start(args, fmt);
	repo_git_pathv(r, 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;

	if (!repo->worktree)
		return NULL;

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

	return strbuf_detach(&path, NULL);
}

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

	if (!repo->worktree)
		return;

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

/* Returns 0 on success, negative on failure. */
static int do_submodule_path(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(&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 *git_pathdup_submodule(const char *path, const char *fmt, ...)
{
	int err;
	va_list args;
	struct strbuf buf = STRBUF_INIT;
	va_start(args, fmt);
	err = do_submodule_path(&buf, path, fmt, args);
	va_end(args);
	if (err) {
		strbuf_release(&buf);
		return NULL;
	}
	return strbuf_detach(&buf, NULL);
}

int strbuf_git_path_submodule(struct strbuf *buf, const char *path,
			      const char *fmt, ...)
{
	int err;
	va_list args;
	va_start(args, fmt);
	err = do_submodule_path(buf, path, fmt, args);
	va_end(args);

	return err;
}

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);
}

void strbuf_git_common_path(struct strbuf *sb,
			    const struct repository *repo,
			    const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	repo_common_pathv(repo, sb, fmt, args);
	va_end(args);
}

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;
}

/*
 * First, one directory to try is determined by the following algorithm.
 *
 * (0) If "strict" is given, the path is used as given and no DWIM is
 *     done. Otherwise:
 * (1) "~/path" to mean path under the running user's home directory;
 * (2) "~user/path" to mean path under named user's home directory;
 * (3) "relative/path" to mean cwd relative directory; or
 * (4) "/absolute/path" to mean absolute directory.
 *
 * Unless "strict" is given, we check "%s/.git", "%s", "%s.git/.git", "%s.git"
 * in this order. We select the first one that is a valid git repository, and
 * chdir() to it. If none match, or we fail to chdir, we return NULL.
 *
 * If all goes well, we return the directory we used to chdir() (but
 * before ~user is expanded), avoiding getcwd() resolving symbolic
 * links.  User relative paths are also returned as they are given,
 * except DWIM suffixing.
 */
const char *enter_repo(const char *path, int strict)
{
	static struct strbuf validated_path = STRBUF_INIT;
	static struct strbuf used_path = STRBUF_INIT;

	if (!path)
		return NULL;

	if (!strict) {
		static const char *suffix[] = {
			"/.git", "", ".git/.git", ".git", NULL,
		};
		const char *gitfile;
		int len = strlen(path);
		int i;
		while ((1 < len) && (path[len-1] == '/'))
			len--;

		/*
		 * We can handle arbitrary-sized buffers, but this remains as a
		 * sanity check on untrusted input.
		 */
		if (PATH_MAX <= len)
			return NULL;

		strbuf_reset(&used_path);
		strbuf_reset(&validated_path);
		strbuf_add(&used_path, path, len);
		strbuf_add(&validated_path, path, len);

		if (used_path.buf[0] == '~') {
			char *newpath = interpolate_path(used_path.buf, 0);
			if (!newpath)
				return NULL;
			strbuf_attach(&used_path, newpath, strlen(newpath),
				      strlen(newpath));
		}
		for (i = 0; suffix[i]; i++) {
			struct stat st;
			size_t baselen = used_path.len;
			strbuf_addstr(&used_path, suffix[i]);
			if (!stat(used_path.buf, &st) &&
			    (S_ISREG(st.st_mode) ||
			    (S_ISDIR(st.st_mode) && is_git_directory(used_path.buf)))) {
				strbuf_addstr(&validated_path, suffix[i]);
				break;
			}
			strbuf_setlen(&used_path, baselen);
		}
		if (!suffix[i])
			return NULL;
		gitfile = read_gitfile(used_path.buf);
		die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
		if (gitfile) {
			strbuf_reset(&used_path);
			strbuf_addstr(&used_path, gitfile);
		}
		if (chdir(used_path.buf))
			return NULL;
		path = validated_path.buf;
	}
	else {
		const char *gitfile = read_gitfile(path);
		die_upon_dubious_ownership(gitfile, NULL, path);
		if (gitfile)
			path = gitfile;
		if (chdir(path))
			return NULL;
	}

	if (is_git_directory(".")) {
		set_git_dir(".", 0);
		check_repository_format(NULL);
		return path;
	}

	return NULL;
}

int calc_shared_perm(int mode)
{
	int tweak;

	if (get_shared_repository() < 0)
		tweak = -get_shared_repository();
	else
		tweak = get_shared_repository();

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

	return mode;
}


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

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

	new_mode = calc_shared_perm(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(const char *dir, int share)
{
	if (mkdir(dir, 0777) < 0) {
		if (errno != EEXIST) {
			perror(dir);
			exit(1);
		}
	}
	else if (share && adjust_shared_perm(dir))
		die(_("Could not make %s writable by group"), dir);
}

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.
 *
 */
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;

	while (is_dir_sep(*src))
		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;
				while (is_dir_sep(*src))
					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;
					while (is_dir_sep(*src))
						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:
		/*
		 * 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 i, max_len = -1;

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

	for (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")
