home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
draco
/
draco-1.ark
/
UUDECODE.DRC
< prev
next >
Wrap
Internet Message Format
|
1986-11-12
|
7KB
Received: from seismo.css.gov by AMSAA.ARPA id a013221; 15 Oct 86 18:28 EDT
Received: from ubc-vision.UUCP by seismo.CSS.GOV (5.54/1.14)
id AA09297; Wed, 15 Oct 86 18:29:30 EDT
Received: by ubc-vision.UUCP id AA09634; Wed, 15 Oct 86 12:50:40 pdt
Received: by pembina.alberta.UUCP (4.12/3.14)
id AA10116; Wed, 15 Oct 86 11:59:50 mdt
Received: by myrias.UUCP (4.12/4.7)
id AA10621; Wed, 15 Oct 86 11:46:15 mdt
Date: Wed, 15 Oct 86 11:40:07 mdt
From: ubc-vision!alberta!myrias!cg@seismo.CSS.GOV (Chris Gray)
Message-Id: <8610151740.AA28641@myrias.UUCP>
To: towson@amsaa.arpa
Subject: UUDECODE.DRC
#util.g
/*
* uudecode.drc
* Decode an ASCII representation into a binary file. This is the
* reverse of uuencode. The single parameter is the name of the
* uuencoded file to decode. The input file contains the name to use
* for the binary file created. It can contain more than one file, even
* though uuencode can't directly produce such a beast.
*/
word
BUFF_SIZE = 10000, /* nice and big */
MAX_BYTES = 45, /* maximum bytes per encoded line */
MAX_LINE = 100; /* maximum input line we use */
channel input text Chin;
channel output binary Chout;
file(BUFF_SIZE) InputFile, OutputFile;
[MAX_LINE] char LineBuff; /* buffer for input line */
word LineMax, LinePos; /* count/position in input line */
bool Eof;
/*
* getLine -
* Read an input line into LineBuff/LineMax.
*/
proc getLine()void:
char ch;
LineMax := 0;
while read(Chin; ch) do
if LineMax ~= MAX_LINE then
LineBuff[LineMax] := ch;
LineMax := LineMax + 1;
fi;
od;
if ioerror(Chin) = CH_MISSING then
readln(Chin;);
else
Eof := true;
fi;
LinePos := 0;
corp;
/*
* getWord -
* Peel an input word off of the input line.
*/
proc getWord()*char:
*char p;
p := &LineBuff[LinePos];
while LinePos < LineMax and LineBuff[LinePos] ~= ' ' do
LinePos := LinePos + 1;
od;
LineBuff[LinePos] := '\e';
LinePos := LinePos + 1;
p
corp;
/*
* isWord -
* Compare two words for equality.
*/
proc isWord(*char p, q)bool:
while p* = q* and p* ~= '\e' do
p := p + 1;
q := q + 1;
od;
p* = q*
corp;
/*
* decodeChar -
* Decode a single character to a six bit value.
*/
proc decodeChar(char ch)byte:
if ch >= ' ' + 1 and ch <= ' ' + ((1 << 6) - 1) then
ch - ' '
elif ch = '`' then
0
else
writeln("Bad encoded character: ", ch - '\e');
close(Chout);
close(Chin);
exit(1);
0
fi
corp;
/*
* decodeFile -
* Decode the file given already opened descriptors, etc.
*/
proc decodeFile()void:
[MAX_BYTES] byte buff;
word count, i, j;
byte b1, b2, b3, b4;
/* fetch and decode lines until we find one starting with "end" */
while
getLine();
not isWord(getWord(), "end")
do
/* check for a valid length line */
if LineMax < 1 or LineMax > MAX_BYTES * 4 / 3 + 1 or
(LineMax - 1) % 4 ~= 0 then
writeln("Invalid line length: ", LineMax);
close(Chout);
close(Chin);
exit(1);
fi;
/* get and check the actual count of encoded bytes on this line */
count := decodeChar(LineBuff[0]);
if (LineMax - 1) / 4 ~= (count + 2) / 3 then
writeln("Invalid record length: ", count, " : ", LineMax);
close(Chout);
close(Chin);
exit(1);
fi;
/* decode the line - groups of 4 characters yield three bytes */
j := 0;
i := 1;
while i ~= LineMax do
b1 := decodeChar(LineBuff[i + 0]);
b2 := decodeChar(LineBuff[i + 1]);
b3 := decodeChar(LineBuff[i + 2]);
b4 := decodeChar(LineBuff[i + 3]);
buff[j + 0] := b1 << 2 | b2 >> 4;
buff[j + 1] := b2 << 4 | b3 >> 2;
buff[j + 2] := b3 << 6 | b4;
j := j + 3;
i := i + 4;
od;
/* write out the correct number (1 - 45) of bytes */
i := 0;
while i ~= count do
write(Chout; buff[i]);
i := i + 1;
od;
od;
corp;
/*
* decode -
* Decode all of the encoded files in the already opened input file.
*/
proc decode()void:
*char outFileName;
FILENAME fn;
bool gotBegin, doneFile;
doneFile := false;
/* decode files until there are no more left */
while not Eof do
gotBegin := false;
/* skip lines until we find a 'begin' line or we hit end-of-file */
while not Eof and not gotBegin do
getLine();
outFileName := getWord();
if isWord(outFileName, "begin") then
outFileName := getWord();
while outFileName* >= '0' and outFileName* <= '7' do
outFileName := outFileName + 1;
od;
if outFileName* = '\e' then
outFileName := getWord();
if outFileName* ~= '\e' then
gotBegin := true;
fi;
fi;
fi;
od;
/* if we just found a 'begin' line, go decode an encoded file */
if gotBegin then
writeln("Decoding file '", outFileName, "'");
/* open output file, etc. */
SetFileName(fn, outFileName);
pretend(FileDestroy(fn), void);
if not FileCreate(fn) then
writeln("Can't create output file '", outFileName, "'");
close(Chin);
exit(1);
fi;
if not open(Chout, OutputFile, outFileName) then
writeln("Can't open output file '", outFileName, "'");
close(Chin);
exit(1);
fi;
/* go decode the file */
decodeFile();
/* close file */
close(Chout);
doneFile := true;
fi;
od;
/* if we found no 'begin' line in the whole input file, then complain */
if not doneFile then
writeln("No 'begin' line found.");
close(Chin);
exit(1);
fi;
corp;
/*
* main -
* The main program. Get the command line parameters and open and decode
* each one. Each input file is decoded into 1 or more output binary
* files.
*/
proc main()void:
*char par;
par := GetPar();
if par = nil then
writeln("usage: uudecode file1.typ ... filen.typ");
else
while par ~= nil do
/* try to open the specified input file */
if not open(Chin, InputFile, par) then
writeln("Can't open input file '", par, "'");
exit(1);
fi;
/* initialize for reading the input line */
Eof := false;
decode();
close(Chin);
par := GetPar();
od;
fi;
corp;