X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=path.c;h=c5d25a4b903bd92930df4004d30d4dffa6054456;hb=e861ce1692fa9809f3e7b898804f8ddaf7cd8975;hp=334b2bd195f56ac6aaf9f9b8a36fe59115cd758c;hpb=521a3f676794987bfd03703fe58fbec46ed69d49;p=git.git diff --git a/path.c b/path.c index 334b2bd19..c5d25a4b9 100644 --- a/path.c +++ b/path.c @@ -11,11 +11,16 @@ * which is what it's designed for. */ #include "cache.h" -#include -static char pathname[PATH_MAX]; static char bad_path[] = "/bad-path/"; +static char *get_pathname(void) +{ + static char pathname_array[4][PATH_MAX]; + static int index; + return pathname_array[3 & ++index]; +} + static char *cleanup_path(char *path) { /* Clean it up */ @@ -31,6 +36,7 @@ char *mkpath(const char *fmt, ...) { va_list args; unsigned len; + char *pathname = get_pathname(); va_start(args, fmt); len = vsnprintf(pathname, PATH_MAX, fmt, args); @@ -43,6 +49,7 @@ char *mkpath(const char *fmt, ...) char *git_path(const char *fmt, ...) { const char *git_dir = get_git_dir(); + char *pathname = get_pathname(); va_list args; unsigned len; @@ -77,24 +84,17 @@ int git_mkstemp(char *path, size_t len, const char *template) pch += n; } - safe_strncpy(pch, template, len); + strlcpy(pch, template, len); return mkstemp(path); } -char *safe_strncpy(char *dest, const char *src, size_t n) -{ - strncpy(dest, src, n); - dest[n - 1] = '\0'; - - return dest; -} - -int validate_symref(const char *path) +int validate_headref(const char *path) { struct stat st; char *buf, buffer[256]; + unsigned char sha1[20]; int len, fd; if (lstat(path, &st) < 0) @@ -114,20 +114,29 @@ int validate_symref(const char *path) fd = open(path, O_RDONLY); if (fd < 0) return -1; - len = read(fd, buffer, sizeof(buffer)-1); + len = read_in_full(fd, buffer, sizeof(buffer)-1); close(fd); /* * Is it a symbolic ref? */ - if (len < 4 || memcmp("ref:", buffer, 4)) + if (len < 4) return -1; - buf = buffer + 4; - len -= 4; - while (len && isspace(*buf)) - buf++, len--; - if (len >= 5 && !memcmp("refs/", buf, 5)) + if (!memcmp("ref:", buffer, 4)) { + buf = buffer + 4; + len -= 4; + while (len && isspace(*buf)) + buf++, len--; + if (len >= 5 && !memcmp("refs/", buf, 5)) + return 0; + } + + /* + * Is this a detached HEAD? + */ + if (!get_sha1_hex(buffer, sha1)) return 0; + return -1; } @@ -242,7 +251,7 @@ char *enter_repo(char *path, int strict) return NULL; if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 && - validate_symref("HEAD") == 0) { + validate_headref("HEAD") == 0) { putenv("GIT_DIR=."); check_repository_format(); return path; @@ -250,3 +259,36 @@ char *enter_repo(char *path, int strict) return NULL; } + +int adjust_shared_perm(const char *path) +{ + struct stat st; + int mode; + + if (!shared_repository) + return 0; + if (lstat(path, &st) < 0) + return -1; + mode = st.st_mode; + if (mode & S_IRUSR) + mode |= (shared_repository == PERM_GROUP + ? S_IRGRP + : (shared_repository == PERM_EVERYBODY + ? (S_IRGRP|S_IROTH) + : 0)); + + if (mode & S_IWUSR) + mode |= S_IWGRP; + + if (mode & S_IXUSR) + mode |= (shared_repository == PERM_GROUP + ? S_IXGRP + : (shared_repository == PERM_EVERYBODY + ? (S_IXGRP|S_IXOTH) + : 0)); + if (S_ISDIR(mode)) + mode |= S_ISGID; + if ((mode & st.st_mode) != mode && chmod(path, mode) < 0) + return -2; + return 0; +}