home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / WWIV2.ZIP / CONIO.C < prev    next >
C/C++ Source or Header  |  1992-12-30  |  43KB  |  1,809 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1993 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15.  
  16.  
  17. #include "vars.h"
  18.  
  19. #pragma hdrstop
  20.  
  21. #include <mem.h>
  22. #include <conio.h>
  23.  
  24.  
  25.  
  26. #define TWO_WAY
  27.  
  28. #define SCROLL_UP(t,b,l) \
  29.   _CH=t;\
  30.   _DH=b;\
  31.   _BH=curatr;\
  32.   _AL=l;\
  33.   _CL=0;\
  34.   _DL=79;\
  35.   _AH=6;\
  36.   my_video_int();
  37.  
  38.  
  39. #define GLOBAL_SIZE 4096
  40.  
  41. static char *global_buf;
  42. static int global_ptr;
  43. static int wx=0;
  44.  
  45. void my_video_int(void)
  46. {
  47. #if __TURBOC__ >= 0x0200
  48.   /* TC 2.0 or TC++ here */
  49.   static unsigned short sav_bp;
  50.  
  51.   __emit__(0x56, 0x57); /* push si, push di */
  52.   sav_bp = _BP;
  53.   geninterrupt(0x10);
  54.   _BP = sav_bp;
  55.   __emit__(0x5f, 0x5e); /* pop di, pop si */
  56. #else
  57.   /* TC 1.5 here */
  58.   _VideoInt();
  59. #endif
  60. }
  61.  
  62.  
  63. void set_global_handle(int i)
  64. {
  65.   char s[81];
  66.  
  67.   if (x_only)
  68.     return;
  69.  
  70.   if (i) {
  71.     if (!global_handle) {
  72.       sprintf(s,"%sGLOBAL.TXT",syscfg.gfilesdir);
  73.       global_handle=open(s,O_RDWR | O_APPEND | O_BINARY | O_CREAT,
  74.                            S_IREAD | S_IWRITE);
  75.       global_ptr=0;
  76.       global_buf=malloca(GLOBAL_SIZE);
  77.       if ((global_handle<0) || (!global_buf)) {
  78.         global_handle=0;
  79.         if (global_buf) {
  80.           farfree(global_buf);
  81.           global_buf=NULL;
  82.         }
  83.       }
  84.  
  85.     }
  86.   } else {
  87.     if (global_handle) {
  88.       write(global_handle,global_buf,global_ptr);
  89.       close(global_handle);
  90.       global_handle=0;
  91.       if (global_buf) {
  92.         farfree(global_buf);
  93.         global_buf=NULL;
  94.       }
  95.     }
  96.   }
  97. }
  98.  
  99.  
  100. void global_char(char ch)
  101. {
  102.  
  103.   if (global_buf && global_handle) {
  104.     global_buf[global_ptr++]=ch;
  105.     if (global_ptr==GLOBAL_SIZE) {
  106.       write(global_handle,global_buf,global_ptr);
  107.       global_ptr=0;
  108.     }
  109.   }
  110. }
  111.  
  112. void set_x_only(int tf, char *fn, int ovwr)
  113. {
  114.   static int gh;
  115.   char s[81];
  116.  
  117.   if (x_only) {
  118.     if (!tf) {
  119.       if (global_handle) {
  120.         write(global_handle,global_buf,global_ptr);
  121.         close(global_handle);
  122.         global_handle=0;
  123.         if (global_buf) {
  124.           farfree(global_buf);
  125.           global_buf=NULL;
  126.         }
  127.       }
  128.       x_only=0;
  129.       set_global_handle(gh);
  130.       gh=0;
  131.       express=expressabort=0;
  132.     }
  133.   } else {
  134.     if (tf) {
  135.       gh=global_handle;
  136.       set_global_handle(0);
  137.       x_only=1;
  138.       wx=0;
  139.       sprintf(s,"%s%s",syscfg.tempdir,fn);
  140.       if (ovwr)
  141.         global_handle=open(s,O_RDWR | O_TRUNC | O_BINARY | O_CREAT,
  142.                              S_IREAD | S_IWRITE);
  143.       else
  144.         global_handle=open(s,O_RDWR | O_APPEND | O_BINARY | O_CREAT,
  145.                              S_IREAD | S_IWRITE);
  146.       global_ptr=0;
  147.       express=1;
  148.       expressabort=0;
  149.       global_buf=farmalloc(GLOBAL_SIZE);
  150.       if ((global_handle<0) || (!global_buf)) {
  151.         global_handle=0;
  152.         if (global_buf) {
  153.           farfree(global_buf);
  154.           global_buf=NULL;
  155.         }
  156.         set_x_only(0, NULL, 0);
  157.       }
  158.     }
  159.   }
  160.   timelastchar1=timer1();
  161. }
  162.  
  163.  
  164. void movecsr(int x,int y)
  165. /* This, obviously, moves the cursor to the location specified, offset from
  166.  * the protected dispaly at the top of the screen
  167.  */
  168. {
  169.   if (x<0)
  170.     x=0;
  171.   if (x>79)
  172.     x=79;
  173.   if (y<0)
  174.     y=0;
  175.   y+=topline;
  176.   if (y>screenbottom)
  177.     y=screenbottom;
  178.  
  179.   if (x_only) {
  180.     wx=x;
  181.     return;
  182.   }
  183.  
  184.   _BH=0x00;
  185.   _DH=y;
  186.   _DL=x;
  187.   _AH=0x02;
  188.   my_video_int();
  189. }
  190.  
  191.  
  192.  
  193. int wherex(void)
  194. /* This function returns the current X cursor position, as the number of
  195.  * characters from the left hand side of the screen.  An X position of zero
  196.  * means the cursor is at the left-most position
  197.  */
  198. {
  199.   if (x_only)
  200.     return(wx);
  201.  
  202.   _BH=0x00;
  203.   _AH=0x03;
  204.   my_video_int();
  205.   tempio=_DL;
  206.   return(tempio);
  207. }
  208.  
  209.  
  210.  
  211. int wherey(void)
  212. /* This function returns the Y cursor position, as the line number from
  213.  * the top of the logical window.  The offset due to the protected top
  214.  * of the screen display is taken into account.  A wherey() of zero means
  215.  * the cursor is at the top-most position it can be at.
  216.  */
  217. {
  218.   _BH=0x00;
  219.   _AH=0x03;
  220.   my_video_int();
  221.   tempio=_DH;
  222.   return(tempio-topline);
  223. }
  224.  
  225.  
  226.  
  227. void lf(void)
  228. /* This function performs a linefeed to the screen (but not remotely) by
  229.  * either moving the cursor down one line, or scrolling the logical screen
  230.  * up one line.
  231.  */
  232. {
  233.   _BH=0x00;
  234.   _AH=0x03;
  235.   my_video_int();
  236.   tempio=_DL;
  237.   if (_DH==screenbottom) {
  238.     SCROLL_UP(topline,screenbottom,1);
  239.     _DL=tempio;
  240.     _DH=screenbottom;
  241.     _BH=0;
  242.     _AH=0x02;
  243.     my_video_int();
  244.   } else {
  245.     tempio=_DH+1;
  246.     _DH=tempio;
  247.     _AH=0x02;
  248.     my_video_int();
  249.   }
  250. }
  251.  
  252.  
  253.  
  254. void cr(void)
  255. /* This short function returns the local cursor to the left-most position
  256.  * on the screen.
  257.  */
  258. {
  259.   _BH=0x00;
  260.   _AH=0x03;
  261.   my_video_int();
  262.   _DL=0x00;
  263.   _AH=2;
  264.   my_video_int();
  265. }
  266.  
  267. void clrscrb(void)
  268. /* This clears the local logical screen */
  269. {
  270.   SCROLL_UP(topline,screenbottom,0);
  271.   movecsr(0,0);
  272.   lines_listed=0;
  273. }
  274.  
  275.  
  276.  
  277. void bs(void)
  278. /* This function moves the cursor one position to the left, or if the cursor
  279.  * is currently at its left-most position, the cursor is moved to the end of
  280.  * the previous line, except if it is on the top line, in which case nothing
  281.  * happens.
  282.  */
  283. {
  284.   _BH=0;
  285.   _AH=3;
  286.   my_video_int();
  287.   if (_DL==0) {
  288.     if (_DH != topline) {
  289.       _DL=79;
  290.       tempio=_DH-1;
  291.       _DH=tempio;
  292.       _AH=2;
  293.       my_video_int();
  294.     }
  295.   } else {
  296.     _DL--;
  297.     _AH=2;
  298.     my_video_int();
  299.   }
  300. }
  301.  
  302.  
  303.  
  304. void out1chx(unsigned char ch)
  305. /* This function outputs one character to the screen, then updates the
  306.  * cursor position accordingly, scolling the screen if necessary.  Not that
  307.  * this function performs no commands such as a C/R or L/F.  If a value of
  308.  * 8, 7, 13, 10, 12 (backspace, beep, C/R, L/F, TOF), or any other command-
  309.  * type characters are passed, the appropriate corresponding "graphics"
  310.  * symbol will be output to the screen as a normal character.
  311.  */
  312. {
  313.   _BL=curatr;
  314.   _BH=0x00;
  315.   _CX=0x01;
  316.   _AL=ch;
  317.   _AH=0x09;
  318.   my_video_int();
  319.   _BH=0x00;
  320.   _AH=0x03;
  321.   my_video_int();
  322.   ++_DL;
  323.   if (_DL==80) {
  324.     _DL=0;
  325.     if (_DH==screenbottom) {
  326.       SCROLL_UP(topline,screenbottom,1);
  327.       _DH=screenbottom;
  328.       _DL=0;
  329.       _BH=0;
  330.       _AH=0x02;
  331.       my_video_int();
  332.     } else {
  333.       tempio=_DH+1;
  334.       _DH=tempio;
  335.       _AH=0x02;
  336.       my_video_int();
  337.     }
  338.   } else {
  339.     _AH=0x02;
  340.     my_video_int();
  341.   }
  342. }
  343.  
  344.  
  345.  
  346.  
  347. void out1ch(unsigned char ch)
  348. /* This function outputs one character to the local screen.  C/R, L/F, TOF,
  349.  * BS, and BELL are interpreted as commands instead of characters.
  350.  */
  351. {
  352.   if (x_only) {
  353.     if (ch>31) {
  354.       wx=(wx+1)%80;
  355.     } else if ((ch==13) || (ch==12)) {
  356.       wx=0;
  357.     } else if (ch==8) {
  358.       if (wx)
  359.         wx--;
  360.     }
  361.     return;
  362.   }
  363.  
  364.   if (ch>31)
  365.     out1chx(ch);
  366.   else
  367.     if (ch==13)
  368.       cr();
  369.     else
  370.       if (ch==10)
  371.         lf();
  372.       else
  373.         if (ch==12)
  374.           clrscrb();
  375.         else
  376.           if (ch==8)
  377.             bs();
  378.           else
  379.             if (ch==7)
  380.               if (outcom==0) {
  381.                 setbeep(1);
  382.                 wait1(4);
  383.                 setbeep(0);
  384.               }
  385. }
  386.  
  387.  
  388. void outs(char *s)
  389. /* This (obviously) outputs a string TO THE SCREEN ONLY */
  390. {
  391.   int i;
  392.   char ch;
  393.  
  394.   for (i=0; s[i]!=0; i++) {
  395.     ch=s[i];
  396.     out1ch(ch);
  397.   }
  398. }
  399.  
  400.  
  401.  
  402. void pr_wait(int i1)
  403. {
  404.   int i,i2;
  405.   char *ss;
  406.  
  407.   ss=get_string(925);
  408.   i2=strlen(ss);
  409.  
  410.   if (i1) {
  411.     if (okansi()) {
  412.       i=curatr;
  413.       setc((thisuser.sysstatus & sysstatus_color) ? thisuser.colors[3] :
  414.             thisuser.bwcolors[3]);
  415.       outstr(ss);
  416.       npr("\x1b[%dD",i2);
  417.       setc(i);
  418.     } else {
  419.       outstr(ss);
  420.     }
  421.   } else {
  422.     if (okansi()) {
  423.       for (i=0; i<i2; i++)
  424.         outchr(' ');
  425.       npr("\x1b[%dD",i2);
  426.     } else {
  427.       for (i=0; i<i2; i++)
  428.         backspace();
  429.     }
  430.   }
  431. }
  432.  
  433.  
  434.  
  435. void set_protect(int l)
  436. /* set_protect sets the number of lines protected at the top of the screen. */
  437. {
  438.   if (l!=topline) {
  439.     if (l>topline) {
  440.       if ((wherey()+topline-l) < 0) {
  441.         _CH=topline;
  442.         _DH=screenbottom+1;
  443.         _AL=l-topline;
  444.         _CL=0;
  445.         _DL=79;
  446.         _BH=0x07;
  447.         _AH=7;
  448.         my_video_int();
  449.         movecsr(wherex(),wherey()+l-topline);
  450.       } else {
  451.         oldy += (topline-l);
  452.       }
  453.     } else {
  454.       SCROLL_UP(l,topline-1,0);
  455.       oldy += (topline-l);
  456.     }
  457.   }
  458.   topline=l;
  459.   if (using_modem)
  460.     screenlinest=thisuser.screenlines;
  461.   else
  462.     screenlinest=defscreenbottom+1-topline;
  463. }
  464.  
  465.  
  466. void savescreen(screentype *s)
  467. {
  468.   if (!s->scrn1)
  469.     s->scrn1=(char *)malloca(screenlen);
  470.  
  471.   if (s->scrn1)
  472.     memmove(s->scrn1,scrn,screenlen);
  473.  
  474.   s->x1=wherex();
  475.   s->y1=wherey();
  476.   s->topline1=topline;
  477.   s->curatr1=curatr;
  478. }
  479.  
  480.  
  481. void restorescreen(screentype far *s)
  482. /* restorescreen restores a screen previously saved with savescreen */
  483. {
  484.   if (s->scrn1) {
  485.     memmove(scrn,s->scrn1,screenlen);
  486.     farfree(s->scrn1);
  487.     s->scrn1=NULL;
  488.   }
  489.   topline=s->topline1;
  490.   curatr=s->curatr1;
  491.   movecsr(s->x1,s->y1);
  492. }
  493.  
  494.  
  495. void makewindow(int x, int y, int xlen, int ylen)
  496. /* makewindow makes a window with the upper-left hand corner at (x,y), and the
  497.    lower-right corner at (x+xlen,y+ylen) */
  498. {
  499.   int i,xx,yy;
  500.   unsigned char s[81];
  501.  
  502.   if (xlen>80)
  503.     xlen=80;
  504.   if (ylen>(screenbottom+1-topline))
  505.     ylen=(screenbottom+1-topline);
  506.   if ((x+xlen)>80)
  507.     x=80-xlen;
  508.   if ((y+ylen)>screenbottom+1)
  509.     y=screenbottom+1-ylen;
  510.  
  511.   xx=wherex();
  512.   yy=wherey();
  513.   for (i=1; i<xlen-1; i++)
  514.     s[i]=196;
  515.   s[0]=218;
  516.   s[xlen-1]=191;
  517.   s[xlen]=0;
  518.   movecsr(x,y);
  519.   outs(s);
  520.   s[0]=192;
  521.   s[xlen-1]=217;
  522.   movecsr(x,y+ylen-1);
  523.   outs(s);
  524.   for (i=1; i<xlen-1; i++)
  525.     s[i]=32;
  526.   s[0]=179;
  527.   s[xlen-1]=179;
  528.   for (i=1; i<ylen-1; i++) {
  529.     movecsr(x,i+y);
  530.     outs(s);
  531.   }
  532.   movecsr(xx,yy);
  533. }
  534.  
  535.  
  536. void editline(char *s, int len, int status, int *returncode, char *ss)
  537. /* editline edits a string, doing I/O to the screen only. */
  538. {
  539.   int i,j,k,oldatr,cx,cy,pos,ch,done,insert,i1;
  540.  
  541.   oldatr=curatr;
  542.   cx=wherex();
  543.   cy=wherey();
  544.   for (i=strlen(s); i<len; i++)
  545.     s[i]=32;
  546.   s[len]=0;
  547.   curatr=0x70;
  548.   outs(s);
  549.   movecsr(cx,cy);
  550.   done=0;
  551.   pos=0;
  552.   insert=0;
  553.   do {
  554.     ch=getchd();
  555.     if (ch==0) {
  556.       ch=getchd();
  557.       switch (ch) {
  558.         case 59:
  559.           done=1;
  560.           *returncode=DONE;
  561.           break;
  562.         case 71: pos=0; movecsr(cx,cy); break;
  563.         case 79: pos=len; movecsr(cx+pos,cy); break;
  564.         case 77: if (pos<len) {
  565.             pos++;
  566.             movecsr(cx+pos,cy);
  567.           }
  568.           break;
  569.         case 75: if (pos>0) {
  570.             pos--;
  571.             movecsr(cx+pos,cy);
  572.           }
  573.           break;
  574.         case 72:
  575.         case 15:
  576.           done=1;
  577.           *returncode=PREV;
  578.           break;
  579.         case 80:
  580.           done=1;
  581.           *returncode=NEXT;
  582.           break;
  583.         case 82:
  584.           if (status!=SET) {
  585.             if (insert)
  586.               insert=0;
  587.             else
  588.               insert=1;
  589.           }
  590.           break;
  591.         case 83:
  592.           if (status!=SET) {
  593.             for (i=pos; i<len; i++)
  594.               s[i]=s[i+1];
  595.             s[len-1]=32;
  596.             movecsr(cx,cy);
  597.             outs(s);
  598.             movecsr(cx+pos,cy);
  599.           }
  600.           break;
  601.       }
  602.     } else {
  603.       if (ch>31) {
  604.         if (status==UPPER_ONLY)
  605.           ch=upcase(ch);
  606.     if (status==SET) {
  607.       ch=upcase(ch);
  608.       if (ch!=' ') {
  609.         i1=1;
  610.             for (i=0; i<len; i++)
  611.           if ((ch==ss[i]) && (i1)) {
  612.         i1=0;
  613.         pos=i;
  614.         movecsr(cx+pos,cy);
  615.         if (s[pos]==' ')
  616.           ch=ss[pos];
  617.         else
  618.           ch=' ';
  619.           }
  620.         if (i1)
  621.           ch=ss[pos];
  622.       }
  623.     }
  624.         if ((pos<len)&&((status==ALL) || (status==UPPER_ONLY) || (status==SET) ||
  625.             ((status==NUM_ONLY) && (((ch>='0') && (ch<='9')) || (ch==' '))))) {
  626.           if (insert) {
  627.             for (i=len-1; i>pos; i--)
  628.               s[i]=s[i-1];
  629.             s[pos++]=ch;
  630.             movecsr(cx,cy);
  631.             outs(s);
  632.             movecsr(cx+pos,cy);
  633.           } else {
  634.             s[pos++]=ch;
  635.             out1ch(ch);
  636.           }
  637.         }
  638.       } else {
  639.     ch=ch;
  640.         switch(ch) {
  641.       case 13:
  642.           case 9:
  643.             done=1;
  644.             *returncode=NEXT;
  645.             break;
  646.           case 27:
  647.             done=1;
  648.             *returncode=DONE;
  649.             break;
  650.           case 8:
  651.             if (pos>0) {
  652.               if (insert) {
  653.                 for (i=pos-1; i<len; i++)
  654.                   s[i]=s[i+1];
  655.                 s[len-1]=32;
  656.                 pos--;
  657.                 movecsr(cx,cy);
  658.                 outs(s);
  659.                 movecsr(cx+pos,cy);
  660.               } else {
  661.                 pos--;
  662.                 movecsr(cx+pos,cy);
  663.               }
  664.             }
  665.             break;
  666.         }
  667.       }
  668.     }
  669.   } while (done==0);
  670.   movecsr(cx,cy);
  671.   curatr=oldatr;
  672.   outs(s);
  673.   movecsr(cx,cy);
  674. }
  675.  
  676.  
  677.  
  678. void val_cur_user(void)
  679. /* val_cur_user allows the sysop at the keyboard to validate the current user,
  680.    chaning sl, dsl, ar, dar, sysop sub, exemptions, restrictions, and user
  681.    note
  682.  */
  683. {
  684.   char sl[4],dsl[4],exempt[4],sysopsub[4],ar[17],dar[17],restrict[17],rst[17],
  685.        tl[50];
  686.   int cp,i,done,rc,wx,wy;
  687.  
  688.   pr_wait(1);
  689.   savescreen(&screensave);
  690.   curatr=7;
  691.   wx=15;
  692.   wy=4;
  693.   makewindow(wx,wy,50,7);
  694.   itoa((int)thisuser.sl,sl,10);
  695.   itoa((int)thisuser.dsl,dsl,10);
  696.   itoa((int)thisuser.exempt,exempt,10);
  697.   itoa((int)*qsc,sysopsub,10);
  698.   strcpy(rst,restrict_string);
  699.   for (i=0; i<=15; i++) {
  700.     if (thisuser.ar & (1 << i))
  701.       ar[i]='A'+i;
  702.     else
  703.       ar[i]=32;
  704.     if (thisuser.dar & (1 << i))
  705.       dar[i]='A'+i;
  706.     else
  707.       dar[i]=32;
  708.     if (thisuser.restrict & (1 << i))
  709.       restrict[i]=rst[i];
  710.     else
  711.       restrict[i]=32;
  712.   }
  713.   dar[16]=0;
  714.   ar[16]=0;
  715.   restrict[16]=0;
  716.   cp=0;
  717.   done=0;
  718.  
  719.   movecsr(wx+2,wy+1); sprintf(tl,get_stringx(1,77),sl); outs(tl);
  720.   movecsr(wx+26,wy+1); sprintf(tl,get_stringx(1,78),ar); outs(tl);
  721.   movecsr(wx+2,wy+2); sprintf(tl,get_stringx(1,79),dsl); outs(tl);
  722.   movecsr(wx+26,wy+2); sprintf(tl,get_stringx(1,80),dar); outs(tl);
  723.   movecsr(wx+2,wy+3); sprintf(tl,get_stringx(1,81),exempt); outs(tl);
  724.   movecsr(wx+26,wy+3); sprintf(tl,get_stringx(1,82),restrict); outs(tl);
  725.   movecsr(wx+2,wy+4); sprintf(tl,get_stringx(1,83),sysopsub); outs(tl);
  726.   movecsr(wx+2,wy+5); sprintf(tl,get_stringx(1,84),thisuser.note); outs(tl);
  727.   while (done==0) {
  728.     switch(cp) {
  729.       case 0:
  730.         movecsr(wx+8,wy+1);
  731.         editline(sl,3,NUM_ONLY,&rc,"");
  732.         thisuser.sl=(char) atoi(sl);
  733.         itoa((int)thisuser.sl,sl,10);
  734.         sprintf(tl,"%-3s",sl); outs(tl);
  735.         break;
  736.       case 1:
  737.         movecsr(wx+32,wy+1);
  738.         editline(ar,16,SET,&rc,"ABCDEFGHIJKLMNOP ");
  739.         thisuser.ar=0;
  740.         for (i=0; i<=15; i++)
  741.           if (ar[i]!=32)
  742.             thisuser.ar |= (1 << i);
  743.         break;
  744.       case 2:
  745.         movecsr(wx+8,wy+2);
  746.         editline(dsl,3,NUM_ONLY,&rc,"");
  747.         thisuser.dsl=(char) atoi(dsl);
  748.         itoa((int)thisuser.dsl,dsl,10);
  749.         sprintf(tl,"%-3s",dsl); outs(tl);
  750.         break;
  751.       case 3:
  752.         movecsr(wx+32,wy+2);
  753.         editline(dar,16,SET,&rc,"ABCDEFGHIJKLMNOP ");
  754.         thisuser.dar=0;
  755.         for (i=0; i<=15; i++)
  756.           if (dar[i]!=32)
  757.             thisuser.dar |= (1 << i);
  758.         break;
  759.       case 4:
  760.         movecsr(wx+8,wy+3);
  761.         editline(exempt,3,NUM_ONLY,&rc,"");
  762.         thisuser.exempt=(char) atoi(exempt);
  763.         itoa((int)thisuser.exempt,exempt,10);
  764.         sprintf(tl,"%-3s",exempt); outs(tl);
  765.         break;
  766.       case 5:
  767.         movecsr(wx+32,wy+3);
  768.         editline(restrict,16,SET,&rc,rst);
  769.         thisuser.restrict=0;
  770.         for (i=0; i<=15; i++)
  771.           if (restrict[i]!=32)
  772.             thisuser.restrict |= (1 << i);
  773.         break;
  774.       case 6:
  775.         movecsr(wx+12,wy+4);
  776.         editline(sysopsub,3,NUM_ONLY,&rc,"");
  777.         *qsc= atoi(sysopsub);
  778.         itoa((int)*qsc,sysopsub,10);
  779.         sprintf(tl,"%-3s",sysopsub); outs(tl);
  780.         break;
  781.       case 7:
  782.         movecsr(wx+8,wy+5);
  783.         editline(thisuser.note,40,ALL,&rc,"");
  784.         break;
  785.     }
  786.     switch(rc) {
  787.       case DONE: done=1; break;
  788.       case NEXT: cp=(cp+1) % 8; break;
  789.       case PREV: cp--; if (cp==-1) cp=7;  break;
  790.     }
  791.   }
  792.   restorescreen(&screensave);
  793.   reset_act_sl();
  794.   changedsl();
  795.   pr_wait(0);
  796. }
  797.  
  798.  
  799. void temp_cmd(char *s, int ccc)
  800. {
  801.   int i;
  802.  
  803.   pr_wait(1);
  804.   savescreen(&screensave);
  805.   i=topline;
  806.   topline=0;
  807.   curatr=0x07;
  808.   clrscrb();
  809.   do_remote(s, ccc);
  810.   restorescreen(&screensave);
  811.   topline=i;
  812.   pr_wait(0);
  813. }
  814.  
  815.  
  816. char xlate[] = {
  817.   'Q','W','E','R','T','Y','U','I','O','P',0,0,0,0,
  818.   'A','S','D','F','G','H','J','K','L',0,0,0,0,0,
  819.   'Z','X','C','V','B','N','M',
  820. };
  821.  
  822. char scan_to_char(unsigned char ch)
  823. {
  824.   if ((ch>=16) && (ch<=50))
  825.     return(xlate[ch-16]);
  826.   else
  827.     return(0);
  828. }
  829.  
  830. void alt_key(unsigned char ch)
  831. {
  832.   char ch1;
  833.   char *ss, *ss1,s[81],cmd[128];
  834.   int f,l;
  835.  
  836.   cmd[0]=0;
  837.   ch1=scan_to_char(ch);
  838.   if (ch1) {
  839.     sprintf(s,"%sMACROS.TXT",syscfg.datadir);
  840.     f=open(s,O_RDONLY | O_BINARY);
  841.     if (f>0) {
  842.       l=filelength(f);
  843.       ss=farmalloc(l+10);
  844.       if (ss) {
  845.         read(f,ss,l);
  846.         close(f);
  847.  
  848.         ss[l]=0;
  849.         ss1=strtok(ss,"\r\n");
  850.         while (ss1) {
  851.           if (upcase(*ss1)==ch1) {
  852.             strtok(ss1," \t");
  853.             ss1=strtok(NULL,"\r\n");
  854.             if (ss1 && (strlen(ss1)<128))
  855.               strcpy(cmd,ss1);
  856.             ss1=NULL;
  857.           } else
  858.             ss1=strtok(NULL,"\r\n");
  859.         }
  860.         farfree(ss);
  861.       } else
  862.         close(f);
  863.       if (cmd[0]) {
  864.         if (cmd[0]=='@') {
  865.           if (okmacro && okskey && (!charbufferpointer) && (cmd[1])) {
  866.             for (l=strlen(cmd)-1; l>=0; l--) {
  867.               if (cmd[l]=='{')
  868.                 cmd[l]='\r';
  869.               strcpy(charbuffer,cmd);
  870.               charbufferpointer=1;
  871.             }
  872.           }
  873.         } else {
  874.           temp_cmd(cmd,1);
  875.         }
  876.       }
  877.     }
  878.   }
  879. }
  880.  
  881. void skey(char ch)
  882. /* skey handles all f-keys and the like hit FROM THE KEYBOARD ONLY */
  883. {
  884.   int i,i1;
  885.  
  886.   if ((syscfg.sysconfig & sysconfig_no_local)==0) {
  887.     if (okskey) {
  888.       if ((ch>=104) && (ch<=113)) {
  889.         set_autoval(ch-104);
  890.       } else {
  891.         switch ((unsigned char) ch) {
  892.           case 59: /* F1 */
  893.             val_cur_user();
  894.             break;
  895.           case 60: /* F2 */
  896.             topdata+=1;
  897.             if (topdata==3)
  898.               topdata=0;
  899.             topscreen();
  900.             break;
  901.           case 61: /* F3 */
  902.             if (using_modem) {
  903.               incom=(!incom);
  904.               dump();
  905.               tleft(0);
  906.             }
  907.             break;
  908.           case 62: /* F4 */
  909.             chatcall=0;
  910.             topscreen();
  911.             break;
  912.           case 63: /* F5 */
  913.             hangup=1;
  914.             dtr(0);
  915.             break;
  916.           case 64: /* F6 */
  917.             sysop_alert=!sysop_alert;
  918.             tleft(0);
  919.             break;
  920.           case 65: /* F7 */
  921.             thisuser.extratime-=5.0*60.0;
  922.             tleft(0);
  923.             break;
  924.           case 66: /* F8 */
  925.             thisuser.extratime+=5.0*60.0;
  926.             tleft(0);
  927.             break;
  928.           case 67: /* F9 */
  929.             if (thisuser.sl!=255) {
  930.               if (actsl!=255)
  931.                 actsl=255;
  932.               else
  933.                 reset_act_sl();
  934.               changedsl();
  935.               tleft(0);
  936.             }
  937.             break;
  938.           case 68: /* F10 */
  939.             if (chatting==0) {
  940.               if (syscfg.sysconfig & sysconfig_2_way)
  941.                 chat1("",1);
  942.               else
  943.                 chat1("",0);
  944.             } else
  945.               chatting=0;
  946.             break;
  947.           case 71: /* HOME */
  948.             if (chatting==1) {
  949.               if (chat_file)
  950.                 chat_file=0;
  951.               else
  952.                 chat_file=1;
  953.             }
  954.             break;
  955.           case 88: /* Shift-F5 */
  956.             i1=(rand() % 20) + 10;
  957.             for (i=0; i<i1; i++)
  958.               outchr(rand() % 256);
  959.             hangup=1;
  960.             dtr(0);
  961.             break;
  962.           case 98: /* Ctrl-F5 */
  963.             nl();
  964.             pl(get_string(924));
  965.             nl();
  966.             hangup=1;
  967.             dtr(0);
  968.             break;
  969.           case 103: /* Ctrl-F10 */
  970.             if (chatting==0)
  971.               chat1("",0);
  972.             else
  973.               chatting=0;
  974.             break;
  975.           case 84: /* Shift-F1 */
  976.             set_global_handle(!global_handle);
  977.             topscreen();
  978.             break;
  979.           case 93: /* Shift-F10 */
  980.             temp_cmd(getenv("COMSPEC"),0);
  981.             break;
  982.           default:
  983.             alt_key((unsigned char) ch);
  984.             break;
  985.         }
  986.       }
  987.     } else {
  988.       if (wfc)
  989.         holdphone(1);
  990.       alt_key((unsigned char) ch);
  991.       if (wfc)
  992.         holdphone(0);
  993.     }
  994.   }
  995. }
  996.  
  997.  
  998. void tleft(int x)
  999. {
  1000.   int cx,cy,ctl,cc,ln,i;
  1001.   double nsln;
  1002.   char tl[30];
  1003.   static char sbuf[200];
  1004.   static char *ss[8];
  1005.  
  1006.   if (!sbuf[0]) {
  1007.     ss[0]=sbuf;
  1008.     for (i=0; i<7; i++) {
  1009.       strcpy(ss[i],get_stringx(1,85+i));
  1010.       ss[i+1]=ss[i]+strlen(ss[i])+1;
  1011.     }
  1012.   }
  1013.  
  1014.   cx=wherex();
  1015.   cy=wherey();
  1016.   ctl=topline;
  1017.   cc=curatr;
  1018.   if (crttype==7)
  1019.     curatr=0x07;
  1020.   else
  1021.     curatr=0x0e;
  1022.   topline=0;
  1023.   nsln=nsl();
  1024.   if (chatcall && (topdata==2))
  1025.     ln=5;
  1026.   else
  1027.     ln=4;
  1028.  
  1029.  
  1030.   if (topdata) {
  1031.  
  1032.     if ((using_modem) && (!incom)) {
  1033.       movecsr(1,ln);
  1034.       outs(ss[0]);
  1035.       for (i=19; i<strlen(curspeed); i++)
  1036.         out1ch('═');
  1037.     } else {
  1038.       movecsr(1,ln);
  1039.       outs(curspeed);
  1040.       for (i=wherex(); i<23; i++)
  1041.         out1ch('═');
  1042.     }
  1043.  
  1044.     if ((thisuser.sl!=255) && (actsl==255)) {
  1045.       movecsr(23,ln);
  1046.       outs(ss[1]);
  1047.     }
  1048.  
  1049.     if (global_handle) {
  1050.       movecsr(40,ln);
  1051.       outs(ss[2]);
  1052.     }
  1053.  
  1054.     movecsr(54,ln);
  1055.     if (sysop_alert) {
  1056.       outs(ss[3]);
  1057.     } else {
  1058.       outs(ss[4]);
  1059.     }
  1060.  
  1061.     movecsr(64,ln);
  1062.     if (sysop1()) {
  1063.       outs(ss[5]);
  1064.     } else {
  1065.       outs(ss[6]);
  1066.     }
  1067.   }
  1068.  
  1069.   switch (topdata)
  1070.     {
  1071.     case 1:
  1072.       if (useron) {
  1073.         movecsr(18,3);
  1074.         sprintf(tl,"T-%6.2f",nsln/60.0);
  1075.         outs(tl);
  1076.       }
  1077.       break;
  1078.     case 2:
  1079.       movecsr(64,3);
  1080.       if (useron)
  1081.         sprintf(tl,"T-%6.2f",nsln/60.0);
  1082.       else
  1083.         strcpy(tl,thisuser.pw);
  1084.       outs(tl);
  1085.       break;
  1086.   }
  1087.   topline=ctl;
  1088.   curatr=cc;
  1089.   movecsr(cx,cy);
  1090.   if ((x) && (useron))
  1091.     if (nsln==0.0) {
  1092.       nl();
  1093.       pl(get_string(926));
  1094.       nl();
  1095.       hangup=1;
  1096.     }
  1097. }
  1098.  
  1099.  
  1100. void topscreen(void)
  1101. {
  1102.   int cc,cx,cy,ctl,i;
  1103.   char sl[81],ar[17],dar[17],restrict[17],rst[17],lo[90],ol[190],calls[20];
  1104.  
  1105.  
  1106.   switch(topdata) {
  1107.     case 0:
  1108.       set_protect(0);
  1109.       break;
  1110.     case 1:
  1111.       set_protect(5);
  1112.       break;
  1113.     case 2:
  1114.       if (chatcall)
  1115.         set_protect(6);
  1116.       else {
  1117.         if (topline==6)
  1118.           set_protect(0);
  1119.         set_protect(5);
  1120.       }
  1121.       break;
  1122.   }
  1123.   cx=wherex();
  1124.   cy=wherey();
  1125.   ctl=topline;
  1126.   cc=curatr;
  1127.   if (crttype==7)
  1128.     curatr=0x07;
  1129.   else
  1130.     curatr=0x0e;
  1131.   topline=0;
  1132.   for (i=0; i<80; i++)
  1133.     sl[i]=205;
  1134.   sl[80]=0;
  1135.  
  1136.   switch (topdata) {
  1137.     case 0:
  1138.       break;
  1139.     case 1:
  1140.  
  1141.       movecsr(0,0);
  1142.       sprintf(ol,"%-50s  Activity for %8s:      ",
  1143.           syscfg.systemname,status.date1);
  1144.       outs(ol);
  1145.  
  1146.       movecsr(0,1);
  1147.       sprintf(ol,"Users: %4u       Total Calls: %5lu      Calls Today: %4u    Posted      :%3u ",
  1148.           status.users,status.callernum1,status.callstoday,status.msgposttoday);
  1149.       outs(ol);
  1150.  
  1151.       movecsr(0,2);
  1152.       sprintf(ol,"%-36s      %-4u min   /  %2u%%    E-mail sent :%3u ",
  1153.           nam(&thisuser,usernum),status.activetoday,
  1154.           (int) (10*status.activetoday/144),status.emailtoday);
  1155.       outs(ol);
  1156.  
  1157.       movecsr(0,3);
  1158.       sprintf(ol,"SL=%3u   DL=%3u               FW=%3u      Uploaded:%2u files    Feedback    :%3u ",
  1159.           thisuser.sl,thisuser.dsl,fwaiting,status.uptoday,status.fbacktoday);
  1160.       outs(ol);
  1161.       break;
  1162.  
  1163.     case 2:
  1164.  
  1165.       strcpy(rst,restrict_string);
  1166.       for (i=0; i<=15; i++) {
  1167.         if (thisuser.ar & (1 << i))
  1168.           ar[i]='A'+i;
  1169.         else
  1170.           ar[i]=32;
  1171.         if (thisuser.dar & (1 << i))
  1172.           dar[i]='A'+i;
  1173.         else
  1174.           dar[i]=32;
  1175.         if (thisuser.restrict & (1 << i))
  1176.           restrict[i]=rst[i];
  1177.         else
  1178.           restrict[i]=32;
  1179.       }
  1180.       dar[16]=0;
  1181.       ar[16]=0;
  1182.       restrict[16]=0;
  1183.       if (strcmp(thisuser.laston,date()))
  1184.         strcpy(lo,thisuser.laston);
  1185.       else
  1186.         sprintf(lo,"Today:%2d",thisuser.ontoday);
  1187.  
  1188.       movecsr(0,0);
  1189.       sprintf(ol,"%-36s W=%2u UL=%4u/%6lu SL=%3u LO=%5u PO=%4u",
  1190.           nam(&thisuser,usernum),thisuser.waiting,thisuser.uploaded,
  1191.           thisuser.uk,thisuser.sl,thisuser.logons,thisuser.msgpost);
  1192.       outs(ol);
  1193.  
  1194.       movecsr(0,1);
  1195.       if (thisuser.wwiv_regnum)
  1196.         sprintf(calls,"%lu",thisuser.wwiv_regnum);
  1197.       else
  1198.         strcpy(calls,thisuser.callsign);
  1199.       sprintf(ol,"%-20s %12s  %-6s DL=%4u/%6lu DL=%3u TO=%5.0lu ES=%4u",
  1200.           thisuser.realname,thisuser.phone,calls,
  1201.           thisuser.downloaded,thisuser.dk,thisuser.dsl,
  1202.           ((long) ((thisuser.timeon+timer()-timeon)/60.0)),
  1203.           thisuser.emailsent+thisuser.emailnet);
  1204.       outs(ol);
  1205.  
  1206.       movecsr(0,2);
  1207.       sprintf(ol,"ARs=%-16s/%-16s R=%-16s EX=%3u %-8s FS=%4u",
  1208.           ar,dar,restrict,thisuser.exempt,lo,thisuser.feedbacksent);
  1209.       outs(ol);
  1210.  
  1211.       movecsr(0,3);
  1212.       sprintf(ol,"%-40s %c %2u %-17s          FW= %3u",
  1213.           thisuser.note,thisuser.sex,thisuser.age,
  1214.           ctypes[thisuser.comp_type],fwaiting);
  1215.       outs(ol);
  1216.  
  1217.       if (chatcall) {
  1218.         movecsr(0,4);
  1219.         outs(chatreason);
  1220.       }
  1221.       break;
  1222.   }
  1223.   if (ctl!=0) {
  1224.     movecsr(0,ctl-1);
  1225.     outs(sl);
  1226.   }
  1227.   topline=ctl;
  1228.   movecsr(cx,cy);
  1229.   curatr=cc;
  1230.   tleft(0);
  1231. }
  1232. /****************************************************************************/
  1233.  
  1234.  
  1235.  
  1236. #ifdef TWO_WAY
  1237.  
  1238. int x1,y1,x2,y2,cp0,cp1;
  1239.  
  1240.  
  1241. void two_way_chat(char *s, char *rollover, int maxlen, int crend)
  1242. {
  1243.   char s2[100], temp1[50], side0[12] [80], side1[12] [80];
  1244.   int side, cnt, cnt2, cntr;
  1245.   int i,i1,done,cm,begx;
  1246.   char s1[255];
  1247.   unsigned char ch;
  1248.  
  1249.  
  1250.   cm=chatting;
  1251.   begx=wherex();
  1252.   if (rollover[0]!=0) {
  1253.     if (charbufferpointer) {
  1254.       strcpy(s1,rollover);
  1255.       strcat(s1,&charbuffer[charbufferpointer]);
  1256.       strcpy(&charbuffer[1],s1);
  1257.       charbufferpointer=1;
  1258.     } else {
  1259.       strcpy(&charbuffer[1],rollover);
  1260.       charbufferpointer=1;
  1261.     }
  1262.     rollover[0]=0;
  1263.   }
  1264.  
  1265.   done=0;
  1266.   side = 0;
  1267.   do {
  1268.     ch=getkey();
  1269.       if (lastcon)
  1270.         {
  1271.           if (wherey() == 11)
  1272.             {
  1273.               outstr("\x1b[12;1H");
  1274.               ansic(3);
  1275.                 for(cnt=0;cnt<=thisuser.screenchars;cnt++)
  1276.                     s2[cnt]=205;
  1277.               strcpy(temp1,get_stringx(1,92));
  1278.               cnt=(((thisuser.screenchars-strlen(temp1)) /2));
  1279.               strncpy(&s2[cnt+1],temp1,(strlen(temp1)));
  1280.               s2[thisuser.screenchars]=0;
  1281.               outstr(s2);
  1282.               s2[0]=0;
  1283.               temp1[0]=0;
  1284.                 for(cntr=1;cntr<12;cntr++)
  1285.                   {
  1286.                     sprintf(s2,"\x1b[%d;%dH",cntr,1);
  1287.                     outstr(s2);
  1288.                       if ((cntr >=0) && (cntr <5))
  1289.                         {
  1290.                           ansic(1);
  1291.                           outstr(side0[cntr+6]);
  1292.                          }
  1293.                     outstr("\x1b[K");
  1294.                     s2[0]=0;
  1295.                   }
  1296.               sprintf(s2,"\x1b[%d;%dH",5,1);
  1297.               outstr(s2);
  1298.               s2[0]=0;
  1299.             }
  1300.           else
  1301.             if (wherey() > 11)
  1302.               {
  1303.                 x2=(wherex()+1);
  1304.                 y2=(wherey()+1);
  1305.                 sprintf(s2,"\x1b[%d;%dH",y1,x1);
  1306.                 outstr(s2);
  1307.                 s2[0]=0;
  1308.               }
  1309.           side = 0;
  1310.           ansic(1);
  1311.         }
  1312.       else
  1313.         {
  1314.           if (wherey() >= 23)
  1315.             {
  1316.               for(cntr=13;cntr<25;cntr++)
  1317.                 {
  1318.                   sprintf(s2,"\x1b[%d;%dH",cntr,1);
  1319.                   outstr(s2);
  1320.                     if ((cntr >= 13) && (cntr <17))
  1321.                       {
  1322.                         ansic(5);
  1323.                         outstr(side1[cntr-7]);
  1324.                       }
  1325.                   outstr("\x1b[K");
  1326.                   s2[0]=0;
  1327.                 }
  1328.               sprintf(s2,"\x1b[%d;%dH",17,1);
  1329.               outstr(s2);
  1330.               s2[0]=0;
  1331.             }
  1332.           else
  1333.             if ((wherey() < 12) && (side == 0))
  1334.               {
  1335.                 x1=(wherex()+1);
  1336.                 y1=(wherey()+1);
  1337.                 sprintf(s2,"\x1b[%d;%dH",y2,x2);
  1338.                 outstr(s2);
  1339.                 s2[0]=0;
  1340.               }
  1341.           side=1;
  1342.           ansic(5);
  1343.         }
  1344.     if (cm)
  1345.       if (chatting==0)
  1346.         ch=13;
  1347.     if ((ch>=32)) {
  1348.       if (side==0)
  1349.        {
  1350.          if ((wherex()<(thisuser.screenchars-1)) && (cp0<maxlen))
  1351.            {
  1352.              if (wherey() < 11)
  1353.                {
  1354.                  side0[wherey()][cp0++]=ch;
  1355.                  outchr(ch);
  1356.                }
  1357.              else
  1358.               {
  1359.               side0[wherey()][cp0++]=ch;
  1360.               side0[wherey()][cp0]=0;
  1361.               for(cntr=0;cntr<12;cntr++)
  1362.                 {
  1363.                   sprintf(s2,"\x1b[%d;%dH",cntr,1);
  1364.                   outstr(s2);
  1365.                   if ((cntr >=0) && (cntr <6))
  1366.                     {
  1367.                       ansic(1);
  1368.                       outstr(side0[cntr+6]);
  1369.                       y1=wherey()+1;
  1370.                       x1=wherex()+1;
  1371.                     }
  1372.                   outstr("\x1b[K");
  1373.                   s2[0]=0;
  1374.                 }
  1375.               sprintf(s2,"\x1b[%d;%dH",y1,x1);
  1376.               outstr(s2);
  1377.               s2[0]=0;
  1378.             }
  1379.         if (wherex()==(thisuser.screenchars-1))
  1380.             done=1;
  1381.       } else {
  1382.         if (wherex()>=(thisuser.screenchars-1))
  1383.             done=1;
  1384.       }
  1385.       }
  1386.       else
  1387.        {
  1388.          if ((wherex()<(thisuser.screenchars-1)) && (cp1<maxlen) )
  1389.            {
  1390.               if (wherey() < 23)
  1391.                 {
  1392.                   side1[wherey()-13][cp1++]=ch;
  1393.                   outchr(ch);
  1394.                 }
  1395.              else
  1396.               {
  1397.                 side1[wherey()-13][cp1++]=ch;
  1398.                 side1[wherey()-13][cp1]=0;
  1399.                   for(cntr=13;cntr<25;cntr++)
  1400.                     {
  1401.                       sprintf(s2,"\x1b[%d;%dH",cntr,1);
  1402.                       outstr(s2);
  1403.                         if ((cntr >=13) && (cntr <18))
  1404.                           {
  1405.                             ansic(5);
  1406.                             outstr(side1[cntr-7]);
  1407.                             y2=wherey()+1;
  1408.                             x2=wherex()+1;
  1409.                           }
  1410.                        outstr("\x1b[K");
  1411.                        s2[0]=0;
  1412.                      }
  1413.               sprintf(s2,"\x1b[%d;%dH",y2,x2);
  1414.               outstr(s2);
  1415.               s2[0]=0;
  1416.             }
  1417.         if (wherex()==(thisuser.screenchars-1))
  1418.             done=1;
  1419.       } else {
  1420.         if (wherex()>=(thisuser.screenchars-1))
  1421.             done=1;
  1422.       }
  1423.       }
  1424.     } else
  1425.         switch(ch) {
  1426.       case 7:
  1427.         if ((chatting) && (outcom))
  1428.           outcomch(7);
  1429.         break;
  1430.           case 13: /* C/R */
  1431.               if (side == 0)
  1432.                 side0[wherey()][cp0]=0;
  1433.               else
  1434.                 side1[wherey()-13][cp1]=0;
  1435.             done=1;
  1436.             break;
  1437.           case 8:  /* Backspace */
  1438.             if (side==0)
  1439.               {
  1440.                 if (cp0)
  1441.                   {
  1442.                     if (side0[wherey()][cp0-2]==3)
  1443.                       {
  1444.                         cp0-=2;
  1445.                         ansic(0);
  1446.                       }
  1447.                     else
  1448.                       if (side0[wherey()][cp0-1]==8)
  1449.                         {
  1450.                           cp0--;
  1451.                           outchr(32);
  1452.                         }
  1453.                       else
  1454.                         {
  1455.                           cp0--;
  1456.                           backspace();
  1457.                         }
  1458.                   }
  1459.               }
  1460.             else
  1461.               if (cp1)
  1462.                 {
  1463.                   if (side1[wherey()-13][cp1-2]==3)
  1464.                     {
  1465.                       cp1-=2;
  1466.                       ansic(0);
  1467.                     }
  1468.                   else
  1469.                     if (side1[wherey()-13][cp1-1]==8)
  1470.                       {
  1471.                         cp1--;
  1472.                         outchr(32);
  1473.                       }
  1474.                     else
  1475.                       {
  1476.                         cp1--;
  1477.                         backspace();
  1478.                       }
  1479.                 }
  1480.             break;
  1481.           case 24: /* Ctrl-X */
  1482.             while (wherex()>begx) {
  1483.               backspace();
  1484.                 if (side==0)
  1485.                   cp0=0;
  1486.                 else
  1487.                   cp1=0;
  1488.             }
  1489.             ansic(0);
  1490.             break;
  1491.           case 23: /* Ctrl-W */
  1492.             if (side==0)
  1493.               {
  1494.               if (cp0) {
  1495.               do {
  1496.                 if (side0[wherey()][cp0-2]==3) {
  1497.                   cp0-=2;
  1498.                   ansic(0);
  1499.                 } else
  1500.                   if (side0[wherey()][cp0-1]==8) {
  1501.                     cp0--;
  1502.                     outchr(32);
  1503.                   } else {
  1504.                     cp0--;
  1505.                     backspace();
  1506.                   }
  1507.               } while ((cp0) && (side0[wherey()][cp0-1]!=32) &&
  1508.                        (side0[wherey()][cp0-1]!=8) &&
  1509.                        (side0[wherey()][cp0-2]!=3));
  1510.               }
  1511.               }
  1512.             else
  1513.               {
  1514.               if (cp1) {
  1515.               do {
  1516.                 if (side1[wherey()-13][cp1-2]==3) {
  1517.                   cp1-=2;
  1518.                   ansic(0);
  1519.                 } else
  1520.                   if (side1[wherey()-13][cp1-1]==8) {
  1521.                     cp1--;
  1522.                     outchr(32);
  1523.                   } else {
  1524.                     cp1--;
  1525.                     backspace();
  1526.                   }
  1527.               } while ((cp1) && (side1[wherey()-13][cp1-1]!=32) &&
  1528.                        (side1[wherey()-13][cp1-1]!=8) &&
  1529.                        (side1[wherey()-13][cp1-2]));
  1530.               }
  1531.             }
  1532.             break;
  1533.           case 14: /* Ctrl-N */
  1534.                 if (side == 0)
  1535.                   {
  1536.                     if ((wherex()) && (cp0<maxlen))
  1537.                       {
  1538.                         outchr(8);
  1539.                         side0[wherey()][cp0++]=8;
  1540.                       }
  1541.                   }
  1542.                 else
  1543.                   if ((wherex()) && (cp1<maxlen))
  1544.                     {
  1545.                       outchr(8);
  1546.                       side1[wherey()-13][cp1++]=8;
  1547.                     }
  1548.             break;
  1549.           case 16: /* Ctrl-P */
  1550.             if (side==0)
  1551.               {
  1552.                 if (cp0<maxlen-1)
  1553.                   {
  1554.                     ch=getkey();
  1555.                       if ((ch>='0') && (ch<='7'))
  1556.                         {
  1557.                           side0[wherey()][cp0++]=3;
  1558.                           side0[wherey()][cp0++]=ch;
  1559.                           ansic(ch-'0');
  1560.                         }
  1561.                   }
  1562.               }
  1563.             else
  1564.               {
  1565.                 if (cp1<maxlen-1)
  1566.                   {
  1567.                     ch=getkey();
  1568.                       if ((ch>='0') && (ch<='7'))
  1569.                         {
  1570.                           side1[wherey()-13][cp1++]=3;
  1571.                           side1[wherey()-13][cp1++]=ch;
  1572.                           ansic(ch-'0');
  1573.                         }
  1574.                   }
  1575.               }
  1576.             break;
  1577.           case 9:  /* Tab */
  1578.             if (side==0)
  1579.               {
  1580.                 i=5-(cp0 % 5);
  1581.                   if (((cp0+i)<maxlen) && ((wherex()+i)<thisuser.screenchars))
  1582.                     {
  1583.                       i=5-((wherex()+1) % 5);
  1584.                         for (i1=0; i1<i; i1++)
  1585.                           {
  1586.                             side0[wherey()][cp0++]=32;
  1587.                             outchr(32);
  1588.                           }
  1589.                     }
  1590.               }
  1591.             else
  1592.               {
  1593.                 i=5-(cp1 % 5);
  1594.                   if (((cp1+i)<maxlen) && ((wherex()+i)<thisuser.screenchars))
  1595.                     {
  1596.                       i=5-((wherex()+1) % 5);
  1597.                         for (i1=0; i1<i; i1++)
  1598.                           {
  1599.                             side1[wherey()-13][cp1++]=32;
  1600.                             outchr(32);
  1601.                           }
  1602.                     }
  1603.               }
  1604.             break;
  1605.         }
  1606.   } while ((done==0) && (hangup==0));
  1607.  
  1608.   if (ch!=13)
  1609.   {
  1610.     if (side==0)
  1611.       {
  1612.         i=cp0-1;
  1613.           while ((i>0) && (side0[wherey()][i]!=32) &&
  1614.                  (side0[wherey()][i]!=8) || (side0[wherey()][i-1]==3))
  1615.             i--;
  1616.               if ((i>(wherex()/2)) && (i!=(cp0-1)))
  1617.                 {
  1618.                   i1=cp0-i-1;
  1619.                     for (i=0; i<i1; i++)
  1620.                       outchr(8);
  1621.                     for (i=0; i<i1; i++)
  1622.                       outchr(32);
  1623.                     for (i=0; i<i1; i++)
  1624.                       rollover[i]=side0[wherey()][cp0-i1+i];
  1625.                   rollover[i1]=0;
  1626.                   cp0 -= i1;
  1627.                 }
  1628.           side0[wherey()][cp0]=0;
  1629.       }
  1630.   else
  1631.       {
  1632.         i=cp1-1;
  1633.           while ((i>0) && (side1[wherey()-13][i]!=32) &&
  1634.                  (side1[wherey()-13][i]!=8) || (side1[wherey()-13][i-1]==3))
  1635.             i--;
  1636.               if ((i>(wherex()/2)) && (i!=(cp1-1)))
  1637.                 {
  1638.                   i1=cp1-i-1;
  1639.                     for (i=0; i<i1; i++)
  1640.                       outchr(8);
  1641.                     for (i=0; i<i1; i++)
  1642.                       outchr(32);
  1643.                     for (i=0; i<i1; i++)
  1644.                       rollover[i]=side1[wherey()-13][cp1-i1+i];
  1645.                   rollover[i1]=0;
  1646.                   cp1 -= i1;
  1647.                 }
  1648.           side1[wherey()-13][cp1]=0;
  1649.       }
  1650.   }
  1651.   if ((crend) && (wherey() != 11) && (wherey()<23))
  1652.     nl();
  1653.   if (side == 0)
  1654.     cp0=0;
  1655.   else
  1656.     cp1=0;
  1657.  s[0]=0;
  1658. }
  1659.  
  1660. #endif
  1661.  
  1662.  
  1663. void chat1(char *chatline, int two_way)
  1664. {
  1665.  
  1666.   int tempdata, cnt;
  1667.   char cl[81],xl[81],s[161],s1[161],atr[81],s2[81],cc;
  1668.   int i,i1,cf,oe;
  1669.   double tc;
  1670.  
  1671.   chatcall=0;
  1672.   if (two_way)
  1673.     chatting=2;
  1674.   else
  1675.     chatting=1;
  1676.   tc=timer();
  1677.   cf=0;
  1678.  
  1679.   savel(cl,atr,xl,&cc);
  1680.   s1[0]=0;
  1681.  
  1682.   oe=echo;
  1683.   echo=1;
  1684.   nl();
  1685.   nl();
  1686.   tempdata=topdata;
  1687.   if (!okansi())
  1688.     two_way=0;
  1689.   if (modem_speed==300)
  1690.     two_way=0;
  1691.  
  1692. #ifndef TWO_WAY
  1693.   two_way=0;
  1694. #endif
  1695.  
  1696.  
  1697.   if (syscfg.sysconfig & sysconfig_two_color)
  1698.     two_color=1;
  1699. #ifdef TWO_WAY
  1700.   if (two_way) {
  1701.     clrscrb();
  1702.     cp0=0;
  1703.     cp1=0;
  1704.     if (defscreenbottom==24) {
  1705.       topdata=0;
  1706.       topscreen();
  1707.     }
  1708.     outstr("\x1b[2J");
  1709.     x2=1;
  1710.     y2=13;
  1711.     outstr("\x1b[1;1H");
  1712.     x1=wherex();
  1713.     y1=wherey();
  1714.     outstr("\x1b[12;1H");
  1715.     ansic(3);
  1716.     for(cnt=0;cnt<thisuser.screenchars;cnt++)
  1717.       outchr(205);
  1718.     strcpy(s,get_stringx(1,93));
  1719.     cnt=((thisuser.screenchars-strlen(s))/2);
  1720.     sprintf(s1,"\x1b[12;%dH",cnt);
  1721.     outstr(s1);
  1722.     ansic(4);
  1723.     outstr(s);
  1724.     outstr("\x1b[1;1H");
  1725.     s[0]=0;
  1726.     s1[0]=0;
  1727.     s2[0]=0;
  1728.   }
  1729. #endif
  1730.   ansic(7);
  1731.   outstr(syscfg.sysopname);
  1732.   pl(get_string(927));
  1733.   nl();
  1734.   strcpy(s1,chatline);
  1735.  
  1736.   do {
  1737. #ifdef TWO_WAY
  1738.     if (two_way)
  1739.       two_way_chat(s,s1,160,1);
  1740.     else
  1741. #endif
  1742.       inli(s,s1,160,1);
  1743.     if ((chat_file) && (!two_way)) {
  1744.       if (cf==0) {
  1745.         if (!two_way)
  1746.           outs(get_stringx(1,94));
  1747.         sprintf(s2,"%sCHAT.TXT",syscfg.gfilesdir);
  1748.         cf=open(s2,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1749.         lseek(cf,0L,SEEK_END);
  1750.         sprintf(s2,get_stringx(1,95),date(),times());
  1751.         write(cf,(void *)s2,strlen(s2));
  1752.         strcpy(s2,get_stringx(1,96));
  1753.         write(cf,(void *)s2,strlen(s2));
  1754.       }
  1755.       strcat(s,"\r\n");
  1756.       write(cf,(void *)s,strlen(s));
  1757.     } else
  1758.       if (cf) {
  1759.     close(cf);
  1760.     cf=0;
  1761.         if (!two_way)
  1762.           outs(get_stringx(1,97));
  1763.       }
  1764.     if (hangup)
  1765.       chatting=0;
  1766.   } while (chatting);
  1767.   if (chat_file) {
  1768.     close(cf);
  1769.     chat_file=0;
  1770.   }
  1771.   ansic(0);
  1772.   two_color=0;
  1773.  
  1774.  
  1775.   if (two_way)
  1776.     outstr("\x1b[2J");
  1777.  
  1778.   nl();
  1779.   ansic(7);
  1780.   pl(get_string(928));
  1781.   nl();
  1782.   chatting=0;
  1783.   tc=timer()-tc;
  1784.   if (tc<0)
  1785.     tc += 86400.0;
  1786.   extratimecall += tc;
  1787.   topdata=tempdata;
  1788.   if (useron)
  1789.     topscreen();
  1790.   echo=oe;
  1791.   restorel(cl,atr,xl,&cc);
  1792. }
  1793.  
  1794.  
  1795. void set_autoval(int n)
  1796. {
  1797.   valrec v;
  1798.  
  1799.   v=syscfg.autoval[n];
  1800.  
  1801.   thisuser.sl=v.sl;
  1802.   thisuser.dsl=v.dsl;
  1803.   thisuser.ar=v.ar;
  1804.   thisuser.dar=v.dar;
  1805.   thisuser.restrict=v.restrict;
  1806.   reset_act_sl();
  1807.   changedsl();
  1808. }
  1809.