home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / SYSPC22.ZIP / SUBS2.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-05-13  |  23.7 KB  |  1,104 lines

  1. const ingetstr:boolean=false;
  2.  
  3. procedure specialmsg (q:anystr);
  4. begin
  5.   pushdevice;
  6.   textcolor (outlockcolor);
  7.   writeln (usr,q);
  8.   if not modemoutlock then textcolor (normbotcolor);
  9.   popdevice
  10. end;
  11.  
  12. PROCEDURE XMITBLK (jack:anystr);
  13. var cnt:integer;
  14. begin
  15. if  carrier then begin
  16. for cnt:=1 to length(jack) do begin
  17. sendchar (jack[cnt]);end;
  18. end;
  19. end;
  20.  
  21. procedure ansicls;
  22. begin
  23. clrscr;
  24. xmitblk (#27+'[2J');
  25. end;
  26.  
  27. procedure bottomline;
  28. var o:integer;
  29.  
  30. begin
  31.   if inuse=0 then exit;
  32.   pushdevice;
  33.   o:=inuse;
  34.   wholescreen;
  35.   gotoxy (1,24);
  36.   textcolor (0);
  37.   textbackground (statlinecolor);
  38.   if timelock then settimeleft (lockedtime);
  39.   write (usr,'[',unam,'] [',urec.phonenum,'] [',timeleft,' left]');
  40.   if chatmode
  41.     then write (usr,' CHAT!')
  42.     else write (usr,' [',sysopavailstr,']');
  43.   if urec.numon>1 then write (usr,' [Last on ',lastonda,']') else
  44.   write (usr,' [First Login]');
  45.   clreol;
  46.   gotoxy (1,25);
  47.   write (usr,'[Lvl:',ulvl,'] [F-Lvl:',urec.udlevel,'] [GF-Lvl:',urec.gflvl,']');
  48.   if timelock then write (usr,' [Timelock]');
  49.   if modeminlock then write (usr,' [InLock]');
  50.   if modemoutlock then write (usr,' [OutLock]');
  51.   if tempsysop then write (usr,' [Sysop]');
  52. (*  if texttrap then write (usr,' [Trap]');
  53.   if printerecho then write (usr,' [Print]'); *)
  54.   clreol;
  55.   usewind (o);
  56.   popdevice
  57. end;
  58.  
  59. function hungupon {:boolean};
  60. begin
  61.   hungupon:=online and not (carrier or modeminlock or modemoutlock)
  62. end;
  63.  
  64. function ansi:boolean;
  65.  begin
  66.    ansi:=(ansigraphics in urec.config);
  67.  end;
  68.  
  69. procedure beepbeep;
  70. begin
  71. {  nosound;
  72.   sound (200);
  73.   delay (10);
  74.   nosound  }
  75. end;
  76.  
  77. procedure movexy (x,y:integer);
  78. var b:boolean;
  79.    joe:lstr;
  80. begin
  81.   y:=y-1;
  82.     write (^B+#27+'['+strr(y)+';'+strr(x)+'H');
  83. end;
  84.  
  85. procedure summonbeep;
  86. var cnt:integer;
  87. begin
  88.   nosound;
  89.   cnt:=1330;
  90.   repeat
  91.     sound (cnt);
  92.     delay (10);
  93.     cnt:=cnt+200;
  94.   until cnt>4300;
  95.   nosound
  96. end;
  97.  
  98. procedure abortttfile (er:integer);
  99. var n:integer;
  100. begin
  101.   specialmsg ('<Texttrap error '+strr(er)+'>');
  102.   texttrap:=false;
  103.   textclose (ttfile);
  104.   n:=ioresult
  105. end;
  106.  
  107. procedure openttfile;
  108. var n:integer;
  109. begin
  110.   appendfile ('Texttrap',ttfile);
  111.   n:=ioresult;
  112.   if n=0
  113.     then begin
  114.     texttrap:=true;
  115.     specialmsg ('(Text trap on)')
  116.     end
  117.     else abortttfile (n)
  118. end;
  119.  
  120. procedure clearbreak;
  121. begin
  122.   break:=false;
  123.   xpressed:=false;
  124.   dontstop:=false;
  125.   nobreak:=false
  126. end;
  127.  
  128. procedure ansicolor (attrib:byte);
  129. var tc:byte;
  130.     b:boolean;
  131. const colorid:array [0..7] of byte=(30,34,32,36,31,35,33,37);
  132. begin
  133.   if not (ansigraphics in urec.config) or (attrib=0) or (usecapsonly)
  134.      or (attrib=curattrib) or break then exit;
  135.   curattrib:=attrib;
  136.   pushdevice;
  137.   b:=nobreak;
  138.   nobreak:=true;
  139.   write (#27'[0');
  140.   tc:=attrib and 7;
  141.  if tc<>7 then write (';',colorid[tc]);
  142.   tc:=(attrib shr 4) and 7;
  143.   if tc<>0 then write (';',colorid[tc]+10);
  144.   if (attrib and 8)=8 then write (';1');
  145.   if (attrib and 128)=128 then write (';5');
  146.   write ('m');
  147.   nobreak:=b;
  148.   popdevice
  149. end;
  150.  
  151. procedure ansireset;
  152. var b:boolean;
  153. begin
  154.   if usecapsonly then exit;
  155.   if urec.regularcolor<>0 then begin
  156.     ansicolor (urec.regularcolor);
  157.     exit
  158.   end;
  159.   if (not (ansigraphics in urec.config)) or (curattrib=0) or break then exit;
  160.   pushdevice;
  161.   b:=nobreak;
  162.   nobreak:=true;
  163.   write (#27'[0m');
  164.   curattrib:=0;
  165.   nobreak:=b;
  166.   popdevice
  167. end;
  168.  
  169. procedure writeturbo (* (k:char) *);
  170. begin
  171.   inline ($8A/$86/k/$50/$ff/$16/turbooutptr)
  172. end;
  173.  
  174. procedure writecon (k:char);
  175. var r:regs;
  176. begin
  177.   if (k=^J) or (not useconmode) then writeturbo (k) else begin
  178.     r.dl:=ord(k);
  179.     r.ah:=2;
  180.     intr($21,r)
  181.   end
  182. end;
  183.  
  184. procedure writeusr (k:char);
  185. begin
  186.   inline ($8A/$86/k/$50/$ff/$16/usroutptr)
  187. end;
  188.  
  189. procedure writelst (k:char);
  190. begin
  191.   inline ($8A/$86/k/$50/$ff/$16/lstoutptr)
  192. end;
  193.  
  194. procedure writeaux (k:char);
  195. begin
  196.   inline ($8A/$86/k/$50/$ff/$16/auxoutptr)
  197. end;
  198.  
  199. procedure toggleavail;
  200. begin
  201.   if sysopavail=notavailable
  202.     then sysopavail:=available
  203.     else sysopavail:=succ(sysopavail)
  204. end;
  205.  
  206. function keyhit:boolean;
  207. var r:regs;
  208. begin
  209.   r.ah:=1;
  210.   intr ($16,r);
  211.   keyhit:=(r.flags and 64)=0
  212. end;
  213.  
  214. function charready (* :boolean *) ;
  215. var k:char;
  216. begin
  217.   if modeminlock then while numchars>0 do k:=getchar;
  218.   if hungupon or keyhit
  219.     then charready:=true
  220.     else if online
  221.       then charready:=(not modeminlock) and (numchars>0)
  222.       else charready:=false
  223. end;
  224.  
  225. function bioskey:char;
  226. var r:regs;
  227. begin
  228.   r.ah:=0;
  229.   intr ($16,r);
  230.   if r.al=0
  231.     then bioskey:=chr(r.ah+128)
  232.     else bioskey:=chr(r.al)
  233. end;
  234.  
  235. procedure setoutlock (b:boolean);
  236. begin
  237.   modemoutlock:=b;
  238.   if b
  239.     then winds[2].color:=outlockcolor
  240.     else winds[2].color:=normbotcolor;
  241.   if inuse=2 then usewind (2)
  242. end;
  243.  
  244. function readchar (* :char   FORWARD *) ;
  245.  
  246.   overlay procedure toggletempsysop;
  247.   begin
  248.     if tempsysop
  249.       then ulvl:=regularlevel
  250.       else
  251.         begin
  252.           regularlevel:=ulvl;
  253.           ulvl:=sysoplevel
  254.         end;
  255.     tempsysop:=not tempsysop
  256.   end;
  257.  
  258.   overlay procedure togviewstats;
  259.   begin
  260.     pushdevice;
  261.     if splitmode
  262.       then unsplit
  263.       else
  264.         begin
  265.           splitscreen (7);
  266.           top;
  267.           clrscr;
  268.           write (usr,'File Level:  ',urec.udlevel,
  269.                  ^M^J'File Points: ',urec.udpoints,
  270.                  ^M^J'Uploads:     ',urec.uploads,
  271.                  ^M^J'Downloads:   ',urec.downloads);
  272.           window (40,1,80,5);
  273.           gotoxy (1,1);
  274.           write (usr,'Posts:       ',urec.nbu,
  275.                  ^M^J'Uploads:     ',urec.gfup,
  276.                  ^M^J'Downloads:   ',urec.gfdown,
  277.                  ^M^J'Total Time:  ',urec.totaltime:0:0,
  278.                  ^M^J'Num. calls:  ',urec.numon);
  279.           window (1,1,80,5);
  280.           bottom
  281.         end;
  282.     popdevice
  283.   end;
  284.  
  285.   overlay procedure showhelp;
  286.   begin
  287.     pushdevice;
  288.     if splitmode
  289.       then unsplit
  290.       else begin
  291.         splitscreen (10);
  292.         top;
  293.         clrscr;
  294.         write (usr,
  295. 'Chat with user: F1               Sysop commands: F2'^M^J,
  296. 'Lock the timer: F8               Lock out all modem input: F9'^M^J,
  297. 'Lock all modem output: F10       View users''s status: Alt-V'^M^J,
  298. 'Chat availabily toggle: Alt-A    Grant temporary sysop powers: Alt-T'^M^J,
  299. 'Grant user more time: Alt-M      Take away user''s time: Alt-L'^M^J,
  300. 'Take away ALL time: Alt-K        Refresh the bottom line: Alt-B'^M^J,
  301. 'Toggle printer echo: Ctrl-PrtSc  Toggle text trap: Alt-E');
  302.  
  303.     end;
  304.     popdevice
  305.   end;
  306.  
  307.   overlay procedure toggletexttrap;
  308.   var n:integer;
  309.   begin
  310.     if texttrap
  311.       then
  312.         begin
  313.           textclose (ttfile);
  314.           n:=ioresult;
  315.           if n<>0 then abortttfile (n);
  316.           texttrap:=false
  317.         end
  318.       else openttfile
  319.   end;
  320.  
  321. var k:char;
  322.     ret:char;
  323.     dorefresh:boolean;
  324. begin
  325.   requestchat:=false;
  326.   requestcom:=false;
  327.   reqspecial:=false;
  328.   if keyhit
  329.     then
  330.       begin
  331.         k:=bioskey;
  332.         ret:=k;
  333.         if ord(k)>127 then begin
  334.           ret:=#0;
  335.           dorefresh:=ingetstr;
  336.           case ord(k)-128 of
  337.             availtogglechar:
  338.               begin
  339.                 toggleavail;
  340.                 chatmode:=false;
  341.                 dorefresh:=true
  342.               end;
  343.             sysopcomchar:
  344.               begin
  345.                 requestcom:=true;
  346.                 requestchat:=true
  347.               end;
  348.             breakoutchar:breakout;
  349.             lesstimechar:urec.timetoday:=urec.timetoday-1;
  350.             moretimechar:urec.timetoday:=urec.timetoday+1;
  351.             notimechar:settimeleft (-1);
  352.             chatchar:requestchat:=true;
  353.             sysnextchar:sysnext:=not sysnext;
  354.             timelockchar:if timelock then timelock:=false else begin
  355.                            timelock:=true;
  356.                            lockedtime:=timeleft
  357.                          end;
  358.             inlockchar:modeminlock:=not modeminlock;
  359.             outlockchar:setoutlock (not modemoutlock);
  360.             tempsysopchar:toggletempsysop;
  361.             bottomchar:bottomline;
  362.             viewstatchar:togviewstats;
  363.             sysophelpchar:if dorefresh then showhelp;
  364.             texttrapchar:toggletexttrap;
  365.             printerechochar:printerecho:=not printerecho;
  366.             72:ret:=^E;
  367.             75:ret:=^S;
  368.             77:ret:=^D;
  369.             80:ret:=^X;
  370.             115:ret:=^A;
  371.             116:ret:=^F;
  372.             73:ret:=^R;
  373.             81:ret:=^C;
  374.             71:ret:=^Q;
  375.             79:ret:=^W;
  376.             83:ret:=^G;
  377.             82:ret:=^V;
  378.             117:ret:=^P;
  379.           end;
  380.           if dorefresh then bottomline
  381.         end
  382.       end
  383.     else
  384.       begin
  385.         k:=getchar;
  386.         if modeminlock
  387.           then ret:=#0
  388.           else ret:=k
  389.       end;
  390.   if ret='+' then write (' '^H);
  391.   readchar:=ret
  392. end;
  393.  
  394. function waitforchar:char;
  395. var t:integer;
  396.     k:char;
  397. begin
  398.   t:=timer+mintimeout;
  399.   if t>=1440 then t:=t-1440;
  400.   repeat
  401.     if timer=t then disconnect
  402.   until charready;
  403.   waitforchar:=readchar
  404. end;
  405.  
  406. procedure clearchain;
  407. begin
  408.   chainstr[0]:=#0
  409. end;
  410.  
  411. function charpressed (k:char):boolean;  { TRUE if K is in typeahead }
  412. begin
  413.   charpressed:=pos(k,chainstr)>0
  414. end;
  415.  
  416. procedure addtochain (l:lstr);
  417. begin
  418.   if length(chainstr)<>0 then chainstr:=chainstr+',';
  419.   chainstr:=chainstr+l
  420. end;
  421.  
  422. procedure writechar (k:char);
  423. var sendtomodem:boolean;
  424.  
  425.   procedure normalchar (k:char);
  426.   var n:integer;
  427.   begin
  428.     if inuse<>1
  429.       then writecon (k)
  430.       else begin
  431.         bottom;
  432.         writecon (k);
  433.         top
  434.       end;
  435.     if wherey>lasty then begin
  436.       gotoxy (wherex,lasty);
  437.       writeturbo (^J)
  438.     end;
  439.     if sendtomodem then sendchar (k);
  440.     if texttrap then begin
  441.       pushdevice;
  442.       write (ttfile,k);
  443.       popdevice;
  444.       n:=ioresult;
  445.       if n<>0 then abortttfile (n)
  446.     end;
  447.     if printerecho then writelst (k)
  448.   end;
  449.  
  450.   procedure endofline;
  451.  
  452.     procedure write13 (k:char);
  453.     var n:integer;
  454.     begin
  455.       for n:=1 to 13 do normalchar (k)
  456.     end;
  457.  
  458.   var b:boolean;
  459.   begin
  460.     normalchar (#13);
  461.     b:=sendtomodem;
  462.     sendtomodem:=sendtomodem and uselinefeeds;
  463.     normalchar (#10);
  464.     sendtomodem:=b;
  465.     if timelock then settimeleft (lockedtime);
  466.     if curattrib=urec.statcolor then ansicolor (urec.regularcolor);
  467.     linecount:=linecount+1;
  468.     if (linecount>=urec.displaylen-1) and (not dontstop)
  469.           and (moreprompts in urec.config) then begin
  470.       linecount:=1;
  471.       pushdevice;
  472.       write ('More (Y/N/C)?');
  473.       repeat
  474.         k:=upcase(waitforchar)
  475.       until (k in [^M,' ','C','N','Y']) or hungupon;
  476.       write13 (^H);
  477.       write13 (' ');
  478.       write13 (^H);
  479.       popdevice;
  480.       if k='N' then break:=true else if k='C' then dontstop:=true
  481.     end
  482.   end;
  483.  
  484.   procedure handleincoming;
  485.   var k:char;
  486.   begin
  487.     k:=readchar;
  488.     case upcase(k) of
  489.       'X',^X,^K,^C,#27,' ':begin
  490.         nobreak:=true;
  491.         writeln;
  492.         nobreak:=false;
  493.         break:=true;
  494.         linecount:=0;
  495.         xpressed:=(upcase(k)='X') or (k=^X);
  496.         if xpressed then clearchain
  497.       end;
  498.       ^S:k:=waitforchar;
  499.       else if length(chainstr)<255 then chainstr:=chainstr+k
  500.     end
  501.   end;
  502.  
  503. begin
  504.   if hungupon then exit;
  505.   sendtomodem:=online and (not modemoutlock);
  506.   if k<=^Z then
  507.     case k of
  508.       ^J,#0:exit;
  509.       ^Q:k:=^H;
  510.       ^B:begin
  511.            clearbreak;
  512.            exit
  513.          end
  514.      end;
  515.    if break then exit;
  516.    if k<=^Z then begin
  517.      case k of
  518.        ^G:beepbeep;
  519.        ^L:cls;
  520.        ^N,^R:ansireset;
  521.        ^S:ansicolor (urec.statcolor);
  522.        ^P:ansicolor (urec.promptcolor);
  523.        ^U:ansicolor (urec.inputcolor);
  524.        ^H:normalchar (k);
  525.        ^M:endofline
  526.      end;
  527.      exit
  528.    end;
  529.    if usecapsonly then k:=upcase(k);
  530.    normalchar (k);
  531.    if (keyhit or ((not modemoutlock) and online and (numchars>0)))
  532.      and (not nobreak) then handleincoming
  533. end;
  534.  
  535. procedure getstr;
  536. var marker,cnt:integer;
  537.     p:byte absolute input;
  538.     k:char;
  539.     oldinput,s:anystr;
  540.     done,wrapped:boolean;
  541.     wordtowrap:lstr;
  542.  
  543.   procedure bkspace;
  544.  
  545.     procedure bkwrite (q:sstr);
  546.     begin
  547.       write (q);
  548.       if splitmode and dots then write (usr,q)
  549.     end;
  550.  
  551.   begin
  552.     if p<>0
  553.       then
  554.         begin
  555.           if input[p]=^Q
  556.             then bkwrite (' ')
  557.             else bkwrite (k+' '+k);
  558.           p:=p-1
  559.         end
  560.       else if wordwrap
  561.         then
  562.           begin
  563.             input:=k;
  564.             done:=true
  565.           end
  566.   end;
  567.  
  568.   procedure sendit (k:char; n:integer);
  569.   var temp:anystr;
  570.   begin
  571.     temp[0]:=chr(n);
  572.     fillchar (temp[1],n,k);
  573.     nobreak:=true;
  574.     write (temp)
  575.   end;
  576.  
  577.   procedure superbackspace (r1:integer);
  578.   var cnt,n:integer;
  579.   begin
  580.     n:=0;
  581.     for cnt:=r1 to p do
  582.       if input[cnt]=^Q
  583.         then n:=n-1
  584.         else n:=n+1;
  585.     if n<0 then sendit (' ',-n) else begin
  586.       sendit (^H,n);
  587.       sendit (' ',n);
  588.       sendit (^H,n)
  589.     end;
  590.     p:=r1-1
  591.   end;
  592.  
  593.   procedure cancelent;
  594.   begin
  595.     superbackspace (1)
  596.   end;
  597.  
  598.   function findspace:integer;
  599.   var s:integer;
  600.   begin
  601.     s:=p;
  602.     while (input[s]<>' ') and (s>0) do s:=s-1;
  603.     findspace:=s
  604.   end;
  605.  
  606.   procedure wrapaword (q:char);
  607.   var s:integer;
  608.   begin
  609.     done:=true;
  610.     if q=' ' then exit;
  611.     s:=findspace;
  612.     if s=0 then exit;
  613.     wrapped:=true;
  614.     wordtowrap:=copy(input,s+1,255)+q;
  615.     superbackspace (s)
  616.   end;
  617.  
  618.   procedure deleteword;
  619.   var s,n:integer;
  620.   begin
  621.     if p=0 then exit;
  622.     s:=findspace;
  623.     if s<>0 then s:=s-1;
  624.     n:=p-s;
  625.     p:=s;
  626.     sendit (^H,n);
  627.     sendit (' ',n);
  628.     sendit (^H,n)
  629.   end;
  630.  
  631.   procedure addchar (k:char);
  632.   begin
  633.     if p<buflen
  634.       then if (k<>' ') or (p>0) or wordwrap
  635.         then
  636.           begin
  637.             p:=p+1;
  638.             input[p]:=k;
  639.             if dots
  640.               then
  641.                 begin
  642.                   writechar (dotchar);
  643.                   if splitmode then writeusr (k)
  644.                 end
  645.              else if echo then writechar (k)
  646.           end
  647.         else
  648.       else if wordwrap then wrapaword (k)
  649.   end;
  650.  
  651.   procedure repeatent;
  652.   var cnt:integer;
  653.   begin
  654.     for cnt:=1 to length(oldinput) do addchar (oldinput[cnt])
  655.   end;
  656.  
  657.   procedure tab;
  658.   var n,c:integer;
  659.   begin
  660.     n:=(p+8) and 248;
  661.     if n>buflen then n:=buflen;
  662.     for c:=1 to n-p do addchar (' ')
  663.   end;
  664.  
  665.   procedure getinput;
  666.  
  667.     function getinputchar:char;
  668.     var k:char;
  669.     begin
  670.       if length(chainstr)=0 then begin
  671.         getinputchar:=waitforchar;
  672.         exit
  673.       end;
  674.       k:=chainstr[1];
  675.       delete (chainstr,1,1);
  676.       if (k=',') and (not nochain) then k:=#13;
  677.       getinputchar:=k
  678.     end;
  679.  
  680.   begin
  681.     oldinput:=input;
  682.     ingetstr:=true;
  683.     done:=false;
  684.     bottomline;
  685.     if splitmode and dots then top;
  686.     p:=0;
  687.     repeat
  688.       clearbreak;
  689.       nobreak:=true;
  690.       k:=getinputchar;
  691.       if hungupon then begin
  692.         input:='';
  693.         k:=#13;
  694.         done:=true
  695.       end;
  696.       case k of
  697.         ^I:tab;
  698.         ^H:bkspace;
  699.         ^M:begin
  700.            if endp then begin
  701.            dots:=false;
  702.            ansicolor (urec.promptcolor);
  703.            addchar (']');
  704.            end;
  705.            done:=true;
  706.            end;
  707.         ^R:repeatent;
  708.         ^X,#27:cancelent;
  709.         ^W:deleteword;
  710.         ' '..'~':addchar (k);
  711.         ^Q:if wordwrap and bkspinmsgs then addchar (k)
  712.       end;
  713.       if requestchat then begin
  714.         p:=0;
  715.         writeln (^B^N^M^M^B);
  716.         chat (requestcom);
  717.         write (^B^M^M^P,lastprompt);
  718.         requestchat:=false
  719.       end
  720.     until done;
  721.     if endp then begin
  722.     s:=input;
  723.     s:=copy(s,1,length(s)-1);
  724.     input:=s;
  725.     endp:=false;
  726.     end;
  727.     writeln;
  728.     if splitmode and dots then begin
  729.       writeln (usr);
  730.       bottom
  731.     end;
  732.     ingetstr:=false;
  733.     ansireset
  734.   end;
  735.  
  736.   procedure divideinput;
  737.   var p:integer;
  738.   begin
  739.     p:=pos(',',input);
  740.     if p=0 then exit;
  741.     addtochain (copy(input,p+1,255)+#13);
  742.     input[0]:=chr(p-1)
  743.   end;
  744.  
  745. begin
  746.   che;
  747.   clearbreak;
  748.   linecount:=1;
  749.   wrapped:=false;
  750.   nochain:=nochain or wordwrap;
  751.   ansicolor (urec.inputcolor);
  752.   getinput;
  753.   if not nochain then divideinput;
  754.   while input[length(input)]=' ' do input[0]:=pred(input[0]);
  755.   if not wordwrap then
  756.     while (length(input)>0) and (input[1]=' ') do delete (input,1,1);
  757.   if wrapped then chainstr:=wordtowrap;
  758.   wordwrap:=false;
  759.   nochain:=false;
  760.   dots:=false;
  761.   buflen:=80;
  762.   linecount:=1
  763. end;
  764.  
  765. procedure readline (var xx);
  766. var a:anystr absolute xx;
  767.     t1,t2,t3:integer;
  768. begin
  769.   t1:=coninptr;
  770.   t2:=conoutptr;
  771.   t3:=constptr;
  772.   coninptr:=turboinptr;
  773.   conoutptr:=turbooutptr;
  774.   constptr:=ofs(keyhit);
  775.   readln (a);
  776.   coninptr:=t1;
  777.   conoutptr:=t2;
  778.   constptr:=t3
  779. end;
  780.  
  781. procedure writestr (* (s:anystr)  FORWARD *) ;
  782. var k:char;
  783.     ex:boolean;
  784. begin
  785.   che;
  786.   clearbreak;
  787.   ansireset;
  788.   uselinefeeds:=linefeeds in urec.config;
  789.   usecapsonly:=not (lowercase in urec.config);
  790.   k:=s[length(s)];
  791.   s:=copy(s,1,length(s)-1);
  792.   endp:=false;
  793.   case k of
  794.     ':':begin
  795.           write (^P,s,': ');
  796.           lastprompt:=s+': ';
  797.           getstr
  798.         end;
  799.     ';':write (s);
  800.     '*':begin
  801.           endp:=true;
  802.           write (^P,s,'[');
  803.           lastprompt:=s;
  804.           getstr
  805.         end;
  806.     '@':begin
  807.           write (^P,s);
  808.           lastprompt:=s;
  809.           getstr
  810.         end;
  811.     '&':begin
  812.           nochain:=true;
  813.           write (^P,s);
  814.           lastprompt:=s;
  815.           getstr
  816.         end
  817.     else writeln (s,k)
  818.   end;
  819.   clearbreak
  820. end;
  821.  
  822. procedure cls;
  823. begin
  824.   bottom;
  825.   clrscr;
  826.   bottomline
  827. end;
  828.  
  829. procedure writehdr (q:anystr);
  830. var cnt:integer;
  831. begin
  832.   writeln (^B^M);
  833.   for cnt:=1 to (40-length(q)) div 2 do write (' ');
  834.   write (q,^M^M^B)
  835. end;
  836.  
  837. function issysop:boolean;
  838. begin
  839.   issysop:=(ulvl>=sysoplevel) or (cursection in urec.config)
  840. end;
  841.  
  842. procedure reqlevel (l:integer);
  843. begin
  844.   writeln (^B'Nice try, but level ',l,' is required.')
  845. end;
  846.  
  847. procedure printfile (fn:lstr);
  848.  
  849.   procedure getextension (var fname:mstr);
  850.  
  851.     procedure tryfiles (a,b,c,d:integer);
  852.     var q:boolean;
  853.  
  854.       function tryfile (n:integer):boolean;
  855.       const exts:array [1..4] of string[3]=('','ANS','ASC','40');
  856.       begin
  857.         if not exist (fname+'.'+exts[n]) then tryfile:=false else begin
  858.           tryfile:=true;
  859.           fname:=fname+'.'+exts[n]
  860.         end
  861.       end;
  862.  
  863.     begin
  864.       if tryfile (a) then exit;
  865.       if tryfile (b) then exit;
  866.       if tryfile (c) then exit;
  867.       q:=tryfile (d)
  868.     end;
  869.  
  870.   begin
  871.     if pos ('.',fname)<>0 then exit;
  872.     if ansigraphics in urec.config  then tryfiles (2,3,1,4) else
  873.     if asciigraphics in urec.config then tryfiles (3,1,4,2) else
  874.     if eightycols in urec.config    then tryfiles (1,4,3,2) else
  875.                                          tryfiles (4,1,3,2)
  876.   end;
  877.  
  878. var tf:text;
  879.     k:char;
  880. begin
  881.   clearbreak;
  882.   writeln;
  883.   getextension (fn);
  884.   assign (tf,fn);
  885.   reset (tf);
  886.   iocode:=ioresult;
  887.   if iocode<>0 then begin
  888.     fileerror ('Printfile',fn);
  889.     exit
  890.   end;
  891.   clearbreak;
  892.   while not (eof(tf) or break or hungupon) do
  893.     begin
  894.       read (tf,k);
  895.       write (k)
  896.     end;
  897.   if break then writeln (^B);
  898.   writeln;
  899.   textclose (tf);
  900.   curattrib:=0;
  901.   ansireset
  902. end;
  903.  
  904.  
  905. overlay procedure windowit(x,y,a,b:integer);
  906. var
  907. z,c:integer;
  908. begin
  909.  movexy(a,b);
  910.  write ('┌');
  911.  for z:=1 to x-2 do write ('─');
  912.  write ('┐');
  913.  c:=1;
  914.  repeat
  915.  movexy (a,(b+c));
  916.  write ('│');
  917.  movexy ((a+x-1),(b+c));
  918.  write ('│');
  919.  c:=c+1;
  920.  until c>=(y-1);
  921.  movexy (a,(b+y-1));
  922.  write ('└');
  923.  for z:=1 to (x-2) do write ('─');
  924.  write ('┘');
  925.  end;
  926.  
  927. overlay procedure printtexttopoint (var tf:text);
  928. var l:lstr;
  929. begin
  930.   l:='';
  931.   clearbreak;
  932.   while not (eof(tf) or hungupon) and (l<>'.') do begin
  933.     if not break then writeln (l);
  934.     readln (tf,l)
  935.   end
  936. end;
  937.  
  938. overlay procedure skiptopoint (var tf:text);
  939. var l:lstr;
  940. begin
  941.   l:='';
  942.   while not eof(tf) and (l<>'.') do
  943.     readln (tf,l)
  944. end;
  945.  
  946.  
  947.  
  948. overlay function minstr (blocks:integer):sstr;
  949. var min,sec:integer;
  950.     rsec:real;
  951.     ss:sstr;
  952. begin
  953.   rsec:=1.38 * blocks * (1200/baudrate);
  954.   min:=trunc (rsec/60.0);
  955.   sec:=trunc (rsec-(min*60.0));
  956.   ss:=strr(sec);
  957.   if length(ss)<2 then ss:='0'+ss;
  958.   minstr:=strr(min)+':'+ss
  959. end;
  960.  
  961. overlay procedure parserange (numents:integer; var f,l:integer);
  962. var rf,rl:mstr;
  963.     p,v1,v2:integer;
  964. begin
  965.   f:=0;
  966.   l:=0;
  967.   if numents<1 then exit;
  968.   repeat
  969.     writestr ('Range [1-'+strr(numents)+', CR=all, ?=help]:');
  970.     if input='?' then printfile ('Rangehlp');
  971.     if (length(input)>0) and (upcase(input[1])='Q') then exit
  972.   until (input<>'?') or hungupon;
  973.   if hungupon then exit;
  974.   if length(input)=0 then begin
  975.     f:=1;
  976.     l:=numents
  977.   end else begin
  978.     p:=pos('-',input);
  979.     v1:=valu(copy(input,1,p-1));
  980.     v2:=valu(copy(input,p+1,255));
  981.     if p=0 then begin
  982.       f:=v2;
  983.       l:=v2
  984.     end else if p=1 then begin
  985.       f:=1;
  986.       l:=v2
  987.     end else if p=length(input) then begin
  988.       f:=v1;
  989.       l:=numents
  990.     end else begin
  991.       f:=v1;
  992.       l:=v2
  993.     end
  994.   end;
  995.   if (f<1) or (l>numents) or (f>l) then begin
  996.     f:=0;
  997.     l:=0;
  998.     writestr ('Invalid range!')
  999.   end;
  1000.   writeln (^B)
  1001. end;
  1002.  
  1003. overlay function menu (mname:mstr; mfn:sstr; choices:anystr):integer;
  1004. var k:char;
  1005.     sysmenu,percent,needsys:boolean;
  1006.     n,p,i:integer;
  1007.     prompt:lstr;
  1008.  
  1009. begin
  1010.   sysmenu:=false;
  1011.   percent:=false;
  1012.   fin:=true;
  1013.   for p:=1 to length(choices)-1 do
  1014.     if choices[p]='%'
  1015.       then if choices[p+1]='@'
  1016.         then percent:=true
  1017.         else
  1018.       else if choices[p+1]='@'
  1019.         then sysmenu:=true;
  1020.   writeln (^B);
  1021.   repeat
  1022.     if chatmode
  1023.       then for n:=1 to 3 do summonbeep;
  1024.     if (timeleft<1) or (timetillevent<=3) then begin
  1025.       printfile (textfiledir+'Timesup');
  1026.       if not hungupon then disconnect;
  1027.       menu:=0;
  1028.       exit
  1029.     end;
  1030.     if usedit then
  1031.     prompt:='[Edit: '+edit_user+'] Command (?=help' else
  1032.     prompt:='['+mname+' menu] Command (?=help';
  1033.     if percent and issysop then prompt:=prompt+', %=sysop';
  1034.     prompt:=prompt+'): ';
  1035.     writeln(^P'['+strr(timeleft)+'] minutes remaining');
  1036.     writestr (prompt+'*');
  1037.     n:=0;
  1038.    if length(input)=0
  1039.       then k:='_'
  1040.       else
  1041.         begin
  1042.           if match(input,'/OFF') then begin
  1043.            disconnect;
  1044.             menu:=0;
  1045.             exit
  1046.           end;
  1047.           n:=valu(input);
  1048.           if n>0
  1049.             then k:='#'
  1050.             else k:=upcase(input[1]);
  1051.           mnu:=false;
  1052.         end;
  1053.     p:=1;
  1054.     i:=1;
  1055.     if k='?'
  1056.       then
  1057.         begin
  1058.           printfile (textfiledir+mfn+'M');
  1059.           if sysmenu and issysop then printfile (textfiledir+mfn+'S')
  1060.         end
  1061.       else
  1062.         while p<=length(choices) do begin
  1063.           needsys:=false;
  1064.           if p<length(choices)
  1065.             then if choices[p+1]='@'
  1066.               then needsys:=true;
  1067.           if upcase(choices[p])=k
  1068.             then if needsys and (not issysop)
  1069.               then
  1070.                 begin
  1071.                   reqlevel (sysoplevel);
  1072.                   p:=255;
  1073.                   needsys:=false
  1074.                 end
  1075.               else p:=256
  1076.             else
  1077.               begin
  1078.                 p:=p+1;
  1079.                 if needsys then p:=p+1;
  1080.                 i:=i+1
  1081.               end
  1082.         end
  1083.   until (p=256) or hungupon;
  1084.   writeln (^B^M);
  1085.   if hungupon
  1086.     then menu:=0
  1087.     else
  1088.       if k='#' then menu:=-n else menu:=i
  1089. end;
  1090.  
  1091. var wasopen:boolean;
  1092. procedure opentempbdfile; { FORWARD }
  1093. begin
  1094.   wasopen:=isopen(bdfile);
  1095.   if not wasopen then openbdfile
  1096. end;
  1097.  
  1098. procedure closetempbdfile; { FORWARD }
  1099. begin
  1100.   if not wasopen then closebdfile
  1101. end;
  1102.  
  1103.  
  1104.