summaryrefslogtreecommitdiff
path: root/sha1_file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-03 07:30:10 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-03 07:30:10 -0700
commit54c26fb9d0cdff94c7717125d0a222b324bfea8a (patch)
treee37b77d2cb4b2aace847080a0be8f356f3ecee1f /sha1_file.c
parentaa03413467a2f2ada900817dc2a8e3904549b5fe (diff)
parentee28152d03f2cf4b5e3ebc25f7f03f9654d3aa0d (diff)
downloadgit-54c26fb9d0cdff94c7717125d0a222b324bfea8a.tar.gz
Automatic merge of /home/torvalds/junkio/.git/
Diffstat (limited to 'sha1_file.c')
-rw-r--r--sha1_file.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/sha1_file.c b/sha1_file.c
index ced0791847..cb556cae5c 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -460,3 +460,54 @@ int has_sha1_file(const unsigned char *sha1)
return 1;
return 0;
}
+
+int index_fd(unsigned char *sha1, int fd, struct stat *st)
+{
+ z_stream stream;
+ unsigned long size = st->st_size;
+ int max_out_bytes = size + 200;
+ void *out = xmalloc(max_out_bytes);
+ void *metadata = xmalloc(200);
+ int metadata_size;
+ void *in;
+ SHA_CTX c;
+
+ in = "";
+ if (size)
+ in = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+ if (!out || (int)(long)in == -1)
+ return -1;
+
+ metadata_size = 1+sprintf(metadata, "blob %lu", size);
+
+ SHA1_Init(&c);
+ SHA1_Update(&c, metadata, metadata_size);
+ SHA1_Update(&c, in, size);
+ SHA1_Final(sha1, &c);
+
+ memset(&stream, 0, sizeof(stream));
+ deflateInit(&stream, Z_BEST_COMPRESSION);
+
+ /*
+ * ASCII size + nul byte
+ */
+ stream.next_in = metadata;
+ stream.avail_in = metadata_size;
+ stream.next_out = out;
+ stream.avail_out = max_out_bytes;
+ while (deflate(&stream, 0) == Z_OK)
+ /* nothing */;
+
+ /*
+ * File content
+ */
+ stream.next_in = in;
+ stream.avail_in = size;
+ while (deflate(&stream, Z_FINISH) == Z_OK)
+ /*nothing */;
+
+ deflateEnd(&stream);
+
+ return write_sha1_buffer(sha1, out, stream.total_out);
+}