Annotation of sbbs/sbbs2/con_out.c, revision 1.1.1.2

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) {
1.1.1.2 ! root      305:        /* mswait(1);   Removed 12/99 via Enigma */
1.1       root      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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.