-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
git-pack-objects: write the pack files with a SHA1 csum
We want to be able to check their integrity later, and putting the sha1-sum of the contents at the end is a good thing. The writing routines are generic, so we could try to re-use them for the index file, instead of having the same logic duplicated. Update unpack-objects to know about the extra 20 bytes at the end of the index.
- Loading branch information
Linus Torvalds
committed
Jun 27, 2005
1 parent
9b66ec0
commit c38138c
Showing
5 changed files
with
158 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/* | ||
* csum-file.c | ||
* | ||
* Copyright (C) 2005 Linus Torvalds | ||
* | ||
* Simple file write infrastructure for writing SHA1-summed | ||
* files. Useful when you write a file that you want to be | ||
* able to verify hasn't been messed with afterwards. | ||
*/ | ||
#include "cache.h" | ||
#include "csum-file.h" | ||
|
||
static int sha1flush(struct sha1file *f, unsigned int count) | ||
{ | ||
void *buf = f->buffer; | ||
|
||
for (;;) { | ||
int ret = write(f->fd, buf, count); | ||
if (ret > 0) { | ||
buf += ret; | ||
count -= ret; | ||
if (count) | ||
continue; | ||
return 0; | ||
} | ||
if (!ret) | ||
die("sha1 file write error. Out of diskspace"); | ||
if (errno == EAGAIN || errno == EINTR) | ||
continue; | ||
die("sha1 file write error (%s)", strerror(errno)); | ||
} | ||
} | ||
|
||
int sha1close(struct sha1file *f) | ||
{ | ||
unsigned offset = f->offset; | ||
if (offset) { | ||
SHA1_Update(&f->ctx, f->buffer, offset); | ||
sha1flush(f, offset); | ||
} | ||
SHA1_Final(f->buffer, &f->ctx); | ||
sha1flush(f, 20); | ||
return 0; | ||
} | ||
|
||
int sha1write(struct sha1file *f, void *buf, unsigned int count) | ||
{ | ||
while (count) { | ||
unsigned offset = f->offset; | ||
unsigned left = sizeof(f->buffer) - offset; | ||
unsigned nr = count > left ? left : count; | ||
|
||
memcpy(f->buffer + offset, buf, nr); | ||
count -= nr; | ||
offset += nr; | ||
left -= nr; | ||
if (!left) { | ||
SHA1_Update(&f->ctx, f->buffer, offset); | ||
sha1flush(f, offset); | ||
offset = 0; | ||
} | ||
f->offset = offset; | ||
} | ||
return 0; | ||
} | ||
|
||
struct sha1file *sha1create(const char *fmt, ...) | ||
{ | ||
static char filename[PATH_MAX]; | ||
struct sha1file *f; | ||
unsigned len; | ||
va_list arg; | ||
int fd; | ||
|
||
va_start(arg, fmt); | ||
len = vsnprintf(filename, PATH_MAX, fmt, arg); | ||
va_end(arg); | ||
|
||
if (len >= PATH_MAX) | ||
die("you wascally wabbit, you"); | ||
fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0644); | ||
if (fd < 0) | ||
die("unable to open %s (%s)", filename, strerror(errno)); | ||
f = xmalloc(sizeof(*f)); | ||
f->fd = fd; | ||
f->error = 0; | ||
f->offset = 0; | ||
SHA1_Init(&f->ctx); | ||
return f; | ||
} | ||
|
||
int sha1write_compressed(struct sha1file *f, void *in, unsigned int size) | ||
{ | ||
z_stream stream; | ||
unsigned long maxsize; | ||
void *out; | ||
|
||
memset(&stream, 0, sizeof(stream)); | ||
deflateInit(&stream, Z_DEFAULT_COMPRESSION); | ||
maxsize = deflateBound(&stream, size); | ||
out = xmalloc(maxsize); | ||
|
||
/* Compress it */ | ||
stream.next_in = in; | ||
stream.avail_in = size; | ||
|
||
stream.next_out = out; | ||
stream.avail_out = maxsize; | ||
|
||
while (deflate(&stream, Z_FINISH) == Z_OK) | ||
/* nothing */; | ||
deflateEnd(&stream); | ||
|
||
size = stream.total_out; | ||
sha1write(f, out, size); | ||
free(out); | ||
return size; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#ifndef CSUM_FILE_H | ||
#define CSUM_FILE_H | ||
|
||
/* A SHA1-protected file */ | ||
struct sha1file { | ||
int fd, error; | ||
unsigned long offset; | ||
SHA_CTX ctx; | ||
unsigned char buffer[8192]; | ||
}; | ||
|
||
extern struct sha1file *sha1create(const char *fmt, ...); | ||
extern int sha1close(struct sha1file *); | ||
extern int sha1write(struct sha1file *, void *, unsigned int); | ||
extern int sha1write_compressed(struct sha1file *, void *, unsigned int); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters