home *** CD-ROM | disk | FTP | other *** search
- Program uuencode;
- {Fixed 'off-by-one' error @ EOF in routine ENCODE1 - B.Eiben@MARKET - 16-Aug-86}
-
- CONST header = 'begin';
- trailer = 'end';
- defaultMode = '644';
- defaultExtension = '.uue';
- offset = 32;
- charsPerLine = 60;
- bytesPerHunk = 3;
- sixBitMask = $3F;
- endofinfile : boolean = FALSE;
-
- TYPE string80 = string[80];
-
- VAR inf : file;
- outfile: text;
- infilename, outfilename, mode: string80;
- lineLength, numbytes, bytesInLine: integer;
- line: array [0..59] of char;
- hunk: array [0..2] of byte;
- chars: array [0..3] of byte;
-
-
- { procedure debug;
-
- var i: integer;
-
- procedure writebin(x: byte);
-
- var i: integer;
-
- begin
- for i := 1 to 8 do
- begin
- write ((x and $80) shr 7);
- x := x shl 1
- end;
- write (' ')
- end;
-
- begin
- for i := 0 to 2 do writebin(hunk[i]);
- writeln;
- for i := 0 to 3 do writebin(chars[i]);
- writeln;
- for i := 0 to 3 do writebin(chars[i] and sixBitMask);
- writeln
- end; }
-
- {Binary file read added by Ross Alford, ...!mcnc!ecsvax!alford. The original
- MSDOS versions of uuencode/decode just use read/write on a FILE OF BYTE.
- CP/M Turbo expects some file info to be stored in the first 4 bytes of files
- of any type other than TEXT. Getbyte (below) and Putbyte (in UUDECODE)
- bypass this 'feature' by using blockread and blockwrite. The only global
- variables either use are 'infilename' and 'inf' or 'outfilename' and 'outf'}
-
- function getbyte(var b : byte) : boolean;
-
- type bufptr = ^bufrec;
- bufrec = record
- next : bufptr;
- buffer : array[1..128] of byte
- end;
-
- const sectstobuf = 8; {max number of sectors to buffer}
- sectsread : integer = 0; {constants are essentially statics}
- bytptr : integer = 129;
- notopen : boolean = TRUE;
- j : integer = 0;
- infsize : integer = 0;
- listsaveofs : integer = 0;
- listsaveseg : integer = 0;
-
- var list,temp,temp2 : bufptr;
-
- begin
- if notopen then
- begin
- notopen := FALSE;
- assign(inf,infilename);
- {$i-}
- reset(inf);
- {$i+}
- if ioresult <> 0 then
- begin
- writeln('File ',infilename,' not found. Aborting');
- halt
- end;
- infsize := filesize(inf);
- new(list);
- list^.next := NIL;
- listsaveofs := ofs(list^);
- listsaveseg := seg(list^);
- sectsread := 0
- end;
- list := ptr(listsaveseg,listsaveofs);
- if bytptr > 128 then
- begin
- if list^.next <> NIL then
- begin
- temp := list^.next;
- dispose(list);
- list := temp;
- bytptr := 1
- end
- else begin
- dispose(list);
- list := NIL;
- j := 0;
- while (sectsread<infsize) and (j<sectstobuf) do
- begin
- new(temp2);
- temp2^.next := NIL;
- if list=NIL then
- begin
- list := temp2;
- temp := list
- end
- else begin
- temp^.next := temp2;
- temp := temp2
- end;
- blockread(inf,temp^.buffer,1);
- j := succ(j);
- sectsread := succ(sectsread)
- end;
- bytptr := 1
- end
- end;
- listsaveofs := ofs(list^);
- listsaveseg := seg(list^);
- if list <> NIL then
- begin
- b := list^.buffer[bytptr];
- bytptr := succ(bytptr);
- getbyte := TRUE
- end
- else begin
- b := 0;
- getbyte := FALSE
- end
- end;
-
- procedure Abort (message: string80);
-
- begin {abort}
- writeln(message);
- close(inf);
- close(outfile);
- halt
- end; {abort}
-
- procedure Init;
-
- procedure GetFiles;
-
- VAR i: integer;
- temp: string80;
- ch: char;
-
- begin {GetFiles}
- if ParamCount < 1 then abort ('No input file specified.');
- infilename := ParamStr(1);
- {$I-}
- assign (inf, infilename);
- reset (inf);
- {$i+}
- if IOResult > 0 then abort (concat ('Can''t open file ', infilename));
-
- write('Uuencoding file ', infilename);
-
- i := pos('.', infilename);
- if i = 0
- then outfilename := infilename
- else outfilename := copy (infilename, 1, pred(i));
- mode := defaultMode;
- if ParamCount > 1 then
- for i := 2 to ParamCount do
- begin
- temp := Paramstr(i);
- if temp[1] in ['0'..'9']
- then mode := temp
- else outfilename := temp
- end;
- if pos ('.', outfilename) = 0
- then outfilename := concat(outfilename, defaultExtension);
- assign (outfile, outfilename);
- writeln (' to file ', outfilename, '.');
-
- {$i-}
- reset(outfile);
- {$i+}
- if IOresult = 0 then
- begin
- Write ('Overwrite current ', outfilename, '? [Y/N] ');
- repeat
- read (kbd, ch);
- ch := Upcase(ch)
- until ch in ['Y', 'N'];
- writeln (ch);
- if ch = 'N' then abort(concat (outfilename, ' not overwritten.'))
- end;
- close(outfile);
-
- {$i-}
- rewrite(outfile);
- {$i+}
- if ioresult > 0 then abort(concat('Can''t open ', outfilename));
- end; {getfiles}
-
- begin {Init}
- GetFiles;
- bytesInLine := 0;
- lineLength := 0;
- numbytes := 0;
- writeln (outfile, header, ' ', mode, ' ', infilename);
- end; {init}
-
- procedure FlushLine;
-
- VAR i: integer;
-
- procedure writeout(ch: char);
-
- begin {writeout}
- if ch = ' ' then write(outfile, '`')
- else write(outfile, ch)
- end; {writeout}
-
- begin {FlushLine}
- write ('.');
- writeout(chr(bytesInLine + offset));
- for i := 0 to pred(lineLength) do
- writeout(line[i]);
- writeln (outfile);
- lineLength := 0;
- bytesInLine := 0
- end; {FlushLine}
-
- procedure FlushHunk;
-
- VAR i: integer;
-
- begin {FlushHunk}
- 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);}
- lineLength := succ(lineLength)
- end;
- {writeln;}
- bytesInLine := bytesInLine + numbytes;
- numbytes := 0
- end; {FlushHunk}
-
- procedure encode1;
-
- begin {encode1};
- if numbytes = bytesperhunk then flushhunk;
- endofinfile := not (getbyte(hunk[numbytes]));
- if not endofinfile then numbytes := succ(numbytes) {No succ at EOF -BE}
- end; {encode1}
-
- procedure terminate;
-
- begin {terminate}
- if numbytes > 0 then flushhunk;
- if lineLength > 0
- then
- begin
- flushLine;
- flushLine;
- end
- else flushline;
- writeln (outfile, trailer);
- close (outfile);
- close (inf);
- end; {terminate}
-
-
- begin {uuencode}
- init;
- while not endofinfile do encode1;
- terminate
- end. {uuencode}
-