diff options
author | Chris Lumens <clumens@redhat.com> | 2005-04-20 21:01:33 +0000 |
---|---|---|
committer | Chris Lumens <clumens@redhat.com> | 2005-04-20 21:01:33 +0000 |
commit | 36bdf78e86bee269373fe899619e375730f53edc (patch) | |
tree | 376b876fc8e6a024b840f5302dea4a57d8a6a0ad /isomd5sum | |
parent | 35ac2a37c6fc6c307c5f0a99e8b8c514542bf869 (diff) | |
download | anaconda-36bdf78e86bee269373fe899619e375730f53edc.tar.gz anaconda-36bdf78e86bee269373fe899619e375730f53edc.tar.xz anaconda-36bdf78e86bee269373fe899619e375730f53edc.zip |
Applied Dustin Kirkland's checkpoint fragment sum patch.
Diffstat (limited to 'isomd5sum')
-rw-r--r-- | isomd5sum/libcheckisomd5.c | 102 |
1 files changed, 91 insertions, 11 deletions
diff --git a/isomd5sum/libcheckisomd5.c b/isomd5sum/libcheckisomd5.c index 12c14ae61..1c4056a77 100644 --- a/isomd5sum/libcheckisomd5.c +++ b/isomd5sum/libcheckisomd5.c @@ -1,6 +1,10 @@ /* Copyright 2001 Red Hat, Inc. */ /* Michael Fulbright msf@redhat.com */ +/* 4/2005 Dustin Kirkland (dustin.kirkland@gmail.com) */ +/* Added support for checkpoint fragment sums; */ +/* Exits media check as soon as bad fragment md5sum'ed */ + #include <stdio.h> #include <stdlib.h> #include <sys/types.h> @@ -15,16 +19,20 @@ #define APPDATA_OFFSET 883 #define SIZE_OFFSET 84 +/* Length in characters of string used for fragment md5sum checking */ +#define FRAGMENT_SUM_LENGTH 60 + #define MAX(x, y) ((x > y) ? x : y) #define MIN(x, y) ((x < y) ? x : y) /* finds primary volume descriptor and returns info from it */ /* mediasum must be a preallocated buffer at least 33 bytes long */ -static int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isosize, int *supported) { +/* fragmentsums must be a preallocated buffer at least FRAGMENT_SUM_LENGTH+1 bytes long */ +static int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isosize, int *supported, char *fragmentsums, long long *fragmentcount) { unsigned char buf[2048]; char buf2[512]; char tmpbuf[512]; - int skipfnd, md5fnd, supportedfnd; + int skipfnd, md5fnd, supportedfnd, fragsumfnd, fragcntfnd; unsigned int loc; long long offset; char *p; @@ -54,6 +62,8 @@ static int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isos md5fnd = 0; skipfnd = 0; + fragsumfnd = 0; + fragcntfnd = 0; supportedfnd = 0; loc = 0; while (loc < 512) { @@ -92,14 +102,46 @@ static int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isos } else if (!strncmp(buf2 + loc, "RHLISOSTATUS=1", 14)) { *supported = 1; supportedfnd = 1; + for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); } else if (!strncmp(buf2 + loc, "RHLISOSTATUS=0", 14)) { *supported = 0; supportedfnd = 1; - } else { + for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); + } else if (!strncmp(buf2 + loc, "FRAGMENT SUMS = ", 16)) { + /* make sure we dont walk off end */ + if ((loc + FRAGMENT_SUM_LENGTH) > 511) + return -1; + + memcpy(fragmentsums, buf2 + loc + 16, FRAGMENT_SUM_LENGTH); + fragmentsums[FRAGMENT_SUM_LENGTH] = '\0'; + fragsumfnd = 1; + loc += FRAGMENT_SUM_LENGTH + 16; + for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); + } else if (!strncmp(buf2 + loc, "FRAGMENT COUNT = ", 17)) { + char *errptr; + /* make sure we dont walk off end */ + if ((loc + 17) > 511) + return -1; + + loc = loc + 17; + for (p=tmpbuf; buf2[loc] != ';' && loc < 512; p++, loc++) + *p = buf2[loc]; + + *p = '\0'; + + *fragmentcount = strtol(tmpbuf, &errptr, 10); + if (errptr && *errptr) { + return -1; + } else { + fragcntfnd = 1; + } + + for (p=buf2+loc; *p != ';' && loc < 512; p++, loc++); + } else { loc++; } - if ((skipfnd & md5fnd) & supportedfnd) + if ((skipfnd & md5fnd & fragsumfnd & fragcntfnd) & supportedfnd) break; } @@ -119,19 +161,25 @@ static int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isos /* both strings must be pre-allocated at least 33 chars in length */ static int checkmd5sum(int isofd, char *mediasum, char *computedsum, int quiet) { int nread; - int i; + int i, j; int appdata_start_offset, appdata_end_offset; int nattempt; int skipsectors; int supported; + int current_fragment = 0; + int previous_fragment = 0; unsigned int bufsize = 32768; unsigned char md5sum[16]; + unsigned char fragmd5sum[16]; unsigned int len; unsigned char *buf; long long isosize, offset, pvd_offset, apoff; - MD5_CTX md5ctx; + char fragmentsums[FRAGMENT_SUM_LENGTH]; + char thisfragsum[FRAGMENT_SUM_LENGTH]; + long long fragmentcount = 0; + MD5_CTX md5ctx, fragmd5ctx; - if ((pvd_offset = parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported)) < 0) + if ((pvd_offset = parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported, fragmentsums, &fragmentcount)) < 0) return -1; /* printf("Mediasum = %s\n",mediasum); */ @@ -179,6 +227,30 @@ static int checkmd5sum(int isofd, char *mediasum, char *computedsum, int quiet) } MD5_Update(&md5ctx, buf, nread); + if (fragmentcount) { + current_fragment = offset * (fragmentcount+1) / (isosize - skipsectors*2048); + /* if we're onto the next fragment, calculate the previous sum and check */ + if ( current_fragment != previous_fragment ) { + memcpy(&fragmd5ctx, &md5ctx, sizeof(MD5_CTX)); + MD5_Final(fragmd5sum, &fragmd5ctx); + *computedsum = '\0'; + j = (current_fragment-1)*FRAGMENT_SUM_LENGTH/fragmentcount; + for (i=0; i<FRAGMENT_SUM_LENGTH/fragmentcount; i++) { + char tmpstr[2]; + snprintf(tmpstr, 2, "%01x", fragmd5sum[i]); + strncat(computedsum, tmpstr, 2); + thisfragsum[i] = fragmentsums[j++]; + } + thisfragsum[j] = '\0'; + /* printf("\nFragment [%i]: %s ?= %s\n", previous_fragment, computedsum, thisfragsum); */ + previous_fragment = current_fragment; + /* Exit immediatiately if current fragment sum is incorrect */ + if (strcmp(thisfragsum, computedsum) != 0) { + free(buf); + return 0; + } + } + } offset = offset + nread; if (!quiet) { @@ -201,7 +273,7 @@ static int checkmd5sum(int isofd, char *mediasum, char *computedsum, int quiet) for (i=0; i<16; i++) { char tmpstr[4]; snprintf (tmpstr, 4, "%02x", md5sum[i]); - strcat(computedsum, tmpstr); + strncat(computedsum, tmpstr, 2); } /* printf("mediasum, computedsum = %s %s\n", mediasum, computedsum); */ @@ -210,7 +282,7 @@ static int checkmd5sum(int isofd, char *mediasum, char *computedsum, int quiet) return 0; else return 1; - } +} #if 0 @@ -233,8 +305,10 @@ static void readCB(void *co, long long pos) { static int doMediaCheck(int isofd, char *mediasum, char *computedsum, long long *isosize, int *supported, int quiet) { int rc; int skipsectors; + long long fragmentcount = 0; + char fragmentsums[FRAGMENT_SUM_LENGTH+1]; - if (parsepvd(isofd, mediasum, &skipsectors, isosize, supported) < 0) { + if (parsepvd(isofd, mediasum, &skipsectors, isosize, supported, fragmentsums, &fragmentcount) < 0) { fprintf(stderr, "Unable to read the disc checksum from the " "primary volume descriptor.\nThis probably " "means the disc was created without adding the " @@ -290,6 +364,8 @@ void printMD5SUM(char *file) { int isofd; char mediasum[64]; long long isosize; + char fragmentsums[FRAGMENT_SUM_LENGTH+1]; + long long fragmentcount = 0; int supported; int skipsectors; @@ -300,7 +376,7 @@ void printMD5SUM(char *file) { exit(1); } - if (parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported) < 0) { + if (parsepvd(isofd, mediasum, &skipsectors, &isosize, &supported, fragmentsums, &fragmentcount) < 0) { fprintf(stderr, "%s: Could not get pvd data", file); fprintf(stderr, "\nUnable to read the disc checksum from the " "primary volume descriptor.\nThis probably " @@ -312,4 +388,8 @@ void printMD5SUM(char *file) { close(isofd); printf("%s: %s\n", file, mediasum); + if ( (strlen(fragmentsums) > 0) && (fragmentcount > 0) ) { + printf("Fragment sums: %s\n", fragmentsums); + printf("Fragment count: %lld\n", fragmentcount); + } } |