home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / cpm / uucode.lbr / UUENCODE.PZS / UUENCODE.PAS
Pascal/Delphi Source File  |  1988-11-13  |  8KB  |  291 lines

  1. { UUENCODE with "encode1" fix by Bernie Eiben }
  2.  
  3. Program uuencode;
  4.  
  5.   CONST header = 'begin';
  6.         trailer = 'end';
  7.         defaultMode = '644';
  8.         defaultExtension = '.uue';
  9.         offset = 32;
  10.         charsPerLine = 60;
  11.         bytesPerHunk = 3;
  12.         sixBitMask = $3F;
  13.         endofinfile : boolean = FALSE;
  14.  
  15.   TYPE string80 = string[80];
  16.  
  17.   VAR inf : file;
  18.       outfile: text;
  19.       infilename, outfilename, mode: string80;
  20.       lineLength, numbytes, bytesInLine: integer;
  21.       line: array [0..59] of char;
  22.       hunk: array [0..2] of byte;
  23.       chars: array [0..3] of byte;
  24.  
  25.  
  26. {  procedure debug;
  27.  
  28.     var i: integer;
  29.  
  30.     procedure writebin(x: byte);
  31.  
  32.       var i: integer;
  33.  
  34.       begin
  35.         for i := 1 to 8 do
  36.           begin
  37.             write ((x and $80) shr 7);
  38.             x := x shl 1
  39.           end;
  40.         write (' ')
  41.       end;
  42.  
  43.     begin
  44.       for i := 0 to 2 do writebin(hunk[i]);
  45.       writeln;
  46.       for i := 0 to 3 do writebin(chars[i]);
  47.       writeln;
  48.       for i := 0 to 3 do writebin(chars[i] and sixBitMask);
  49.       writeln
  50.     end;  }
  51.  
  52. {Binary file read added by Ross Alford,  ...!mcnc!ecsvax!alford.  The original
  53.  MSDOS versions of uuencode/decode just use read/write on a FILE OF BYTE.
  54.  CP/M Turbo expects some file info to be stored in the first 4 bytes of files
  55.  of any type other than TEXT.  Getbyte (below) and Putbyte (in UUDECODE)
  56.  bypass this 'feature' by using blockread and blockwrite.  The only global
  57.  variables either use are 'infilename' and 'inf' or 'outfilename' and 'outf'}
  58.  
  59. function getbyte(var b : byte) : boolean;
  60.  
  61. type bufptr = ^bufrec;
  62.      bufrec = record
  63.                 next : bufptr;
  64.                 buffer : array[1..128] of byte
  65.               end;
  66.  
  67. const sectstobuf = 8;                {max number of sectors to buffer}
  68.       sectsread : integer = 0;       {constants are essentially statics}
  69.       bytptr : integer = 129;
  70.       notopen : boolean = TRUE;
  71.       j : integer = 0;
  72.       infsize : integer = 0;
  73.       listsave : integer  = 0;
  74.  
  75. var list,temp,temp2 : bufptr;
  76.  
  77. begin
  78.   if notopen then
  79.     begin
  80.       notopen := FALSE;
  81.       assign(inf,infilename);
  82.       {$i-}
  83.       reset(inf);
  84.       {$i+}
  85.       if ioresult <> 0 then
  86.         begin
  87.           writeln('File ',infilename,' not found.  Aborting');
  88.           halt
  89.         end;
  90.       infsize := filesize(inf);
  91.       new(list);
  92.       list^.next := NIL;
  93.       listsave := ord(list);
  94.       sectsread := 0
  95.     end;
  96.   list := ptr(listsave);
  97.   if bytptr > 128 then
  98.     begin
  99.       if list^.next <> NIL then
  100.         begin
  101.           temp := list^.next;
  102.           dispose(list);
  103.           list := temp;
  104.           bytptr := 1
  105.         end
  106.         else begin
  107.           dispose(list);
  108.           list := NIL;
  109.           j := 0;
  110.           while (sectsread<infsize) and (j<sectstobuf) do
  111.             begin
  112.               new(temp2);
  113.               temp2^.next := NIL;
  114.               if list=NIL then
  115.                 begin
  116.                   list := temp2;
  117.                   temp := list
  118.                 end
  119.                 else begin
  120.                   temp^.next := temp2;
  121.                   temp := temp2
  122.                 end;
  123.               blockread(inf,temp^.buffer,1);
  124.               j := succ(j);
  125.               sectsread := succ(sectsread)
  126.             end;
  127.           bytptr := 1
  128.         end
  129.     end;
  130.     listsave := ord(list);
  131.     if list <> NIL then
  132.       begin
  133.         b := list^.buffer[bytptr];
  134.         bytptr := succ(bytptr);
  135.         getbyte := TRUE
  136.       end
  137.       else begin
  138.         b := 0;
  139.         getbyte := FALSE
  140.       end
  141. end;
  142.  
  143.   procedure Abort (message: string80);
  144.  
  145.     begin {abort}
  146.       writeln(message);
  147.       close(inf);
  148.       close(outfile);
  149.       halt
  150.     end; {abort}
  151.  
  152.   procedure Init;
  153.  
  154.     procedure GetFiles;
  155.  
  156.       VAR i: integer;
  157.           temp: string80;
  158.           ch: char;
  159.  
  160.       begin {GetFiles}
  161.         if ParamCount < 1 then abort ('No input file specified.');
  162.         infilename := ParamStr(1);
  163.         {$I-}
  164.         assign (inf, infilename);
  165.         reset (inf);
  166.         {$i+}
  167.         if IOResult > 0 then abort (concat ('Can''t open file ', infilename));
  168.  
  169.         write('Uuencoding file ', infilename);
  170.  
  171.         i := pos('.', infilename);
  172.         if i = 0
  173.           then outfilename := infilename
  174.           else outfilename := copy (infilename, 1, pred(i));
  175.         mode := defaultMode;
  176.         if ParamCount > 1 then
  177.           for i := 2 to ParamCount do
  178.             begin
  179.               temp := Paramstr(i);
  180.               if temp[1] in ['0'..'9']
  181.                 then mode := temp
  182.                 else outfilename := temp
  183.             end;
  184.         if pos ('.', outfilename) = 0
  185.           then outfilename := concat(outfilename, defaultExtension);
  186.         assign (outfile, outfilename);
  187.         writeln (' to file ', outfilename, '.');
  188.  
  189.         {$i-}
  190.         reset(outfile);
  191.         {$i+}
  192.         if IOresult = 0 then
  193.           begin
  194.             Write ('Overwrite current ', outfilename, '? [Y/N] ');
  195.             repeat
  196.               read (kbd, ch);
  197.               ch := Upcase(ch)
  198.             until ch in ['Y', 'N'];
  199.             writeln (ch);
  200.             if ch = 'N' then abort(concat (outfilename, ' not overwritten.'))
  201.           end;
  202.         close(outfile);
  203.  
  204.         {$i-}
  205.         rewrite(outfile);
  206.         {$i+}
  207.         if ioresult > 0 then abort(concat('Can''t open ', outfilename));
  208.       end; {getfiles}
  209.  
  210.     begin {Init}
  211.       GetFiles;
  212.       bytesInLine := 0;
  213.       lineLength := 0;
  214.       numbytes := 0;
  215.       writeln (outfile, header, ' ', mode, ' ', infilename);
  216.     end; {init}
  217.  
  218.   procedure FlushLine;
  219.  
  220.     VAR i: integer;
  221.  
  222.     procedure writeout(ch: char);
  223.  
  224.       begin {writeout}
  225.         if ch = ' ' then write(outfile, '`')
  226.                     else write(outfile, ch)
  227.       end; {writeout}
  228.  
  229.     begin {FlushLine}
  230.       write ('.');
  231.       writeout(chr(bytesInLine + offset));
  232.       for i := 0 to pred(lineLength) do
  233.         writeout(line[i]);
  234.       writeln (outfile);
  235.       lineLength := 0;
  236.       bytesInLine := 0
  237.     end; {FlushLine}
  238.  
  239.   procedure FlushHunk;
  240.  
  241.     VAR i: integer;
  242.  
  243.     begin {FlushHunk}
  244.       if lineLength = charsPerLine then FlushLine;
  245.       chars[0] := hunk[0] shr 2;
  246.       chars[1] := (hunk[0] shl 4) + (hunk[1] shr 4);
  247.       chars[2] := (hunk[1] shl 2) + (hunk[2] shr 6);
  248.       chars[3] := hunk[2] and sixBitMask;
  249.       {debug;}
  250.       for i := 0 to 3 do
  251.         begin
  252.           line[lineLength] := chr((chars[i] and sixBitMask) + offset);
  253.           {write(line[linelength]:2);}
  254.           lineLength := succ(lineLength)
  255.         end;
  256.       {writeln;}
  257.       bytesInLine := bytesInLine + numbytes;
  258.       numbytes := 0
  259.     end; {FlushHunk}
  260.  
  261.   procedure encode1;
  262.  
  263.     begin {encode1};
  264.       if numbytes = bytesperhunk then flushhunk;
  265.       endofinfile := not (getbyte(hunk[numbytes]));
  266.       if not endofinfile then numbytes := succ(numbytes)  {No succ at EOF -BE}
  267.     end; {encode1}
  268.  
  269.   procedure terminate;
  270.  
  271.     begin {terminate}
  272.       if numbytes > 0 then flushhunk;
  273.       if lineLength > 0
  274.         then
  275.           begin
  276.             flushLine;
  277.             flushLine;
  278.           end
  279.         else flushline;
  280.       writeln (outfile, trailer);
  281.       close (outfile);
  282.       close (inf);
  283.     end; {terminate}
  284.  
  285.  
  286.   begin {uuencode}
  287.     init;
  288.     while not endofinfile do encode1;
  289.     terminate
  290.   end. {uuencode}
  291.