|
|
1.1 ! root 1: /* con_out.cpp */ ! 2: ! 3: /* Synchronet console output routines */ ! 4: ! 5: /* $Id: con_out.cpp,v 1.51 2006/08/23 01:45:05 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: ! 39: /**********************************************************************/ ! 40: /* Functions that pertain to console i/o - color, strings, chars etc. */ ! 41: /* Called from functions everywhere */ ! 42: /**********************************************************************/ ! 43: ! 44: #include "sbbs.h" ! 45: ! 46: /***************************************************/ ! 47: /* Seven bit table for EXASCII to ASCII conversion */ ! 48: /***************************************************/ ! 49: static const char *sbtbl="CUeaaaaceeeiiiAAEaAooouuyOUcLYRfaiounNao?--24!<>" ! 50: "###||||++||++++++--|-+||++--|-+----++++++++##[]#" ! 51: "abrpEout*ono%0ENE+><rj%=o..+n2* "; ! 52: ! 53: /****************************************************************************/ ! 54: /* Convert string from IBM extended ASCII to just ASCII */ ! 55: /****************************************************************************/ ! 56: char* DLLCALL ascii_str(uchar* str) ! 57: { ! 58: size_t i; ! 59: ! 60: for(i=0;str[i];i++) ! 61: if(str[i]&0x80) ! 62: str[i]=sbtbl[str[i]^0x80]; /* seven bit table */ ! 63: else if(str[i]==CTRL_A /* ctrl-a */ ! 64: && str[i+1]!=0) /* valid */ ! 65: i++; /* skip the attribute code */ ! 66: ! 67: return((char*)str); ! 68: } ! 69: ! 70: /****************************************************************************/ ! 71: /* Outputs a NULL terminated string locally and remotely (if applicable) */ ! 72: /* Handles ctrl-a characters */ ! 73: /****************************************************************************/ ! 74: int sbbs_t::bputs(char *str) ! 75: { ! 76: int i; ! 77: ulong l=0; ! 78: ! 79: if(online==ON_LOCAL && console&CON_L_ECHO) /* script running as event */ ! 80: return(eprintf(LOG_INFO,"%s",str)); ! 81: ! 82: while(str[l]) { ! 83: if(str[l]==CTRL_A /* ctrl-a */ ! 84: && str[l+1]!=0) { /* valid */ ! 85: ctrl_a(str[++l]); /* skip the ctrl-a */ ! 86: l++; /* skip the attribute code */ ! 87: continue; ! 88: } ! 89: if(str[l]=='@') { /* '@' */ ! 90: if(str==mnestr /* Mnemonic string or */ ! 91: || (str>=text[0] /* Straight out of TEXT.DAT */ ! 92: && str<=text[TOTAL_TEXT-1])) { ! 93: i=show_atcode(str+l); /* return 0 if not valid @ code */ ! 94: l+=i; /* i is length of code string */ ! 95: if(i) /* if valid string, go to top */ ! 96: continue; ! 97: } ! 98: for(i=0;i<TOTAL_TEXT;i++) ! 99: if(str==text[i]) ! 100: break; ! 101: if(i<TOTAL_TEXT) { /* Replacement text */ ! 102: i=show_atcode(str+l); ! 103: l+=i; ! 104: if(i) ! 105: continue; ! 106: } ! 107: } ! 108: outchar(str[l++]); ! 109: } ! 110: return(l); ! 111: } ! 112: ! 113: /****************************************************************************/ ! 114: /* Outputs a NULL terminated string locally and remotely (if applicable) */ ! 115: /* Does not expand ctrl-a characters (raw) */ ! 116: /* Max length of str is 64 kbytes */ ! 117: /****************************************************************************/ ! 118: int sbbs_t::rputs(char *str) ! 119: { ! 120: ulong l=0; ! 121: ! 122: if(online==ON_LOCAL && console&CON_L_ECHO) /* script running as event */ ! 123: return(eprintf(LOG_INFO,"%s",str)); ! 124: ! 125: while(str[l]) ! 126: outchar(str[l++]); ! 127: return(l); ! 128: } ! 129: ! 130: /****************************************************************************/ ! 131: /* Performs printf() using bbs bputs function */ ! 132: /****************************************************************************/ ! 133: int sbbs_t::bprintf(char *fmt, ...) ! 134: { ! 135: va_list argptr; ! 136: char sbuf[4096]; ! 137: ! 138: if(strchr(fmt,'%')==NULL) ! 139: return(bputs(fmt)); ! 140: va_start(argptr,fmt); ! 141: vsnprintf(sbuf,sizeof(sbuf),fmt,argptr); ! 142: sbuf[sizeof(sbuf)-1]=0; /* force termination */ ! 143: va_end(argptr); ! 144: return(bputs(sbuf)); ! 145: } ! 146: ! 147: /****************************************************************************/ ! 148: /* Performs printf() using bbs rputs function */ ! 149: /****************************************************************************/ ! 150: int sbbs_t::rprintf(char *fmt, ...) ! 151: { ! 152: va_list argptr; ! 153: char sbuf[4096]; ! 154: ! 155: va_start(argptr,fmt); ! 156: vsnprintf(sbuf,sizeof(sbuf),fmt,argptr); ! 157: sbuf[sizeof(sbuf)-1]=0; /* force termination */ ! 158: va_end(argptr); ! 159: return(rputs(sbuf)); ! 160: } ! 161: ! 162: /****************************************************************************/ ! 163: /* Outputs destructive backspace locally and remotely (if applicable), */ ! 164: /****************************************************************************/ ! 165: void sbbs_t::backspace(void) ! 166: { ! 167: int oldconsole; ! 168: ! 169: oldconsole=console; ! 170: console &= ~(CON_R_ECHOX|CON_L_ECHOX); ! 171: outchar('\b'); ! 172: outchar(' '); ! 173: outchar('\b'); ! 174: console=oldconsole; ! 175: } ! 176: ! 177: /****************************************************************************/ ! 178: /* Returns true if the user (or the yet-to-be-logged-in client) supports */ ! 179: /* all of the specified terminal 'cmp_flags' (e.g. ANSI, COLOR, RIP). */ ! 180: /* If no flags specified, returns all terminal flag bits supported */ ! 181: /****************************************************************************/ ! 182: long sbbs_t::term_supports(long cmp_flags) ! 183: { ! 184: long flags = sys_status&SS_USERON ? useron.misc : autoterm; ! 185: ! 186: return(cmp_flags ? ((flags&cmp_flags)==cmp_flags) : (flags&TERM_FLAGS)); ! 187: } ! 188: ! 189: /****************************************************************************/ ! 190: /* Outputs character locally and remotely (if applicable), preforming echo */ ! 191: /* translations (X's and r0dent emulation) if applicable. */ ! 192: /****************************************************************************/ ! 193: void sbbs_t::outchar(char ch) ! 194: { ! 195: int i; ! 196: ! 197: if(console&CON_ECHO_OFF) ! 198: return; ! 199: if(ch==ESC) ! 200: outchar_esc=1; ! 201: else if(outchar_esc==1) { ! 202: if(ch=='[') ! 203: outchar_esc++; ! 204: else ! 205: outchar_esc=0; ! 206: } ! 207: else if(outchar_esc==2) { ! 208: if((ch>='@' && ch<='Z') || (ch>='a' && ch<='z')) ! 209: outchar_esc++; ! 210: } ! 211: else ! 212: outchar_esc=0; ! 213: if(term_supports(NO_EXASCII) && ch&0x80) ! 214: ch=sbtbl[(uchar)ch^0x80]; /* seven bit table */ ! 215: if(ch==FF && lncntr>1 && !tos) { ! 216: lncntr=0; ! 217: CRLF; ! 218: if(!(sys_status&SS_PAUSEOFF)) { ! 219: pause(); ! 220: while(lncntr && online && !(sys_status&SS_ABORT)) ! 221: pause(); ! 222: sys_status&=~SS_ABORT; ! 223: } ! 224: } ! 225: #if 0 ! 226: if(sys_status&SS_CAP /* Writes to Capture File */ ! 227: && (sys_status&SS_ANSCAP || (ch!=ESC /* && !lclaes() */))) ! 228: fwrite(&ch,1,1,capfile); ! 229: #endif ! 230: #if 0 ! 231: if(console&CON_L_ECHO) { ! 232: if(console&CON_L_ECHOX && (uchar)ch>=' ') ! 233: putch(password_char); ! 234: else if(cfg.node_misc&NM_NOBEEP && ch==BEL); /* Do nothing if beep */ ! 235: else if(ch==BEL) { ! 236: sbbs_beep(2000,110); ! 237: nosound(); ! 238: } ! 239: else putch(ch); ! 240: } ! 241: #endif ! 242: ! 243: if(online==ON_REMOTE && console&CON_R_ECHO) { ! 244: if(console&CON_R_ECHOX && (uchar)ch>=' ' && !outchar_esc) { ! 245: ch=text[YN][3]; ! 246: if(text[YN][2]==0 || ch==0) ch='X'; ! 247: } ! 248: if(ch==FF && term_supports(ANSI)) { ! 249: putcom("\x1b[2J\x1b[H"); /* clear screen, home cursor */ ! 250: } ! 251: else { ! 252: if(ch==(char)TELNET_IAC && !(telnet_mode&TELNET_MODE_OFF)) ! 253: outcom(TELNET_IAC); /* Must escape Telnet IAC char (255) */ ! 254: i=0; ! 255: while(outcom(ch)&TXBOF && i<1440) { /* 3 minute pause delay */ ! 256: if(!online) ! 257: break; ! 258: i++; ! 259: if(sys_status&SS_SYSPAGE) ! 260: sbbs_beep(i,80); ! 261: else ! 262: mswait(80); ! 263: } ! 264: if(i==1440) { /* timeout - beep flush outbuf */ ! 265: i=rioctl(TXBC); ! 266: lprintf(LOG_NOTICE,"timeout(outchar) %04X %04X\r\n",i,rioctl(IOFO)); ! 267: outcom(BEL); ! 268: rioctl(IOCS|PAUSE); ! 269: } ! 270: } ! 271: } ! 272: if(ch==LF) { ! 273: lncntr++; ! 274: lbuflen=0; ! 275: tos=0; ! 276: } else if(ch==FF) { ! 277: lncntr=0; ! 278: lbuflen=0; ! 279: tos=1; ! 280: } else { ! 281: if(!lbuflen) ! 282: latr=curatr; ! 283: if(lbuflen<LINE_BUFSIZE) ! 284: lbuf[lbuflen++]=ch; ! 285: } ! 286: if(outchar_esc==3) ! 287: outchar_esc=0; ! 288: ! 289: if(lncntr==rows-1 && ((useron.misc&UPAUSE) || sys_status&SS_PAUSEON) ! 290: && !(sys_status&SS_PAUSEOFF)) { ! 291: lncntr=0; ! 292: pause(); ! 293: } ! 294: } ! 295: ! 296: void sbbs_t::center(char *instr) ! 297: { ! 298: char str[256]; ! 299: int i,j; ! 300: ! 301: SAFECOPY(str,instr); ! 302: truncsp(str); ! 303: j=bstrlen(str); ! 304: for(i=0;i<(cols-j)/2;i++) ! 305: outchar(' '); ! 306: bputs(str); ! 307: CRLF; ! 308: } ! 309: ! 310: void sbbs_t::clearline(void) ! 311: { ! 312: int i; ! 313: ! 314: outchar(CR); ! 315: if(term_supports(ANSI)) ! 316: rputs("\x1b[K"); ! 317: else { ! 318: for(i=0;i<cols-1;i++) ! 319: outchar(' '); ! 320: outchar(CR); ! 321: } ! 322: } ! 323: ! 324: void sbbs_t::cursor_home(void) ! 325: { ! 326: if(term_supports(ANSI)) ! 327: rputs("\x1b[H"); ! 328: else ! 329: outchar(FF); ! 330: } ! 331: ! 332: void sbbs_t::cursor_up(int count) ! 333: { ! 334: if(count<1) ! 335: return; ! 336: if(!term_supports(ANSI)) ! 337: return; ! 338: if(count>1) ! 339: rprintf("\x1b[%dA",count); ! 340: else ! 341: rputs("\x1b[A"); ! 342: } ! 343: ! 344: void sbbs_t::cursor_down(int count) ! 345: { ! 346: if(count<1) ! 347: return; ! 348: if(!term_supports(ANSI)) ! 349: return; ! 350: if(count>1) ! 351: rprintf("\x1b[%dB",count); ! 352: else ! 353: rputs("\x1b[B"); ! 354: } ! 355: ! 356: void sbbs_t::cursor_right(int count) ! 357: { ! 358: if(count<1) ! 359: return; ! 360: if(term_supports(ANSI)) { ! 361: if(count>1) ! 362: rprintf("\x1b[%dC",count); ! 363: else ! 364: rputs("\x1b[C"); ! 365: } else { ! 366: for(int i=0;i<count;i++) ! 367: outchar(' '); ! 368: } ! 369: } ! 370: ! 371: void sbbs_t::cursor_left(int count) ! 372: { ! 373: if(count<1) ! 374: return; ! 375: if(term_supports(ANSI)) { ! 376: if(count>1) ! 377: rprintf("\x1b[%dD",count); ! 378: else ! 379: rputs("\x1b[D"); ! 380: } else { ! 381: for(int i=0;i<count;i++) ! 382: outchar('\b'); ! 383: } ! 384: } ! 385: ! 386: void sbbs_t::cleartoeol(void) ! 387: { ! 388: if(term_supports(ANSI)) ! 389: rputs("\x1b[K"); ! 390: #if 0 ! 391: else { ! 392: i=j=lclwx(); /* commented out */ ! 393: while(i++<79) ! 394: outchar(' '); ! 395: while(j++<79) ! 396: outchar(BS); ! 397: } ! 398: #endif ! 399: } ! 400: ! 401: /****************************************************************************/ ! 402: /* performs the correct attribute modifications for the Ctrl-A code */ ! 403: /****************************************************************************/ ! 404: void sbbs_t::ctrl_a(char x) ! 405: { ! 406: char tmp1[128],atr=curatr; ! 407: struct tm tm; ! 408: ! 409: if(x && (uchar)x<=CTRL_Z) { /* Ctrl-A through Ctrl-Z for users with MF only */ ! 410: if(!(useron.flags1&FLAG(x+64))) ! 411: console^=(CON_ECHO_OFF); ! 412: return; ! 413: } ! 414: if((uchar)x>0x7f) { ! 415: cursor_right((uchar)x-0x7f); ! 416: return; ! 417: } ! 418: switch(toupper(x)) { ! 419: case '!': /* level 10 or higher */ ! 420: if(useron.level<10) ! 421: console^=CON_ECHO_OFF; ! 422: break; ! 423: case '@': /* level 20 or higher */ ! 424: if(useron.level<20) ! 425: console^=CON_ECHO_OFF; ! 426: break; ! 427: case '#': /* level 30 or higher */ ! 428: if(useron.level<30) ! 429: console^=CON_ECHO_OFF; ! 430: break; ! 431: case '$': /* level 40 or higher */ ! 432: if(useron.level<40) ! 433: console^=CON_ECHO_OFF; ! 434: break; ! 435: case '%': /* level 50 or higher */ ! 436: if(useron.level<50) ! 437: console^=CON_ECHO_OFF; ! 438: break; ! 439: case '^': /* level 60 or higher */ ! 440: if(useron.level<60) ! 441: console^=CON_ECHO_OFF; ! 442: break; ! 443: case '&': /* level 70 or higher */ ! 444: if(useron.level<70) ! 445: console^=CON_ECHO_OFF; ! 446: break; ! 447: case '*': /* level 80 or higher */ ! 448: if(useron.level<80) ! 449: console^=CON_ECHO_OFF; ! 450: break; ! 451: case '(': /* level 90 or higher */ ! 452: if(useron.level<90) ! 453: console^=CON_ECHO_OFF; ! 454: break; ! 455: case ')': /* turn echo back on */ ! 456: console&=~CON_ECHO_OFF; ! 457: break; ! 458: case '+': /* push current attribte */ ! 459: if(attr_sp<(int)sizeof(attr_stack)) ! 460: attr_stack[attr_sp++]=curatr; ! 461: break; ! 462: case '-': /* pop current attribute OR optimized "normal" */ ! 463: if(attr_sp>0) ! 464: attr(attr_stack[--attr_sp]); ! 465: else /* turn off all attributes if */ ! 466: if(atr&(HIGH|BLINK|BG_LIGHTGRAY)) /* high intensity, blink or */ ! 467: attr(LIGHTGRAY); /* background bits are set */ ! 468: break; ! 469: case '_': /* turn off all attributes if */ ! 470: if(atr&(BLINK|BG_LIGHTGRAY)) /* blink or background is set */ ! 471: attr(LIGHTGRAY); ! 472: break; ! 473: case 'P': /* Pause */ ! 474: pause(); ! 475: break; ! 476: case 'Q': /* Pause reset */ ! 477: lncntr=0; ! 478: break; ! 479: case 'T': /* Time */ ! 480: now=time(NULL); ! 481: localtime_r(&now,&tm); ! 482: bprintf("%02d:%02d %s" ! 483: ,tm.tm_hour==0 ? 12 ! 484: : tm.tm_hour>12 ? tm.tm_hour-12 ! 485: : tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am"); ! 486: break; ! 487: case 'D': /* Date */ ! 488: now=time(NULL); ! 489: bputs(unixtodstr(&cfg,now,tmp1)); ! 490: break; ! 491: case ',': /* Delay 1/10 sec */ ! 492: mswait(100); ! 493: break; ! 494: case ';': /* Delay 1/2 sec */ ! 495: mswait(500); ! 496: break; ! 497: case '.': /* Delay 2 secs */ ! 498: mswait(2000); ! 499: break; ! 500: case 'S': /* Synchronize */ ! 501: ASYNC; ! 502: break; ! 503: case 'L': /* CLS (form feed) */ ! 504: CLS; ! 505: break; ! 506: case '>': /* CLREOL */ ! 507: cleartoeol(); ! 508: break; ! 509: case '<': /* Non-destructive backspace */ ! 510: outchar(BS); ! 511: break; ! 512: case '[': /* Carriage return */ ! 513: outchar(CR); ! 514: break; ! 515: case ']': /* Line feed */ ! 516: outchar(LF); ! 517: break; ! 518: case 'A': /* Ctrl-A */ ! 519: outchar(CTRL_A); ! 520: break; ! 521: case 'H': /* High intensity */ ! 522: atr|=HIGH; ! 523: attr(atr); ! 524: break; ! 525: case 'I': /* Blink */ ! 526: atr|=BLINK; ! 527: attr(atr); ! 528: break; ! 529: case 'N': /* Normal */ ! 530: attr(LIGHTGRAY); ! 531: break; ! 532: case 'R': ! 533: atr=(atr&0xf8)|RED; ! 534: attr(atr); ! 535: break; ! 536: case 'G': ! 537: atr=(atr&0xf8)|GREEN; ! 538: attr(atr); ! 539: break; ! 540: case 'B': ! 541: atr=(atr&0xf8)|BLUE; ! 542: attr(atr); ! 543: break; ! 544: case 'W': /* White */ ! 545: atr=(atr&0xf8)|LIGHTGRAY; ! 546: attr(atr); ! 547: break; ! 548: case 'C': ! 549: atr=(atr&0xf8)|CYAN; ! 550: attr(atr); ! 551: break; ! 552: case 'M': ! 553: atr=(atr&0xf8)|MAGENTA; ! 554: attr(atr); ! 555: break; ! 556: case 'Y': /* Yellow */ ! 557: atr=(atr&0xf8)|BROWN; ! 558: attr(atr); ! 559: break; ! 560: case 'K': /* Black */ ! 561: atr=(atr&0xf8)|BLACK; ! 562: attr(atr); ! 563: break; ! 564: case '0': /* Black Background */ ! 565: atr=(atr&0x8f); ! 566: attr(atr); ! 567: break; ! 568: case '1': /* Red Background */ ! 569: atr=(atr&0x8f)|(uchar)BG_RED; ! 570: attr(atr); ! 571: break; ! 572: case '2': /* Green Background */ ! 573: atr=(atr&0x8f)|(uchar)BG_GREEN; ! 574: attr(atr); ! 575: break; ! 576: case '3': /* Yellow Background */ ! 577: atr=(atr&0x8f)|(uchar)BG_BROWN; ! 578: attr(atr); ! 579: break; ! 580: case '4': /* Blue Background */ ! 581: atr=(atr&0x8f)|(uchar)BG_BLUE; ! 582: attr(atr); ! 583: break; ! 584: case '5': /* Magenta Background */ ! 585: atr=(atr&0x8f)|(uchar)BG_MAGENTA; ! 586: attr(atr); ! 587: break; ! 588: case '6': /* Cyan Background */ ! 589: atr=(atr&0x8f)|(uchar)BG_CYAN; ! 590: attr(atr); ! 591: break; ! 592: case '7': /* White Background */ ! 593: atr=(atr&0x8f)|(uchar)BG_LIGHTGRAY; ! 594: attr(atr); ! 595: break; ! 596: } ! 597: } ! 598: ! 599: /***************************************************************************/ ! 600: /* Changes local and remote text attributes accounting for monochrome */ ! 601: /***************************************************************************/ ! 602: /****************************************************************************/ ! 603: /* Sends ansi codes to change remote ansi terminal's colors */ ! 604: /* Only sends necessary codes - tracks remote terminal's current attributes */ ! 605: /* through the 'curatr' variable */ ! 606: /****************************************************************************/ ! 607: void sbbs_t::attr(int atr) ! 608: { ! 609: char str[16]; ! 610: ! 611: if(!term_supports(ANSI)) ! 612: return; ! 613: if(!term_supports(COLOR)) { /* eliminate colors if user doesn't have them */ ! 614: if(atr&LIGHTGRAY) /* if any foreground bits set, set all */ ! 615: atr|=LIGHTGRAY; ! 616: if(atr&BG_LIGHTGRAY) /* if any background bits set, set all */ ! 617: atr|=BG_LIGHTGRAY; ! 618: if(atr&LIGHTGRAY && atr&BG_LIGHTGRAY) ! 619: atr&=~LIGHTGRAY; /* if background is solid, foreground is black */ ! 620: if(!atr) ! 621: atr|=LIGHTGRAY; /* don't allow black on black */ ! 622: } ! 623: if(curatr==atr) /* text hasn't changed. don't send codes */ ! 624: return; ! 625: ! 626: #if 1 ! 627: strcpy(str,"\033["); ! 628: if((!(atr&HIGH) && curatr&HIGH) || (!(atr&BLINK) && curatr&BLINK) ! 629: || atr==LIGHTGRAY) { ! 630: strcat(str,"0;"); ! 631: curatr=LIGHTGRAY; ! 632: } ! 633: if(atr&BLINK) { /* special attributes */ ! 634: if(!(curatr&BLINK)) ! 635: strcat(str,"5;"); ! 636: } ! 637: if(atr&HIGH) { ! 638: if(!(curatr&HIGH)) ! 639: strcat(str,"1;"); ! 640: } ! 641: if((atr&0x07) != (curatr&0x07)) { ! 642: switch(atr&0x07) { ! 643: case BLACK: ! 644: strcat(str,"30;"); ! 645: break; ! 646: case RED: ! 647: strcat(str,"31;"); ! 648: break; ! 649: case GREEN: ! 650: strcat(str,"32;"); ! 651: break; ! 652: case BROWN: ! 653: strcat(str,"33;"); ! 654: break; ! 655: case BLUE: ! 656: strcat(str,"34;"); ! 657: break; ! 658: case MAGENTA: ! 659: strcat(str,"35;"); ! 660: break; ! 661: case CYAN: ! 662: strcat(str,"36;"); ! 663: break; ! 664: case LIGHTGRAY: ! 665: strcat(str,"37;"); ! 666: break; ! 667: } ! 668: } ! 669: if((atr&0x70) != (curatr&0x70)) { ! 670: switch(atr&0x70) { ! 671: /* The BG_BLACK macro is 0x200, so isn't in the mask */ ! 672: case 0 /* BG_BLACK */: ! 673: strcat(str,"40;"); ! 674: break; ! 675: case BG_RED: ! 676: strcat(str,"41;"); ! 677: break; ! 678: case BG_GREEN: ! 679: strcat(str,"42;"); ! 680: break; ! 681: case BG_BROWN: ! 682: strcat(str,"43;"); ! 683: break; ! 684: case BG_BLUE: ! 685: strcat(str,"44;"); ! 686: break; ! 687: case BG_MAGENTA: ! 688: strcat(str,"45;"); ! 689: break; ! 690: case BG_CYAN: ! 691: strcat(str,"46;"); ! 692: break; ! 693: case BG_LIGHTGRAY: ! 694: strcat(str,"47;"); ! 695: break; ! 696: } ! 697: } ! 698: if(strlen(str)==2) ! 699: return; ! 700: str[strlen(str)-1]='m'; ! 701: rputs(str); ! 702: #else ! 703: if((!(atr&HIGH) && curatr&HIGH) || (!(atr&BLINK) && curatr&BLINK) ! 704: || atr==LIGHTGRAY) { ! 705: rputs(ansi(ANSI_NORMAL)); ! 706: curatr=LIGHTGRAY; ! 707: } ! 708: ! 709: if(atr==LIGHTGRAY) /* no attributes */ ! 710: return; ! 711: ! 712: if(atr&BLINK) { /* special attributes */ ! 713: if(!(curatr&BLINK)) ! 714: rputs(ansi(BLINK)); ! 715: } ! 716: if(atr&HIGH) { ! 717: if(!(curatr&HIGH)) ! 718: rputs(ansi(HIGH)); ! 719: } ! 720: ! 721: if((atr&0x7)==BLACK) { /* foreground colors */ ! 722: if((curatr&0x7)!=BLACK) ! 723: rputs(ansi(BLACK)); ! 724: } ! 725: else if((atr&0x7)==RED) { ! 726: if((curatr&0x7)!=RED) ! 727: rputs(ansi(RED)); ! 728: } ! 729: else if((atr&0x7)==GREEN) { ! 730: if((curatr&0x7)!=GREEN) ! 731: rputs(ansi(GREEN)); ! 732: } ! 733: else if((atr&0x7)==BROWN) { ! 734: if((curatr&0x7)!=BROWN) ! 735: rputs(ansi(BROWN)); ! 736: } ! 737: else if((atr&0x7)==BLUE) { ! 738: if((curatr&0x7)!=BLUE) ! 739: rputs(ansi(BLUE)); ! 740: } ! 741: else if((atr&0x7)==MAGENTA) { ! 742: if((curatr&0x7)!=MAGENTA) ! 743: rputs(ansi(MAGENTA)); ! 744: } ! 745: else if((atr&0x7)==CYAN) { ! 746: if((curatr&0x7)!=CYAN) ! 747: rputs(ansi(CYAN)); ! 748: } ! 749: else if((atr&0x7)==LIGHTGRAY) { ! 750: if((curatr&0x7)!=LIGHTGRAY) ! 751: rputs(ansi(LIGHTGRAY)); ! 752: } ! 753: ! 754: if((atr&0x70)==0) { /* background colors */ ! 755: if((curatr&0x70)!=0) ! 756: rputs(ansi(BG_BLACK)); ! 757: } ! 758: else if((atr&0x70)==BG_RED) { ! 759: if((curatr&0x70)!=BG_RED) ! 760: rputs(ansi(BG_RED)); ! 761: } ! 762: else if((atr&0x70)==BG_GREEN) { ! 763: if((curatr&0x70)!=BG_GREEN) ! 764: rputs(ansi(BG_GREEN)); ! 765: } ! 766: else if((atr&0x70)==BG_BROWN) { ! 767: if((curatr&0x70)!=BG_BROWN) ! 768: rputs(ansi(BG_BROWN)); ! 769: } ! 770: else if((atr&0x70)==BG_BLUE) { ! 771: if((curatr&0x70)!=BG_BLUE) ! 772: rputs(ansi(BG_BLUE)); ! 773: } ! 774: else if((atr&0x70)==BG_MAGENTA) { ! 775: if((curatr&0x70)!=BG_MAGENTA) ! 776: rputs(ansi(BG_MAGENTA)); ! 777: } ! 778: else if((atr&0x70)==BG_CYAN) { ! 779: if((curatr&0x70)!=BG_CYAN) ! 780: rputs(ansi(BG_CYAN)); ! 781: } ! 782: else if((atr&0x70)==BG_LIGHTGRAY) { ! 783: if((curatr&0x70)!=BG_LIGHTGRAY) ! 784: rputs(ansi(BG_LIGHTGRAY)); ! 785: } ! 786: #endif ! 787: ! 788: curatr=atr; ! 789: } ! 790: ! 791: /****************************************************************************/ ! 792: /* Checks to see if user has hit Pause or Abort. Returns 1 if user aborted. */ ! 793: /* If the user hit Pause, waits for a key to be hit. */ ! 794: /* Emulates remote XON/XOFF flow control on local console */ ! 795: /* Preserves SS_ABORT flag state, if already set. */ ! 796: /* Called from various listing procedures that wish to check for abort */ ! 797: /****************************************************************************/ ! 798: bool sbbs_t::msgabort() ! 799: { ! 800: static ulong counter; ! 801: ! 802: if(sys_status&SS_SYSPAGE && !(++counter%100)) ! 803: sbbs_beep(sbbs_random(800),1); ! 804: ! 805: checkline(); ! 806: if(sys_status&SS_ABORT) ! 807: return(true); ! 808: if(!online) ! 809: return(true); ! 810: return(false); ! 811: } ! 812: ! 813:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.