$current_floppy = ""; open(LOG, ">/dev/null"); $floppy_header_length = 4 * 4; $floppy_size = (1440*1024); $floppy_amount = $floppy_size - $floppy_header_length; sub floppy_disk_prompt { local ($filevar, $diskname, $realmagic, $realsig) = @_; local ($gotit, $diskmagic, $disksig, $allmagic, $seriesnum, $disknum); local ($version, $timestamp); if ($current_floppy eq $diskname) { open($filevar, " Now please remove the floppy from the first drive and insert $diskname into /dev/fd0 (DOS drive A:). > Press when ready. > EOM , 70); $gotit = 0; while (! $gotit) { open($filevar, " The isn't any disk in /dev/fd0 (DOS drive A:), or the disk you're using is bad. > Press to try again. > EOM , 70); next; } ; (8 == read($filevar, $allmagic, 8)) || do { &rhs_msgbox ( "Bad Floppy", < I can't read anything from that disk! > Press to try again. > EOM , 70); next; } ; ($diskmagic, $disksig) = unpack("NN", $allmagic); if ($diskmagic != $realmagic) { &rhs_msgbox ( "Bad Floppy", < That's not a Red Hat floppy! > Press to try again. > EOM , 70); next; } ; if ($disksig != $realsig) { if ($disksig == 0xFFFFFFFF) { &rhs_msgbox ( "Wrong Floppy", < You inserted the main Red Hat disk. Please insert $diskname. > Press to try again. > EOM , 70); next; } $seriesnum = $disksig >> 16; $disknum = $disksig & 0xFFFF; if ($floppy_series_names[$seriesnum]) { &rhs_msgbox ( "Wrong Floppy", < You inserted the wrong Red Hat floppy. You inserted disk $disknum from series $floppy_series_names[$seriesnum]. Insert $diskname instead. > Press to try again. > EOM , 70); next; } else { &rhs_msgbox ( "Wrong Floppy", < You inserted the wrong Red Hat floppy. Insert $diskname instead. > Press to try again. > EOM , 70); next; } } if ($realsig != 0xFFFFFFFF) { (8 == read($filevar, $allmagic, 8)) || do { &rhs_msgbox ( "Bad Floppy", < I can't read from that disk! > Press to try again. > EOM , 70); next; } ; ($version, $timestamp) = unpack("NN", $allmagic); if ($timestamp != $floppy_timestamp) { &rhs_msgbox ( "Wrong Floppy", < That floppy is from a different Red Hat release then the first floppy. > Press to try again. > EOM , 70); next; } } $gotit = 1; } seek(FLDEVICE, 0, 0); # just like we never touched it $current_floppy = $diskname; return 0; } sub floppy_read_header { local ($series_file_name) = @_; local ($header, $magic, $version, $series_table_length, $series_table_off); local ($file_table, $series_table, $file_table_offset, $file_table_length); local ($series_file, $series_file_length, $series_file_offset); local ($hlen, $strlen, $moremagic); $hlen = 10 * 4; &floppy_disk_prompt(FLDEVICE, "the main floppy", 0x3245eadc, 0xFFFFFFFF); ($hlen == read(FLDEVICE, $header, $hlen)) || die "cannot read header from /dev/fd0"; ($magic, $moremagic, $version, $floppy_timestamp, $series_table_length, $series_table_offset, $file_table_length, $file_table_offset, $series_file_length, $series_file_offset) = unpack("NNNNNNNNNN", $header); ($magic == 0x3245eadc) || die "bad header magic on /dev/fd0"; ($moremagic == 0xFFFFFFFF) || die "bad extra magic on /dev/fd0"; ($version == 1) || die "I can only read version 1 floppies"; ($series_table_length == read(FLDEVICE, $series_table, $series_table_length)) || die "cannot read series table from /dev/fd0"; ($file_table_length == read(FLDEVICE, $file_table, $file_table_length)) || die "cannot read file table from /dev/fd0"; ($series_file_length == read(FLDEVICE, $series_file, $series_file_length)) || die "cannot read series file from /dev/fd0"; close(FLDEVICE); open(F, ">$series_file_name") || die "cannot create $series_file_name"; print F $series_file; close(F); # put together the series array undef(@floppy_series_names); while ($series_table) { $strlen = unpack("N", $series_table); push(@floppy_series_names, substr($series_table, 4, $strlen)); $series_table = substr($series_table, 4 + $strlen); } # a filename has to be enough to give us the series and offset the file # is located at undef(@floppy_file_list); while ($file_table) { $strlen = unpack("N", $file_table); $filename = substr($file_table, 4, $strlen); $file_table = substr($file_table, 4 + $strlen); ($file_size, $file_series_num, $file_offset) = unpack("NNN", $file_table); $file_table = substr($file_table, 12); $floppy_file_info{"${filename}:size"} = $file_size; $floppy_file_info{"${filename}:series_num"} = $file_series_num; $floppy_file_info{"${filename}:offset"} = $file_offset; push(@floppy_file_list, $filename); } return 1; } sub floppy_copy_file { local ($filename, $dir, *newfloppy) = @_; local ($disknum, $size); $floppy_file_info{"${filename}:size"} || do { print STDERR "I can't find file $filename!\n\n"; return 0; } ; $seriesnum = $floppy_file_info{"${filename}:series_num"}; $disknum = int(($floppy_file_info{"${filename}:offset"} / $floppy_amount )); $size = $floppy_file_info{"${filename}:size"}; $offset = $floppy_file_info{"${filename}:offset"} - ($disknum * $floppy_amount) + $floppy_header_length; $disknum++; print LOG "file is $filename\n"; print LOG "series num is $seriesnum\n"; print LOG "disk num is $disknum\n"; print LOG "absolute offset: ", $floppy_file_info{"${filename}:offset"}, "\n"; print LOG "offset: ", $offset, "\n"; open(OUTFILE, ">$dir/$filename") || do { close(FLDEVICE); print STDERR "Error creating $dir/$filename.\n"; ; return 0; } ; while ($size) { &floppy_disk_prompt(FLDEVICE, "$floppy_series_names[$seriesnum] disk $disknum", 0x3245eadc, $seriesnum << 16 | $disknum); print LOG "reading starts at offset $offset in disk $disknum\n"; seek(FLDEVICE, $offset, 0); if ($size <= ($floppy_size - $offset)) { &floppy_copychunk(FLDEVICE, OUTFILE, $size); $size = 0; } else { print LOG "reading $floppy_size - $offset (", $floppy_size - $offset, ") bytes\n"; &floppy_copychunk(FLDEVICE, OUTFILE, $floppy_size - $offset); $size -= $floppy_size - $offset; close(FLDEVICE); $disknum++; $offset = $floppy_header_length; } } close(FLDEVICE); close(OUTFILE); } sub floppy_get_rpm_list { local (@l); for $n (@floppy_file_list) { if ($n =~ /\.rpm$/) { push(@l, $n); } } return @l; } sub floppy_rpm_compare { if ($floppy_file_info{"${a}:series_num"} < $floppy_file_info{"${b}:series_num"}) { return -1 } if ($floppy_file_info{"${a}:series_num"} > $floppy_file_info{"${b}:series_num"}) { return 1 } if ($floppy_file_info{"${a}:offset"} < $floppy_file_info{"${b}:offset"}) { return -1 } return 1; } sub floppy_sort_rpms { return (sort floppy_rpm_compare @_); } sub floppy_init { &umount_bootdisk(); &floppy_read_header("/tmp/series") || return 0; return 1; } sub floppy_copychunk { local ($from, $to, $size) = @_; local ($buffer); if ($size != read($from, $buffer, $size)) { print STDERR "read failed :-(\n"; ; } print $to $buffer; } 1;