[Back to MISC SWAG index] [Back to Main SWAG index] [Original]
{
> Yeah ! Please post your UU(EN/DE)CODE here ! I am interested, as well !
Here she goes then.
}
PROGRAM uuencode;
Uses Dos,Crt;
CONST
Header = 'begin';
Trailer = 'end';
DefaultMode = '644';
DefaultExtension = '.uue';
OFFSET = 32;
CHARSPERLINE = 60;
BYTESPERHUNK = 3;
SIXBITMASK = $3F;
TYPE
Str80 = STRING[80];
VAR
Infile: FILE OF Byte;
Outfile: TEXT;
Infilename, Outfilename, Mode: Str80;
lineLength, numbytes, bytesInLine: INTEGER;
Line: ARRAY [0..59] OF CHAR;
hunk: ARRAY [0..2] OF Byte;
chars: ARRAY [0..3] OF Byte;
size,remaining : longint; {v1.1 REAL;}
PROCEDURE Abort (Msg : Str80);
BEGIN
WRITELN(Msg);
{$I-} {v1.1}
CLOSE(Infile);
CLOSE(Outfile);
{$I+} {v1.1}
HALT
END; {of Abort}
PROCEDURE Init;
PROCEDURE GetFiles;
VAR
i : INTEGER;
TempS : Str80;
Ch : CHAR;
BEGIN
IF ParamCount < 1 THEN Abort ('No input file specified.');
Infilename := ParamStr(1);
{$I-}
ASSIGN (Infile, Infilename);
RESET (Infile);
{$I+}
IF IOResult > 0 THEN Abort (CONCAT ('Can''t open file ', Infilename));
size := FileSize(Infile);
{ IF size < 0 THEN size:=size+65536.0; }
remaining := size;
WRITE('Uuencoding file ', Infilename);
i := POS('.', Infilename);
IF i = 0
THEN Outfilename := Infilename
ELSE Outfilename := COPY (Infilename, 1, PRED(i));
Mode := DefaultMode;
{ Process 2d cmdline arg (if any).
It could be a new mode (rather than default "644")
or it could be a forced output name (rather than
"infile.uue") }
IF ParamCount > 1 {got more args}
THEN FOR i := 2 TO ParamCount DO BEGIN
TempS := ParamStr(i);
IF TempS[1] IN ['0'..'9'] {numeric : it's a mode}
THEN Mode := TempS
ELSE Outfilename := TempS {it's output filename}
END;
IF POS ('.', Outfilename) = 0 {he didn't give us extension..}
{..so make it ".uue"}
THEN Outfilename := CONCAT(Outfilename, DefaultExtension);
ASSIGN (Outfile, Outfilename);
WRITELN (' to file ', Outfilename, '.');
{$I-}
RESET(Outfile);
{$I+}
IF IOResult = 0 THEN BEGIN {output file exists!}
WRITE ('Overwrite current ', Outfilename, '? [Y/N] ');
REPEAT
Ch := Upcase(ReadKey);
UNTIL Ch IN ['Y', 'N'];
WRITELN (Ch);
IF Ch = 'N' THEN Abort(CONCAT (Outfilename, ' not overwritten.'))
END;
{$I-}
CLOSE(Outfile);
IF IOResult <> 0 THEN ; {v1.1 we don't care}
REWRITE(Outfile);
{$I+}
IF IOResult > 0 THEN Abort(CONCAT('Can''t open ', Outfilename));
END; {of GetFiles}
BEGIN {Init}
GetFiles;
bytesInLine := 0;
lineLength := 0;
numbytes := 0;
WRITELN (Outfile, Header, ' ', Mode, ' ', Infilename);
END; {init}
{You'll notice from here on we don't do any error-trapping on disk
read/writes. We just let DOS do the job. Any errors are terminal
anyway, right? }
PROCEDURE FlushLine;
VAR i: INTEGER;
PROCEDURE WriteOut(Ch: CHAR);
BEGIN
IF Ch = ' ' THEN WRITE(Outfile, '`')
ELSE WRITE(Outfile, Ch)
END; {of WriteOut}
BEGIN {FlushLine}
{write ('.');}
WRITE('bytes remaining: ',remaining:7,' (',
remaining/size*100.0:3:0,'%)',CHR(13));
WriteOut(CHR(bytesInLine + OFFSET));
FOR i := 0 TO PRED(lineLength) DO
WriteOut(Line[i]);
WRITELN (Outfile);
lineLength := 0;
bytesInLine := 0
END; {of FlushLine}
PROCEDURE FlushHunk;
VAR i: INTEGER;
BEGIN
IF lineLength = CHARSPERLINE THEN FlushLine;
chars[0] := hunk[0] ShR 2;
chars[1] := (hunk[0] ShL 4) + (hunk[1] ShR 4);
chars[2] := (hunk[1] ShL 2) + (hunk[2] ShR 6);
chars[3] := hunk[2] AND SIXBITMASK;
{debug;}
FOR i := 0 TO 3 DO BEGIN
Line[lineLength] := CHR((chars[i] AND SIXBITMASK) + OFFSET);
{write(line[linelength]:2);}
Inc(lineLength);
END;
{writeln;}
Inc(bytesInLine,numbytes);
numbytes := 0
END; {of FlushHunk}
PROCEDURE Encode1;
BEGIN
IF numbytes = BYTESPERHUNK THEN FlushHunk;
READ (Infile, hunk[numbytes]);
Dec(remaining);
Inc(numbytes);
END; {of Encode1}
PROCEDURE Terminate;
BEGIN
IF numbytes > 0 THEN FlushHunk;
IF lineLength > 0 THEN BEGIN
FlushLine;
FlushLine;
END
ELSE FlushLine;
WRITELN (Outfile, Trailer);
CLOSE (Outfile);
CLOSE (Infile);
END; {Terminate}
BEGIN {uuencode}
Init;
WHILE NOT EOF (Infile) DO Encode1;
Terminate;
WRITELN;
END. {uuencode}
[Back to MISC SWAG index] [Back to Main SWAG index] [Original]