summaryrefslogtreecommitdiffstats
path: root/loader
diff options
context:
space:
mode:
authorMike Fulbright <msf@redhat.com>2001-11-16 21:59:37 +0000
committerMike Fulbright <msf@redhat.com>2001-11-16 21:59:37 +0000
commitf658739cc73876bcd844545cfe6ef6a1a4d4f9a7 (patch)
tree3557517fb6fbaf6f9902306e5af92476cbfd0b6b /loader
parent3f40e75f7d5d1db948783c54a97849a1acaf32f2 (diff)
downloadanaconda-f658739cc73876bcd844545cfe6ef6a1a4d4f9a7.tar.gz
anaconda-f658739cc73876bcd844545cfe6ef6a1a4d4f9a7.tar.xz
anaconda-f658739cc73876bcd844545cfe6ef6a1a4d4f9a7.zip
added mediacheck
Diffstat (limited to 'loader')
-rw-r--r--loader/Makefile4
-rw-r--r--loader/loader.c118
-rw-r--r--loader/mediacheck.c66
3 files changed, 177 insertions, 11 deletions
diff --git a/loader/Makefile b/loader/Makefile
index 6adab74e4..3658a866a 100644
--- a/loader/Makefile
+++ b/loader/Makefile
@@ -5,7 +5,7 @@ VERSION = 7.2
DESTDIR = ../../trees/initrd
OBJS = log.o windows.o modules.o devices.o cdrom.o urls.o kickstart.o lang.o \
- misc.o ftp.o
+ misc.o ftp.o md5.o mediacheck.o
SLANGLIB = -lslang
ifneq (ia64, $(ARCH))
@@ -27,7 +27,7 @@ DEBUG = -g
MODULELINKAGE :=../isys/modutils/insmod/libmodutils.a \
../isys/modutils/util/libutil.a \
../isys/modutils/obj/libobj.a
-
+
COPTS = $(DEBUG) -Wall -DVERSION='"$(VERSION)"'
CFLAGS = $(COPTS) $(OPTS) -ffunction-sections -D_GNU_SOURCE=1 -I/usr/include/kudzu -I/usr/include/rpm -I.. -DHAVE_LIBIO_H -ggdb
diff --git a/loader/loader.c b/loader/loader.c
index 7d1a44e3a..12381f074 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -41,6 +41,10 @@
#include <unistd.h>
#include <sys/vt.h>
+#if defined(__i386__) || defined(__ia64__) || defined(__alpha__)
+#include <linux/cdrom.h>
+#endif
+
#include <popt.h>
/* Need to tell loop.h what the actual dev_t type is. */
#undef dev_t
@@ -910,6 +914,61 @@ static char * mountHardDrive(struct installMethod * method,
return url;
}
+
+void ejectCdrom(void) {
+ int ejectfd;
+
+ logMessage("ejecting /tmp/cdrom...");
+ if ((ejectfd = open("/tmp/cdrom", O_RDONLY | O_NONBLOCK, 0)) >= 0) {
+ if (ioctl(ejectfd, CDROMEJECT, 0))
+ logMessage("eject failed %d ", errno);
+ close(ejectfd);
+ } else {
+ logMessage("eject failed %d ", errno);
+ }
+}
+
+
+/* XXX this ignores "location", which should be fixed */
+static char * mediaCheckCdrom(char *cddriver, int flags) {
+
+ int i;
+ int rc;
+ char * buf;
+
+ devMakeInode(cddriver, "/tmp/cdrom");
+
+ do {
+ mediaCheckFile("/tmp/cdrom");
+
+ ejectCdrom();
+
+ rc = newtWinChoice(_("Media Check"), _("Test"), _("Continue"),
+ _("Please insert any additional media you "
+ "would like to test and press %s.\n\n"
+ "Otherwise insert CD #1 into your drive "
+ "and press %s to continue."),
+ _("Test"), _("Continue"));
+
+ if (rc == 2) {
+ unlink("/tmp/cdrom");
+ return NULL;
+ } else {
+ continue;
+ }
+ } while (1);
+
+ return NULL;
+}
+
+static void wrongCDMessage(void) {
+ newtWinMessage(_("Error"), _("OK"),
+ _("I could not find a Red Hat Linux "
+ "CDROM in any of your CDROM drives. Please insert "
+ "the Red Hat CD and press \"OK\" to retry."));
+}
+
+
/* XXX this ignores "location", which should be fixed */
static char * setupCdrom(struct installMethod * method,
char * location, struct knownDevices * kd,
@@ -918,7 +977,7 @@ static char * setupCdrom(struct installMethod * method,
int needRedHatCD) {
int i;
int rc;
- int hasCdrom = 0;
+ int hasCdrom = 0, gotcd1;
char * buf;
do {
@@ -937,7 +996,57 @@ static char * setupCdrom(struct installMethod * method,
"/mnt/runtime", "loop0")) {
buf = malloc(200);
sprintf(buf, "cdrom://%s/mnt/source", kd->known[i].name);
- return buf;
+
+ /* check image(s) if not kickstart and requested */
+ if (!FL_KICKSTART(flags) && FL_MEDIACHECK(flags)) {
+
+ startNewt(flags);
+ rc = newtWinChoice(_("CD Found"), _("OK"),
+ _("Skip"),
+ _("We will now test your media before installing.\n\nChoose 'Skip' "
+ "if you would like to skip this test."));
+
+ if (rc != 2) {
+
+ umount("/mnt/runtime");
+ umountLoopback("/mnt/runtime", "loop0");
+ umount("/mnt/source");
+
+ mediaCheckCdrom(kd->known[i].name, flags);
+
+ /* put mounts back and continue */
+ devMakeInode(kd->known[i].name, "/tmp/cdrom");
+ gotcd1 = 0;
+ do {
+ logMessage("1");
+ do {
+ if (doPwMount("/tmp/cdrom", "/mnt/source",
+ "iso9660", 1, 0, NULL, NULL)) {
+ logMessage("1w");
+ ejectCdrom();
+ wrongCDMessage();
+ } else {
+ logMessage("2");
+ break;
+ }
+ } while (1);
+
+ logMessage("3");
+ if (mountLoopback("/mnt/source/RedHat/base/stage2.img",
+ "/mnt/runtime", "loop0")) {
+ umount("/mnt/source");
+ logMessage("2w");
+ ejectCdrom();
+ wrongCDMessage();
+ } else {
+ logMessage("4");
+ gotcd1 = 1;
+ }
+ } while (!gotcd1);
+ }
+
+ return buf;
+ }
}
}
umount("/mnt/source");
@@ -969,6 +1078,9 @@ static char * mountCdromImage(struct installMethod * method,
char * location, struct knownDevices * kd,
moduleInfoSet modInfo, moduleList modLoaded,
moduleDeps * modDepsPtr, int flags) {
+
+ /* first do media check if necessary */
+
return setupCdrom(method, location, kd, modInfo, modLoaded, modDepsPtr,
flags, 0, 1);
}
@@ -2600,6 +2712,8 @@ int main(int argc, char ** argv) {
if (testing) flags |= LOADER_FLAGS_TESTING;
+ flags |= LOADER_FLAGS_MEDIACHECK;
+
flags = parseCmdLineFlags(flags, cmdLine, &ksSource, &ksNetDevice,
&instClass);
diff --git a/loader/mediacheck.c b/loader/mediacheck.c
index d27f1f42b..c476bb763 100644
--- a/loader/mediacheck.c
+++ b/loader/mediacheck.c
@@ -19,10 +19,20 @@
#define MAX(x, y) ((x > y) ? x : y)
#define MIN(x, y) ((x < y) ? x : y)
+/* number of sectors to ignore at end of iso when computing sum */
+#define SKIPSECTORS 15
+
typedef void (*checkCallback)(void *, long long offset);
+struct progressCBdata {
+ newtComponent scale;
+ newtComponent label;
+};
+
#ifdef TESTING
#define _(x) (x)
+#else
+#include "lang.h"
#endif
/* finds primary volume descriptor and returns info from it */
@@ -76,6 +86,7 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
int dirty;
int sector;
int appdata_start_offset, appdata_end_offset;
+ int nattempt;
unsigned int bufsize = 32768;
unsigned char md5sum[16];
unsigned int len;
@@ -86,6 +97,8 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
if ((pvd_offset = parsepvd(isofd, mediasum, &isosize)) < 0)
return -1;
+ /* printf("Mediasum = %s\n",mediasum); */
+
/* rewind, compute md5sum */
lseek(isofd, 0L, SEEK_SET);
@@ -95,8 +108,12 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
apoff = pvd_offset + APPDATA_OFFSET;
buf = malloc(bufsize * sizeof(unsigned char));
- while (offset < isosize) {
- nread = read(isofd, buf, bufsize);
+ while (offset < isosize - SKIPSECTORS*2048) {
+ nattempt = MIN(isosize - SKIPSECTORS*2048 - offset, bufsize);
+
+ /* printf("%lld %lld %lld %d\n", offset, isosize, isosize-SKIPSECTORS*2048, nattempt); */
+
+ nread = read(isofd, buf, nattempt);
if (nread <= 0)
break;
@@ -125,6 +142,11 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
cb(cbdata, offset);
}
+ if (cb)
+ cb(cbdata, isosize);
+
+ sleep(1);
+
free(buf);
MD5_Final(md5sum, &md5ctx);
@@ -136,6 +158,8 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
strcat(computedsum, tmpstr);
}
+ /* printf("mediasum, computedsum = %s %s\n", mediasum, computedsum); */
+
if (strcmp(mediasum, computedsum))
return 0;
else
@@ -144,13 +168,34 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
static void readCB(void *co, long long pos) {
- newtScaleSet((newtComponent) co, pos);
+ struct progressCBdata *data = co;
+ static tick = 0;
+ char *tickmark;
+
+ newtScaleSet(data->scale, pos);
+ tick++;
+ if (tick < 100)
+ tickmark = "-";
+ if (tick >= 100 && tick < 200)
+ tickmark = "\\";
+ else if (tick >= 200 && tick < 300)
+ tickmark = "|";
+ else if (tick >= 300 && tick < 400)
+ tickmark = "/";
+ else if (tick >= 400) {
+ tick = 0;
+ tickmark = "-";
+ }
+
+ newtLabelSetText(data->label, tickmark);
newtRefresh();
}
int doMediaCheck(int isofd, char *mediasum, char *computedsum, long long *isosize) {
- newtComponent t, f, scale;
+ struct progressCBdata data;
+ newtComponent t, f, scale, label;
int rc;
+ int llen;
if (parsepvd(isofd, mediasum, isosize) < 0) {
newtWinMessage(_("Error"), _("OK"),
@@ -161,6 +206,9 @@ int doMediaCheck(int isofd, char *mediasum, char *computedsum, long long *isosiz
newtCenteredWindow(35, 6, _("Media Check"));
t = newtTextbox(1, 1, 24, 3, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(t, _("Checking media now..."));
+ llen = strlen(_("Checking media now..."));
+
+ label = newtLabel(llen+2, 1, "-");
f = newtForm(NULL, NULL, 0);
newtFormAddComponent(f, t);
scale = newtScale(3, 3, 25, *isosize);
@@ -169,8 +217,10 @@ int doMediaCheck(int isofd, char *mediasum, char *computedsum, long long *isosiz
newtDrawForm(f);
newtRefresh();
- rc = checkmd5sum(isofd, mediasum, computedsum, readCB, scale);
- sleep(1);
+ data.scale = scale;
+ data.label = label;
+
+ rc = checkmd5sum(isofd, mediasum, computedsum, readCB, &data);
newtFormDestroy(f);
newtPopWindow();
@@ -208,6 +258,7 @@ int mediaCheckFile(char *file) {
result = _("PASS.\n\nIt is OK to install from this media.");
else
result = _("NA.\n\nNo checksum information available, unable to verify media.");
+
newtCenteredWindow(60, 10, _("Media Check Result"));
t = newtTextbox(4, 1, 52 , 5, NEWT_TEXTBOX_WRAP);
snprintf(tmpstr, sizeof(tmpstr), _("The media check is complete, the "
@@ -218,7 +269,8 @@ int mediaCheckFile(char *file) {
newtFormAddComponent(f, newtButton(26, 6, _("OK")));
newtRunForm(f);
-
+ newtFormDestroy(f);
+ newtPopWindow();
return rc;
}