home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / ucsdibmpc / kermpack.text < prev    next >
Text File  |  1984-05-22  |  13KB  |  349 lines

  1. unit kermpack;
  2.  
  3. interface
  4.  
  5.    uses {$U kermglob.code} kermglob;
  6.  
  7.  
  8.    procedure spar(var packet: packettype);
  9.  
  10.    procedure rpar(var packet: packettype);
  11.  
  12.    procedure spack(ptype: char; num:integer; len: integer; data: packettype);
  13.  
  14.    function rpack(var len, num: integer; var data: packettype): char;
  15.  
  16.    procedure bufemp(buffer: packettype; var f: text; len: integer);
  17.  
  18.    function bufill(var buffer: packettype): integer;
  19.  
  20.  
  21. implementation
  22.  
  23. uses {$U kermutil.code} kermutil;
  24.  
  25.  
  26. procedure bufemp(*buffer: packettype; var f: text; len: integer*);
  27.  
  28. (* empties a packet into a file *)
  29.  Note: this strips out ALL linefeed characters! 
  30.  
  31. var i,ls: integer;
  32.     r: char_int_rec;
  33.     s: string255;
  34.  
  35. begin
  36.    s := copy('',0,0);
  37.    ls := 0;
  38.    i := 0;
  39.    while i < len do begin
  40.       r.ch := buffer[i];          (* get a character *)
  41.       if (r.ch = myquote) then begin   (* if character is control quote *)
  42.          i := i + 1;               (* skip over quote and *)
  43.          r.ch := buffer[i];        (* get quoted character *)
  44.          if (aand(r.i,127) <> ord(myquote)) then
  45.             r.ch := ctl(r.ch);    (* controllify it *)
  46.       end; (* if *)
  47.       if (r.i = lf) then { skip linefeeds SP }
  48.          i := i + 1
  49.       else if (r.i = cr) then begin     (* else if a carriage return then *)
  50.          i := i + 1;
  51.          {  i := i + 3;  }         (* skip over that and line feed *)
  52.          (*$I-*)                   (* turn i/o checking off *)
  53.          writeln(f,s);             (* and write out line to file *)
  54.          s := copy('',0,0);        (* empty the string var *)
  55.          ls := 0;
  56.          if (io_result <> 0) then begin (* if io_error *)
  57.             io_error(ioresult);     (* tell them and *)
  58.             currstate := 'a';           (* abort *)
  59.          end (* if *)
  60.       end
  61.       (*$I+*)                      (* turn i/o checking back on *)
  62.       else begin                   (* else, is a regular char, so *)
  63.          r.i := aand(r.i,127);     (* mask off parity bit *)
  64.          s := concat(s,' ');       (* and add character to out string *)
  65.          ls := ls + 1;
  66.          s[ls] := r.ch;
  67.          i := i + 1                (* increase buffer pointer *)
  68.       end; (* else *)
  69.    end; (* while *)              (* and get another char *)
  70.    (*$I-*)                     (* turn i/o checking off *)
  71.    write(f,s);                 (* and write out line to file *)
  72.    if (io_result <> 0) then begin   (* if io_error *)
  73.       io_error(ioresult);       (* tell them and *)
  74.       currstate := 'a';             (* abort *)
  75.    end (* if *)
  76.    (*$I+*)                      (* turn i/o checking back on *)
  77. end; (* bufemp *)
  78.  
  79.  
  80. function bufill(*var buffer: packettype): integer*);
  81.  
  82. (* fill a packet with data from a file...manages a 2 block buffer *)
  83.  
  84. var i, j, k, t7, count: integer;
  85.     r: char_int_rec;
  86.  
  87.   begin
  88.     i := 0;
  89.     (* while file has some data & packet has some room we'll keep going *)
  90.     while ((bufpos <= bufend) or (not eof(oldf))) and (i < spsiz-12) do
  91.       begin
  92.         (* if we need more data from disk then *)
  93.         if (bufpos > bufend) and (not eof(oldf)) then
  94.           begin
  95.             (* read a couple of blocks *)
  96.             bufend := blockread(oldf,filebuf[1],2) * blksize;
  97.             (* and adjust buffer pointer *)
  98.             bufpos := 1
  99.           end; (* if *)
  100.         if (bufpos <= bufend) then     (* if we're within buffer bounds *)
  101.           begin
  102.             r.ch := filebuf[bufpos];      (* get a character *)
  103.             bufpos := bufpos + 1;         (* increase buffer pointer *)
  104.             if (r.i = xdle) then           (* if it's space compression char, *)
  105.               begin
  106.                 count := ord(unchar(filebuf[bufpos])); (* get # of spaces *)
  107.                 bufpos := bufpos + 1;       (* read past # *)
  108.                 r.ch := ' ';                (* and make current char a space *)
  109.               end (* else if *)
  110.             else                           (* otherwise, it's just a char *)
  111.                 count := 1;                (* so only 1 copy of it *)
  112.             if (r.ch in ctlset) then     (* if a control char *)
  113.               begin
  114.                 if (r.i = cr) then         (* if a carriage return *)
  115.                   begin
  116.                     buffer[i] := quote;      (* put (quoted) CR in buffer *)
  117.                     i := i + 1;
  118.                     buffer[i] := ctl(chr(cr));
  119.                     i := i + 1;
  120.                     r.i := lf;                (* and we'll stick a LF after *)
  121.                   end; (* if *)
  122.                 if r.i <> 0 then           (* if not a NUL then *)
  123.                   begin
  124.                     buffer[i] := quote;      (* put the quote in buffer *)
  125.                     i := i + 1;
  126.                     if r.ch <> quote then
  127.                         r.ch := ctl(r.ch);   (* and un-controllify char *)
  128.                   end (* if *)
  129.               end; (* if *)
  130.           end; (* if *)
  131.         j := 1;
  132.         while (j <= count) and (i <= spsiz - 8) do
  133.           begin                           (* put all the chars in buffer *)
  134.             if (r.i <> 0) then            (* so long as not a NUL *)
  135.               begin
  136.                 buffer[i] := r.ch;
  137.                 i := i + 1;
  138.               end (* if *)
  139.             else                          (* if is a NUL so *)
  140.                 if (bufpos > blksize) then  (* skip to end of block *)
  141.                     bufpos := bufend + 1    (* since rest will be NULs *)
  142.                 else
  143.                     bufpos := blksize + 1;
  144.             j := j + 1
  145.           end; (* while *)
  146.       end; (* while *)
  147.     if (i = 0) then                         (* if we're at end of file, *)
  148.         bufill := (at_eof)                    (* indicate it *)
  149.     else                                    (* else *)
  150.       begin
  151.         if (j <= count) then                  (* if didn't all fit in packet *)
  152.           begin
  153.             bufpos := bufpos - 2;               (* put buf pointer at DLE *)
  154.                                                 (* and update compress count *)
  155.             filebuf[bufpos + 1] := tochar(chr(count-j+1));
  156.           end; (* if *)
  157.         bufill := i                           (* return # of chars in packet *)
  158.       end; (* else *)
  159.   end; (* bufill *)
  160.  
  161.  
  162. procedure spar(*var packet: packettype*);
  163.  
  164. (* fills data array with my send-init parameters *)
  165.  
  166.   begin
  167.     packet[0] := tochar(chr(maxpack));   (* biggest packet i can receive *)
  168.     packet[1] := tochar(chr(mytime));    (* when i want to be timed out *)
  169.     packet[2] := tochar(chr(mypad));     (* how much padding i need *)
  170.     packet[3] := ctl(chr(mypchar));      (* padding char i want *)
  171.     packet[4] := tochar(chr(myeol));     (* end of line character i want *)
  172.     packet[5] := myquote;                (* control-quote char i want *)
  173.     packet[6] := 'N';                    (* I won't do 8-bit quoting *)
  174.   end; (* spar *)
  175.  
  176. procedure rpar(*var packet: packettype*);
  177.  
  178. (* gets their init params *)
  179.  
  180.   begin
  181.     spsiz := ord(unchar(packet[0]));     (* max send packet size *)
  182.     timint := ord(unchar(packet[1]));    (* when i should time out *)
  183.     pad := ord(unchar(packet[2]));       (* number of pads to send *)
  184.     padchar := ctl(packet[3]);           (* padding char to send *)
  185.     xeol := unchar(packet[4]);            (* eol char i must send *)
  186.     quote := packet[5];                  (* incoming data quote char *)
  187.   end; (* rpar *)
  188.  
  189. procedure packetwrite(p: packettype; len: integer);
  190.  
  191. (* writes out all of a packet for debugging purposes *)
  192.  
  193. var i: integer;
  194.  
  195.   begin
  196.     gotoxy(0,debugline);
  197.     for i := 0 to len+3 do
  198.         write(p[i])
  199.   end; (* packetwrite *)
  200.  
  201. procedure spack(*ptype: char; num: integer; len: integer; data: packettype*);
  202.  
  203. (* send a packet *)
  204.  
  205. const maxtry = 10000;
  206.  
  207. var bufp, i, count: integer;
  208.     chksum: char;
  209.     buffer: packettype;
  210.     ch: char;
  211.  
  212.   begin
  213.     if ibm and (currstate <> 's') then           (* if ibm and not SINIT then *)
  214.       begin
  215.         count := 0;
  216.         repeat                                 (* wait for an xon *)
  217.             repeat
  218.                 count := count + 1
  219.             until (readch(inport, ch)) or (count > maxtry );
  220.         until (ch = xon) or (count > maxtry);
  221.         if count > maxtry then                 (* if wait too long then *)
  222.           begin
  223.             exit(spack)                          (* get out *)
  224.           end; (* if *)
  225.       end; (* if *)
  226.  
  227.     bufp := 0;
  228.     for i := 1 to pad do
  229.         write_ch(oport,padchar);          (* write out any padding chars *)
  230.     buffer[bufp] := chr(soh);                (* packet sync character *)
  231.     bufp := bufp + 1;
  232.     chksum := tochar(chr(len + 3));          (* init chksum *)
  233.     buffer[bufp] := tochar(chr(len + 3));    (* character count *)
  234.     bufp := bufp + 1;
  235.     chksum := chr(ord(chksum) + ord(tochar(chr(num))));
  236.     buffer[bufp] := tochar(chr(num));
  237.     bufp := bufp + 1;
  238.     chksum := chr(ord(chksum) + ord(ptype));
  239.     buffer[bufp] := ptype;                   (* packet type *)
  240.     bufp := bufp + 1;
  241.  
  242.     for i := 0 to len - 1 do                 (* loop through data chars *)
  243.       begin
  244.         buffer[bufp] := data[i];             (* store char *)
  245.         bufp := bufp + 1;
  246.         chksum := chr(ord(chksum) + ord(data[i]))
  247.       end; (* for i *)
  248.                                              (* compute final chksum *)
  249.     chksum := chr(aand(ord(chksum) + (aand(ord(chksum),192) div 64), 63));
  250.     buffer[bufp] := tochar(chksum);
  251.     bufp := bufp + 1;
  252.     buffer[bufp] := xeol;
  253.  
  254.     if (parity <> nopar) then
  255.         for i := 0 to bufp do                 (* set correct parity on buffer *)
  256.             buffer[i] := parity_array[buffer[i]];
  257.  
  258.     {unitwrite(oport,buffer[0],bufp+1,,12);}       (* send the packet out *)
  259.  
  260.     for i := 0 to bufp do
  261.        write_ch(oport, buffer[i]);
  262.  
  263.     if debug then
  264.         packetwrite(buffer,len);
  265.   end; (* spack *)
  266.  
  267. (*$G+*) (* turn on goto option...need it for next routine *)
  268.  
  269. function rpack(*var len, num: integer; var data: packettype): char*);
  270.  
  271. (* read a packet *)
  272.  
  273. label 1; (* used to emulate C's CONTINUE statement *)
  274.  
  275. const maxtry = 10000;
  276.  
  277. var count, i, ichksum: integer;
  278.     chksum, ptype: char;
  279.     r: char_int_rec;
  280.  
  281.   begin
  282.     count := 0;
  283.  
  284.     if not getsoh and (currstate<>'r') then (*if don't get synch char then *)
  285.       begin
  286.         rpack := 'N';                        (* treat as a NAK *)
  287.         num := n mod 64;
  288.         exit(rpack)                          (* and get out of here *)
  289.       end;
  290.  
  291.   1: count := count + 1;
  292.      if (count>maxtry)and(currstate<>'r') then (* if we've tried too many times *)
  293.         begin                               (* and aren't waiting for init *)
  294.           rpack := 'N';                      (* treat as NAK *)
  295.           exit(rpack)                        (* and get out of here *)
  296.         end; (* if *)
  297.  
  298.     if not getch(r) then                (* get a char and *)
  299.             goto 1;                        (* resynch if soh *)
  300.  
  301.     ichksum := r.i;                        (* start checksum *)
  302.     len := ord(unchar(r.ch)) - 3;          (* character count *)
  303.  
  304.     if not getch(r) then                (* get a char and *)
  305.         goto 1;                            (* resynch if soh *)
  306.     ichksum := ichksum + r.i;
  307.     num := ord(unchar(r.ch));              (* packet number *)
  308.  
  309.     if not getch(r) then                (* get a char and *)
  310.         goto 1;                            (* resynch if soh *)
  311.     ichksum := ichksum + r.i;
  312.     ptype := r.ch;                         (* packet type *)
  313.  
  314.     for i := 0 to len-1 do                 (* get any data *)
  315.       begin
  316.         if not getch(r) then            (* get a char and *)
  317.             goto 1;                        (* resynch if soh *)
  318.         ichksum := ichksum + r.i;
  319.         data[i] := r.ch;
  320.       end; (* for i *)
  321.     data[len] := chr(0);                   (* mark end of data *)
  322.  
  323.     if not getch(r) then                (* get a char and *)
  324.         goto 1;                            (* resynch if soh *)
  325.  
  326.                                            (* compute final checksum *)
  327.     chksum := chr(aand(ichksum + (aand(ichksum,192) div 64), 63));
  328.  
  329.     if (chksum <> unchar(r.ch)) then       (* if checksum bad *)
  330.         rpack := chr(0)                      (* return 'false' indicator *)
  331.     else                                   (* else *)
  332.         rpack := ptype;                      (* return packet type *)
  333.  
  334.     if debug then
  335.       begin
  336.         gotoxy(0,debugline);
  337.         write(len,num,ptype);
  338.         for i := 1 to 1000 do
  339.             ;
  340.       end; (* if *)
  341.   end; (* rpack *)
  342.  
  343. (*$G-*) (* turn off goto option...don't need it anymore *)
  344.  
  345.  
  346. end. { kermpack }
  347.  
  348.  
  349.