diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-08-11 19:56:11 +0300 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-08-11 19:56:11 +0300 |
commit | 8b1a53011b3aa56594e785c425b318c21fba8684 (patch) | |
tree | b554752ad322b3ac17432e580c387360c005fedd /abuild-tar.c | |
parent | 6b2c6c0c0325be3ea2a0b827106ae90b42128fa3 (diff) | |
download | abuild-8b1a53011b3aa56594e785c425b318c21fba8684.tar.gz abuild-8b1a53011b3aa56594e785c425b318c21fba8684.tar.bz2 abuild-8b1a53011b3aa56594e785c425b318c21fba8684.tar.xz abuild-8b1a53011b3aa56594e785c425b318c21fba8684.zip |
abuild-tar: embed checksum for symlinks
and relocate the place of the symlink in tar header, as symlink
use the linkname field. now it's split to devmajor, devminor and
padding fields.
Diffstat (limited to 'abuild-tar.c')
-rw-r--r-- | abuild-tar.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/abuild-tar.c b/abuild-tar.c index 1293ddc..011fff6 100644 --- a/abuild-tar.c +++ b/abuild-tar.c @@ -42,6 +42,8 @@ struct tar_header { char padding[12]; /* 500-512 */ }; +#define MAX_MD_SIZE 20 + #define GET_OCTAL(s) get_octal(s, sizeof(s)) #define PUT_OCTAL(s,v) put_octal(s, sizeof(s), v) @@ -94,10 +96,10 @@ static int usage(void) fprintf(stderr, "abuild-tar " VERSION "\n" "\n" -"usage: abuild-tar [--hash [<algorithm>]] [--cut]\n" +"usage: abuild-tar [--hash[=<algorithm>]] [--cut]\n" "\n" "options:\n" -" --hash [sha1|md5] Read tar archive from stdin, precalculate hash for \n" +" --hash[=sha1|md5] Read tar archive from stdin, precalculate hash for \n" " regular entries and output tar archive on stdout\n" " --cut Remove the end of file tar record\n" "\n"); @@ -173,7 +175,7 @@ static int do_it(const EVP_MD *md, int cut) struct tar_header hdr; size_t size, aligned_size; void *ptr; - int dohash = 0, r; + int r; struct { char id[4]; uint16_t nid; @@ -193,22 +195,34 @@ static int do_it(const EVP_MD *md, int cut) if (cut && hdr.name[0] == 0) return 0; + ptr = NULL; size = GET_OCTAL(hdr.size); aligned_size = (size + 511) & ~511; - if (md != NULL) - dohash = (hdr.typeflag == '0' || hdr.typeflag == '7'); - if (dohash) { + if (md != NULL && + (hdr.typeflag == '0' || hdr.typeflag == '2' || + hdr.typeflag == '7')) { const unsigned char *src; + unsigned char csdata[MAX_MD_SIZE]; int chksum, i; - ptr = malloc(aligned_size); - if (full_read(STDIN_FILENO, ptr, aligned_size) != aligned_size) - return 1; + if (hdr.typeflag == '0' || hdr.typeflag == '7') { + ptr = malloc(aligned_size); + if (full_read(STDIN_FILENO, ptr, aligned_size) + != aligned_size) + return 1; + + memcpy(&hdr.linkname[3], &mdinfo, sizeof(mdinfo)); + EVP_Digest(ptr, size, csdata, NULL, md, NULL); + } else { + EVP_Digest(hdr.linkname, strlen(hdr.linkname), + csdata, NULL, md, NULL); + } - memcpy(&hdr.linkname[3], &mdinfo, sizeof(mdinfo)); - EVP_Digest(ptr, size, &hdr.linkname[3+sizeof(mdinfo)], - NULL, md, NULL); + /* Embed to header */ + memcpy(&hdr.devmajor, &mdinfo, sizeof(hdr.devmajor)); + memcpy(&hdr.devminor, &csdata[0], sizeof(hdr.devminor)); + memcpy(&hdr.padding, &csdata[sizeof(hdr.devminor)], sizeof(hdr.padding)); /* Recalculate checksum */ memset(hdr.chksum, ' ', sizeof(hdr.chksum)); @@ -221,7 +235,7 @@ static int do_it(const EVP_MD *md, int cut) if (full_write(STDOUT_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr)) return 2; - if (dohash) { + if (ptr != NULL) { if (full_write(STDOUT_FILENO, ptr, aligned_size) != aligned_size) return 2; free(ptr); @@ -271,6 +285,10 @@ int main(int argc, char **argv) md = EVP_get_digestbyname(digest); if (md == NULL) return usage(); + if (EVP_MD_size(md) > MAX_MD_SIZE) { + fprintf(stderr, "digest size is too large\n"); + return -1; + } } return do_it(md, cut); |