|
|
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.