OF Rope.
IF Rope.Match["-*", name,
FALSE]
THEN {
Switch processing done here. We set the specified switches, then loop to get another name. The ~ character can be used to invert the sense of a switch.
sense: BOOL ← TRUE;
FOR i:
INT
IN [1..Rope.Length[name])
DO
c: CHAR = Rope.Fetch[name, i];
SELECT c
FROM
'~ => {sense ← FALSE; LOOP};
'C, 'c => setChecksum ← sense;
'D, 'd => setDate ← sense;
'S, 's => store ← sense;
ENDCASE =>
IO.PutF[cmd.out, "** Warning, bogus switch: %g\n",
[rope[Rope.Substr[name, i, 1]]]];
sense ← TRUE;
ENDLOOP;
LOOP;
};
IO.PutF[cmd.out, "Open %g", [rope[name]]];
inStream ←
FS.StreamOpen[name
! FS.Error => {IO.PutF[cmd.out, "\n Error - %g\n", [rope[error.explanation]]]; LOOP};
];
outStream ←
FS.StreamOpen[
fileName: "///Temp/BootSmash.temp$", accessOptions: create,
keep: 4, createByteCount: IO.GetLength[inStream]
!
FS.Error => {
IO.PutF[cmd.out, "\n** Error - %g\n", [rope[error.explanation]]];
IO.Close[inStream]; inStream ← NIL;
LOOP;
}];
IO.PutRope[cmd.out, " ."];
bytes ← IO.GetBlock[inStream, buffer, 0, bufferBytes];
IF setDate
THEN {
We must scramble a certain 4 bytes in the file to be a funny-format date.
buffer[6+0] ← timeBytes[2];
buffer[6+1] ← timeBytes[3];
buffer[6+2] ← timeBytes[0];
buffer[6+3] ← timeBytes[1];
};
IF setChecksum
THEN
TRUSTED {
runningChecksum ← Checksum.ComputeChecksum[
lagChecksum ← 0, bufferWords, LOOPHOLE[buffer, LONG POINTER] + SIZE[TEXT[0]]];
};
WHILE bytes > 0
DO
IO.PutRope[cmd.out, "."];
IF setChecksum
AND
IO.GetLength[inStream] =
IO.GetIndex[inStream]
THEN
TRUSTED {
This is the last page, so set the checksum in the last word of the last page.
lastLoc:
LONG
POINTER
TO
CARDINAL =
LOOPHOLE[buffer, LONG POINTER TO CARDINAL] + SIZE[TEXT[bytes]] - 1;
words: INT = (IO.GetLength[inStream]+1) / 2;
oldVal: CARDINAL = lastLoc^;
newVal:
CARDINAL ← lastLoc^ ← NewValueToMakeChecksumZero[
runningChecksum, oldVal, words - 1, words];
newCS:
CARDINAL ← Checksum.ComputeChecksum[
lagChecksum, bytes/2,
LOOPHOLE[buffer, LONG POINTER] + SIZE[TEXT[0]]];
lastLoc^ ← newVal;
IO.PutF[cmd.out,
"\n (old last word: %bB, new last word: %bB, new checksum: %bB)",
[cardinal[oldVal]], [cardinal[newVal]], [cardinal[newCS]] ];
};
IO.PutBlock[outStream, buffer, 0, bytes];
bytes ← IO.GetBlock[inStream, buffer, 0, bufferBytes ! IO.EndOfStream => EXIT];
IF setChecksum
THEN
TRUSTED {
runningChecksum ← Checksum.ComputeChecksum[
lagChecksum ← runningChecksum, bytes/2,
LOOPHOLE[buffer, LONG POINTER] + SIZE[TEXT[0]]];
};
ENDLOOP;
IO.Close[outStream]; outStream ← NIL;
IO.Close[inStream]; inStream ← NIL;
};
IF store
THEN {
dest: ROPE = Rope.Cat["/" , server, "//", name];
IO.PutF[cmd.out, "Start copy to %g ...", [rope[dest]]];
[] ← FS.Copy["///Temp/BootSmash.temp$", dest];
IO.PutRope[cmd.out, " done.\n"];
};