home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / ucsdpecan / kermpack.text < prev    next >
Text File  |  2020-01-01  |  14KB  |  430 lines

  1. unit kermpack;
  2.  
  3. interface
  4.  
  5.    uses {$U kermglob.code} kermglob;
  6.  
  7. {Change log:
  8. 30 Apr 89, V1.1: Eliminated "no timeout on receive" checks   RTC
  9. 26 Apr 89, V1.1: Changed to "timer" controlled timeouts   RTC
  10. 19 Apr 89, V1.1: minor cleanups   RTC
  11. 13 Apr 89, V1.1: Added Version message        RTC
  12. 14 Aug 88: Fixed packetwrite to output to debf          RTC
  13. 31 Jul 88: Modified for exact size binary xfr, misc. cleanup    RTC
  14. 02 Jul 88: Added binary transfers        RTC
  15.  
  16. }
  17.  
  18.    procedure spar(var packet: packettype);
  19.  
  20.    procedure rpar(var packet: packettype; len : integer);
  21.  
  22.    procedure spack(ptype: char; num:integer; len: integer; data: packettype);
  23.  
  24.    function rpack(var len, num: integer; var data: packettype): char;
  25.  
  26.    procedure bufemp(buffer: packettype; len: integer);
  27.  
  28.    function bufill(var buffer: packettype): integer;
  29.  
  30.    procedure pak_version;
  31.  
  32.  
  33. implementation
  34.  
  35. uses {$U kermutil.code} kermutil;
  36.  
  37. const
  38.   my_version = '   Kermpack Unit V1.1, 30 Apr 89';
  39.  
  40.  
  41. procedure bufemp(*buffer: packettype; var f: text; len: integer*);
  42.  
  43. (* empties a packet into a file *)
  44.  Note: this strips out ALL linefeed characters! 
  45.  
  46. var i,ls: integer;
  47.     r: char;
  48.     set_bit_8 : boolean;
  49.     s: string255;
  50.  
  51. procedure write_bin;
  52.  
  53.   var
  54.     dummy : integer;
  55.  
  56.   begin {write_bin}
  57.     filebuf[bufpos] := r;
  58.     i := succ(i); bufpos := succ(bufpos);
  59.     if bufpos > blksize then
  60.       begin
  61.         {$I-}
  62.         dummy := blockwrite(b_file,filebuf,1);
  63.         if io_result <> 0 then
  64.           begin
  65.             io_error(ioresult);         {tell them and...}
  66.             currstate := 'a'            {abort}
  67.           end;
  68.         {$I+}
  69.         bufpos := 1
  70.       end
  71.   end {write_bin};
  72.  
  73. procedure write_text;
  74.  
  75.   var
  76.     dummy : integer;
  77.  
  78.   begin {write_text}
  79.       if ord(r) = lf then { skip linefeeds SP }
  80.          i := i + 1
  81.       else if (ord(r) = cr) then begin     (* else if a carriage return then *)
  82.          i := i + 1;
  83.          (*$I-*)                           (* turn i/o checking off *)
  84.          writeln(t_file,s);                (* and write out line to file *)
  85.          s := copy('',0,0);                (* empty the string var *)
  86.          ls := 0;
  87.          (*$I+*)                           (* turn i/o checking back on *)
  88.       end
  89.       else begin                           (* else, is a regular char, so Q5R      $H     s := concat(s,' ');               (* and add character to out string *)
  90.         ls := ls + 1;
  91.          s[ls] := r;
  92.          if length(s) >= 255 then          {dump full string  RTC}
  93.            begin
  94.              {$I-}
  95.              write(t_file,s);
  96.              s := ''; ls := 0
  97.              {$I+}
  98.            end;
  99.          i := i + 1                (* increase buffer pointer *)
  100.       end; (* else *)
  101.       if (io_result <> 0) then begin (* if io_error *)
  102.          io_error(ioresult);     (* tell them and *)
  103.          currstate := 'a';           (* abort *)
  104.       end (* if *)
  105.   end {write_text};
  106.  
  107. begin
  108.    s := copy('',0,0);
  109.    ls := 0;
  110.    i := 0;
  111.    while i < len do begin
  112.       r := buffer[i];          (* get a character *)
  113.       if en_qbin and (r = qbin) then
  114.         begin
  115.           i := succ(i);
  116.           r := buffer[i];      {get 8 bit quoted char}
  117.           set_bit_8 := true
  118.         end
  119.       else set_bit_8 := false;
  120.       if (r = myquote) then begin   (* if character is control quote *)
  121.          i := i + 1;                (* skip over quote and *)
  122.          r := buffer[i];            (* get quoted character *)
  123.          if not (chr(aand(ord(r),127)) in
  124.                  ctl_set - [chr(0)..chr(31),chr(del)]) then
  125.             r := ctl(r);    (* controllify it *)
  126.       end; (* if *)
  127.       if set_bit_8 then r := chr(aor(ord(r),128));
  128.       if f_is_binary
  129.         then write_bin
  130.         else write_text
  131.    end; (* while *)                     (* and get another char *)
  132.    if not f_is_binary then
  133.      begin
  134.        (*$I-*)                          (* turn i/o checking off *)
  135.        write(t_file,s);                 (* and write out line to file *)
  136.        if (io_result <> 0) then begin   (* if io_error *)
  137.           io_error(ioresult);           (* tell them and *)
  138.           currstate := 'a';             (* abort *)
  139.        end (* if *)
  140.        (*$I+*)                          (* turn i/o checking back on *)
  141.      end
  142. end; (* bufemp *)
  143.  
  144.  
  145. function bufill(*var buffer: packettype): integer*);
  146.  
  147. (* fill a packet with data from a file *)
  148.  
  149. var i : integer;
  150.     r : char;
  151.  
  152.   function done : boolean;
  153.  
  154.     begin {done}
  155.       if f_is_binary
  156.         then done := (bufpos > last_blksize) and eof(b_file)
  157.         else done := eof(t_file)
  158.     end {done};
  159.  
  160.   begin
  161.     i := 0;
  162.     (* while file has some data & packet has some room we'll keep going *)
  163.     while not done and (i < spsiz-9) do
  164.       begin
  165.         if f_is_binary then
  166.           begin
  167.             (* if we need more data from disk then *)
  168.             if (bufpos > bufend) and (not eof(b_file)) then
  169.               begin
  170.                 {$I-}
  171.                 bufend := blockread(b_file,filebuf[1],1) * blksize;
  172.                 if io_result <> 0 then
  173.                   begin
  174.                     bufill := at_badblk;
  175.                     exit(bufill)
  176.                   end;
  177.                 {$I+}
  178.                 (* and adjust buffer pointer *)
  179.                 bufpos := 1
  180.               end; (* if *)
  181.             r := filebuf[bufpos];      (* get a character *)
  182.             bufpos := bufpos + 1;         (* increase buffer pointer *)
  183.           end
  184.         else
  185.           begin
  186.             r := t_file^;
  187.             {$I-}
  188.             if eoln(t_file) then
  189.               begin
  190.                 buffer[i] := quote;      (* put (quoted) CR in buffer *)
  191.                 i := i + 1;
  192.                 buffer[i] := ctl(chr(cr));
  193.                 i := i + 1;
  194.                 r := chr(lf);            (* and we'll stick a LF after *)
  195.               end;
  196.             get(t_file);
  197.             if io_result <> 0 then
  198.               begin
  199.                 bufill := at_badblk;
  200.                 exit(bufill)
  201.               end
  202.             {$I+}
  203.           end;
  204.         if en_qbin and (ord(r) > 127) then
  205.           begin
  206.             r := chr(ord(r)-128);       {remove the 8th bit}
  207.             buffer[i] := qbin;          {insert prefix}
  208.             i := succ(i)
  209.           end;
  210.         if chr(aand(ord(r),127)) in ctl_set then     (* if a control char *)
  211.           begin
  212.             buffer[i] := quote;      (* put the quote in buffer *)
  213.             i := i + 1;
  214.             if not (chr(aand(ord(r),127)) in
  215.                     ctl_set - [chr(0)..chr(31),chr(del)]) then
  216.                 r := ctl(r);   (* and un-controllify char *)
  217.           end (* if *);
  218.         buffer[i] := r;
  219.         i := i + 1;
  220.       end; (* while *)
  221.     if (i = 0) then                         (* if we're at end of file, *)
  222.         bufill := at_eof                    (* indicate it *)
  223.     else                                    (* else *)
  224.         bufill := i                         (* return # of chars in packet *)
  225.   end; (* bufill *)
  226.  
  227.  
  228. procedure spar(*var packet: packettype*);
  229.  
  230. (* fills data array with my send-init parameters *)
  231.  
  232.   begin
  233.     packet[0] := tochar(chr(maxpack+1));   (* biggest packet i can receive *)
  234.     packet[1] := tochar(chr(mytime));    (* when i want to be timed out *)
  235.     packet[2] := tochar(chr(mypad));     (* how much padding i need *)
  236.     packet[3] := ctl(chr(mypchar));      (* padding char i want *)
  237.     packet[4] := tochar(chr(myeol));     (* end of line character i want *)
  238.     packet[5] := myquote;                (* control-quote char i want *)
  239.     if parity = nopar
  240.       then packet[6] := 'Y'              (* I will do 8-bit quoting *)
  241.       else packet[6] := my_qbin;         { I need to do 8-bit quoting }
  242.     packet[7] := '1';                    { checksum type I want }
  243.     packet[8] := 'N';                    { I will not do run len encoding }
  244.     packet[9] := tochar(chr(8));         { I can do attributes packets }
  245.     debugwrite('spar:')
  246.   end; (* spar *)
  247.  
  248. procedure rpar(*var packet: packettype; len : integer*);
  249.  
  250. (* gets their init params *)
  251.  
  252.   begin
  253.     if len > 0
  254.       then spsiz := ord(unchar(packet[0]))     (* max send packet size *)
  255.       else spsiz := 80;
  256.     if len > 1
  257.       then timint := ord(unchar(packet[1]))    (* when i should time out *)
  258.       else timint := my_time;
  259.     if len > 2
  260.       then pad := ord(unchar(packet[2]))       (* number of pads to send *)
  261.       else pad := 0;
  262.     if len > 3
  263.       then padchar := ctl(packet[3])           (* padding char to send *)
  264.       else padchar := chr(my_pchar);
  265.     if len > 4
  266.       then xeol := unchar(packet[4])           (* eol char i must send *)
  267.       else xeol := chr(my_eol);
  268.     if len > 5
  269.       then quote := packet[5]                  (* incoming data quote char *)
  270.       else quote := my_quote;
  271.     if len > 6
  272.       then qbin := packet[6]                   { incoming 8th bit quote }
  273.       else qbin := 'N';
  274.     if parity = nopar
  275.       then en_qbin := qbin in [chr(33)..chr(62),chr(96)..chr(126)]
  276.       else
  277.         begin
  278.           if q_bin = 'Y' then qbin := my_qbin;
  279.           en_qbin := qbin = my_qbin
  280.         end;
  281.     if len > 9
  282.       then en_attr := aand(ord(unchar(packet[9])),8) = 8
  283.       else en_attr := false;
  284.     debugwrite('rpar:')
  285.   end; (* rpar *)
  286.  
  287. procedure packetwrite(p: packettype; len: integer);
  288.  
  289. (* writes out all of a packet for debugging purposes *)
  290.  
  291. var i: integer;
  292.  
  293.   begin
  294.     gotoxy(0,debugline);
  295.     for i := 0 to len-1 do
  296.         write(debf,p[i])
  297.   end; (* packetwrite *)
  298.  
  299. procedure spack(*ptype: char; num: integer; len: integer; data: packettype*);
  300.  
  301. (* send a packet *)
  302.  
  303. var i: integer;
  304.     chksum: char;
  305.     ch: char;
  306.  
  307.   begin
  308.     debugwrite('spack:');
  309.     if ibm and (currstate <> 's') then           (* if ibm and not SINIT then *)
  310.       begin
  311.         set_timer(timint);
  312.         repeat                                 (* wait for an xon *)
  313.             repeat
  314.             until (readch(inport, ch)) or timeout;
  315.         until (ch = xon) or timeout;
  316.         if timeout then                 (* if wait too long then *)
  317.           begin
  318.             exit(spack)                          (* get out *)
  319.           end; (* if *)
  320.       end; (* if *)
  321.  
  322.     for i := 1 to pad do
  323.         write_ch(oport,parity_array[padchar]);(* write out any padding chars *)
  324.     write_ch(oport,parity_array[chr(soh)]);                (* packet sync character *)
  325.     chksum := tochar(chr(len + 3));          (* init chksum *)
  326.     write_ch(oport,parity_array[tochar(chr(len + 3))]);    (* character count *)
  327.     chksum := chr(ord(chksum) + ord(tochar(chr(num))));
  328.     write_ch(oport,parity_array[tochar(chr(num))]);
  329.     chksum := chr(ord(chksum) + ord(ptype));
  330.     write_ch(oport,parity_array[ptype]);                   (* packet type *)
  331.  
  332.     for i := 0 to len - 1 do                 (* loop through data chars *)
  333.       begin
  334.         write_ch(oport,parity_array[data[i]]);             (* store char *)
  335.         chksum := chr(ord(chksum) + ord(data[i]))
  336.       end; (* for i *)
  337.                                              (* compute final chksum *)
  338.     chksum := chr(aand(ord(chksum) + (aand(ord(chksum),192) div 64), 63));
  339.     write_ch(oport,parity_array[tochar(chksum)]);
  340.     write_ch(oport,parity_array[xeol]);
  341.  
  342.     if debug then
  343.       begin
  344.         write(debf,' len:',len,' num:',num,' ptype:',ptype);
  345.         packetwrite(data,len); write(debf,' chksum:',tochar(chksum))
  346.       end
  347.   end; (* spack *)
  348.  
  349. (*$G+*) (* turn on goto option...need it for next routine *)
  350.  
  351. function rpack(*var len, num: integer; var data: packettype): char*);
  352.  
  353. (* read a packet *)
  354.  
  355. label 1; (* used to emulate C's CONTINUE statement *)
  356.  
  357. var i, ichksum: integer;
  358.     chksum, ptype: char;
  359.     r: char;
  360.  
  361.   begin
  362.     debugwrite('rpack:');
  363.     set_timer(timint);
  364.  
  365.     if not getsoh then                       (*if don't get synch char then *)
  366.       begin
  367.         rpack := 'N';                        (* treat as a NAK *)
  368.         num := n mod 64;
  369.         exit(rpack)                          (* and get out of here *)
  370.       end;
  371.  
  372.   1: if timeout then                        (* if we've tried too many times *)
  373.         begin                               (* and aren't waiting for init *)
  374.           rpack := 'N';                      (* treat as NAK *)
  375.           exit(rpack)                        (* and get out of here *)
  376.         end; (* if *)
  377.  
  378.     if not getch(r) then                (* get a char and *)
  379.             goto 1;                        (* resynch if soh *)
  380.  
  381.     ichksum := ord(r);                        (* start checksum *)
  382.     len := ord(unchar(r)) - 3;          (* character count *)
  383.  
  384.     if not getch(r) then                (* get a char and *)
  385.         goto 1;                            (* resynch if soh *)
  386.     ichksum := ichksum + ord(r);
  387.     num := ord(unchar(r));              (* packet number *)
  388.  
  389.     if not getch(r) then                (* get a char and *)
  390.         goto 1;                            (* resynch if soh *)
  391.     ichksum := ichksum + ord(r);
  392.     ptype := r;                         (* packet type *)
  393.  
  394.     for i := 0 to len-1 do                 (* get any data *)
  395.       begin
  396.         if not getch(r) then            (* get a char and *)
  397.             goto 1;                        (* resynch if soh *)
  398.         ichksum := ichksum + ord(r);
  399.         data[i] := r;
  400.       end; (* for i *)
  401.     data[len] := chr(0);                   (* mark end of data *)
  402.  
  403.     if not getch(r) then                (* get a char and *)
  404.         goto 1;                            (* resynch if soh *)
  405.  
  406.                                            (* compute final checksum *)
  407.     chksum := chr(aand(ichksum + (aand(ichksum,192) div 64), 63));
  408.  
  409.     if (chksum <> unchar(r)) then       (* if checksum bad *)
  410.         rpack := chr(0)                      (* return 'false' indicator *)
  411.     else                                   (* else *)
  412.         rpack := ptype;                      (* return packet type *)
  413.  
  414.     if debug then
  415.       begin
  416.         write(debf,' len:',len,' num:',num,' ptype:',ptype);
  417.         packetwrite(data,len); write(debf,' chksum:',r)
  418.       end; (* if *)
  419.   end; (* rpack *)
  420.  
  421. (*$G-*) (* turn off goto option...don't need it anymore *)
  422.  
  423. procedure pak_version;
  424.  
  425.   begin
  426.     writeln(my_version)
  427.   end {pak_version};
  428.  
  429. end. { kermpack }
  430.