Received: from seismo.css.gov by AMSAA.ARPA id a013548; 15 Oct 86 19:05 EDT Received: from ubc-vision.UUCP by seismo.CSS.GOV (5.54/1.14) id AA09291; Wed, 15 Oct 86 18:29:23 EDT Received: by ubc-vision.UUCP id AA09624; Wed, 15 Oct 86 12:50:29 pdt Received: by pembina.alberta.UUCP (4.12/3.14) id AA10102; Wed, 15 Oct 86 11:59:33 mdt Received: by myrias.UUCP (4.12/4.7) id AA10613; Wed, 15 Oct 86 11:45:40 mdt Date: Wed, 15 Oct 86 11:39:33 mdt From: ubc-vision!alberta!myrias!cg@seismo.CSS.GOV (Chris Gray) Message-Id: <8610151739.AA28630@myrias.UUCP> To: towson@amsaa.arpa Subject: UUENCODE.DRC #util.g /* * uuencode.drc * Encode a binary file into an ASCII representation that can be mailed * around. No blanks are sent - graves (`) are used instead. If only one * parameter is given on the run command, then that is the name of the * file to endcode. It's name is used as the target maChine name, and * the encoded output is left in a file with the same name but with * '.UUE' appended. If a second parameter is given, it is the name to * use for the target maChine file name. */ word BUFF_SIZE = 10000, /* nice and big */ MAX_BYTES = 45; /* maximum bytes per encoded line */ channel input binary Chin; channel output text Chout; file(BUFF_SIZE) InputFile, OutputFile; /* * encodeByte - * Encode a six-bit value as an ASCII char and add it to the output. * The main function is to replace blanks by graves. */ proc encodeByte(byte b)void: write(Chout; if b = 0 then '`' else b + ' ' fi); corp; /* * encode - * Encode the already opened input file into the already opened output * file, using the given remote system file name. */ proc encode(*char remFileName)void: *char p; [MAX_BYTES] byte buff; word i, len; byte b1, b2, b3; /* add the 'begin' line */ writeln(Chout; "begin 644 ", remFileName); /* add the encoded binary file */ while /* get a bufferful (or however much is left to get) */ len := 0; while len ~= MAX_BYTES and read(Chin; buff[len]) do len := len + 1; od; if len ~= 0 then /* first char on output line is encoded actual length */ encodeByte(len); /* followed by up to MAX_BYTES * 4 / 3 chars of encoded data */ i := 0; while i < len do b1 := buff[i]; b2 := buff[i + 1]; b3 := buff[i + 2]; i := i + 3; encodeByte(b1 >> 2); encodeByte(b1 & 0x03 << 4 | b2 >> 4); encodeByte(b2 & 0x0f << 2 | b3 >> 6); encodeByte(b3 & 0x3f); od; /* and a newline */ writeln(Chout;); len = MAX_BYTES else false fi do od; /* add the zero length terminator line so the UNIX version will live */ encodeByte(0); writeln(Chout;); /* add the 'end' line */ writeln(Chout; "end"); corp; /* * main - * The main program. Get the command line parameters, parse them, open * files as needed and pass the remote file name to 'encode'. */ proc main()void: *char inFileName, remFileName; FILENAME fn; [15] char outputName; inFileName := GetPar(); if inFileName = nil then writeln("usage: uuencode localFileName [remoteFileName]"); else remFileName := GetPar(); if remFileName = nil then /* if no explicit remote file name is given, use the input file name */ remFileName := inFileName; fi; if not open(Chin, InputFile, inFileName) then writeln("Can't open input file '", inFileName, "'"); exit(1); fi; SetFileName(fn, inFileName); fn.fn_type[0] := 'U'; fn.fn_type[1] := 'U'; fn.fn_type[2] := 'E'; GetFileName(fn, &outputName[0]); pretend(FileDestroy(fn), void); if not FileCreate(fn) then writeln("Can't create output file '", &outputName[0], "'"); close(Chin); exit(1); fi; if not open(Chout, OutputFile, &outputName[0]) then writeln("Can't open output file '", &outputName[0], "'"); close(Chin); exit(1); fi; /* go encode the file */ encode(remFileName); /* close files */ close(Chout); close(Chin); fi; corp;