* This handles basic git sha1 object files - packing, unpacking,
* creation etc.
*/
-#include <sys/types.h>
-#include <dirent.h>
#include "cache.h"
#include "delta.h"
#include "pack.h"
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++;
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;
*buf++ = hex[val >> 4];
*buf++ = hex[val & 0xf];
}
+ *buf = '\0';
+
return buffer;
}
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);
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;
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;
if (dir) {
*dir = 0;
mkdir(filename, 0777);
+ if (adjust_shared_perm(filename))
+ return -2;
*dir = '/';
if (!link(tmpfile, filename))
return 0;