this function does the following: 1. if $XDG_RUNTIME_DIR is non-empty, `$XDG_RUNTIME_DIR/git` is used in next step, otherwise `/tmp/git-$uid` is taken. 2. ensure that above directory does exist. what's more, it must has correct permission and ownership. 3. a newly allocated string consisting of the path of above directory and $filename is returned.
Under following situation, NULL will be returned: + the directory mentioned in step 1 exists but have wrong permission or ownership. + the directory or its parent cannot be created. Notice: + the caller is responsible for deallocating the returned string. Signed-off-by: Hui Yiqun <huiyi...@gmail.com> --- cache.h | 23 +++++++++++++++++++++++ path.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/cache.h b/cache.h index ef843c1..f8b649b 100644 --- a/cache.h +++ b/cache.h @@ -1001,6 +1001,29 @@ extern int is_ntfs_dotgit(const char *name); */ extern char *xdg_config_home(const char *filename); +/** + * this function does the following: + * + * 1. if $XDG_RUNTIME_DIR is non-empty, `$XDG_RUNTIME_DIR/git` is used in next + * step, otherwise `/tmp/git-$uid` is taken. + * 2. ensure that above directory does exist. what's more, it must has correct + * permission and ownership. + * 3. a newly allocated string consisting of the path of above directory and + * $filename is returned. + * + * Under following situation, NULL will be returned: + * + * + the directory mentioned in step 1 exists but have wrong permission or + * ownership. + * + the directory or its parent cannot be created. + * + * Notice: + * + * + the caller is responsible for deallocating the returned string. + * + */ +extern char *xdg_runtime_dir(const char *filename); + /* object replacement */ #define LOOKUP_REPLACE_OBJECT 1 #define LOOKUP_UNKNOWN_OBJECT 2 diff --git a/path.c b/path.c index 699af68..2886e59 100644 --- a/path.c +++ b/path.c @@ -5,6 +5,7 @@ #include "strbuf.h" #include "string-list.h" #include "dir.h" +#include "git-compat-util.h" static int get_st_mode_bits(const char *path, int *mode) { @@ -1206,6 +1207,61 @@ char *xdg_config_home(const char *filename) return NULL; } +char *xdg_runtime_dir(const char *filename) +{ + struct strbuf sb = STRBUF_INIT; + char *runtime_dir; + struct stat st; + uid_t uid = getuid(); + + assert(filename); + runtime_dir = getenv("XDG_RUNTIME_DIR"); + if (runtime_dir && *runtime_dir) + strbuf_mkpath(&sb, "%s/git/", runtime_dir); + else + strbuf_mkpath(&sb, "/tmp/git-%d", uid); + + if (!lstat(sb.buf, &st)) { + /* + * As described in XDG base dir spec[1], the subdirectory + * under $XDG_RUNTIME_DIR or its fallback MUST be owned by + * the user, and its unix access mode MUST be 0700. + * + * Calling chmod or chown silently may cause security + * problem if somebody chdir to it, sleep, and then, try + * to open our protected runtime cache or socket. + * So we just put warning and left it to user to solve. + * + * [1]https://specifications.freedesktop.org/basedir-spec/ + * basedir-spec-latest.html + */ + if ((st.st_mode & 0777) != S_IRWXU) { + warning("permission of runtime directory '%s' " + "MUST be 0700 instead of 0%o\n", + sb.buf, (st.st_mode & 0777)); + return NULL; + } else if (st.st_uid != uid) { + warning("owner of runtime directory '%s' " + "MUST be %d instead of %d\n", + sb.buf, uid, st.st_uid); + return NULL; + } + /* TODO: check whether st.buf is an directory */ + } else { + if (safe_create_leading_directories_const(sb.buf) < 0) { + warning("unable to create directories for '%s'\n", + sb.buf); + return NULL; + } + if (mkdir(sb.buf, 0700) < 0) { + warning("unable to mkdir '%s'\n", sb.buf); + return NULL; + } + } + strbuf_addf(&sb, "/%s", filename); + return strbuf_detach(&sb, NULL); +} + GIT_PATH_FUNC(git_path_cherry_pick_head, "CHERRY_PICK_HEAD") GIT_PATH_FUNC(git_path_revert_head, "REVERT_HEAD") GIT_PATH_FUNC(git_path_squash_msg, "SQUASH_MSG") -- 2.7.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html