summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cache.h1
-rw-r--r--sha1_file.c59
-rw-r--r--ssh-push.c33
3 files changed, 72 insertions, 21 deletions
diff --git a/cache.h b/cache.h
index 84d43d3..4d2bde5 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 b2914dd..b13578b 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 090d6f9..aac70af 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);