|
|
1.1 ! root 1: #line 1 "CON_OUT.C" ! 2: ! 3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ ! 4: ! 5: /**********************************************************************/ ! 6: /* Functions that pertain to console i/o - color, strings, chars etc. */ ! 7: /* Called from functions everywhere */ ! 8: /**********************************************************************/ ! 9: ! 10: #include "sbbs.h" ! 11: ! 12: extern char *mnestr; ! 13: ! 14: /***************************************************/ ! 15: /* Seven bit table for EXASCII to ASCII conversion */ ! 16: /***************************************************/ ! 17: char *sbtbl="CUeaaaaceeeiiiAAEaAooouuyOUcLYRfaiounNao?--24!<>" ! 18: "###||||++||++++++--|-+||++--|-+----++++++++##[]#" ! 19: "abrpEout*ono%0ENE+><rj%=o..+n2* "; ! 20: ! 21: char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; ! 22: char *mon[]={"Jan","Feb","Mar","Apr","May","Jun" ! 23: ,"Jul","Aug","Sep","Oct","Nov","Dec"}; ! 24: ! 25: uchar outchar_esc=0; ! 26: ! 27: #ifdef __WIN32__ ! 28: ! 29: int lclatr(int atr) ! 30: { ! 31: ! 32: textattr(atr); ! 33: return(curatr); ! 34: } ! 35: ! 36: void lputc(ch) ! 37: { ! 38: switch(ch) { ! 39: case CLREOL: ! 40: clreol(); ! 41: break; ! 42: case FF: ! 43: clrscr(); ! 44: break; ! 45: case TAB: ! 46: if(!(wherex()%8)) ! 47: putchar(SP); ! 48: while(wherex()%8) ! 49: putchar(SP); ! 50: break; ! 51: default: ! 52: putchar(ch); ! 53: break; } ! 54: } ! 55: ! 56: #endif ! 57: ! 58: #ifdef __OS2__ ! 59: ! 60: HEV con_out_sem; /* Console command semaphore */ ! 61: ! 62: #define CON_OUT_BUFLEN 8192 /* Console output (ANSI) buffer */ ! 63: #define CON_BLK_BUFLEN 4096 /* Console block (all same atr) buffer */ ! 64: ! 65: uchar conoutbuf[CON_OUT_BUFLEN]; ! 66: uchar conblkbuf[CON_BLK_BUFLEN]; ! 67: volatile uint conblkcnt=0; ! 68: volatile uint conoutbot=0; ! 69: volatile uint conouttop=0; ! 70: ! 71: uchar lcl_curatr=LIGHTGRAY; ! 72: ! 73: /****************************************************************************/ ! 74: /* Prints one block of text (all same attribute) at current cursor position */ ! 75: /****************************************************************************/ ! 76: void print_conblkbuf() ! 77: { ! 78: conblkbuf[conblkcnt]=0; ! 79: cputs(conblkbuf); ! 80: conblkcnt=0; ! 81: } ! 82: ! 83: void con_outch(int ch) ! 84: { ! 85: static uchar ansi_esc; ! 86: static uchar ansi_curval; ! 87: static uchar ansi_val[3]; ! 88: static uchar ansi_x; ! 89: static uchar ansi_y; ! 90: int x,y; ! 91: ! 92: if(ch==ESC) { ! 93: ansi_esc=1; ! 94: ansi_val[0]=ansi_val[1]=ansi_val[2]=ansi_curval=0; ! 95: return; } ! 96: ! 97: if(ansi_esc==1) { /* Received ESC already */ ! 98: if(ch=='[') { ! 99: ansi_esc++; ! 100: return; } ! 101: ansi_esc=ansi_val[0]=ansi_val[1]=ansi_val[2]=ansi_curval=0; } ! 102: ! 103: if(ansi_esc==2) { /* Received ESC[ already */ ! 104: ! 105: if(isdigit(ch)) { ! 106: if(ansi_curval>2) ansi_curval=0; ! 107: ansi_val[ansi_curval]*=10; ! 108: ansi_val[ansi_curval]+=ch&0xf; ! 109: return; } ! 110: ! 111: if(ch==';') { ! 112: ansi_curval++; ! 113: return; } ! 114: ! 115: /* looks like valid ANSI, so purge the output block */ ! 116: if(conblkcnt) ! 117: print_conblkbuf(); ! 118: switch(ch) { ! 119: case 'A': // Move cursor up ! 120: y=wherey(); ! 121: if(ansi_val[0]) ! 122: y-=ansi_val[0]; ! 123: else ! 124: y--; ! 125: if(y<1) y=1; ! 126: gotoxy(wherex(),y); ! 127: break; ! 128: case 'B': // Move cursor down ! 129: y=wherey(); ! 130: if(ansi_val[0]) ! 131: y+=ansi_val[0]; ! 132: else ! 133: y++; ! 134: if(y>node_scrnlen) y=node_scrnlen; ! 135: gotoxy(wherex(),y); ! 136: break; ! 137: case 'C': // Move cursor right ! 138: x=wherex(); ! 139: if(ansi_val[0]) ! 140: x+=ansi_val[0]; ! 141: else ! 142: x++; ! 143: if(x>80) x=80; ! 144: gotoxy(x,wherey()); ! 145: break; ! 146: case 'D': // Move cursor left ! 147: x=wherex(); ! 148: if(ansi_val[0]) ! 149: x-=ansi_val[0]; ! 150: else ! 151: x--; ! 152: if(x<1) x=1; ! 153: gotoxy(x,wherey()); ! 154: break; ! 155: case 'J': // clear screen ! 156: if(ansi_val[0]==2) ! 157: clrscr(); ! 158: break; ! 159: case 'K': // clearn from cursor to end of line ! 160: clreol(); ! 161: break; ! 162: case 'H': // Position cursor ! 163: case 'f': ! 164: y=ansi_val[0]; ! 165: x=ansi_val[1]; ! 166: if(x<1) x=1; ! 167: if(x>80) x=80; ! 168: if(y<1) y=1; ! 169: if(y>node_scrnlen) y=node_scrnlen; ! 170: gotoxy(x,y); ! 171: break; ! 172: case 's': // Save cursor position ! 173: ansi_x=wherex(); ! 174: ansi_y=wherey(); ! 175: break; ! 176: case 'u': // Restore cursor position ! 177: if(ansi_x) ! 178: gotoxy(ansi_x,ansi_y); ! 179: break; ! 180: case 'm': // Select character attributes ! 181: for(x=0;x<=ansi_curval;x++) ! 182: switch(ansi_val[x]) { ! 183: case 0: // no special attributes ! 184: case 8: // concealed text (no display) ! 185: lcl_curatr=LIGHTGRAY; ! 186: break; ! 187: case 1: // high intensity ! 188: case 3: // italic ! 189: case 4: // underline ! 190: lcl_curatr|=HIGH; ! 191: break; ! 192: case 2: // low intensity ! 193: lcl_curatr&=~HIGH; ! 194: break; ! 195: case 5: // blink ! 196: case 6: // rapid blink ! 197: case 7: // reverse video ! 198: lcl_curatr|=BLINK; ! 199: break; ! 200: case 30: // foreground black ! 201: lcl_curatr&=0xf8; ! 202: lcl_curatr|=BLACK; ! 203: break; ! 204: case 31: // foreground red ! 205: lcl_curatr&=0xf8; ! 206: lcl_curatr|=RED; ! 207: break; ! 208: case 32: // foreground green ! 209: lcl_curatr&=0xf8; ! 210: lcl_curatr|=GREEN; ! 211: break; ! 212: case 33: // foreground yellow ! 213: lcl_curatr&=0xf8; ! 214: lcl_curatr|=BROWN; ! 215: break; ! 216: case 34: // foreground blue ! 217: lcl_curatr&=0xf8; ! 218: lcl_curatr|=BLUE; ! 219: break; ! 220: case 35: // foreground magenta ! 221: lcl_curatr&=0xf8; ! 222: lcl_curatr|=MAGENTA; ! 223: break; ! 224: case 36: // foreground cyan ! 225: lcl_curatr&=0xf8; ! 226: lcl_curatr|=CYAN; ! 227: break; ! 228: case 37: // foreground white ! 229: lcl_curatr&=0xf8; ! 230: lcl_curatr|=LIGHTGRAY; ! 231: break; ! 232: case 40: // background black ! 233: lcl_curatr&=0x8f; ! 234: lcl_curatr|=(BLACK<<4); ! 235: break; ! 236: case 41: // background red ! 237: lcl_curatr&=0x8f; ! 238: lcl_curatr|=(RED<<4); ! 239: break; ! 240: case 42: // background green ! 241: lcl_curatr&=0x8f; ! 242: lcl_curatr|=(GREEN<<4); ! 243: break; ! 244: case 43: // background yellow ! 245: lcl_curatr&=0x8f; ! 246: lcl_curatr|=(BROWN<<4); ! 247: break; ! 248: case 44: // background blue ! 249: lcl_curatr&=0x8f; ! 250: lcl_curatr|=(BLUE<<4); ! 251: break; ! 252: case 45: // background magenta ! 253: lcl_curatr&=0x8f; ! 254: lcl_curatr|=(MAGENTA<<4); ! 255: break; ! 256: case 46: // background cyan ! 257: lcl_curatr&=0x8f; ! 258: lcl_curatr|=(CYAN<<4); ! 259: break; ! 260: case 47: // background white ! 261: lcl_curatr&=0x8f; ! 262: lcl_curatr|=(LIGHTGRAY<<4); ! 263: break; } ! 264: textattr(lcl_curatr); ! 265: break; } ! 266: ! 267: ansi_esc=ansi_val[0]=ansi_val[1]=ansi_val[2]=ansi_curval=0; ! 268: return; } ! 269: ! 270: if(conblkcnt+1>=CON_BLK_BUFLEN) ! 271: print_conblkbuf(); ! 272: switch(ch) { ! 273: case CLREOL: ! 274: if(conblkcnt) print_conblkbuf(); ! 275: clreol(); ! 276: break; ! 277: case FF: ! 278: if(conblkcnt) print_conblkbuf(); ! 279: clrscr(); ! 280: break; ! 281: case TAB: ! 282: if(conblkcnt) print_conblkbuf(); ! 283: if(!(wherex()%8)) ! 284: putch(SP); ! 285: while(wherex()%8) ! 286: putch(SP); ! 287: break; ! 288: default: ! 289: conblkbuf[conblkcnt++]=ch; ! 290: break; } ! 291: } ! 292: ! 293: ! 294: /****************************************************************************/ ! 295: /* Thread that services the console output buffer (conoutbuf) which */ ! 296: /* contains ANSI escape sequences */ ! 297: /* All output is for the text window (mirroring the remote console) */ ! 298: /****************************************************************************/ ! 299: void con_out_thread(void *unused) ! 300: { ! 301: int i,top,cnt; ! 302: ulong l; ! 303: ! 304: while(1) { ! 305: mswait(1); ! 306: if(conoutbot==conouttop) { ! 307: DosWaitEventSem(con_out_sem,10000); /* every 10 seconds */ ! 308: DosResetEventSem(con_out_sem,&l); ! 309: continue; } ! 310: top=conouttop; ! 311: if(top<conoutbot) ! 312: cnt=CON_OUT_BUFLEN-conoutbot; ! 313: else ! 314: cnt=top-conoutbot; ! 315: for(i=conoutbot;i<conoutbot+cnt;i++) ! 316: con_outch(conoutbuf[i]); ! 317: conoutbot=i; ! 318: if(conblkcnt) ! 319: print_conblkbuf(); ! 320: if(conoutbot==CON_OUT_BUFLEN) ! 321: conoutbot=0; } ! 322: } ! 323: ! 324: ! 325: ! 326: void outcon(char ch) ! 327: { ! 328: int i=conouttop+1; ! 329: ! 330: if(i==CON_OUT_BUFLEN) ! 331: i=0; ! 332: while(conoutbot==i) // Wait for thread to service queue ! 333: mswait(1); ! 334: conoutbuf[conouttop++]=ch; ! 335: if(conouttop==CON_OUT_BUFLEN) ! 336: conouttop=0; ! 337: DosPostEventSem(con_out_sem); // Enable output ! 338: } ! 339: ! 340: int outcon_pending() ! 341: { ! 342: if(conoutbot!=conouttop) ! 343: return(1); ! 344: if(conblkcnt) { ! 345: print_conblkbuf(); ! 346: return(1); } ! 347: return(0); ! 348: } ! 349: ! 350: int conaes() ! 351: { ! 352: return(outchar_esc==2); ! 353: } ! 354: ! 355: void lputc(int ch) ! 356: { ! 357: ! 358: while(outcon_pending()) ! 359: mswait(1); ! 360: switch(ch) { ! 361: case CLREOL: ! 362: clreol(); ! 363: break; ! 364: case FF: ! 365: clrscr(); ! 366: break; ! 367: case TAB: ! 368: if(!(wherex()%8)) ! 369: putch(SP); ! 370: while(wherex()%8) ! 371: putch(SP); ! 372: break; ! 373: default: ! 374: putch(ch); ! 375: break; } ! 376: } ! 377: ! 378: long lputs(char *str) ! 379: { ! 380: while(outcon_pending()) ! 381: mswait(1); ! 382: return(cputs(str)); ! 383: } ! 384: ! 385: int lclwx(void) ! 386: { ! 387: while(outcon_pending()) ! 388: mswait(1); ! 389: return(wherex()); ! 390: } ! 391: ! 392: int lclwy(void) ! 393: { ! 394: while(outcon_pending()) ! 395: mswait(1); ! 396: return(wherey()); ! 397: } ! 398: ! 399: void lclxy(int x, int y) ! 400: { ! 401: while(outcon_pending()) ! 402: mswait(1); ! 403: gotoxy(x,y); ! 404: } ! 405: ! 406: int lclatr(int x) ! 407: { ! 408: int i; ! 409: ! 410: while(conoutbot!=conouttop) /* wait for output buf to empty */ ! 411: mswait(1); ! 412: if(x==-1) ! 413: return(lcl_curatr); ! 414: ! 415: textattr(x); ! 416: i=lcl_curatr; ! 417: lcl_curatr=x; ! 418: return(i); /* Return previous attribute */ ! 419: } ! 420: ! 421: #endif ! 422: ! 423: /****************************************************************************/ ! 424: /* Outputs a NULL terminated string locally and remotely (if applicable) */ ! 425: /* Handles ctrl-a characters */ ! 426: /****************************************************************************/ ! 427: int bputs(char *str) ! 428: { ! 429: int i; ! 430: ulong l=0; ! 431: ! 432: while(str[l]) { ! 433: if(str[l]==1) { /* ctrl-a */ ! 434: ctrl_a(str[++l]); /* skip the ctrl-a */ ! 435: l++; /* skip the attribute code */ ! 436: continue; } ! 437: if(str[l]=='@') { /* '@' */ ! 438: if(str==mnestr /* Mnemonic string or */ ! 439: || (str>=text[0] /* Straight out of TEXT.DAT */ ! 440: && str<=text[TOTAL_TEXT-1])) { ! 441: i=atcodes(str+l); /* return 0 if not valid @ code */ ! 442: l+=i; /* i is length of code string */ ! 443: if(i) /* if valid string, go to top */ ! 444: continue; } ! 445: for(i=0;i<TOTAL_TEXT;i++) ! 446: if(str==text[i]) ! 447: break; ! 448: if(i<TOTAL_TEXT) { /* Replacement text */ ! 449: //lputc(7); ! 450: i=atcodes(str+l); ! 451: l+=i; ! 452: if(i) ! 453: continue; } } ! 454: outchar(str[l++]); } ! 455: return(l); ! 456: } ! 457: ! 458: /****************************************************************************/ ! 459: /* Outputs a NULL terminated string locally and remotely (if applicable) */ ! 460: /* Does not expand ctrl-a characters (raw) */ ! 461: /* Max length of str is 64 kbytes */ ! 462: /****************************************************************************/ ! 463: int rputs(char *str) ! 464: { ! 465: ulong l=0; ! 466: ! 467: while(str[l]) ! 468: outchar(str[l++]); ! 469: return(l); ! 470: } ! 471: ! 472: /****************************************************************************/ ! 473: /* Performs printf() through local assembly routines */ ! 474: /* Called from everywhere */ ! 475: /****************************************************************************/ ! 476: int lprintf(char *fmat, ...) ! 477: { ! 478: va_list argptr; ! 479: char sbuf[256]; ! 480: int chcount; ! 481: ! 482: va_start(argptr,fmat); ! 483: chcount=vsprintf(sbuf,fmat,argptr); ! 484: va_end(argptr); ! 485: lputs(sbuf); ! 486: return(chcount); ! 487: } ! 488: ! 489: /****************************************************************************/ ! 490: /* Performs printf() using bbs bputs function */ ! 491: /****************************************************************************/ ! 492: int bprintf(char *fmt, ...) ! 493: { ! 494: va_list argptr; ! 495: char sbuf[1024]; ! 496: ! 497: if(!strchr(fmt,'%')) ! 498: return(bputs(fmt)); ! 499: va_start(argptr,fmt); ! 500: vsprintf(sbuf,fmt,argptr); ! 501: va_end(argptr); ! 502: return(bputs(sbuf)); ! 503: } ! 504: ! 505: /****************************************************************************/ ! 506: /* Performs printf() using bbs rputs function */ ! 507: /****************************************************************************/ ! 508: int rprintf(char *fmt, ...) ! 509: { ! 510: va_list argptr; ! 511: char sbuf[1024]; ! 512: ! 513: va_start(argptr,fmt); ! 514: vsprintf(sbuf,fmt,argptr); ! 515: va_end(argptr); ! 516: return(rputs(sbuf)); ! 517: } ! 518: ! 519: /****************************************************************************/ ! 520: /* Outputs character locally and remotely (if applicable), preforming echo */ ! 521: /* translations (X's and r0dent emulation) if applicable. */ ! 522: /****************************************************************************/ ! 523: void outchar(char ch) ! 524: { ! 525: char lch; ! 526: int i; ! 527: ! 528: if(console&CON_ECHO_OFF) ! 529: return; ! 530: if(ch==ESC) ! 531: outchar_esc=1; ! 532: else if(outchar_esc==1) { ! 533: if(ch=='[') ! 534: outchar_esc++; ! 535: else ! 536: outchar_esc=0; } ! 537: else ! 538: outchar_esc=0; ! 539: if(useron.misc&NO_EXASCII && ch&0x80) ! 540: ch=sbtbl[(uchar)ch^0x80]; /* seven bit table */ ! 541: if(ch==FF && lncntr>1 && !tos) { ! 542: lncntr=0; ! 543: CRLF; ! 544: pause(); ! 545: while(lncntr && online && !(sys_status&SS_ABORT)) ! 546: pause(); } ! 547: if(sys_status&SS_CAP /* Writes to Capture File */ ! 548: && (sys_status&SS_ANSCAP || (ch!=ESC && !lclaes()))) ! 549: fwrite(&ch,1,1,capfile); ! 550: if(console&CON_L_ECHO) { ! 551: if(console&CON_L_ECHOX && (uchar)ch>=SP) ! 552: outcon('X'); ! 553: else if(node_misc&NM_NOBEEP && ch==7); /* Do nothing if beep */ ! 554: else if(ch==7) { ! 555: beep(2000,110); ! 556: nosound(); } ! 557: else outcon(ch); } ! 558: if(online==ON_REMOTE && console&CON_R_ECHO) { ! 559: if(console&CON_R_ECHOX && (uchar)ch>=SP) ! 560: ch='X'; ! 561: i=0; ! 562: while(outcom(ch)&TXBOF && i<1440) { /* 3 minute pause delay */ ! 563: ! 564: if(lkbrd(1)) { ! 565: lch=lkbrd(0); /* ctrl-c */ ! 566: if(lch==3) { ! 567: lputs("local abort (outchar)\r\n"); ! 568: i=1440; ! 569: break; } ! 570: ungetkey(lch); } ! 571: if(!DCDHIGH) ! 572: break; ! 573: i++; ! 574: if(sys_status&SS_SYSPAGE) ! 575: beep(i,80); ! 576: else ! 577: mswait(80); } ! 578: if(i==1440) { /* timeout - beep flush outbuf */ ! 579: i=rioctl(TXBC); ! 580: lprintf("timeout(outchar) %04X %04X\r\n",i,rioctl(IOFO)); ! 581: outcom(7); ! 582: lputc(7); ! 583: rioctl(IOCS|PAUSE); } } ! 584: if(ch==LF) { ! 585: lncntr++; ! 586: lbuflen=0; ! 587: tos=0; } ! 588: else if(ch==FF) { ! 589: lncntr=0; ! 590: lbuflen=0; ! 591: tos=1; } ! 592: ! 593: else { ! 594: if(!lbuflen) ! 595: latr=curatr; ! 596: if(lbuflen<LINE_BUFSIZE) ! 597: lbuf[lbuflen++]=ch; } ! 598: ! 599: if(lncntr==rows-1 && ((useron.misc&UPAUSE && !(sys_status&SS_PAUSEOFF)) ! 600: || sys_status&SS_PAUSEON)) { ! 601: lncntr=0; ! 602: pause(); } ! 603: ! 604: } ! 605: ! 606: ! 607: /****************************************************************************/ ! 608: /* performs the correct attribute modifications for the Ctrl-A code */ ! 609: /****************************************************************************/ ! 610: void ctrl_a(char x) ! 611: { ! 612: int i,j; ! 613: char tmp1[128],atr=curatr; ! 614: ! 615: if(x && (uchar)x<ESC) { /* Ctrl-A through Ctrl-Z for users with MF only */ ! 616: if(!(useron.flags1&FLAG(x+64))) ! 617: console^=(CON_ECHO_OFF); ! 618: return; } ! 619: if((uchar)x>=0x7f) { ! 620: if(useron.misc&ANSI) ! 621: bprintf("\x1b[%uC",(uchar)x-0x7f); ! 622: else ! 623: for(i=0;i<(uchar)x-0x7f;i++) ! 624: outchar(SP); ! 625: return; } ! 626: switch(toupper(x)) { ! 627: case '!': /* level 10 or higher */ ! 628: if(useron.level<10) ! 629: console^=CON_ECHO_OFF; ! 630: break; ! 631: case '@': /* level 20 or higher */ ! 632: if(useron.level<20) ! 633: console^=CON_ECHO_OFF; ! 634: break; ! 635: case '#': /* level 30 or higher */ ! 636: if(useron.level<30) ! 637: console^=CON_ECHO_OFF; ! 638: break; ! 639: case '$': /* level 40 or higher */ ! 640: if(useron.level<40) ! 641: console^=CON_ECHO_OFF; ! 642: break; ! 643: case '%': /* level 50 or higher */ ! 644: if(useron.level<50) ! 645: console^=CON_ECHO_OFF; ! 646: break; ! 647: case '^': /* level 60 or higher */ ! 648: if(useron.level<60) ! 649: console^=CON_ECHO_OFF; ! 650: break; ! 651: case '&': /* level 70 or higher */ ! 652: if(useron.level<70) ! 653: console^=CON_ECHO_OFF; ! 654: break; ! 655: case '*': /* level 80 or higher */ ! 656: if(useron.level<80) ! 657: console^=CON_ECHO_OFF; ! 658: break; ! 659: case '(': /* level 90 or higher */ ! 660: if(useron.level<90) ! 661: console^=CON_ECHO_OFF; ! 662: break; ! 663: case ')': /* turn echo back on */ ! 664: console&=~CON_ECHO_OFF; ! 665: break; ! 666: case '-': /* turn off all attributes if */ ! 667: if(atr&(HIGH|BLINK|(LIGHTGRAY<<4))) /* high intensity, blink or */ ! 668: attr(LIGHTGRAY); /* background bits are set */ ! 669: break; ! 670: case '_': /* turn off all attributes if */ ! 671: if(atr&(BLINK|(LIGHTGRAY<<4))) /* blink or background is set */ ! 672: attr(LIGHTGRAY); ! 673: break; ! 674: case 'P': /* Pause */ ! 675: pause(); ! 676: break; ! 677: case 'Q': /* Pause reset */ ! 678: lncntr=0; ! 679: break; ! 680: case 'T': /* Time */ ! 681: now=time(NULL); ! 682: unixtodos(now,&date,&curtime); ! 683: bprintf("%02d:%02d %s" ! 684: ,curtime.ti_hour==0 ? 12 ! 685: : curtime.ti_hour>12 ? curtime.ti_hour-12 ! 686: : curtime.ti_hour, curtime.ti_min, curtime.ti_hour>11 ? "pm":"am"); ! 687: break; ! 688: case 'D': /* Date */ ! 689: now=time(NULL); ! 690: bputs(unixtodstr(now,tmp1)); ! 691: break; ! 692: case ',': /* Delay 1/10 sec */ ! 693: mswait(100); ! 694: break; ! 695: case ';': /* Delay 1/2 sec */ ! 696: mswait(500); ! 697: break; ! 698: case '.': /* Delay 2 secs */ ! 699: mswait(2000); ! 700: break; ! 701: case 'S': /* Synchronize */ ! 702: ASYNC; ! 703: break; ! 704: case 'L': /* CLS (form feed) */ ! 705: CLS; ! 706: break; ! 707: case '>': /* CLREOL */ ! 708: if(useron.misc&ANSI) ! 709: bputs("\x1b[K"); ! 710: else { ! 711: i=j=lclwx(); ! 712: while(i++<79) ! 713: outchar(SP); ! 714: while(j++<79) ! 715: outchar(BS); } ! 716: break; ! 717: case '<': /* Non-destructive backspace */ ! 718: outchar(BS); ! 719: break; ! 720: case '[': /* Carriage return */ ! 721: outchar(CR); ! 722: break; ! 723: case ']': /* Line feed */ ! 724: outchar(LF); ! 725: break; ! 726: case 'A': /* Ctrl-A */ ! 727: outchar(1); ! 728: break; ! 729: case 'H': /* High intensity */ ! 730: atr|=HIGH; ! 731: attr(atr); ! 732: break; ! 733: case 'I': /* Blink */ ! 734: atr|=BLINK; ! 735: attr(atr); ! 736: break; ! 737: case 'N': /* Normal */ ! 738: attr(LIGHTGRAY); ! 739: break; ! 740: case 'R': ! 741: atr=(atr&0xf8)|RED; ! 742: attr(atr); ! 743: break; ! 744: case 'G': ! 745: atr=(atr&0xf8)|GREEN; ! 746: attr(atr); ! 747: break; ! 748: case 'B': ! 749: atr=(atr&0xf8)|BLUE; ! 750: attr(atr); ! 751: break; ! 752: case 'W': /* White */ ! 753: atr=(atr&0xf8)|LIGHTGRAY; ! 754: attr(atr); ! 755: break; ! 756: case 'C': ! 757: atr=(atr&0xf8)|CYAN; ! 758: attr(atr); ! 759: break; ! 760: case 'M': ! 761: atr=(atr&0xf8)|MAGENTA; ! 762: attr(atr); ! 763: break; ! 764: case 'Y': /* Yellow */ ! 765: atr=(atr&0xf8)|BROWN; ! 766: attr(atr); ! 767: break; ! 768: case 'K': /* Black */ ! 769: atr=(atr&0xf8)|BLACK; ! 770: attr(atr); ! 771: break; ! 772: case '0': /* Black Background */ ! 773: atr=(atr&0x8f)|(BLACK<<4); ! 774: attr(atr); ! 775: break; ! 776: case '1': /* Red Background */ ! 777: atr=(atr&0x8f)|(RED<<4); ! 778: attr(atr); ! 779: break; ! 780: case '2': /* Green Background */ ! 781: atr=(atr&0x8f)|(GREEN<<4); ! 782: attr(atr); ! 783: break; ! 784: case '3': /* Yellow Background */ ! 785: atr=(atr&0x8f)|(BROWN<<4); ! 786: attr(atr); ! 787: break; ! 788: case '4': /* Blue Background */ ! 789: atr=(atr&0x8f)|(BLUE<<4); ! 790: attr(atr); ! 791: break; ! 792: case '5': /* Magenta Background */ ! 793: atr=(atr&0x8f)|(MAGENTA<<4); ! 794: attr(atr); ! 795: break; ! 796: case '6': /* Cyan Background */ ! 797: atr=(atr&0x8f)|(CYAN<<4); ! 798: attr(atr); ! 799: break; ! 800: case '7': /* White Background */ ! 801: atr=(atr&0x8f)|(LIGHTGRAY<<4); ! 802: attr(atr); ! 803: break; } ! 804: } ! 805: ! 806: /***************************************************************************/ ! 807: /* Changes local and remote text attributes accounting for monochrome */ ! 808: /***************************************************************************/ ! 809: /****************************************************************************/ ! 810: /* Sends ansi codes to change remote ansi terminal's colors */ ! 811: /* Only sends necessary codes - tracks remote terminal's current attributes */ ! 812: /* through the 'curatr' variable */ ! 813: /****************************************************************************/ ! 814: void attr(int atr) ! 815: { ! 816: ! 817: if(!(useron.misc&ANSI)) ! 818: return; ! 819: if(!(useron.misc&COLOR)) { /* eliminate colors if user doesn't have them */ ! 820: if(atr&LIGHTGRAY) /* if any foreground bits set, set all */ ! 821: atr|=LIGHTGRAY; ! 822: if(atr&(LIGHTGRAY<<4)) /* if any background bits set, set all */ ! 823: atr|=(LIGHTGRAY<<4); ! 824: if(atr&LIGHTGRAY && atr&(LIGHTGRAY<<4)) ! 825: atr&=~LIGHTGRAY; /* if background is solid, foreground is black */ ! 826: if(!atr) ! 827: atr|=LIGHTGRAY; } /* don't allow black on black */ ! 828: if(curatr==atr) /* text hasn't changed. don't send codes */ ! 829: return; ! 830: ! 831: if((!(atr&HIGH) && curatr&HIGH) || (!(atr&BLINK) && curatr&BLINK) ! 832: || atr==LIGHTGRAY) { ! 833: bputs("\x1b[0m"); ! 834: curatr=LIGHTGRAY; } ! 835: ! 836: if(atr==LIGHTGRAY) /* no attributes */ ! 837: return; ! 838: ! 839: if(atr&BLINK) { /* special attributes */ ! 840: if(!(curatr&BLINK)) ! 841: bputs(ansi(BLINK)); } ! 842: if(atr&HIGH) { ! 843: if(!(curatr&HIGH)) ! 844: bputs(ansi(HIGH)); } ! 845: ! 846: if((atr&0x7)==BLACK) { /* foreground colors */ ! 847: if((curatr&0x7)!=BLACK) ! 848: bputs(ansi(BLACK)); } ! 849: else if((atr&0x7)==RED) { ! 850: if((curatr&0x7)!=RED) ! 851: bputs(ansi(RED)); } ! 852: else if((atr&0x7)==GREEN) { ! 853: if((curatr&0x7)!=GREEN) ! 854: bputs(ansi(GREEN)); } ! 855: else if((atr&0x7)==BROWN) { ! 856: if((curatr&0x7)!=BROWN) ! 857: bputs(ansi(BROWN)); } ! 858: else if((atr&0x7)==BLUE) { ! 859: if((curatr&0x7)!=BLUE) ! 860: bputs(ansi(BLUE)); } ! 861: else if((atr&0x7)==MAGENTA) { ! 862: if((curatr&0x7)!=MAGENTA) ! 863: bputs(ansi(MAGENTA)); } ! 864: else if((atr&0x7)==CYAN) { ! 865: if((curatr&0x7)!=CYAN) ! 866: bputs(ansi(CYAN)); } ! 867: else if((atr&0x7)==LIGHTGRAY) { ! 868: if((curatr&0x7)!=LIGHTGRAY) ! 869: bputs(ansi(LIGHTGRAY)); } ! 870: ! 871: if((atr&0x70)==(BLACK<<4)) { /* background colors */ ! 872: if((curatr&0x70)!=(BLACK<<4)) ! 873: bputs("\x1b[40m"); } ! 874: else if((atr&0x70)==(RED<<4)) { ! 875: if((curatr&0x70)!=(RED<<4)) ! 876: bputs(ansi(RED<<4)); } ! 877: else if((atr&0x70)==(GREEN<<4)) { ! 878: if((curatr&0x70)!=(GREEN<<4)) ! 879: bputs(ansi(GREEN<<4)); } ! 880: else if((atr&0x70)==(BROWN<<4)) { ! 881: if((curatr&0x70)!=(BROWN<<4)) ! 882: bputs(ansi(BROWN<<4)); } ! 883: else if((atr&0x70)==(BLUE<<4)) { ! 884: if((curatr&0x70)!=(BLUE<<4)) ! 885: bputs(ansi(BLUE<<4)); } ! 886: else if((atr&0x70)==(MAGENTA<<4)) { ! 887: if((curatr&0x70)!=(MAGENTA<<4)) ! 888: bputs(ansi(MAGENTA<<4)); } ! 889: else if((atr&0x70)==(CYAN<<4)) { ! 890: if((curatr&0x70)!=(CYAN<<4)) ! 891: bputs(ansi(CYAN<<4)); } ! 892: else if((atr&0x70)==(LIGHTGRAY<<4)) { ! 893: if((curatr&0x70)!=(LIGHTGRAY<<4)) ! 894: bputs(ansi(LIGHTGRAY<<4)); } ! 895: ! 896: curatr=atr; ! 897: } ! 898: ! 899: /****************************************************************************/ ! 900: /* Returns the ANSI code to obtain the value of atr. Mixed attributes */ ! 901: /* high intensity colors, or background/forground cobinations don't work. */ ! 902: /* A call to attr is more appropriate, being it is intelligent */ ! 903: /****************************************************************************/ ! 904: char *ansi(char atr) ! 905: { ! 906: ! 907: switch(atr) { ! 908: case (char)BLINK: ! 909: return("\x1b[5m"); ! 910: case HIGH: ! 911: return("\x1b[1m"); ! 912: case BLACK: ! 913: return("\x1b[30m"); ! 914: case RED: ! 915: return("\x1b[31m"); ! 916: case GREEN: ! 917: return("\x1b[32m"); ! 918: case BROWN: ! 919: return("\x1b[33m"); ! 920: case BLUE: ! 921: return("\x1b[34m"); ! 922: case MAGENTA: ! 923: return("\x1b[35m"); ! 924: case CYAN: ! 925: return("\x1b[36m"); ! 926: case LIGHTGRAY: ! 927: return("\x1b[37m"); ! 928: case (RED<<4): ! 929: return("\x1b[41m"); ! 930: case (GREEN<<4): ! 931: return("\x1b[42m"); ! 932: case (BROWN<<4): ! 933: return("\x1b[43m"); ! 934: case (BLUE<<4): ! 935: return("\x1b[44m"); ! 936: case (MAGENTA<<4): ! 937: return("\x1b[45m"); ! 938: case (CYAN<<4): ! 939: return("\x1b[46m"); ! 940: case (LIGHTGRAY<<4): ! 941: return("\x1b[47m"); } ! 942: ! 943: return("-Invalid use of ansi()-"); ! 944: } ! 945: ! 946: ! 947: /****************************************************************************/ ! 948: /* Checks to see if user has hit Pause or Abort. Returns 1 if user aborted. */ ! 949: /* If the user hit Pause, waits for a key to be hit. */ ! 950: /* Emulates remote XON/XOFF flow control on local console */ ! 951: /* Preserves SS_ABORT flag state, if already set. */ ! 952: /* Called from various listing procedures that wish to check for abort */ ! 953: /****************************************************************************/ ! 954: char msgabort() ! 955: { ! 956: char ch; ! 957: ! 958: if(sys_status&SS_SYSPAGE) ! 959: beep(random(800),1); ! 960: if(lkbrd(1)) { ! 961: ch=inkey(0); ! 962: if(sys_status&SS_ABORT) { /* ^c */ ! 963: keybufbot=keybuftop=0; ! 964: return(1); } ! 965: else if(ch==17 && online==ON_REMOTE) /* ^q */ ! 966: rioctl(IOCS|PAUSE); ! 967: else if(ch==19) /* ^s */ ! 968: while(online) { ! 969: if((ch=inkey(0))!=0) { ! 970: if(ch==17) /* ^q */ ! 971: return(0); ! 972: ungetkey(ch); } ! 973: if(sys_status&SS_ABORT) { /* ^c */ ! 974: keybufbot=keybuftop=0; ! 975: return(1); } ! 976: checkline(); } ! 977: else if(ch) ! 978: ungetkey(ch); } ! 979: checkline(); ! 980: if(sys_status&SS_ABORT) ! 981: return(1); ! 982: if(online==ON_REMOTE && rioctl(IOSTATE)&ABORT) { ! 983: rioctl(IOCS|ABORT); ! 984: sys_status|=SS_ABORT; ! 985: return(1); } ! 986: if(!online) ! 987: return(1); ! 988: return(0); ! 989: } ! 990: ! 991: ! 992: /****************************************************************************/ ! 993: /* Takes the value 'sec' and makes a string the format HH:MM:SS */ ! 994: /****************************************************************************/ ! 995: char *sectostr(uint sec,char *str) ! 996: { ! 997: uchar hour,min,sec2; ! 998: ! 999: hour=(sec/60)/60; ! 1000: min=(sec/60)-(hour*60); ! 1001: sec2=sec-((min+(hour*60))*60); ! 1002: sprintf(str,"%2.2d:%2.2d:%2.2d",hour,min,sec2); ! 1003: return(str); ! 1004: } ! 1005: ! 1006: ! 1007: /****************************************************************************/ ! 1008: /* Generates a 24 character ASCII string that represents the time_t pointer */ ! 1009: /* Used as a replacement for ctime() */ ! 1010: /****************************************************************************/ ! 1011: char *timestr(time_t *intime) ! 1012: { ! 1013: static char str[256]; ! 1014: char mer[3],hour; ! 1015: struct tm *gm; ! 1016: ! 1017: gm=localtime(intime); ! 1018: if(gm==NULL) { ! 1019: strcpy(str,"Invalid Time"); ! 1020: return(str); } ! 1021: if(sys_misc&SM_MILITARY) { ! 1022: sprintf(str,"%s %s %02d %4d %02d:%02d:%02d" ! 1023: ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year ! 1024: ,gm->tm_hour,gm->tm_min,gm->tm_sec); ! 1025: return(str); } ! 1026: if(gm->tm_hour>=12) { ! 1027: if(gm->tm_hour==12) ! 1028: hour=12; ! 1029: else ! 1030: hour=gm->tm_hour-12; ! 1031: strcpy(mer,"pm"); } ! 1032: else { ! 1033: if(gm->tm_hour==0) ! 1034: hour=12; ! 1035: else ! 1036: hour=gm->tm_hour; ! 1037: strcpy(mer,"am"); } ! 1038: sprintf(str,"%s %s %02d %4d %02d:%02d %s" ! 1039: ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year ! 1040: ,hour,gm->tm_min,mer); ! 1041: return(str); ! 1042: } ! 1043:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.