[PATCH] write_sha1_to_fd()
Add write_sha1_to_fd(), which writes an object to a file descriptor. This includes support for unpacking it and recompressing it. Signed-off-by: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>maint
parent
454fbbcde3
commit
a5eda52bfe
1
cache.h
1
cache.h
|
@ -185,6 +185,7 @@ extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned l
|
||||||
extern int read_tree(void *buffer, unsigned long size, int stage);
|
extern int read_tree(void *buffer, unsigned long size, int stage);
|
||||||
|
|
||||||
extern int write_sha1_from_fd(const unsigned char *sha1, int fd);
|
extern int write_sha1_from_fd(const unsigned char *sha1, int fd);
|
||||||
|
extern int write_sha1_to_fd(int fd, const unsigned char *sha1);
|
||||||
|
|
||||||
extern int has_sha1_pack(const unsigned char *sha1);
|
extern int has_sha1_pack(const unsigned char *sha1);
|
||||||
extern int has_sha1_file(const unsigned char *sha1);
|
extern int has_sha1_file(const unsigned char *sha1);
|
||||||
|
|
59
sha1_file.c
59
sha1_file.c
|
@ -1221,6 +1221,65 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int write_sha1_to_fd(int fd, const unsigned char *sha1)
|
||||||
|
{
|
||||||
|
ssize_t size;
|
||||||
|
unsigned long objsize;
|
||||||
|
int posn = 0;
|
||||||
|
char *buf = map_sha1_file_internal(sha1, &objsize, 0);
|
||||||
|
z_stream stream;
|
||||||
|
if (!buf) {
|
||||||
|
unsigned char *unpacked;
|
||||||
|
unsigned long len;
|
||||||
|
char type[20];
|
||||||
|
char hdr[50];
|
||||||
|
int hdrlen;
|
||||||
|
// need to unpack and recompress it by itself
|
||||||
|
unpacked = read_packed_sha1(sha1, type, &len);
|
||||||
|
|
||||||
|
hdrlen = sprintf(hdr, "%s %lu", type, len) + 1;
|
||||||
|
|
||||||
|
/* Set it up */
|
||||||
|
memset(&stream, 0, sizeof(stream));
|
||||||
|
deflateInit(&stream, Z_BEST_COMPRESSION);
|
||||||
|
size = deflateBound(&stream, len + hdrlen);
|
||||||
|
buf = xmalloc(size);
|
||||||
|
|
||||||
|
/* Compress it */
|
||||||
|
stream.next_out = buf;
|
||||||
|
stream.avail_out = size;
|
||||||
|
|
||||||
|
/* First header.. */
|
||||||
|
stream.next_in = hdr;
|
||||||
|
stream.avail_in = hdrlen;
|
||||||
|
while (deflate(&stream, 0) == Z_OK)
|
||||||
|
/* nothing */;
|
||||||
|
|
||||||
|
/* Then the data itself.. */
|
||||||
|
stream.next_in = unpacked;
|
||||||
|
stream.avail_in = len;
|
||||||
|
while (deflate(&stream, Z_FINISH) == Z_OK)
|
||||||
|
/* nothing */;
|
||||||
|
deflateEnd(&stream);
|
||||||
|
|
||||||
|
objsize = stream.total_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
size = write(fd, buf + posn, objsize - posn);
|
||||||
|
if (size <= 0) {
|
||||||
|
if (!size) {
|
||||||
|
fprintf(stderr, "write closed");
|
||||||
|
} else {
|
||||||
|
perror("write ");
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
posn += size;
|
||||||
|
} while (posn < objsize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int write_sha1_from_fd(const unsigned char *sha1, int fd)
|
int write_sha1_from_fd(const unsigned char *sha1, int fd)
|
||||||
{
|
{
|
||||||
char *filename = sha1_file_name(sha1);
|
char *filename = sha1_file_name(sha1);
|
||||||
|
|
33
ssh-push.c
33
ssh-push.c
|
@ -7,13 +7,13 @@
|
||||||
static unsigned char local_version = 1;
|
static unsigned char local_version = 1;
|
||||||
static unsigned char remote_version = 0;
|
static unsigned char remote_version = 0;
|
||||||
|
|
||||||
|
static int verbose = 0;
|
||||||
|
|
||||||
static int serve_object(int fd_in, int fd_out) {
|
static int serve_object(int fd_in, int fd_out) {
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
int posn = 0;
|
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
unsigned long objsize;
|
|
||||||
void *buf;
|
|
||||||
signed char remote;
|
signed char remote;
|
||||||
|
int posn = 0;
|
||||||
do {
|
do {
|
||||||
size = read(fd_in, sha1 + posn, 20 - posn);
|
size = read(fd_in, sha1 + posn, 20 - posn);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
|
@ -25,12 +25,12 @@ static int serve_object(int fd_in, int fd_out) {
|
||||||
posn += size;
|
posn += size;
|
||||||
} while (posn < 20);
|
} while (posn < 20);
|
||||||
|
|
||||||
/* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */
|
if (verbose)
|
||||||
|
fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1));
|
||||||
|
|
||||||
remote = 0;
|
remote = 0;
|
||||||
|
|
||||||
buf = map_sha1_file(sha1, &objsize);
|
if (!has_sha1_file(sha1)) {
|
||||||
|
|
||||||
if (!buf) {
|
|
||||||
fprintf(stderr, "git-ssh-push: could not find %s\n",
|
fprintf(stderr, "git-ssh-push: could not find %s\n",
|
||||||
sha1_to_hex(sha1));
|
sha1_to_hex(sha1));
|
||||||
remote = -1;
|
remote = -1;
|
||||||
|
@ -41,20 +41,7 @@ static int serve_object(int fd_in, int fd_out) {
|
||||||
if (remote < 0)
|
if (remote < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
posn = 0;
|
return write_sha1_to_fd(fd_out, sha1);
|
||||||
do {
|
|
||||||
size = write(fd_out, buf + posn, objsize - posn);
|
|
||||||
if (size <= 0) {
|
|
||||||
if (!size) {
|
|
||||||
fprintf(stderr, "git-ssh-push: write closed");
|
|
||||||
} else {
|
|
||||||
perror("git-ssh-push: write ");
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
posn += size;
|
|
||||||
} while (posn < objsize);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serve_version(int fd_in, int fd_out)
|
static int serve_version(int fd_in, int fd_out)
|
||||||
|
@ -76,6 +63,10 @@ static int serve_ref(int fd_in, int fd_out)
|
||||||
return -1;
|
return -1;
|
||||||
posn++;
|
posn++;
|
||||||
} while (ref[posn - 1]);
|
} while (ref[posn - 1]);
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "Serving %s\n", ref);
|
||||||
|
|
||||||
if (get_ref_sha1(ref, sha1))
|
if (get_ref_sha1(ref, sha1))
|
||||||
remote = -1;
|
remote = -1;
|
||||||
write(fd_out, &remote, 1);
|
write(fd_out, &remote, 1);
|
||||||
|
|
Loading…
Reference in New Issue