home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / CON_MID.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-01  |  25.8 KB  |  809 lines

  1. #line 1 "CON_MID.C"
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. #include "sbbs.h"
  6.  
  7. extern char *wday[];    /* 3 char days of week */
  8.  
  9. /****************************************************************************/
  10. /* Waits for remote or local user to hit a key. Inactivity timer is checked */
  11. /* and hangs up if inactive for 4 minutes. Returns key hit, or uppercase of */
  12. /* key hit if mode&K_UPPER or key out of KEY BUFFER. Does not print key.    */
  13. /* Called from functions all over the place.                                */
  14. /****************************************************************************/
  15. char getkey(long mode)
  16. {
  17.     char ch,coldkey,c=0,spin=random(5);
  18.  
  19. if(!online)
  20.     return(0);
  21. sys_status&=~SS_ABORT;
  22. if((sys_status&SS_USERON || action==NODE_DFLT) && !(mode&K_GETSTR))
  23.     mode|=(useron.misc&SPIN);
  24. lncntr=0;
  25. timeout=time(NULL);
  26. if(mode&K_SPIN)
  27.     outchar(' ');
  28. do {
  29.     checkline();    /* check to make sure remote user is still online */
  30.     if(online==ON_REMOTE && console&CON_R_INPUT && rioctl(IOSTATE)&ABORT) {
  31.         rioctl(IOCS|ABORT);
  32.         sys_status|=SS_ABORT;
  33.         if(mode&K_SPIN) /* back space once if on spinning cursor */
  34.             bputs("\b \b");
  35.         return(0); }
  36.     if(sys_status&SS_SYSPAGE)
  37.         beep(random(800),100);
  38.     if(mode&K_SPIN)
  39.         switch(spin) {
  40.             case 0:
  41.                 switch(c++) {
  42.                     case 0:
  43.                         outchar(BS);
  44.                         outchar('│');
  45.                         break;
  46.                     case 10:
  47.                         outchar(BS);
  48.                         outchar('/');
  49.                         break;
  50.                     case 20:
  51.                         outchar(BS);
  52.                         outchar('─');
  53.                         break;
  54.                     case 30:
  55.                         outchar(BS);
  56.                         outchar('\\');
  57.                         break;
  58.                     case 40:
  59.                         c=0;
  60.                         break;
  61.                     default:
  62.                         if(!inDV && !(node_misc&NM_WINOS2))
  63.                             mswait(DELAY_SPIN);
  64.                         break;  }
  65.                 break;
  66.             case 1:
  67.                 switch(c++) {
  68.                     case 0:
  69.                         outchar(BS);
  70.                         outchar('░');
  71.                         break;
  72.                     case 10:
  73.                         outchar(BS);
  74.                         outchar('▒');
  75.                         break;
  76.                     case 20:
  77.                         outchar(BS);
  78.                         outchar('▓');
  79.                         break;
  80.                     case 30:
  81.                         outchar(BS);
  82.                         outchar('█');
  83.                         break;
  84.                     case 40:
  85.                         outchar(BS);
  86.                         outchar('▓');
  87.                         break;
  88.                     case 50:
  89.                         outchar(BS);
  90.                         outchar('▒');
  91.                         break;
  92.                     case 60:
  93.                         c=0;
  94.                         break;
  95.                     default:
  96.                         if(!inDV && !(node_misc&NM_WINOS2))
  97.                             mswait(DELAY_SPIN);
  98.                         break;  }
  99.                 break;
  100.             case 2:
  101.                 switch(c++) {
  102.                     case 0:
  103.                         outchar(BS);
  104.                         outchar('-');
  105.                         break;
  106.                     case 10:
  107.                         outchar(BS);
  108.                         outchar('=');
  109.                         break;
  110.                     case 20:
  111.                         outchar(BS);
  112.                         outchar('≡');
  113.                         break;
  114.                     case 30:
  115.                         outchar(BS);
  116.                         outchar('=');
  117.                         break;
  118.                     case 40:
  119.                         c=0;
  120.                         break;
  121.                     default:
  122.                         if(!inDV && !(node_misc&NM_WINOS2))
  123.                             mswait(DELAY_SPIN);
  124.                         break;  }
  125.                 break;
  126.             case 3:
  127.                 switch(c++) {
  128.                     case 0:
  129.                         outchar(BS);
  130.                         outchar('┌');
  131.                         break;
  132.                     case 10:
  133.                         outchar(BS);
  134.                         outchar('└');
  135.                         break;
  136.                     case 20:
  137.                         outchar(BS);
  138.                         outchar('┘');
  139.                         break;
  140.                     case 30:
  141.                         outchar(BS);
  142.                         outchar('┐');
  143.                         break;
  144.                     case 40:
  145.                         c=0;
  146.                         break;
  147.                     default:
  148.                         if(!inDV && !(node_misc&NM_WINOS2))
  149.                             mswait(DELAY_SPIN);
  150.                         break;  }
  151.                 break;
  152.             case 4:
  153.                 switch(c++) {
  154.                     case 0:
  155.                         outchar(BS);
  156.                         outchar('▄');
  157.                         break;
  158.                     case 10:
  159.                         outchar(BS);
  160.                         outchar('▐');
  161.                         break;
  162.                     case 20:
  163.                         outchar(BS);
  164.                         outchar('▀');
  165.                         break;
  166.                     case 30:
  167.                         outchar(BS);
  168.                         outchar('▌');
  169.                         break;
  170.                     case 40:
  171.                         c=0;
  172.                         break;
  173.                     default:
  174.                         if(!inDV && !(node_misc&NM_WINOS2))
  175.                             mswait(DELAY_SPIN);
  176.                         break;  }
  177.                 break; }
  178.     if(keybuftop!=keybufbot) {
  179.         ch=keybuf[keybufbot++];
  180.         if(keybufbot==KEY_BUFSIZE)
  181.             keybufbot=0; }
  182.     else
  183.         ch=inkey(mode);
  184.     if(sys_status&SS_ABORT)
  185.         return(0);
  186.     now=time(NULL);
  187.     if(ch) {
  188.         if(mode&K_NUMBER && isprint(ch) && !isdigit(ch))
  189.             continue;
  190.         if(mode&K_ALPHA && isprint(ch) && !isalpha(ch))
  191.             continue;
  192.         if(mode&K_NOEXASC && ch&0x80)
  193.             continue;
  194.         if(mode&K_SPIN)
  195.             bputs("\b \b");
  196.         if(mode&K_COLD && ch>SP && useron.misc&COLDKEYS) {
  197.             if(mode&K_UPPER)
  198.                 outchar(toupper(ch));
  199.             else
  200.                 outchar(ch);
  201.             while((coldkey=inkey(mode))==0 && online && !(sys_status&SS_ABORT))
  202.                 checkline();
  203.             bputs("\b \b");
  204.             if(coldkey==BS)
  205.                 continue;
  206.             if(coldkey>SP)
  207.                 ungetkey(coldkey); }
  208.         if(mode&K_UPPER)
  209.             return(toupper(ch));
  210.         return(ch); }
  211.     if(sys_status&SS_USERON && !(sys_status&SS_LCHAT)) gettimeleft();
  212.     else if(online &&
  213.         ((node_dollars_per_call && now-answertime>SEC_BILLING)
  214.         || (now-answertime>SEC_LOGON && !(sys_status&SS_LCHAT)))) {
  215.         console&=~(CON_R_ECHOX|CON_L_ECHOX);
  216.         console|=(CON_R_ECHO|CON_L_ECHO);
  217.         bputs(text[TakenTooLongToLogon]);
  218.         hangup(); }
  219.     if(sys_status&SS_USERON && online && (timeleft/60)<(5-timeleft_warn)
  220.         && !SYSOP && !(sys_status&SS_LCHAT)) {
  221.         timeleft_warn=5-(timeleft/60);
  222.         SAVELINE;
  223.         attr(LIGHTGRAY);
  224.         bprintf(text[OnlyXminutesLeft]
  225.             ,((ushort)timeleft/60)+1,(timeleft/60) ? "s" : nulstr);
  226.         RESTORELINE; }
  227.  
  228.     if(online==ON_LOCAL && node_misc&NM_NO_INACT)
  229.         timeout=now;
  230.     if(now-timeout>=sec_warn) {                     /* warning */
  231.         if(sys_status&SS_USERON) {
  232.             SAVELINE;
  233.             bputs(text[AreYouThere]); }
  234.         else
  235.             bputs("\7\7");
  236.         while(!inkey(0) && online && now-timeout>=sec_warn) {
  237.             now=time(NULL);
  238.             if(now-timeout>=sec_hangup) {
  239.                 if(online==ON_REMOTE) {
  240.                     console|=CON_R_ECHO;
  241.                     console&=~CON_R_ECHOX; }
  242.                 bputs(text[CallBackWhenYoureThere]);
  243.                 logline(nulstr,"Inactive");
  244.                 hangup();
  245.                 return(0); }
  246.             mswait(100); }
  247.         if(sys_status&SS_USERON) {
  248.             bputs("\r\1n\1>");
  249.             RESTORELINE; }
  250.         timeout=now; }
  251.  
  252.     } while(online);
  253. return(0);
  254. }
  255.  
  256. /****************************************************************************/
  257. /* This function lists users that are online.                               */
  258. /* If listself is true, it will list the current node.                      */
  259. /* Returns number of active nodes (not including current node).             */
  260. /****************************************************************************/
  261. int whos_online(char listself)
  262. {
  263.     int i,j;
  264.     node_t node;
  265.  
  266. CRLF;
  267. bputs(text[NodeLstHdr]);
  268. for(j=0,i=1;i<=sys_nodes && i<=sys_lastnode;i++) {
  269.     getnodedat(i,&node,0);
  270.     if(i==node_num) {
  271.         if(listself)
  272.             printnodedat(i,node);
  273.         continue; }
  274.     if(node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) {
  275.         printnodedat(i,node);
  276.         if(!lastnodemsg)
  277.             lastnodemsg=i;
  278.         j++; } }
  279. if(!j)
  280.     bputs(text[NoOtherActiveNodes]);
  281. return(j);
  282. }
  283.  
  284. /****************************************************************************/
  285. /* Displays the information for node number 'number' contained in 'node'    */
  286. /****************************************************************************/
  287. void printnodedat(uint number, node_t node)
  288. {
  289.     uint i;
  290.     char hour,mer[3];
  291.  
  292. attr(color[clr_nodenum]);
  293. bprintf("%3d  ",number);
  294. attr(color[clr_nodestatus]);
  295. switch(node.status) {
  296.     case NODE_WFC:
  297.         bputs("Waiting for call");
  298.         break;
  299.     case NODE_OFFLINE:
  300.         bputs("Offline");
  301.         break;
  302.     case NODE_NETTING:
  303.         bputs("Networking");
  304.         break;
  305.     case NODE_LOGON:
  306.         bputs("At logon prompt");
  307.         break;
  308.     case NODE_EVENT_WAITING:
  309.         bputs("Waiting for all nodes to become inactive");
  310.         break;
  311.     case NODE_EVENT_LIMBO:
  312.         bprintf("Waiting for node %d to finish external event",node.aux);
  313.         break;
  314.     case NODE_EVENT_RUNNING:
  315.         bputs("Running external event");
  316.         break;
  317.     case NODE_NEWUSER:
  318.         attr(color[clr_nodeuser]);
  319.         bputs("New user");
  320.         attr(color[clr_nodestatus]);
  321.         bputs(" applying for access ");
  322.         if(!node.connection)
  323.             bputs("Locally");
  324.         else
  325.             bprintf("at %ubps",node.connection);
  326.         break;
  327.     case NODE_QUIET:
  328.         if(!SYSOP) {
  329.             bputs("Waiting for call");
  330.             break; }
  331.     case NODE_INUSE:
  332.         if(node.misc&NODE_EXT) {
  333.             getnodeext(number,tmp);
  334.             bputs(tmp);
  335.             break; }
  336.         attr(color[clr_nodeuser]);
  337.         if(node.misc&NODE_ANON && !SYSOP)
  338.             bputs("UNKNOWN USER");
  339.         else
  340.             bputs(username(node.useron,tmp));
  341.         attr(color[clr_nodestatus]);
  342.         bputs(" ");
  343.         switch(node.action) {
  344.             case NODE_MAIN:
  345.                 bputs("at main menu");
  346.                 break;
  347.             case NODE_RMSG:
  348.                 bputs("reading messages");
  349.                 break;
  350.             case NODE_RMAL:
  351.                 bputs("reading mail");
  352.                 break;
  353.             case NODE_RSML:
  354.                 bputs("reading sent mail");
  355.                 break;
  356.             case NODE_RTXT:
  357.                 bputs("reading text files");
  358.                 break;
  359.             case NODE_PMSG:
  360.                 bputs("posting message");
  361.                 break;
  362.             case NODE_SMAL:
  363.                 bputs("sending mail");
  364.                 break;
  365.             case NODE_AMSG:
  366.                 bputs("posting auto-message");
  367.                 break;
  368.             case NODE_XTRN:
  369.                 if(!node.aux)
  370.                     bputs("at external program menu");
  371.                 else {
  372.                     bputs("running ");
  373.                     i=node.aux-1;
  374.                     if(SYSOP || chk_ar(xtrn[i]->ar,useron))
  375.                         bputs(xtrn[node.aux-1]->name);
  376.                     else
  377.                         bputs("external program"); }
  378.                 break;
  379.             case NODE_DFLT:
  380.                 bputs("changing defaults");
  381.                 break;
  382.             case NODE_XFER:
  383.                 bputs("at transfer menu");
  384.                 break;
  385.             case NODE_RFSD:
  386.                 bprintf("retrieving from device #%d",node.aux);
  387.                 break;
  388.             case NODE_DLNG:
  389.                 bprintf("downloading");
  390.                 break;
  391.             case NODE_ULNG:
  392.                 bputs("uploading");
  393.                 break;
  394.             case NODE_BXFR:
  395.                 bputs("transferring bidirectional");
  396.                 break;
  397.             case NODE_LFIL:
  398.                 bputs("listing files");
  399.                 break;
  400.             case NODE_LOGN:
  401.                 bputs("logging on");
  402.                 break;
  403.             case NODE_LCHT:
  404.                 bprintf("in local chat with %s",sys_op);
  405.                 break;
  406.             case NODE_MCHT:
  407.                 if(node.aux) {
  408.                     bprintf("in multinode chat channel %d",node.aux&0xff);
  409.                     if(node.aux&0x1f00) { /* password */
  410.                         outchar('*');
  411.                         if(SYSOP)
  412.                             bprintf(" %s",unpackchatpass(tmp,node)); } }
  413.                 else
  414.                     bputs("in multinode global chat channel");
  415.                 break;
  416.             case NODE_PAGE:
  417.                 bprintf("paging node %u for private chat",node.aux);
  418.                 break;
  419.             case NODE_PCHT:
  420.                 bprintf("in private chat with node %u",node.aux);
  421.                 break;
  422.             case NODE_GCHT:
  423.                 i=node.aux;
  424.                 if(i>=total_gurus)
  425.                     i=0;
  426.                 bprintf("chatting with %s",guru[i]->name);
  427.                 break;
  428.             case NODE_CHAT:
  429.                 bputs("in chat section");
  430.                 break;
  431.             case NODE_TQWK:
  432.                 bputs("transferring QWK packet");
  433.                 break;
  434.             case NODE_SYSP:
  435.                 bputs("performing sysop activities");
  436.                 break;
  437.             default:
  438.                 bputs(itoa(node.action,tmp,10));
  439.                 break;  }
  440.         if(!node.connection)
  441.             bputs(" locally");
  442.         else
  443.             bprintf(" at %ubps",node.connection);
  444.         if(node.action==NODE_DLNG) {
  445.             if(sys_misc&SM_MILITARY) {
  446.                 hour=node.aux/60;
  447.                 mer[0]=0; }
  448.             else if((node.aux/60)>=12) {
  449.                 if(node.aux/60==12)
  450.                     hour=12;
  451.                 else
  452.                     hour=(node.aux/60)-12;
  453.                 strcpy(mer,"pm"); }
  454.             else {
  455.                 if((node.aux/60)==0)    /* 12 midnite */
  456.                     hour=12;
  457.                 else hour=node.aux/60;
  458.                 strcpy(mer,"am"); }
  459.             bprintf(" ETA %02d:%02d %s"
  460.                 ,hour,node.aux%60,mer); }
  461.         break; }
  462. i=NODE_LOCK;
  463. if(node.status==NODE_INUSE || SYSOP)
  464.     i|=NODE_POFF|NODE_AOFF|NODE_MSGW|NODE_NMSG;
  465. if(node.misc&i) {
  466.     bputs(" (");
  467.     if(node.misc&(i&NODE_AOFF))
  468.         outchar('A');
  469.     if(node.misc&NODE_LOCK)
  470.         outchar('L');
  471.     if(node.misc&(i&(NODE_MSGW|NODE_NMSG)))
  472.         outchar('M');
  473.     if(node.misc&(i&NODE_POFF))
  474.         outchar('P');
  475.     outchar(')'); }
  476. if(SYSOP && ((node.misc
  477.     &(NODE_ANON|NODE_UDAT|NODE_INTR|NODE_RRUN|NODE_EVENT|NODE_DOWN))
  478.     || node.status==NODE_QUIET)) {
  479.     bputs(" [");
  480.     if(node.misc&NODE_ANON)
  481.         outchar('A');
  482.     if(node.misc&NODE_INTR)
  483.         outchar('I');
  484.     if(node.misc&NODE_RRUN)
  485.         outchar('R');
  486.     if(node.misc&NODE_UDAT)
  487.         outchar('U');
  488.     if(node.status==NODE_QUIET)
  489.         outchar('Q');
  490.     if(node.misc&NODE_EVENT)
  491.         outchar('E');
  492.     if(node.misc&NODE_DOWN)
  493.         outchar('D');
  494.     outchar(']'); }
  495. if(node.errors && SYSOP) {
  496.     attr(color[clr_err]);
  497.     bprintf(" %d error%c",node.errors, node.errors>1 ? 's' : '\0' ); }
  498. attr(LIGHTGRAY);
  499. CRLF;
  500. }
  501.  
  502. /****************************************************************************/
  503. /* Prints/updates the local status line (line #25) with the user/system     */
  504. /* information. Which info depends on value of statline.                    */
  505. /* Called from several functions                                            */
  506. /****************************************************************************/
  507. void statusline()
  508. {
  509.     int row,col,atr;
  510.     char tmp1[128],tmp2[256],tmp3[256],age;
  511.  
  512. #ifndef __OS2__
  513. if(lclaes())
  514.     return;
  515. #endif
  516. col=lclwx();
  517. row=lclwy();
  518. STATUSLINE;
  519. lclxy(1,node_scrnlen);
  520. age=getage(useron.birth);
  521. if(sys_status&(SS_CAP|SS_TMPSYSOP)) {
  522.     atr=lclatr((LIGHTGRAY<<4)|BLINK);
  523.     sys_status&SS_CAP ? lputc('C') : lputc(SP);
  524.     sys_status&SS_TMPSYSOP ? lputc('*') : lputc(SP);
  525.     lclatr(LIGHTGRAY<<4); }
  526. else {
  527.     atr=lclatr(LIGHTGRAY<<4);
  528.     lputs("  "); }
  529. switch(statline) {
  530.     case -1:
  531.         lputs("Terminal:  Alt-X Exit  Alt-D DOS  Alt-H Hangup  "
  532.             "Alt-L Logon  Alt-U User Edit");
  533.         break;
  534.     case 0:     /* Alias ML Password Modem Birthday Age Sex Phone */
  535.         lprintf("%-24.24s %02d %-8.8s %-8.8s %-8.8s %02d %c %s"
  536.             ,useron.alias,useron.level,sys_misc&SM_ECHO_PW ? useron.pass:"XXXX"
  537.             ,useron.modem,useron.birth,age,useron.sex,useron.phone);
  538.         break;
  539.     case 1:     /* Alias ML RealName Alt-Z for Help */
  540.         lprintf("%-24.24s %02d %-25.25s  "
  541.             ,useron.alias,useron.level,useron.name);
  542.         lputs("Alt-Z for Help");
  543.         break;
  544.     case 2:     /* Alias ML RealName Age Sex Phone */
  545.         lprintf("%-24.24s %02d %-25.25s  %02d %c %s"
  546.             ,useron.alias,useron.level,useron.name,age,useron.sex,useron.phone);
  547.         break;
  548.     case 3:     /* Alias ML Location Phone */
  549.         lprintf("%-24.24s %02d %-30.30s  %s"
  550.             ,useron.alias,useron.level,useron.location,useron.phone);
  551.         break;
  552.     case 4:     /* Alias ML Note Phone */
  553.         lprintf("%-24.24s %02d %-30.30s  %s"
  554.             ,useron.alias,useron.level,useron.note,useron.phone);
  555.         break;
  556.     case 5:     /* Alias ML MF Age Sex Phone */
  557.         lprintf("%-24.24s %02d %-26.26s %02d %c %s"
  558.             ,useron.alias,useron.level,ltoaf(useron.flags1,tmp1)
  559.             ,age,useron.sex,useron.phone);
  560.         break;
  561.     case 6:     /* Alias ML MF Expiration */
  562.         lprintf("%-24.24s %02d %-26.26s Exp: %s"
  563.             ,useron.alias,useron.level,ltoaf(useron.flags1,tmp1)
  564.             ,unixtodstr(useron.expire,tmp2));
  565.         break;
  566.     case 7:     /* Alias ML Firston Laston Expire */
  567.         lprintf("%-24.24s %02d First: %s Last: %s Exp: %s"
  568.             ,useron.alias,useron.level,unixtodstr(useron.firston,tmp1)
  569.             ,unixtodstr(useron.laston,tmp2),unixtodstr(useron.expire,tmp3));
  570.         break;
  571.     case 8:     /* Alias Credits Minutes Expire */
  572.         lprintf("%-24.24s Cdt: %-13.13s Min: %-10luExp: %s"
  573.             ,useron.alias,ultoac(useron.cdt,tmp1),useron.min
  574.             ,unixtodstr(useron.expire,tmp2));
  575.         break;
  576.     case 9:    /* Exemptions Restrictions */
  577.         lprintf("  Exempt:%-26.26s   Restrict:%s"
  578.             ,ltoaf(useron.exempt,tmp1),ltoaf(useron.rest,tmp2));
  579.         break;
  580.     case 10:    /* Computer Modem Handle*/
  581.         lprintf("Comp: %-30.30s  Modem: %-8.8s  Handle: %s"
  582.             ,useron.comp,connection,useron.handle);
  583.         break;
  584.     case 11:    /* StreetAddress Location Zip */
  585.         lprintf("%-30.30s %-30.30s %s"
  586.             ,useron.address,useron.location,useron.zipcode);
  587.         break;
  588.     case 12:    /* UploadBytes Uploads DownloadBytes Downloads Leeches */
  589.         lprintf("Uloads: %-13.13s / %-5u Dloads: %-13.13s / %-5u Leech: %u"
  590.             ,ultoac(useron.ulb,tmp1),useron.uls
  591.             ,ultoac(useron.dlb,tmp2),useron.dls,useron.leech);
  592.         break;
  593.     case 13:    /* Posts Emails Fbacks Waiting Logons Timeon */
  594.         lprintf("P: %-5u E: %-5u F: %-5u W: %-5u L: %-5u T: %-5u"
  595.             ,useron.posts,useron.emails,useron.fbacks,getmail(useron.number,0)
  596.             ,useron.logons,useron.timeon);
  597.         break;
  598.     case 14:    /* NetMail forwarding address */
  599.         lprintf("NetMail: %s",useron.netmail);
  600.         break;
  601.     case 15:    /* Comment */
  602.         lprintf("Comment: %s",useron.comment);
  603.         break;
  604.         }
  605. lputc(CLREOL);
  606. lclxy(75,lclwy());
  607. getnodedat(node_num,&thisnode,0);
  608. if(sys_status&SS_SYSALERT
  609.     || thisnode.misc&(NODE_RRUN|NODE_DOWN|NODE_LOCK|NODE_EVENT)) {
  610.     lclatr((LIGHTGRAY<<4)|BLINK);
  611.     sys_status&SS_SYSALERT ? lputc('A'):lputc(SP);
  612.     thisnode.misc&NODE_RRUN ? lputc('R'):lputc(SP);
  613.     thisnode.misc&NODE_DOWN ? lputc('D'):lputc(SP);
  614.     thisnode.misc&NODE_LOCK ? lputc('L'):lputc(SP);
  615.     thisnode.misc&NODE_EVENT ? lputc('E'):lputc(SP); }
  616. TEXTWINDOW;
  617. lclxy(col,row);
  618. lclatr(atr);
  619. }
  620.  
  621. /****************************************************************************/
  622. /* Prints PAUSE message and waits for a key stoke                           */
  623. /****************************************************************************/
  624. void pause()
  625. {
  626.     uchar tempattrs=curatr; /* was lclatr(-1) */
  627.     int i,j;
  628.     long l=K_UPPER;
  629.  
  630. RIOSYNC(0);
  631. if(sys_status&SS_ABORT)
  632.     return;
  633. lncntr=0;
  634. if(online==ON_REMOTE)
  635.     rioctl(IOFI);
  636. bputs(text[Pause]);
  637. j=bstrlen(text[Pause]);
  638. if(sys_status&SS_USERON && !(useron.misc&NO_EXASCII) && !(useron.misc&WIP))
  639.     l|=K_SPIN;
  640. if(getkey(l)==text[YN][1])
  641.     sys_status|=SS_ABORT;
  642. if(text[Pause][0]!='@')
  643.     for(i=0;i<j;i++)
  644.         bputs("\b \b");
  645. getnodedat(node_num,&thisnode,0);
  646. nodesync();
  647. attr(tempattrs);
  648. }
  649.  
  650. void getlines()
  651. {
  652. if(useron.misc&ANSI && !useron.rows         /* Auto-detect rows */
  653.     && online==ON_REMOTE) {                 /* Remote */
  654.     SYNC;   
  655.     putcom("\x1b[s\x1b[99B\x1b[6n\x1b[u");
  656.     while(online && !rioctl(RXBC) && !lkbrd(1))
  657.         checkline();
  658.     inkey(0); }
  659.  
  660. }
  661.  
  662.  
  663. /****************************************************************************/
  664. /* Prints a file remotely and locally, interpreting ^A sequences, checks    */
  665. /* for pauses, aborts and ANSI. 'str' is the path of the file to print      */
  666. /* Called from functions menu and text_sec                                  */
  667. /****************************************************************************/
  668. void printfile(char *str, int mode)
  669. {
  670.     char HUGE16 *buf;
  671.     int file,wip=0,rip=0;
  672.     long length,savcon=console;
  673.     FILE *stream;
  674.  
  675. if(strstr(str,".WIP"))
  676.     wip=1;
  677. if(strstr(str,".RIP"))
  678.     rip=1;
  679.  
  680. if(mode&P_NOABORT || wip || rip) {
  681.     if(online==ON_REMOTE && console&CON_R_ECHO) {
  682.         rioctl(IOCM|ABORT);
  683.         rioctl(IOCS|ABORT); }
  684.     sys_status&=~SS_ABORT; }
  685.  
  686. if(!tos && !wip && !rip)
  687.     CRLF;
  688.  
  689. if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
  690.     bputs(text[FileNotFound]);
  691.     if(SYSOP) bputs(str);
  692.     CRLF;
  693.     return; }
  694.  
  695. if(wip || rip || !(console&CON_L_ECHO)) {
  696.     if(online!=ON_REMOTE || !(console&CON_R_ECHO)) {
  697.         fclose(stream);
  698.         return; }
  699.     console&=~CON_L_ECHO;
  700.     lprintf("PRINTFILE (Remote Only): %s\r\n",str);  }
  701. if(mode&P_OPENCLOSE) {
  702.     length=filelength(file);
  703.     if((buf=MALLOC(length+1L))==NULL) {
  704.         close(file);
  705.         console=savcon;
  706.         errormsg(WHERE,ERR_ALLOC,str,length+1L);
  707.         return; }
  708.     buf[lread(file,buf,length)]=0;
  709.     fclose(stream);
  710.     putmsg(buf,mode);
  711.     FREE((char *)buf); }
  712. else {
  713.     putmsg_fp(stream,filelength(file),mode);
  714.     fclose(stream); }
  715. if((mode&P_NOABORT || wip || rip) && online==ON_REMOTE) {
  716.     SYNC;
  717.     rioctl(IOSM|ABORT); }
  718. if(rip)
  719.     getlines();
  720. console=savcon;
  721. }
  722.  
  723. void printtail(char *str, int lines, int mode)
  724. {
  725.     char HUGE16 *buf,HUGE16 *p;
  726.     int file,cur=0;
  727.     ulong length,l;
  728.  
  729. if(mode&P_NOABORT) {
  730.     if(online==ON_REMOTE) {
  731.         rioctl(IOCM|ABORT);
  732.         rioctl(IOCS|ABORT); }
  733.     sys_status&=~SS_ABORT; }
  734. strupr(str);
  735. if(!tos) {
  736.     CRLF; }
  737. if((file=nopen(str,O_RDONLY))==-1) {
  738.     bputs(text[FileNotFound]);
  739.     if(SYSOP) bputs(str);
  740.     CRLF;
  741.     return; }
  742. length=filelength(file);
  743. if((buf=MALLOC(length+1L))==NULL) {
  744.     close(file);
  745.     errormsg(WHERE,ERR_ALLOC,str,length+1L);
  746.     return; }
  747. l=lread(file,buf,length);
  748. buf[l]=0;
  749. close(file);
  750. p=(buf+l)-1;
  751. if(*p==LF) p--;
  752. while(*p && p>buf) {
  753.     if(*p==LF)
  754.         cur++;
  755.     if(cur>=lines) {
  756.         p++;
  757.         break; }
  758.     p--; }
  759. putmsg(p,mode);
  760. if(mode&P_NOABORT && online==ON_REMOTE) {
  761.     SYNC;
  762.     rioctl(IOSM|ABORT); }
  763. FREE((char *)buf);
  764. }
  765.  
  766. /****************************************************************************/
  767. /* Prints the menu number 'menunum' from the text directory. Checks for ^A  */
  768. /* ,ANSI sequences, pauses and aborts. Usually accessed by user inputing '?'*/
  769. /* Called from every function that has an available menu.                   */
  770. /* The code definitions are as follows:                                     */
  771. /****************************************************************************/
  772. void menu(char *code)
  773. {
  774.     char str[256],path[256];
  775.     int c,i,l;
  776.  
  777. sys_status&=~SS_ABORT;
  778. if(menu_file[0])
  779.     strcpy(path,menu_file);
  780. else {
  781.     sprintf(str,"%sMENU\\",text_dir);
  782.     if(menu_dir[0]) {
  783.         strcat(str,menu_dir);
  784.         strcat(str,"\\"); }
  785.     strcat(str,code);
  786.     strcat(str,".");
  787.     sprintf(path,"%s%s",str,useron.misc&WIP ? "WIP":"RIP");
  788.     if(!(useron.misc&(RIP|WIP)) || !fexist(path)) {
  789.         sprintf(path,"%sMON",str);
  790.         if((useron.misc&(COLOR|ANSI))!=ANSI || !fexist(path)) {
  791.             sprintf(path,"%sANS",str);
  792.             if(!(useron.misc&ANSI) || !fexist(path))
  793.                 sprintf(path,"%sASC",str); } } }
  794.  
  795. printfile(path,P_OPENCLOSE);
  796. }
  797.  
  798. /****************************************************************************/
  799. /* Puts a character into the input buffer                                   */
  800. /****************************************************************************/
  801. void ungetkey(char ch)
  802. {
  803.  
  804. keybuf[keybuftop++]=ch;
  805. if(keybuftop==KEY_BUFSIZE)
  806.     keybuftop=0;
  807. }
  808.  
  809.