summaryrefslogtreecommitdiffstats
path: root/isomd5sum
diff options
context:
space:
mode:
authorChris Lumens <clumens@redhat.com>2005-04-20 21:01:33 +0000
committerChris Lumens <clumens@redhat.com>2005-04-20 21:01:33 +0000
commit36bdf78e86bee269373fe899619e375730f53edc (patch)
tree376b876fc8e6a024b840f5302dea4a57d8a6a0ad /isomd5sum
parent35ac2a37c6fc6c307c5f0a99e8b8c514542bf869 (diff)
downloadanaconda-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.c102
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);
+ }
}