X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=sha1_file.c;h=3d11a9bfdc56c00056c2057af5e6455742ab31f5;hb=070879ca93a7d358086f4c8aff4553493dcb9210;hp=d451a94efed7d36d55cf1b77324eaf55e0d50d69;hpb=3a75f674017fdf86d8b742cdfeb0df8700a2d03a;p=git.git diff --git a/sha1_file.c b/sha1_file.c index d451a94e..3d11a9bf 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -6,8 +6,6 @@ * This handles basic git sha1 object files - packing, unpacking, * creation etc. */ -#include -#include #include "cache.h" #include "delta.h" #include "pack.h" @@ -48,9 +46,34 @@ int get_sha1_hex(const char *hex, unsigned char *sha1) return 0; } +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 |= S_IRGRP; + if (mode & S_IWUSR) + mode |= S_IWGRP; + if (mode & S_IXUSR) + mode |= S_IXGRP; + if (S_ISDIR(mode)) + mode |= S_ISGID; + if (chmod(path, mode) < 0) + return -2; + return 0; +} + int safe_create_leading_directories(char *path) { char *pos = path; + struct stat st; + if (*pos == '/') pos++; @@ -59,11 +82,21 @@ int safe_create_leading_directories(char *path) if (!pos) break; *pos = 0; - if (mkdir(path, 0777) < 0) - if (errno != EEXIST) { + if (!stat(path, &st)) { + /* path exists */ + if (!S_ISDIR(st.st_mode)) { *pos = '/'; - return -1; + return -3; } + } + else if (mkdir(path, 0777)) { + *pos = '/'; + return -1; + } + else if (adjust_shared_perm(path)) { + *pos = '/'; + return -2; + } *pos++ = '/'; } return 0; @@ -1241,6 +1274,8 @@ static int link_temp_to_file(const char *tmpfile, char *filename) if (dir) { *dir = 0; mkdir(filename, 0777); + if (adjust_shared_perm(filename)) + return -2; *dir = '/'; if (!link(tmpfile, filename)) return 0;