From 36bdf78e86bee269373fe899619e375730f53edc Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Wed, 20 Apr 2005 21:01:33 +0000 Subject: Applied Dustin Kirkland's checkpoint fragment sum patch. --- isomd5sum/libcheckisomd5.c | 102 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 11 deletions(-) (limited to 'isomd5sum') 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 #include #include @@ -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 0) && (fragmentcount > 0) ) { + printf("Fragment sums: %s\n", fragmentsums); + printf("Fragment count: %lld\n", fragmentcount); + } } -- cgit