home *** CD-ROM | disk | FTP | other *** search
- 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;