X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=sha1_file.c;h=1d799f793a936a696cea86deb36fa2bdb04c29f4;hb=eb38cc689e84a8fd01c1856e889fe8d3b4f1bfb4;hp=6b7577dbc4ed845da1a70b6d727370423b086735;hpb=797bd6f490c91c07986382b9f268e0df712cb246;p=git.git diff --git a/sha1_file.c b/sha1_file.c index 6b7577db..1d799f79 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; @@ -321,16 +354,12 @@ struct packed_git *packed_git; static int check_packed_git_idx(const char *path, unsigned long *idx_size_, void **idx_map_) { - SHA_CTX ctx; - unsigned char sha1[20]; void *idx_map; unsigned int *index; unsigned long idx_size; int nr, i; - int fd; + int fd = open(path, O_RDONLY); struct stat st; - - fd = open(path, O_RDONLY); if (fd < 0) return -1; if (fstat(fd, &st)) { @@ -368,16 +397,6 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_, if (idx_size != 4*256 + nr * 24 + 20 + 20) return error("wrong index file size"); - /* - * File checksum. - */ - SHA1_Init(&ctx); - SHA1_Update(&ctx, idx_map, idx_size-20); - SHA1_Final(sha1, &ctx); - - if (memcmp(sha1, idx_map + idx_size - 20, 20)) - return error("index checksum mismatch"); - return 0; } @@ -532,8 +551,10 @@ static void prepare_packed_git_one(char *objdir, int local) sprintf(path, "%s/pack", objdir); len = strlen(path); dir = opendir(path); - if (!dir) + if (!dir) { + fprintf(stderr, "unable to open object pack directory: %s: %s\n", path, strerror(errno)); return; + } path[len++] = '/'; while ((de = readdir(dir)) != NULL) { int namelen = strlen(de->d_name); @@ -811,7 +832,7 @@ void packed_object_info_detail(struct pack_entry *e, char *type, unsigned long *size, unsigned long *store_size, - int *delta_chain_length, + unsigned int *delta_chain_length, unsigned char *base_sha1) { struct packed_git *p = e->p; @@ -825,7 +846,7 @@ void packed_object_info_detail(struct pack_entry *e, if (kind != OBJ_DELTA) *delta_chain_length = 0; else { - int chain_length = 0; + unsigned int chain_length = 0; memcpy(base_sha1, pack, 20); do { struct pack_entry base_ent; @@ -1255,6 +1276,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;