From a5eda52bfe8f0afe3abc0c7eaceb487c2ffb7ebb Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Sun, 10 Jul 2005 18:25:38 -0400 Subject: [PATCH] [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 Signed-off-by: Linus Torvalds --- cache.h | 1 + sha1_file.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ssh-push.c | 33 +++++++++++------------------- 3 files changed, 72 insertions(+), 21 deletions(-) diff --git a/cache.h b/cache.h index 84d43d366..4d2bde568 100644 --- a/cache.h +++ b/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 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_file(const unsigned char *sha1); diff --git a/sha1_file.c b/sha1_file.c index b2914dd2e..b13578bdf 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1221,6 +1221,65 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha 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) { char *filename = sha1_file_name(sha1); diff --git a/ssh-push.c b/ssh-push.c index 090d6f9f8..aac70af51 100644 --- a/ssh-push.c +++ b/ssh-push.c @@ -7,13 +7,13 @@ static unsigned char local_version = 1; static unsigned char remote_version = 0; +static int verbose = 0; + static int serve_object(int fd_in, int fd_out) { ssize_t size; - int posn = 0; unsigned char sha1[20]; - unsigned long objsize; - void *buf; signed char remote; + int posn = 0; do { size = read(fd_in, sha1 + posn, 20 - posn); if (size < 0) { @@ -25,12 +25,12 @@ static int serve_object(int fd_in, int fd_out) { posn += size; } 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; - buf = map_sha1_file(sha1, &objsize); - - if (!buf) { + if (!has_sha1_file(sha1)) { fprintf(stderr, "git-ssh-push: could not find %s\n", sha1_to_hex(sha1)); remote = -1; @@ -41,20 +41,7 @@ static int serve_object(int fd_in, int fd_out) { if (remote < 0) return 0; - posn = 0; - 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; + return write_sha1_to_fd(fd_out, sha1); } 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; posn++; } while (ref[posn - 1]); + + if (verbose) + fprintf(stderr, "Serving %s\n", ref); + if (get_ref_sha1(ref, sha1)) remote = -1; write(fd_out, &remote, 1); -- 2.30.2